Introduction
The JNI or Java Native Interface is a set of features available in the Java platform. Applications that use the JNI can incorporate Java code with code written in other languages such as C++, Delphi, and C#.
In my example, I will show you how to call a couple of Java methods from a C# client.
Advantages
You can reuse your existing libraries/classes that were previously written in Java from your new application written in C#. This means that you do not have to abandon your legacy code written in Java and reinvent the wheel again in C#.
Background
One of the most important things to be familiar in JNI is Field Descriptors. As you will notice in the test harness, when I call a Java method that takes a string parameter, I pass in "Ljava/lang/String;". This represents a field type in the Java programming language. For example, if you wanted to represent an int field, then you would use "I", a float field would be "F", and a boolean field would be "Z", etc.
The table below describes the primitive types in the Java programming language and the corresponding types in JNI. All field descriptors that start with L are dealt with as objects (note: a string is passed as an object) and must be terminated by a ";" character. An array type is always prefixed with the "[" character.
JNI Field Descriptor |
Java Language Type |
Z |
boolean |
B |
byte |
C |
char |
S |
short |
I |
int |
J |
long |
F |
float |
D |
double |
Ljava/lang/String; |
string |
[Ljava/lang/Object; |
object[] |
Method descriptors make use of the fields descriptors and describe the structure of a Java method. There are no spaces between the field descriptors in a method descriptor.
Apart from the void
return type which is denoted by V, all other return types use the field descriptor. The table below describes the Java method declaration and the corresponding JNI descriptor. The JNI method descriptor is used when calling a Java method from C# via JNI.
Java Method Declaration |
JNI Method Descriptor |
String foo(); |
"()Ljava/lang/String;" |
Void bar(int I, bool b); |
(IZ)V |
Using the code
An example of calling Java code from a .NET GUI application
Once a reference is set to the assembly JNI located in the download section of my code, you can start to call Java methods in only a few lines of code.
The first thing that needs to be done is to create a dictionary object that will contain all of the parameters to pass to the Java Virtual Machine. In the example below, I am doing the minimum of setting the class path that will tell the JVM where to look for the classes and packages.
private Dictionary<string, string> jvmParameters = new Dictionary<string, string>();
jvmParameters.Add("-Djava.class.path", Location of the java class);
Once the JVM parameters have been assigned to the dictionary object, an instance of JavaNativeInterface
can be created. Once created, the method LoadJVM
needs to be called with the JVM parameters, and this will then load up the Java Virtual Machine. Once loaded, the user calls the method to instantiate the Java object (note that the use of the method InstantiateJavaObject
is optional as the user may just want to call a static method, in which case, this method does not need to be called; however, it will not cause any harm).
Java = new JavaNativeInterface();
Java.LoadVM(jvmParameters, false);
Java.InstantiateJavaObject(Name of the java class excluding the extension);
Once the JVM has been loaded and a class instantiated, the user may call any method they wish. First create an object list that will contain all of the parameters to pass into the Java method. As it is an object list, it can hold parameters of different types as everything inherits from an object.
List<object> olParameters = new List<object>();
olParameters.Add(Value of the parameter to be passed to the java method);
Next, simply call the generic method CallMethod
passing in the return type of the Java method as the template type. In the example below, I am calling CallMethod<string>
which means that the return type of my Java method that I want to call is a string.
Next, pass in the name of the Java method to call and the method descriptor (see above); finally, pass in the list of all of the parameters. (Note: If no parameters are required, then pass in an empty list.)
Java.CallMethod<string>("AddTwoNumbers", "(IILjava/lang/String;)I", olParameters);
Well, I guess that wraps it all up, but remember that there is so much more you can do with JNI. The test application was just a quick and dirty way to demonstrate the basics of the JNI component. For a full understanding of JNI, I advise you to read this book: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/.