Invoking Java Code in C#.NET

The real concept driving this article is to develop solutions using the .NET or Java Framework that interoperate with heterogeneous systems or even mutually communicated with each other.

Interoperability between JVM & CLR

Abstract

The real concept driving this article is to develop solutions using the .NET or Java Framework that interoperate with heterogeneous systems or even mutually communicated with each other. The Java Virtual Machine (JVM) exposes the Java Native Interface (JNI) that allows other programs to control the JVM. For instance, load classes, create instances and run methods. This sample shows the amazing tactics of mingling both C# and Java code in one source code file and producing the desired results. Nowadays, the organization works on multiple projects simultaneously and the corporating infrastructure is usually configured with a couple of platforms such as .NET, Java and PHP to fulfill the developer's requirements. So, it is good to interoperate or set up communication across these technologies to save human efforts and computer resources because one algorithm developed on the .NET platform could be packed as an API or DLL files and be consumed across diverse platforms.

Essential

The aspirant is supposed to be convenient in both the Java and C# programming languages as well as having a deep understanding of the JVM and CLR internals. This operation requires the subsequent software to be installed as listed below.

  • Jni4net
  • Jdk
  • JVM
  • Eclipse (optional)
  • .NET Framework
  • Visual Studio 2010 (optional)

Interoperability

Interoperability enables communication, data exchange, or program execution among diverse systems in a way that requires the user to have little awareness of the underlying operations of those systems. The programmers can get an advantage of the power of the Java platform by applying the JNI without having to abandon their investments in legacy code because the JNI is a core part of the JVM. Programmers can address interoperability issues once and expect their solution to work with all implementations of the Java platform. Suspicions often occur in the mind of a developer, such as why is interoperability so important? What kind of issues is it precisely addressing? At what extent is interoperability technology between Java and .NET beneficial? Here, the subsequent advantages are outlined to justify interoperability as in the following:

    Migrations: migration must be well planned and carefully executed when the system is updated or replaced and often involves moving an application a few parts at a time. This way of dividing a system for migration purposes, often creates a demand for interoperability because some parts that have been migrated still might need to communicate with others that have not.

    Reusability: most established companies have a number of legacy systems. By the term legacy, I mean technology that's not been keenly developed upon today. For example, a system located in the data center that's still in production but no longer offers a strategic advantage to the company is a legacy system. A plan to move these systems to a new platform might be a longer-term strategy. A solution that has the ability to interoperate with these systems have the potential to extend the life of these systems and more importantly, the knowledge of the developers who work with them.

    Adoption: when organizations want to deploy a new technology such as the .NET Framework, it's rare that they simply replace an entire application or system. In many cases, a replacement is normally triggered by a pilot project. Such a pilot tends to be a short-term project with an intent to prove that the technology can work well with existing systems and applications. The ability for this pilot project to interoperate with existing production systems is imperative and in many cases, can often determine its success.

Java Native Interface (JNI)

Sometimes, a situation arises where Java or .NET alone does not fit in the needs of your application. While we can write and execute applications entirely in Java and the .NET Framework independently. Programmers use the JNI to write native methods to handle those situations when an application cannot be written in Java and .NET independently. The Java Native Interface framework is devised to enable Java code running in a Java Virtual Machine (JVM) to call, and be called by, native applications and libraries written in other programming languages, for instance, .NET, C++ and assembly. JNI can also modify an existing application that is developed and executed under the CLR to be accessible to Java applications. In simple terms, we can say that we can call .NET applications and libraries in Java and vice-versa using the JNI. Native code relatively runs faster than JVM code so such implementations can assist, at a great extent, in solving complicated and time-critical operations.

Java, native languages and .NET have their own data type infrastructure. During interoperability or communication of these diverse languages among each other, it is necessary to comply with a common data type scheme so that all participant languages can send messages between each other and follow the data type semantics. The following table describes the primitive types in the Java programming language and the corresponding types in the JNI.

                                    Java Native Interface

The Java platform is implemented on top of a host platform. So, it is necessary to allow Java applications to work closely with other language's native code written so that the developer can adopt the Java platform to build applications that were traditionally written in .NET and C++. The JNI is specially designed to interoperate or combine Java applications with the CLR or native code. The JNI typically offers two types of native code: native application and library. We can utilize the JNI to write native methods that allow Java applications to call functions implemented in native libraries. Java applications are called native methods in the same way that they call methods implemented in the Java programming language.

Jni4net Framework

Sometimes circumstances demand that Java and .NET technology send messages or communicate with each other in order to save human effort or reduce the programming glitches. It is not necessary that a company infrastructure to choose J2EE or the .NET Framework particularly. An algorithm written in the Java language could be consumed or manipulated in a .NET Framework or vice-versa. Jni4net is a mechanism that allows a Java program to call a function in a C# program and a C# program to call a method in a Java program. The jni4net framework includes both .NET FCL and JDK core classes to possibly use a Reflection technology implementation across the boundary.

                                    Jni4net
So, jni4net could be conceived as an API that is frequently used in Java or .NET technology. Apart from that, this framework offers a couple of other functionalities such as garbage collection, automatic proxy generation and inter-process communication. The jni4net framework also addresses the interoperability mechanisms similarly supported by other languages. This is, however, not designed for a specific implementation of the Java Virtual Machine. Rather, it is a native interface that can be supported by every implementation of the Java Virtual Machine.

Embedding Java code in C#

This section illustrates how to implant Java code into existing CLR C# code. The subsequent Java sample code does some arbitrary mathematical calculations. This sample integrates Java code with C# code and justifies the means for interoperability by taking the input from C# code and passing that argument to Java code to do the addition operation. So, the message communication is happening across the JVM and the CLR. That is one of the most noticeable mechanisms of this sample.

Getting Started

First of all download jni4net from the internet that is in fact, an open source product. The jni4net package contains a couple of DLL and jar files that shall portray the key role in cross-boundary communication across the JVM and CLR. The jni4net-0.8.6.0-s-bin Zip file havs a lib folder that contains all the necessary library files as in the following:

Jni4net dll

                                                            Figure: jni4net package files

Thereafter, create a Console based C# application as jniDemo and add a reference for jni4net.n-0.8.6.0.dll from the Solution Explorer as follows:

Jni4net demo

         Figure: adding reference

Now, provide the entry of a jni4net package from the beginning of the source file in the using statement as net.sf.jni4net that provides the Java primitive classes access into the C# IDE.

  1. using net.sf.jni4net;  
Later, in the main method, call the CreateJVM () methods that create a temporary Java Virtual Machine environment in order to execute, interpret or execute the Java code as in the following: 
  1. Bridge.CreateJVM(new BridgeSetup());  
Thereafter, provide the arbitrary mathematical calculation implementation. We can access the Java class name by the java.lang namespace followed by the @ character. Here notice one more point, we are getting user input from the command line argument, which is C# code indeed. So, we are mingling the implementation of C# with Java code as follows:
  1. int a = java.lang.@Integer.parseInt(args[0]);  
  2. int b = java.lang.@Integer.parseInt(args[1]);  
Finally, use some C# code again as follows:
  1. Console.WriteLine("\n\nPress any key....");   
  2. Console.ReadLine();  
So this sample showcases a perfect mix of source code paradigm of Java and .Net into one file. Here, the entire code of this implementation is as in the following:
  1. using System;  
  2. using net.sf.jni4net;  
  3.   
  4. namespace jniDemo  
  5. {  
  6.    class Program  
  7.    {  
  8.       static void Main(string[] args)  
  9.       {  
  10.          //******* Java code Start...*******  
  11.          Bridge.CreateJVM(new BridgeSetup());  
  12.          java.lang.System.@out.println("\n\nWelcome Java! in .NET world!\n");  
  13.      
  14.          int a = java.lang.@Integer.parseInt(args[0]);  
  15.          int b = java.lang.@Integer.parseInt(args[1]);  
  16.          int p = a * b;  
  17.          int q = a + b;  
  18.   
  19.          java.lang.System.@out.println(a + " * " + b + " = " + p);  
  20.          java.lang.System.@out.println(a + " + " + b + " = " + q);  
  21.          //******* Java code end...*******  
  22.   
  23.          // C# code  
  24.          Console.WriteLine("\n\nPress any key....");   
  25.          Console.ReadLine();  
  26.       }  
  27.    }  
  28. }  
After finishing the code, the important point to remember is to place the jni4net.j-0.8.6.0.jar file into the project bind/debug folder. Otherwise this project won't compile successfully.

Jni4net jar file

                  Figure: placing jar file in the bin/debug folder

Finally, run the application from the command prompt and pass the integer type argument followed by the executable and notice the output.

run application command prompt
                        Figure: Java code calling from C# output

So, it is no more wonder to execute Java code in the CLR. The jn4net framework makes it possible to mingle the source code of these languages and let them communicate with each other.

Embedding C# code in Java

We have seen how to call Java classes and methods from the C# code earlier. Now, we shall do the opposite in this segment. So, first open the Eclipse IDE and create a new console based application as a test. Then, right-click on the test project from the package explorer and select Properties. Here go to the Java build path and select the libraries tab. Then add or import the jni4net.j-0.8.6.0.jar reference in order to show C# classes in Java source code as in the following:

Adding jar file

                                                         Figure: C# Adding jar file

After adding the jar file, you can notice its reference entry into the package explorer as follows:

 Package explorer

                  Figure: C# jar file reference in the Package explorer

It is now time to write the C# code in the Java source code file. However, first import the C# class specification namespace as follows:
  1. import net.sf.jni4net.*;  
  2. import system.*;  
The following sample just implements the logic of showing the environment variables and crucial information of the machine by employing the C# dictionary classes. As in the earlier sample, create a CLR virtual machine by the init() method that invokes the CLR to execute and run the C# code as in the following:

Bridge.init();

Now put the C# code for the environment variable enumeration accessing in the while loops and display the data as follows:
  1. Dictionary ev = system.Environment.GetEnvironmentVariables();  
  2. IEnumerator keys = ev.getKeys().GetEnumerator();  
Here, the entire code for this sample is given below.
  1. import net.sf.jni4net.*;  
  2. import java.io.IOException;  
  3. import java.lang.String;  
  4. import system.*;  
  5. import system.Object;  
  6. import system.collections.IDictionary;  
  7. import system.collections.IEnumerator;  
  8.   
  9. public class ajay   
  10. {  
  11.    public static void main(String[] args) throws IOException  
  12.    {  
  13.       // create bridge, with default setup  
  14.       Bridge.setVerbose(true);  
  15.   
  16.       Bridge.init();  
  17.   
  18.       // here you go!  
  19.       Console.WriteLine("Hello .NET world!\n\n");  
  20.       Dictionary ev = system.Environment.GetEnvironmentVariables();  
  21.       IEnumerator keys = ev.getKeys().GetEnumerator();  
  22.   
  23.       while (keys.MoveNext())   
  24.       {  
  25.          system.String k = (system.String) keys.getCurrent();  
  26.          Console.Write(k);  
  27.          Console.Write(" = ");  
  28.          Object value = ev.getItem(k);  
  29.          String valueToString = value.toString();  
  30.          Console.WriteLine(valueToString);  
  31.       }   
  32.    }  
  33. }  
If we want to observe the behind-scenes processing related to the CLR virtual machine initialization, we can put this code before the init() method as in the following:

Bridge.setVerbose(true);

Enabling this option will show everything related to the CLR and JVM just before the actual output as follows:

CLR initialization

                                                      Figure: C# CLR initialization

Finally, debug and run this application. We will see in the output the C# code enumerating all the environment variables of the system via Java code as in the following:

calling from Java output

                                          Figure: C# code calling from Java output

Final Note

This paper addressed the interoperability concept across Java and the .NET platform through the jni4net framework. We have heard that it is not possible to call Java code from C# and vice-versa, but jni2net makes it possible by mixing both source code into a single executable file. This paper shows how to partially place both technology's source code in a file and by invoking their corresponding virtual machine such as the JVM and CLR. The important thing is that cross-boundary communication is possible, to properly configure the Java jar and a C# DLL file as a reference in order to access these class library methods.