Browse DevX
Sign up for e-mail newsletters from DevX


Calling Java Classes Directly from .NET

As the frequency of .NET and Java applications increases, we're headed for an interoperability imperative—we have to get both sides to work together. One way to do that is by adding an interoperability layer that gives .NET direct access to Java classes.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

t's a fact that most production environments now use a mixture of both Java and .NET, despite all the partisan disputes over which side should "win." To be prudently responsible in the face of this business reality, it is imperative that developers get both sides to work together. Interoperability is no longer an option: fortunately, you do have some options for choosing the best path for achieving interoperability for your project. Your specific interoperability needs may vary, based on your current systems and project specifications. Perhaps you already have some perfectly good "legacy" Java code that you don't need to change, but want to extend with new .NET components. Or, you're creating a new system, and want to assign tasks to the better-suited platform, so you're using J2EE's Enterprise Java Beans (EJBs) for the scalable back-end system, and .NET Windows Forms to create a rich desktop GUI. In either case, you may need direct access to Java classes from .NET. This article briefly discusses the major interoperability methods available and highlights some issues to consider as you make your interoperability selection, and demonstrate class-level interop with a specific example.

Click here to see or hide the author's description of other interoperability methods.

Web services
Web services are intended to provide a standards-based mechanism for allowing cross-platform components to interoperate. However, Web services are designed for loosely coupled interactions that are infrequent and coarse-grained: therefore they're not appropriate for applications that require frequent and fine-grained calls between Java and .NET classes. The service-oriented interface supported by Web services is the equivalent of exposing a single persistent object activated by the server. If you need to expose a rich interface for a large number of Java classes and objects, or you need to allow the .NET client process to create Java objects through the standard constructor (new) mechanism, Web services won't work.

In addition, Web services use a SOAP-based communications mechanism that's inherently slower than alternative binary communications mechanisms. Web services are also not well-suited for passing custom objects between Java and .NET as parameters and return values. Visual J#
.NET supports development of systems using multiple languages concurrently. One way to support Java/.NET interoperability is to translate the Java code directly into .NET's MSIL (Microsoft Intermediate Language) rather than into Java bytecodes. Although Microsoft can't call its J# language Java, J# really is a way to compile Java code for .NET. Unfortunately, J# a significant limitation: it's legally limited to the Java supported by JDK 1.1.4 plus JDK1.2's collection classes. Using J# works only when these limitations don't matter to you, and when you have access to the original Java source. However, when the Java code you need uses more advanced features, including just about any J2EE feature such as EJBs or servlets, or when you don't have the source, J# isn't a good choice.

Java Native Interface (JNI)
Java code can access, and be accessed by, non-Java code via the Java Native Interface (JNI). JNI is mainly suited for accessing Java code running in a standalone JVM on the same machine as your .NET code, and can be difficult to use. If you're communicating with Java code on a different machine, or running in a J2EE application server, you may have problems. There are some third-party products that may help: JuggerNET, from CodeMesh ) is one example. BytecodeTranslation
It may be possible to convert the compiled Java bytecodes to .NET MSIL so that you can link it directly into your .NET program. Microsoft's J# distribution includes a tool called jbimp.exe that converts Java bytecodes to MSIL at compile time. Of course, jbimp.exe has many of the same limitations as J# in that it can convert only bytecodes from JDK 1.1.4 and earlier (plus JDK 1.2 collections. Unlike J#, however, jbimp.exe works without source code. IKVM.NET is an intriguing open-source project that translates Java bytecodes to MSIL as needed at runtime. In theory, IKVM.NET should allow any Java code to run on the .NET platform. However, the project is at a very early stage and far from complete, but certainly worth following for the future.

Close Runtime Bridges
Perhaps the most natural interoperability method is to run the Java code in a JVM, the .NET code in a CLR, and use a runtime bridge to manage the communications between them. In this scenario, the .NET code calls .NET classes and objects that act as proxies for the Java classes and objects. The proxies manage the communication; the calling .NET classes aren't even aware that they're ultimately calling Java classes. A runtime bridge provides interoperability for a wide variety of architectures, because the Java code and the .NET code can be on different machines, the Java code can run in a standalone JVM or in a J2EE application server, and the solution provides interoperability for any JDK version. As with bytecode translation solutions, you need only the Java bytecodes, not the source.

There are several runtime bridges commercially available. The code for this article uses JNBridgePro from JNBridge. See the related resources section of this article for other bridge products. In the remainder of this article, you'll see how to use JNBridgePro to solve a real-world interoperability problem.

Thanks for your registration, follow us on our social networks to keep up-to-date