Click here to Skip to main content
15,885,032 members
Articles / Programming Languages / C# 4.0

Using the Java Native Interface in C#

Rate me:
Please Sign up or sign in to vote.
4.90/5 (18 votes)
16 Feb 2016CPOL4 min read 154.7K   4.9K   77   36
How to invoke Java methods from a .NET application.

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.

Java
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
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.

C#
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.)

C#
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/.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
AnswerRe: Failure passing objects and arrays into Java Pin
Simon Agholor27-Nov-13 1:19
Simon Agholor27-Nov-13 1:19 
QuestionComplex Data Types, Methods, Structures, Constructors and Classes Using Java Native Interface in C# 2008 Pin
MrKyaw27-Jan-13 19:15
MrKyaw27-Jan-13 19:15 
AnswerRe: Complex Data Types, Methods, Structures, Constructors and Classes Using Java Native Interface in C# 2008 Pin
MrKyaw27-Jan-13 20:00
MrKyaw27-Jan-13 20:00 
GeneralRe: Complex Data Types, Methods, Structures, Constructors and Classes Using Java Native Interface in C# 2008 Pin
MrKyaw27-Jan-13 22:09
MrKyaw27-Jan-13 22:09 
AnswerRe: Complex Data Types, Methods, Structures, Constructors and Classes Using Java Native Interface in C# 2008 Pin
Simon Agholor27-Nov-13 1:24
Simon Agholor27-Nov-13 1:24 
AnswerImplementing IDisposable Pin
Simon Agholor15-Jan-13 2:32
Simon Agholor15-Jan-13 2:32 
BugYou leek a lot of unmanaged resources Pin
leftler26-Aug-12 10:09
leftler26-Aug-12 10:09 
AnswerRe: You leek a lot of unmanaged resources Pin
Simon Agholor11-Mar-13 5:38
Simon Agholor11-Mar-13 5:38 
I disagree with this the memory space that was assigned to from FindClass & NewObject need to be freed however reading the java documentation the rest do not need to freeded. If I try to implement your code snippets I just get access violations whenever I try to do multiple calls.
However I have implemented the IDisposable as you suggested
QuestionFinding files in JNI Pin
andreh12313-Aug-12 15:00
andreh12313-Aug-12 15:00 
AnswerRe: Finding files in JNI Pin
Simon Agholor14-Aug-12 4:48
Simon Agholor14-Aug-12 4:48 
GeneralRe: Finding files in JNI Pin
andreh12314-Aug-12 15:19
andreh12314-Aug-12 15:19 
GeneralRe: Finding files in JNI Pin
Simon Agholor14-Aug-12 23:06
Simon Agholor14-Aug-12 23:06 
Questiondoes not handle array Pin
zigcjunk8-Feb-12 6:38
zigcjunk8-Feb-12 6:38 
AnswerRe: does not handle array Pin
Simon Agholor9-Feb-12 6:39
Simon Agholor9-Feb-12 6:39 
AnswerRe: does not handle array Pin
Simon Agholor27-Nov-13 1:21
Simon Agholor27-Nov-13 1:21 
Suggestionjni4net Pin
Zamboch28-Aug-11 1:46
Zamboch28-Aug-11 1:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.