# Wednesday, March 10, 2004
« Object Model Mapping Part 4 | Main | JDK 1.5 beta »
To Invert Or Not To Invert

Stuart commented:
I'm not convinced that cli.System.Object should be visible to Java at all. AIUI, Java code will never see instances of cli.System.Object, because all such objects appear to inherit from java.lang.Object instead.

If cli.System.Object *is* visible to Java code, it introduces a paradox: java.lang.Object inherits from cli.System.Object (per the way it's actually implemented) but cli.System.Object should appear to inherit from java.lang.Object (per Java's rule that *everything* inherits from java.lang.Object). Now, it may be possible to create magic glue code that inverts the apparent inheritance relationship like that, but do you really want to go there? :)

The inversion is exactly what I was thinking about. Stuart's analysis above contains a crucial mistake, java.lang.Object does not inherit from cli.System.Object. However, it is virtually impossible not to get confused about this stuff, so let's try to make the discussion a little easier by defining a naming convention:

  • java.lang.Object
    This is the base class of all Java classes (as seen from the Java side of the world).
  • [classpath]java.lang.Object
    This is an implementation artifact of IKVM, it is a .NET type that is used as the base type for all non-remapped Java classes.
  • System.Object
    This is the base class of all .NET classes (as seen from the .NET side of the world).
  • cli.System.Object
    This is the IKVM manifestation of the System.Object type on the Java side of the world.

The paradox is that [classpath]java.lang.Object inherits from System.Object and cli.System.Object inherits from java.lang.Object, but hopefully it is now clear that this isn't a problem. (BTW, one of the definitions of a paradox is "A seemingly contradictory statement that may nonetheless be true").

There are actually two reasons why I would want to do this:

  1. If a Java class extends a .NET type (that was exported using netexp) you see both the virtual methods in java.lang.Object as well as the ones in System.Object that the class in question happens to override (a fairly arbitrary set). By introducing cli.System.Object as the penultimate base class for all .NET types, this can be made much more consistent. cli.System.Object would have final implementations for all the virtual methods in java.lang.Object (to make sure that the essentially non-existing methods don't get overridden) and it would introduce the real virtual methods of System.Object.

  2. If you want to define your own "first class" .NET exception class in Java, you need to extend cli.System.Exception. In other words, it makes for a more powerful programming model to expose the remapped types in this way.

Wednesday, March 10, 2004 10:15:16 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [6]
Wednesday, March 10, 2004 6:44:54 PM (W. Europe Standard Time, UTC+01:00)
<wounded-pride type="tongue-in-cheek">I wouldn't go so far as to call that a *mistake* so much as an unclear choice of wording... if you take "as actually implemented" to mean on the .NET side, and "as they appear" to refer to the Java side, and use the meaning of the word "paradox" that you identified, there's nothing actually incorrect about my comment...</wounded-pride>

So the answer to my question is yes, you really do want to go there :)

I guess the implication is that you're going to need to be very, very careful in the implementation of IKVM whenever you do anything which depends on the inheritance chain with regard to *which* inheritance chain applies, but obviously you've already thought of that in great detail :)

I understand your reason #1, but I'm not quite sure I understand your reason #2. Can you clarify why an exception that inherits from java.lang.Throwable *isn't* a "first class" .NET exception? Do you just mean that you can inherit from an existing subclass of System.Exception?
Wednesday, March 10, 2004 6:47:00 PM (W. Europe Standard Time, UTC+01:00)
Oops, apologies for the overly-escaped pseudo-xml there. It appears that when it says "HTML not allowed" it really means it: there's no way to get angle brackets into a comment at all, that I can find?
Wednesday, March 10, 2004 7:18:43 PM (W. Europe Standard Time, UTC+01:00)
To start with the easy question: I changed a setting, I think you can now use angle brackets. Let's see: <test>
Wednesday, March 10, 2004 7:22:25 PM (W. Europe Standard Time, UTC+01:00)
>>if you take "as actually implemented" to mean on the .NET side,<<

Yeah, but you did say cli.System.Object that isn't the name on the .NET side ;-)

Reason 2 as I stated it is actually not a very good reason, since you're not supposed to create direct subclasses of System.Exception. Anyway, what I was thinking of was that a "first class" .NET exception needs to support serialization and to do that you need to call the special serialization constructor (to support deserialization). Anyway I still think the general principle that you should be able to do as much as possible on the Java side applies and this change would be an improvement in that area. The complexity cost isn't really that high.
Wednesday, March 10, 2004 8:57:28 PM (W. Europe Standard Time, UTC+01:00)
Ooh, I didn't know that rule about .NET exceptions. Then again, I usually cheat and just throw ApplicationException instead of actually defining my own exception subclass. Somehow the lack of checked exceptions makes it more tempting to be lazy in this area...

Anyway, I think I agree with your reasoning (you've obviously been thinking about this much more than I have, which is unsurprising, but I've been impressed at the way you have an answer to everything I say right off the top of your head...). Making an artificial inheritance-inversion really does seem to be much less complex than the hoops you have to jump through to pretend that they're actually the same type, or that one of them doesn't exist at all.

BTW, in the new model, java.lang.String and System.String are still the same type, right?
Wednesday, March 10, 2004 8:59:13 PM (W. Europe Standard Time, UTC+01:00)
>>BTW, in the new model, java.lang.String and System.String are still the same type, right?<<

Comments are closed.