Java Code Embedding in C# [Updated 2019]
Interoperability Between JVM & CLR
The real concept driving this article is to develop solutions using the .NET or Java Framework that interoperate with heterogeneous systems or even mutually communicate with each other. Java Virtual Machine (JVM) is exposing Java Native Interface (JNI), which allows other programs to control JVM in a manner, for instance, load classes, create instances and run methods.
This example shows the amazing tactics of mingling both C# and Java code in one source code file and producing the desired result. Nowadays, organizations work on multiple projects simultaneously, and the corporate infrastructure usually is configured with 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 in order to save human efforts and computer resources, because one algorithm developed on the .NET platform could be packed as API or DLL files and run across diverse platforms.
The aspirant should be knowledgeable in both Java and C# programming languages, as well as having deep understanding of JVM and CLR internal. This operation requires the subsequent software to be installed:
- Eclipse (optional)
- .net framework
- Vs studio 2010 (optional)
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 take advantage of the power of the Java platform by applying 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.
Questions that often occur in the mind of developer include: why is interoperability so important? What kind of issues it is precisely addressing? To what extent is interoperability technology between Java and. NET beneficial? Here, the advantages outlined to justify interoperability are as following:
- Migrations: migration has to be well-planned and carefully executed when s system is updated or replaced, and often involves moving an application by 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 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 being keenly developed 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 has 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 aim 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 into the needs of your application. While we can write and execute applications entirely in Java and .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 to 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 which is developed and executed under CLR- to be accessible to Java applications. In simple terms, we can say that we can call a .NET application and library in Java and vice-versa by using JNI. Native code runs relatively faster than JVM code, so such implementation can assist at a great extent to solve complicated and time-critical operations.
Java, native languages, and .NET have their own data type infrastructure. During interoperability or communication of these diverse languages to each other, it is necessary to comply with a common data type scheme so that all participant languages can send messages to each other and follow data type semantics. The following table describes the primitive types in the Java programming language and the corresponding types in the JNI.
|Native Fields||Java Fields||Descriptor|
The Java platform is implemented on top of the host platform. So, it is necessary to allow Java applications to work closely with other languages written in native code so that 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 CLR or native code. 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 call native methods in the same way that they call methods implemented in the Java programming language.
Sometimes circumstances demand that JAVA and .NET technology send messages or communicate with each other in order to save human effort or reduce programming glitches. It is not necessary that a company infrastructure is reliant particularly upon the J2EE or .NET framework. An algorithm written in Java could be consumed or manipulated in the .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 in order to possibly reflect technology implementation across the boundaries.
So, jni4net could be conceived as API, which 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 particular 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#.net
This section illustrates how to implant Java code into existing CLR C# code. The subsequent Java sample code performs some arbitrary mathematical calculations. This sample integrates Java code with C# code and justifies the means of interoperability by taking the input from C# code and passing that argument to Java code in order perform additional operations. So, the message of communication is happening across JVM and CLR, which is one of the most noticeable mechanisms of this sample.
First of all, download jni4net, which is in fact an open source product. The jni4net package contains a couple of dll and jar files which shall play a key role in cross boundary communication across JVM and CLR. The jni4net-0.8.6.0-s-bin zip file has a lib folder which contains entire necessary library files:
Figure: jni4net package files
Thereafter, create a console-based C# application as jniDemo and add the reference of jni4net.n-0.8.6.0.dll from the solution explorer as shown:
Figure: Adding a reference
Now, mention the entry of the jni4net package from the beginning of the source file in a using statement as net.sf.jni4net, which provides Java primitive classes access into C# IDE.
Later, in the main method, call the CreateJVM () methods, which create a temporary Java virtual machine environment in order to execute interpret or execute Java code.
Thereafter, place the arbitrary mathematical calculation implementation. We can access the Java class name by java.lang namespace followed by @ character. Notice that 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:
int a = java.lang.@Integer.parseInt(args);
int b = java.lang.@Integer.parseInt(args);
Finally, put C# code again:
Console.WriteLine("nnPress any key….");
So this sample showcases a perfect mix source code paradigm of Java and .NET into one file. Here, the whole code of this implementation is:
After finishing the coding, an 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.
Figure: Placing jar file in the bin/debug folder
Finally, run the application from the command prompt and pass to an integer type argument, followed by the executable, and notice the output.
Figure: Java code calling from C# output
So, it is no longer a wonder to execute Java code in 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 perform the opposite in this segment. Open the eclipse IDE and create a new console-based application as test. Then, right click on the test project from the Package Eexplorer and select properties. Here, go to 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:
Figure: C# Adding jar file
After adding the jar file, you can notice its reference entry into the Package Explorer:
Figure: C# jar file reference in the Package Explorer
Now, it is time to write C# code in Java source code file. However, of first import is the C# class specification namespace:
The following sample implements the logic of showing the environment variables and crucial information of the machine by employing the C# dictionary classes. As with the earlier sample, create a CLR virtual machine by init() method, which invokes the CLR in order to execute and run C# code as:
Now, put the C# code for environment variable enumeration access in the loops, and display data as:
Dictionary ev = system.Environment.GetEnvironmentVariables();
IEnumerator keys = ev.getKeys().GetEnumerator();
Here, the whole code for this sample is given below.
public class ajay
public static void main(String args) throws IOException
// create bridge, with default setup
// here you go!
Console.WriteLine("Hello .NET world!nn");
Dictionary ev = system.Environment.GetEnvironmentVariables();
IEnumerator keys = ev.getKeys().GetEnumerator();
system.String k = (system.String) keys.getCurrent();
Console.Write(" = ");
Object value = ev.getItem(k);
String valueToString = value.toString();
If we want to observe the behind-the-scenes processing related to the CLR virtual machine initialization, we can put this code before the init() method as:
Enabling this option will show everything related to CLR and JVM just before the actual output as:
Figure: C# CLR initialization
Finally, debug and run this application. We can notice in the output that the C# code enumerates the entire environment variable of the system via Java code:
Figure: C# code calling from Java output
This paper addressed the interoperability concept across Java and .NET platforms through the jni4net framework. We have heard that it is not possible to call Java code from C# and vice-versa, but jni4net makes it possible by mixing both source codes into a single executable file. This paper shows how can we partially place both technology source codes in a file by invoking their corresponding virtual machine such as JVM and CLR. The important thing to make such cross-boundary communication possible is to properly configurate Java jar and C# dll files as a reference in order to access these class library methods.