CS351 Spring 2004 Lab 14

Java Native Interface


A Quick Review


	public class HelloWorld {
        public native void displayHelloWorld();

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

        public static void main(String[] args) {
                new HelloWorld().displayHelloWorld();
        }
	}

Actually getting this all working can be tricky.

	create header file: javah HelloWorld

C program:



	#include <jni.h>
	#include "HelloWorld.h"
	#include <stdio.h>

	JNIEXPORT void JNICALL
        Java_HelloWorld_displayHelloWorld(JNIEnv* env, jobject obj)
	{
        printf("Hello world!\n");
        return;
	}

Compile C program (include paths are for CS machines):
 gcc -I/usr/local/pkg/jdk/current/include/ -I/usr/local/pkg/jdk/current/include/linux
 	hello.c -c -o hello.o
 ld -G hello.o -o libhello.so

Run java program:

java -Djava.library.path=./ HelloWorld

If you set your library path to include the local directory, you don't need the -D option:

	export LD_LIBRARY_PATH=./

Working with Arrays

Suppose we had an array of integers, and we wanted to sum them in native code:
	native int sumArray(int arr[]);
We would have this native code:
	JNIEXPORT jint JNICALL
		Java_IntArray_sumArray(JNIEnv* env, jobject obj, jintArray arr);
{
	//Get Length of Array
	jsize len = (*env)->GetArrayLength(env, arr);
	int i, sum=0;

	//Get pointer to the array of primitive Java objects
	jint* body = (*env)->GetIntArrayElements(env,arr,0);

	for(i=0; i<len, i++) {
		sum += body[i];
	}

	//Tell Java we're done with the array. (This is important for the GC)
	(*env)->ReleaseIntArrayElements(env,arr,body,0);
	return sum;
}

Exercise

A common usage of JNI is to use native code for the CPU intensive part of the application. Write two program, one a Java program to multiply two 3x3 matrices, and a Java program that does the same thing with a native method.

The signature of the Java method should be multiplyMatrices(int[] a, int[] b, int[] result).

Here's a simple C program that multiplies two 3x3 matrices for your reference: det.c.

Time the two programs. Which is faster? Is the overhead of transitioning to native code worth the speed-up of the multiply? What about for 4x4 matrices?