Advertisment

Java Native Interface

author-image
PCQ Bureau
New Update

In the first part, we demonstrated Java multithreading (Multithreading in Java, January 2005, page 90). This article will show how Java can call other programming language functions using JNI (Java Native Interface). JNI allows the use of function libraries made in languages such as C, C++, VB from Java applications. The advantage of JNI is that you don't need to write the calling function definition in Java. This ability resides in the native language. Java code can also be invoked from C or C++ but you need to load the Java Virtual Machine in C or C++ program. 

Advertisment

Pre-requisites



We will first create a DLL using Microsoft Visual C++ Toolkit 2003 and then we will create an appliaction in Java to call the function in our DLL. For this, you need JDK to be installed. Install JDK (jdk1.5.0_01) and the VC++ Toolkit given on this month's PCQEssential CD and note their installation location. We installed jdk1.5.0_01 in C drive and the toolkit in the program files. Set the location of JDK in the 'PATH' variable of the OS. We will run the application in Win XP. 

Calling a function written in C 



A Java file, Java header file, C file and DLL need to be created. We will first show what each file does, and then compile and run it. 

Java file 



The Java file loads DLL and declares the C function, which is to be called. There is no restriction to the number of functions that can be called. The C function that needs to be called is declared in line 2 of the code shown here with the keyword 'native'. Every function that is called must have a native keyword. This keyword tells the Java complier that the function is from another language. The implementation of the function is in the C file. Line 3 loads the .dll file named hello, which is created using System.loadLibary method in Java. Line 5 creates class object and calls the C function, display(). 

Advertisment
Direct Hit!
Applies to: Java programmers
USP:

Create a DLL using VC++ toolkit and invoke it in a Java application
Links:

www.java.sun.com  
On PCQEssential CD:

system\cdrom\developers

1. public class test{



2. public native void display(); 


3. static { System.loadLibrary("hello");}


4. public static void main(String<> args) {


5. new test().display( ); }


6. }



Copy the above (lines 1 to 6) in notepad, remove the line numbers and save it as 'test.java' in C drive. Compile the program by going to command prompt and type C:\ javac test.java. A class file with name 'test' will be created. 

Advertisment

Java header file



The header file is created from the class file. The header file provides the signature of the C function defined in the Java file. Javah utility creates the header file and provides the signature of the native method. The signature is of the form java_ plus name of package and class plus _ plus name of the native method and two arguments. Note that the two arguments are not there in declaration in the Java file, instead they are there in the header file for every function. The first argument is JNIEnv interface pointer. It is through this pointer that the C program will access parameters and objects passed to it by the Java program. Our example does not require JNIEnv. The second parameter jobject gives a reference to the current java object. It is similar to 'this' in Java. 

#include



#ifndef _Included_test


.


extern "C" {


#endif


.


JNIEXPORT void JNICALL Java_test_display (JNIEnv *, jobject);




Let's now create the header file from the class file created above. Run the command C:\ javah -jni test. A header file with name 'test' is created. The file will be similar to the one shown above. 

Advertisment

C file



The C file contains the implementation of the native function defined in the Java file. It includes three files, namely jni.h, test.h and stdio.h. It also implements the native method defined in the Java file. The file, jni.h provides the necessary information for C program to interact with java runtime. The header file is test.h, while stdio.h is the C library file that shows the output 'native'. 

1. #include



2. #include "test.h"


3. #include


4. JNIEXPORT void JNICALL Java_test_display(JNIEnv *env, jobject obj){


5. printf("native");


6. return;


}




Copy these lines in notepad, remove the line number and save it as 'test.c' where the Visual C++ toolkit is installed. 

Advertisment

The DLL 



Open the Visual C++ 2003 Toolkit command prompt by going to Start>Program >Microsoft Visual C++ Toolkit 2003. Type the command as shown below: 

CL -Ic:\jdk1.5.0_01\include -Ic:\jdk1.5.0_01\include\win32 -LD test.c

-Fehello.dll

The command has jdk path (C drive), replace 1.5.0_01 with whatever version of jdk you have. The C file created above is called test.c. The name of the .dll file is 'hello',called by the Java program. The file 'hello.dll' is created in C:\Program Files\Microsoft Visual C++ Toolkit 2003. Copy it to C:\, where 'test.java' is also saved.

Advertisment

Here is what you see when you build and run your code 

Running the program



Go to command prompt and type C:>java test. The command prompt will display 'native' as output. This string,of course, comes from DLL and this means everything is working fine. JNI also allows passing parameters such as integer, float, double and strings to and from the native method. JNI has defined data types to be used with native method. For instance, jint should be issued if an integer is to be passed to native method and so on for other data types.

Issues with JNI



Though JNI enables to call native language code, but Java portability is no longer maintained. If you want to distribute the above application for a platform other than Windows you need to create native library (DLL) for that platform. The user then needs to be told how to create DLLs for that platform. Java language write once run anywhere is no longer maintained. Native method can also possess security risk depending upon which language method is invoked. For instance, C language does not have the capability to handle runtime error such as array overflow and bad pointers. The developer must take care to handle errors that can occur while invoking other language methods. If an error occurs, it must be handled by Java application. In the next article, we will demonstrate other Java applications. 

Sushil Oswal

Advertisment