Thursday, September 19, 2024

Java Native Interface

Ok, so now you finally admitted to yourself that you’ve got a problem! You have all this code that has been doing its job for years now but it really needs a bit of a makeover. What doesn’t help your cause is that it has come to your boss’s attention that “Java is the way to go!” and he or she is now eager to harness the powers of this mystical thing they call “Java”. This situation may seem a little far-fetched but a lot of developers have found themselves facing the problem of dealing with “legacy code” or code that has been written in a style or language that is now considered outdated.

Thankfully in your situation you do not have to go and re-write your existing code from scratch in Java. This is because the nice people at Sun Microsystems, who developed Java, anticipated that this tiny problem may pop up at some point in time. Their solution was the Java Native Interface (please, call me JNI!), which enables developers to incorporate their native code from C, C++ or assembly into Java and thus ensure the portability of your code across multiple platforms.

Anyways, enough jibber-jabber for now and onwards to the code:
//Filename: goodMorning.java
class goodMorning{
    public native void whatNow();
    static
    {
      System.loadLibrary(“goodMorning”);
    }

    public static void main( String args[])
    {
      new goodMorning().whatNow();
    }
}

Native?

    public native void whatNow();

Hang on a second! What is that “native” doing there in the function declaration? Well, the keyword “native” is what lets the Java compiler know that the implementation for that specific function is done in a language other than Java. This actual implementation should be located in a source file of the native language. In our case, this will be “goodMorning.c”. goodMorning?

static
    {
      System.loadLibrary(“goodMorning”);
    }

We will see a little later on how to build a library that contains the native implementations but for right now all you need to understand is that the System.loadLibrary() call will perform the loading of this library. The static block is makes sure that the library is only loaded one per class. Compiling the code

The next step is to compile the code using:

javac goodMorning.java

Generating the header file
This was in my opinion the coolest part because this is where Java generates the header files FOR YOU! (I don’t get out much as you can tell). You can do this by simply running the following command: javah –jni goodMorning The result is file called goodMorning.h that looks rather interesting if you take a look at it.

/* DO NOT EDIT THIS FILE – it is machine generated */
#include <jni.h>
/* Header for class goodMorning */

#ifndef _Included_goodMorning
#define _Included_goodMorning
#ifdef __cplusplus
extern “C” {
#endif
/*
  * Class: goodMorning
  * Method: whatNow
  * Signature: ()V
*/
JNIEXPORT void JNICALL Java_goodMorning_whatNow
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

The Java_goodMorning_whatNow function provides the implementation for the goodMorning class’s native method whatNow. We will use the same function signature to write the native implementation next but before that it would be worth taking a look at the parameters of the function signature. The JNIEnv pointer is what allows the native code to access those parameters and objects that the Java application passes onto it. The second parameter or jobject refers to the method that is calling this bit of native code. The native implementation

As promised, the Java_goodMorning_whatNow reappears but this time in the actual native implementation in our C source file!

//Filename: goodMorning.c
#include <stdio.h>
#include <jni.h>
#include “goodMorning.h”

JNIEXPORT void JNICALL Java_goodMorning_whatNow
  (JNIEnv *env, jobject obj)
{
    printf(“How about some COFFEE!!!!”);
    return;
}

Didn’t you say something about a library?
Now we can finally get down to building that library that will be loaded during runtime. Gnu C/Linux:
gcc -o libgoodMorning.so -shared -Wl,-soname,libgoodMorning.so

    -I/export/home/j2sdk1.4.0/include
    -I/export/home/j2sdk1.4.0/include/linux goodMorning.c
    -static -lc

Win32/WinNT/Win2000
cl -Ic:/j2sdk1.4.0/include
  -Ic:/j2sdk1.4.0/include/win32
  -LD goodMorning.c -FegoodMorning.dll

If you encounter an error like java.lang.UnsatisfiedLinkError, then your path has not been set. To go about setting it :
Unix or Linux:
  LD_LIBRARY_PATH=`pwd`
  export LD_LIBRARY_PATH

Windows NT/2000/95:
  set PATH=%path%;.

Finally, to run the program, type:
java goodMorning
and you should get a nice little message saying:
How about some COFFEE!!!!

Feel free to change the message depending on your preference of beverage! Back to the point, what you have just seen is a very basic JNI example and for those of you who would like to learn more about it, Sun has it’s JNI tutorial (see link below)

And that concludes our look at the Java Native Interface or JNI, which to recap, could make your life easier the next time you are asked to port over your old C, C++ or assembly code to Java possibly alleviating you of those legacy code problems! Now if you will excuse me, I am going to my code’s advice and go get myself a cup of coffee! Until next time!

murdok provides free highly informative newsletters for web developers, IT professionals and small business owners. We deliver 50 million email newsletters per month and have over 4,000,000 unique opt-in subscribers. From our extensive range of email newsletters we can provide you with a selection of newsletters that best meet your interests.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles

Content management software.