A question about virtual class methods' inheritance in Oxygene

Consider the classes:

type
  BasicClass = public class
  public
    class method ClassVirtualMethod; virtual;
    begin
      VirtualMethod;
    end;

    class method VirtualMethod; virtual;
      begin writeLn('BasicClass VirtualMethod'); end;
  end;

  DerivedClass = public class(BasicClass)
  public
    class method VirtualMethod; override;
      begin writeLn('DerivedClass VirtualMethod'); end;
  end;

It appears that the following two calls

 BasicClass.ClassVirtualMethod;
 DerivedClass.ClassVirtualMethod;

both call BasicClass.VirtualMetod. Shouldn’t the second one actually call DerivedClass.VirtualMethod?

So, how are inherited virtual class methods actually handled in Oxygene? Is this the correct behavior? If so, how can I (easily) ensure that DerivedClass.VirtualMethod is called in the second case? Redefining ClassVirtualMethod in each derived class would be a poor option.

Thanks, logged as bugs://81298

Hrmm if I run this, I get:

C:\projects\oxygene-rebirth\out>ConsoleApplication28.exe
BasicClass VirtualMethod
DerivedClass VirtualMethod

with:

unit issue81298_virtualtest;
interface

uses System,System.Collections.Generic,System.Linq,System.IO;
type
  BasicClass = public class
  public
    class method ClassVirtualMethod; virtual;
    begin
      VirtualMethod;
    end;

    class method VirtualMethod; virtual;
      begin writeLn('BasicClass VirtualMethod'); end;
  end;

  DerivedClass = public class(BasicClass)
  public
    class method VirtualMethod; override;
      begin writeLn('DerivedClass VirtualMethod'); end;
  end;

implementation

begin
    BasicClass.ClassVirtualMethod;
 DerivedClass.ClassVirtualMethod;
end.

as a testcase. What am I missing?

Also, what platform?

I tested it under java.

This java console application

namespace TestClassInheritance;

interface

uses
  java.util;

type
  BasicClass = public class
  public
    class method ClassVirtualMethod; virtual;
    begin
      VirtualMethod;
    end;

    class method VirtualMethod; virtual;
    begin writeLn('BasicClass VirtualMethod'); end;
  end;

  DerivedClass = public class(BasicClass)
  public
    class method VirtualMethod; override;
    begin writeLn('DerivedClass VirtualMethod'); end;
  end;

type
  ConsoleApp = class
  public
    class method Main(args: array of String);
  end;

implementation

class method ConsoleApp.Main(args: array of String);
begin
  BasicClass.ClassVirtualMethod;    // calls BasicClass.VirtualMethod
  DerivedClass.ClassVirtualMethod;  // calls BasicClass.VirtualMethod, too
  readLn;
end;

end.

compiled in Microsoft Visual Studio 2015 with RemObjects Elements 10.0.0.2275
produces the following output::

> java -jar testclassinheritance.jar
BasicClass VirtualMethod
BasicClass VirtualMethod

Can you try updating?

With latest I get:

C:\projects\oxygene-rebirth\out>"c:\Program Files (x86)\Java\jdk1.7.0_55\bin\java.exe" -jar consoleapplication28.jar
BasicClass VirtualMethod
DerivedClass VirtualMethod

Updating what, jdk or Elements?

With jdk 1.8.0_161 and RemObjects Elements 10.0.0.2289 I get:

D:\RemObjects\TestClassInheritance\bin\Debug> "c:\Program Files\Java\jdk1.8.0_161\bin\java.exe"  -jar testclassinheritance.jar
BasicClass VirtualMethod
BasicClass VirtualMethod

In a recent conversation with you and Marc I explained my troubles updating to 2331, after which I had to revert back to 2289. Since 2331 is still the latest stable version, I am reluctant to give it another chance.

Do you think the update to 2331 would really resolve the problem? Or is it rather the issue of java 1.7.0 vs. 1.8.0?

I think 2331 would resolve the virtual issue as I get the same result wth java 8.

Remind me what your remaining issues with .2331 were?

Remind me what your remaining issues with .2331 were?

The conversation took place here:
https://talk.remobjects.com/t/problems-after-installing-remobjects-elements-with-water-10-0-0-2331/17571

In summary, after installing 2331:

  • My software didn’t compile for java because of unrecognized global
    methods.

  • The software did seemingly compile for .NET, but it didn’t run. My
    hypothesis at the time was that references to libraries were broken
    after the installation.

Hope this helps,

Marko

Ah yes, I recall now. The Java issue seems to be fixed, for the .NET issue we’re awaiting additional infos, if I read the thread correctly?

thanx,
marc

Yes, exactly.

Knowing that 2331 doesn’t work for me, I’ll wait for the next stable release and give it a try.

Ok, but the .NET issue won’t be fixed in that release, then, because that’s on hold until we hear back from you own that. So it’d be better of you could re-test with current, and give us the details we need to look at the other issue as well…

          Ok, but the .NET issue won’t be fixed in that release, then, because that’s on hold until we hear back from you own that. So it’d be better of you could re-test with current, and give us the details we need to look at the other issue as well…

OK, let’s try to do it then with 2331.

  1. I took a laptop with Windows 7 on which no software development tools had ever been installed.
2. I installed RemObjects Elements with Water - 10.0.0.2331 and jdk-8u191-windows-x64, with default settings. No problems.

3. I took two Oxygene Elements projects of mine. Project A is a recent one, programmed in a very "correct" fashion without using globals - this avoids the java globals problem. Project B is based on an old Delphi class library, uses Delphi RTL and employs global methods. Both projects use Elements RTL and EUnit. All programs from these projects compile and run correctly for both java and .NET under 2289.

4. Then I opened Project A in Water, leaving it to interpret the .sln file itself. I got:

Under .NET: First, there were two internal compiler errors. After some minor hampering with the code (which I can explain later, but no big deal), the test-suite program compiled and run CORRECTLY.

Under java: Didn’t compile, giving many errors. It seems that sequences are now treated differently. Please see the example in the attached FigSequences.PNG. There, fModels and fViews are of the types List and List, where T1 and T2 are descendant classes of DexObject. This worked previously and apparently still works in .NET. Any need to redesign this and similar code would cause a lot of problems to me.

I also noticed another annoying issue. When switching between java and .NET in Water, the two platforms compete and each wants to change method names in its own way. When working with .NET (see FigNet.PNG), the case is fixed to the capital first letter (which is correct and is in accordance with my definitions in the code). After switching to java and rebuilding (FigJava.PNG), the same code is erroneously changed to lower-case first letters.

  1. Moving to project B:

Under .NET: After a successful compilation, the program gives:

Unhandled Exception: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)

   at System.Reflection.Assembly.GetTypes()

   at RemObjects.Elements.EUnit.AssemblyDiscovery.Filter() in c:\CI\b\elements\937\Source\RemObjects.Elements.EUnit\Sources\Discovery\NET\AssemblyDiscovery.pas:line 31

   at RemObjects.Elements.EUnit.BaseDiscovery.Discover() in c:\CI\b\elements\937

\Source\RemObjects.Elements.EUnit\Sources\Discovery\BaseDiscovery.pas:line 25

   at RemObjects.Elements.EUnit.Discovery.DiscoverTests() in c:\CI\b\elements\937\Source\RemObjects.Elements.EUnit\Sources\Discovery\Discovery.pas:line 118

   at TestDEXiModNet.__Global.Main(String[] __args) in D:\DEXiMod\DEXiMod\TestDEXiModNet\Program.pas:line 12

Under java: Doesn’t compile, there are many unrecognized globals:

E: Unknown identifier "Max" [D:\DEXiMod\DEXiMod\DexiMod.pas (2098)]

E: Unknown identifier "Round" [D:\DEXiMod\DEXiMod\DexiMod.pas (2098)]

E: Unknown identifier "Abs" [D:\DEXiMod\DEXiMod\DexiMod.pas (2107)]

E: Unknown identifier "Abs" [D:\DEXiMod\DEXiMod\DexiMod.pas (2133)]

E: Unknown identifier "Max" [D:\DEXiMod\DEXiMod\DexiMod.pas (4526)]

E: Unknown identifier "AnsiCompareText", did you mean "OnCompareText"? [D:\DEXiMod\DEXiMod\Lists.pas (162)]

E: Unknown identifier "Abs" [D:\DEXiMod\DEXiMod\DexiUtl.pas (150)]

...

With so many issues, I really can’t use 2331 for production. What do you suggest, what to do next?

Thanks,

Marko

Sorry for cluttering this thread with my previous post, which addresses a different topic. I thought I was sending a private mail. But the issues raised there are serious, could you please take a look at them?

In relation to the original question raised in this thread, I can confirm that virtual class inheritance works correctly with Elements 2331. Thank you.

My apologies; I didn’t see your original reply. Do you have a testcase that shows us the above issues? I don’t think we can fix hem from a screenshot. (Obviously, we’ll keep them private if needed)

OK, I’ll make test cases for the issues related to sequences (first issue, first figure) and bizarre renaming behavior in Water (the remaining two figures). I’ll post them in separate threads.

But regarding the issue that occurs with Project B on .NET, I have no idea what to look at. Any suggestions?