18-749 JNI tutorial
by Hwi H. Cheong (Paul)

If you're using EJB for your middleware, you'll realize that Java supports only down to milliseconds in its timers. For evaluating your system and its round trip times, you'll need timers that can return times in microseconds, not milliseconds. Therefore, you can't use Java timers for your evaluation. Instead, you'll have to gain access to a C timer through JNI (Java Native Interface). This tutorial is designed to guide you in making your own JNI timer library so you can use it when you develop your probes for the evaluation.

Steps to JNI implementation
1. Declare a JNI method and statically load the JNI library.
2. Compile the probe java file to produce a binary file.
3. Generate a header file using javah command.
4. Write a .c file that corresponds to the header file declaration. Implement your timer inside this file.
5. Create the library file.

1. Declare a JNI method and statically load the JNI library in probe.java.
Add the following code to the probe class definition:

native long getTimeMicroseconds();

static{
      System.load("/path/to/your/library/libjnitimer.so");
}

Your probe class should look something like this:

public class probe
{
      native long getTimeMicroseconds();

      static{
            System.load("/path/to/your/library/libjnitimer.so");
      }


      public probe(...){}

      ...
}

2. Compile the probe java file to produce a binary file.

% javac probe.java

3. Generate a header file using javah command.

% javah probe

This will create probe.h. This is the header file you'll use to implement your timer method in the next step. The header file probe.h should look something like this:

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

#ifndef _Included_probe
#define _Included_probe
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: probe
* Method: getTimeMicroseconds
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_probe_getTimeMicroseconds
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

4. Write a .c file that corresponds to the header file declaration. Implement your timer inside this file.
I'm going to call this .c file probeTimer.c. The name of the file really is up to you.

#include "probe.h"
#include <sys/time.h>

JNIEXPORT jlong JNICALL Java_probe_getTimeMicroseconds
(JNIEnv *env, jobject obj)
{
      struct timeval tim;
      jlong ret;

      gettimeofday(&tim, 0);
      ret = tim.tv_sec*1000000 + tim.tv_usec;
      return ret;
}

The above method Java_probe_getTimeMicroseconds (which will be just getTimeMicroseconds inside probe.java) returns the current time in microseconds.

5. Create the library file.

% cc probeTimer.c -I/usr/local/j2sdk1.4.2_02/include -I/usr/local/j2sdk1.4.2_02/include/linux -shared -fpic -o libjnitimer.so

If your Java path is different from /usr/local/j2sdk1.4.2_02, simply make appropriate changes.

That's it! You're now able to access the gettimeofday method through JNI. If you want to get fancy, you can use this tutorial as a guide to implement multiple JNI calls in addition to getTimeMicroseconds.