Part 1: The basics of using native methods

In order to tell java that a method is implemented nativly (not inside java) we must use the native keyword.  When the java virtual machine encounters a native method, it will look for a suitable function in one of the DLLs that are currently loaded. Every program which uses a native function must tell the java virtual machine to load the DLL with the specified function, otherwise we will get an UnsatisfiedLinkError.

Here is an example of how to compile a native program. Do not change the code below since even though it seems trivial, changing several things (such as the package, function name and so on) can cause big changes in the way we compile this.
For this first part only, please do not use your IDE.

Program 1.java:

public class Program1 {
   
    // This is our native method, it will be implemented in C
    public static native int random();
   
    // Example usage of our native function
    public static void main(String[] args) {
        int i = random();
        System.out.println("This random number was generated in C: " + i);
    }
   
    static {
        System.loadLibrary("JNI Tutorial");
    }

}

This code is pretty self explanatory. We have a native method which is similar to an abstract method. However, unlike abstract methods, this method will not be implemented by any of the classes that extend this class. Instead, it will be implemnted nativly (in some DLL).
Let’s look for a moment on the last few lines:

    static {
        System.loadLibrary("JNI Tutorial");
    }

 The static keyword means that this section will be done when the class is intialized. The loadLibrary method loads a library (a DLL) which is inside the path for java libraries. In our case, we will put the library in the same directory as our java class file, to make it easier to find later. JNI Tutorial is the name of our library (although the filename is “JNI Tutorial.dll” or something like that, depending on your system. On Solaris it will be ”JNI Tutorial.so” ) and this will be the library which will contain our native function.

Now, we will need to generate the header file for the C code of our DLL. In order to do so, there is a special tool called javah, which comes with our JDK. To use it we must do the following steps:

  1. Open up a command line window (aka terminal).
  2. Add the “bin” directory of your JDK installation to your path. On In windows the directory is usually C:\Program Files\Java\jdkX.X.X_XX\bin and on linux it’s usually /usr/local/jdk/bin.
  3. Change the working directory to the directory of your java file.
  4. Compile it: javac Program1.java (this will produce a class file), and then type javah Program1 (This will work on the class file).

Now we have a file called Program1.h which looks like this:

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

#ifndef _Included_Program1
#define _Included_Program1
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Program1
 * Method:    random
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_Program1_random
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif 

Now we will compile this file to a dll called “JNI Tutorial.dll” and put it in the same directory as all the other files. To do so, we must add the JDK’s include directory to our compiler’s search path.
With MSVC on windows it will look like this (without the line breaks):

cl -I"C:\Program Files\Java\jdk1.6.0_07\include\win32"
   -I"C:\Program Files\Java\jdk1.6.0_07\include"
   -LD Program1.c -Fe"JNI Tutorial.dll"

With GCC on windows it will look like this (without the line breaks):

gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at
   -I"C:\Program Files\Java\jdk1.6.0_07\include"
   -I"C:\Program Files\Java\jdk1.6.0_07\include\win32"
   -shared -o "JNI Tutorial.dll" Program1.c

On other operating systems with gcc, change the path of the included directory to the path of the JDK’s include directory. Notive that the second line of include won’t be win32. Instead, it will match your operating system.

Now, let’s run our program – in the command line, type java Program1 (this will run Program1.class).

This random number was generated in C: 8069

As you can see, our function used jint to represent a java integer. But, what about other types? Here is a table to answer that:

Java Type

Corresponding C type

boolean jboolean
byte jbyte
char jchar
short jshort
int jint
long jlong
float jfloat
double jdouble
void void

Java arrays and objects are not covered in this part, they will be covered in the following parts of this tutorial.

Part 2 of this tutorial will be avialable soon.

3 Responses to “Part 1: The basics of using native methods”
  1. kjv007 says:

    Nice tutorial. But “Program1.C” code is missing.

    “gcc: Program1.C: No such file or directory”

  2. admin says:

    kjv007, I wrote the tutorial without actual access to linux (I did it from my memory), so it may have a problem as you say…
    I’ll look at it tomorrow and fix the tutorial. Thanks for your correction - I appriciate it =)

    I forgot to write the Program1.c file :P
    I’ll write it later on today…

    Thanks again

  3. Virtual PBX says:

    Its good to see you posting on this topic, I need to bookmark this website. Just keep up the good work.

  4.  
Leave a Reply