[Mono-list] Mono/Java interop - Usage scenarios

Ben Hutchison ben.hutchison@intamission.com
Tue, 12 Nov 2002 12:20:21 -0000


I felt the recent discussion on Mono (ie .Net) and Java interoperability
rapidly became quite low-level. 

I want to step back for a moment to summarize the usage scenarios,
because different ones suggest different solutions. Below I use the word
"foreign" to mean "the other platform"; Java in a .Net context, and .Net
in a Java context.


1. Transform Java bytecode to CIL, or the reverse

This would allow you to transform your binaries into a form that would
run on the foreign system. Its more flexible and powerful than
source-code level transformation, because it handles the many source
languages that compile to both bytecode formats (C#, VB, Haskell; Java,
Jpython, AspectJ), and because source code can be compiled then fed into
such a tool. 

My understanding is that Java bytecode -> CIL would be much more
feasible than the reverse. Roughly, CIL has a superset of Java
capabilities. CIL has delegates (for which Java has no analog [anon-
classes don't count!]) and the type-polymorphism (ie <templates>)
planned for .Net future versions is more powerful than that planned for
future Java.

IMO the bytecode transformation process would not be particularly
difficult to implement. MS have done it for their JUMP and Visual J#
products.

However, we hit the afore-mentioned obstacle of the Java (or .Net)
libraries. Most code will be riddled with calls to standard APIs that
will not exist in the target platform. (Because this is a deep, complex
and undecided issue, I wont go further here, but refer the reader to
other posts in the "Mono/Java interop" thread.)

Note that such a bytecode converter might be used on-the-fly like a JIT
if it was sufficient fast.


2. Transform Java source code into C# (possibly the reverse)

If a developer has some Java or C# source that they wish to use in a
foreign system long-term, they will want to convert the source code to
maintain it. Having a binary only converter (1) is not sufficient.

Such a tool would be less flexible than (1), probably operating on
C#<->Java only. It is a definite second priority IMO to bytecode
conversion. It may encounter similar difficulties to (1) regarding
conversion of C# -> Java (lack of delegates, attributes, etc), and
platform API support, but is otherwise quite feasible. MS have an
implementation in JUMP.


3. Call into foreign binaries (eg libraries) locally from within a VM
process

We could call this "in-process bridging". I am running a CLR, and I want
to call into my Java libraries and get a return value. (Somehow!) I
obtain a ref to a Java object or class, and call a method. This will be
a native .Net call, which will be using JNI (Java Native Interface)
under the surface. It will find (& if required, start) an embedded JVM,
and the call will enter the JVM on the same stack, which might look
like:

    Java method executing in JVM
    JNI Invocation layer
    C interop library layer
    Pinvoke
    .Net code

Theoretically, I think JNI allows this to be done, but I see many
practical difficulties, including passing/returning objects types
between CLR and JVM, and garbage collection between 2 systems, and
controlling JVM lifecycle (eg shutdown at least).


4. Make remote calls to a foreign system

"Out-of-process bridging" seems a very common scenario in enterprise
systems. Eg I have a J2EE system and now I want to support .Net clients,
or vice versa. Like (3), there is a JVM and a CLR involved, but they are
separate processes communicating using remotes calls (probably sockets
underneath), rather than the stack. 

Technically it seems *much* more feasible to me. Because calls a remote,
parameters/return types are either remote refs (ie proxies) or they are
serialized (pass-by-value).  There is still the issue of wire protocol
(much discussed in earlier posts), and handling of foreign types/classes
of pass-by-value objects.


Regards
Ben

PS I hope to respond to the specific posts recently made on this topic
later today.