Jun 13, 2008

Hello World With JNI

Java Native Interface (JNI) can be used to call native code from your Java application. I needed to call a function from a DLL file. Basically JNI addresses interoperability issues and lets your Java code access legacy system. Here I want to share basic “Hello World” application with you which I developed using JNI.

Starting with Java side, all you need to keep in mind while coding is that you have to declare signature of all legacy methods you need to access. All those methods must be declared with native modifier.

Secondly you need to load native library. That you can achieve using System.loadLibrary(). It will try to load library file from basic operating system library location. e.g. WINDOWS\system32 in windows operating system. If you want to provide a specified location, you can use System.load(String filePath) method.

This is how I code HelloWorld.java.


package com.jay.jni;

public class HelloWorld
{
static
{
System.loadLibrary("TestDll");
}

public static void main(String ar[])
{
System.out.println("Hello world from Java");
HelloWorld t=new HelloWorld();
String strFromDLL = t.inDll();

System.out.println(""+strFromDLL);
}

public native String inDll();

}

Next step is to create a header file. For that you need to run following command

javah -jni com.jay.jni.HelloWorld

This will create a header file with name “com_jay_jni_HelloWorld.h”. Generate header file will be as follow.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_jay_jni_HelloWorld */

#ifndef _Included_com_jay_jni_HelloWorld
#define _Included_com_jay_jni_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jay_jni_HelloWorld
* Method: inDll
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jay_jni_HelloWorld_inDll
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Note the package name in header file. Most of the time people copies code from internet and tries to run program after modification in package and/or class name. You need to be very careful while dealing with JNI.

Now comes native code portion. I created a MFC DLL project in VC++.

Once you create a simple DLL project, add three header files into your project.

1. com_jay_jni_HelloWorld.h
2. jni.h
3. jni_md.h

Second and third can be found in \include folder. Then you need to implement your native function.

For that I created a header file my application TesetDLL with name TestDLL.h. Then I added following code into in it at last.

JNIEXPORT jstring JNICALL Java_com_jay_jni_HelloWorld_inDll (JNIEnv * env, jobject jobj)
{
jstring js = (env)->NewStringUTF("Hello From DLL");
return js;
}

That’s all; I build it and created a DLL. Now all I need to do is put my DLL in system library folder (as I used loadLibrary) and run my program.

No comments: