Invoking Java Code in C#.NET

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 communicate 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 file 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 the 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. Do suspicions often occur in the mind of a developer, such as why is interoperability so important? What kind of issues is it precisely addressing? To 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 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 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 of 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 the needs of your application. 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, to a great extent, in solving complicated and time-critical operations.

Java, native languages, and .NET have their own data type infrastructure. During the 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 adapt 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 for 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 Framework

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 an 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 downloading jni4net from the internet which 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 has 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 a 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.

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.

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.

int a = [email protected](args[0]);
int b = [email protected](args[1]);

Finally, use some C# code again as follows.

Console.WriteLine("\n\nPress any key....");
Console.ReadLine();

So this sample showcases a perfect mix of source code paradigms of Java and .Net into one file. Here, the entire code of this implementation is as in the following.

using System;
using net.sf.jni4net;
namespace jniDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //******* Java code Start...*******
            Bridge.CreateJVM(new BridgeSetup());
            [email protected]("\n\nWelcome Java! in .NET world!\n");

            int a = [email protected](args[0]);
            int b = [email protected](args[1]);
            int p = a * b;
            int q = a + b;

            [email protected](a + " * " + b + " = " + p);
            [email protected](a + " + " + b + " = " + q);
            //******* Java code end...*******

            // C# code
            Console.WriteLine("\n\nPress any key....");
            Console.ReadLine();
        }
    }
}

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 pass the integer type argument followed by the executable, and notice the output.

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.

Java

Figure: C# Adding jar file

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

Jar file

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.

import net.sf.jni4net.*;
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.

Dictionary ev = system.Environment.GetEnvironmentVariables();
IEnumerator keys = ev.getKeys().GetEnumerator();

Here, the entire code for this sample is given below.

import net.sf.jni4net.*;
import java.io.IOException;
import java.lang.String;
import system.*;
import system.Object;
import system.collections.IDictionary;
import system.collections.IEnumerator;

public class ajay
{
   public static void main(String[] args) throws IOException
   {
      // create bridge, with default setup
      Bridge.setVerbose(true);
      
      Bridge.init();
      
      // here you go!
      Console.WriteLine("Hello .NET world!\n\n");
      Dictionary ev = system.Environment.GetEnvironmentVariables();
      IEnumerator keys = ev.getKeys().GetEnumerator();
      
      while (keys.MoveNext())
      {
         system.String k = (system.String) keys.getCurrent();
         Console.Write(k);
         Console.Write(" = ");
         Object value = ev.getItem(k);
         String valueToString = value.toString();
         Console.WriteLine(valueToString);
      }   
   }
}

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.

 System via Java

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 codes into a single executable file. This paper shows how to partially place both technology's source code in a file and invoke their corresponding virtual machines 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.


Similar Articles