# Wednesday, July 31, 2002
« No Title | Main | What's wrong with this picture? »
No Title

I only just noticed that Stuart commented on the July 25 item:

The natural "con" that I can think of regarding your alternative implementation is that it would make it very difficult for Java code to catch System.Exception. At least it would require that code that wants to catch *any* exception would have to know that it might be running under IK.VM and explicitly catch System.Exception, where a normal Java program might expect to be able to catch Throwable.

I didn't mention this, but I would still map all usages of java.lang.Throwable to System.Exception (except in the case of the base class, when a class is derived from Throwable, it would be derived from Throwable). Sensible interop between .NET and Java exceptions is definitely something I'm aiming for.

The difficulty, it seems to me, is ensuring that you don't just have a good mapping from Java to C#, but that your mapping is fully *reversible*, and makes just as much sense going the other way. Java code expects to know exactly what exceptions are going to happen for a particular method, so you'll need to be remapping things like IOException already - and you'll need some way to ensure that any exception that's going to be thrown by a method where Java doesn't expect it gets mapped to a RuntimeException (or Error or direct Throwable subclass) with the original exception as the cause.

I'm not actually remapping exceptions like IOException, what happens is that the "native" code that implements an I/O function catches the System.IO.IOException and throws a java.io.IOException.

CLR generated exceptions get converted to the Java equivalent when they are first caught. At the moment I don't convert them back, so when .NET code calls Java code it can expect both System.NullReferenceException and java.lang.NullPointerException to be thrown (for example) depending on whether the Java code "caught" (a finally also triggers the conversion) the exception before it was propagated out the calling .NET code. This isn't very elegant, so I expect that in the future I'll be swapping the original exception back when the Java code rethrows the exception.

I suppose that your generated JAR files (described in your previous entry in response to my comment) will have to declare every method as "throws Exception", right?

To be honest, I hadn't even thought about this. My initial thought would be to make it seem (for the Java compiler) as if every .NET exception is derived from RuntimeException to get around this mess. This might cause additional complications, so I'm going to have to think about this a little more. Adding "throws Exception" doesn't appeal to me either, because that would make it very uncomfortable for the Java programmer trying to call .NET code.

Wednesday, July 31, 2002 3:29:13 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
Wednesday, July 31, 2002 12:03:22 PM (W. Europe Daylight Time, UTC+02:00)

"Just noticed" - heh - I only just commented yesterday :) (on the July 13th one also, btw, but that was mostly content-free happy ravings).

I'm not sure what I think about your choice to not remap things like IOException, and to handle it in the pseudo-native code. I'll have to think about it some more to decide how I feel. I have a feeling of "wrongness" about the way you're doing it, but at this point I can't explain why, so I'll accept that since you've probably thought about it more than I have, you're probably doing the right thing (unless I can figure out the reason for my feeling and decide that it's legit, in which case I'll comment again...)

With regard to "throws Exception" in the generated JAR files, I'm not sure how I feel about it either. On the one hand, yes, it's certainly awkward for the Java programmer. On the other hand, it's exactly what the CLR really *does*, by implication - any method *can* throw any exception.

Here's a problem case: I could define a Java exception, use IK.VM to compile it to CIL, and then write a C# class that throws it and call that C# class from Java - how would you handle that case with your proposed solution? You can either preserve the "real" Java mapping of the compiled Java exception, OR you can make it a subclass of RuntimeException, but you can't do both. But you really do want to be able to preserve the semantics of a custom-compiled Java exception. Assuming "throws Exception" for all C# code seems to be the only way you *can* deal with this case, because you there's no way you can detect it to specialcase it.

Wednesday, July 31, 2002 12:28:13 PM (W. Europe Daylight Time, UTC+02:00)

Ooh, even worse (and yet more common) case:

Java code declares "throws FooException", and does throw it.
C# code calls java code and accepts and propagates the exception with no problem, because it doesn't care.
Java code calls C# code which *isn't* declared as "throws FooException". But it actually did throw the FooException propagated from the Java code.

Yet another couple of semantics-impedance-mismatch issues that I just thought of: Do you plan to allow indexers and foreach to work on java.util.List and java.util.Collection, respectively? Will Collection implement(/extend) IEnumerable with Iterator remapping to IEnumerator? How about the converse ( for (Iterator i = new System.ArrayList().iterator(); i.hasNext(); ) {...} )? Or even, more complicatedly, {Input,Output}Stream and Reader/Writer mapping to .NET equivalents? Will JavaBeans-compatible getFoo()/setFoo() methods remap to a property called foo? Or even to a property called Foo? (even the naming conventions are incompatible...)

You'll notice that I'm posing ever more complicated scenarios - sorry! :) The reason I'm deliberately making your life difficult is that you seem to have all the easy cases well covered already... and besides, I'm highly interested to see just how deeply integrated into the .NET platform Java can really get without losing it's soul...

Comments are closed.