Java Native Interface

To Compile and Run
The most recent copy of the code is in:
For JNI:
/users/projects/class/vrmidtown/nickjp/java
For JNI stubbed code:
/users/projects/class/vrmidtown/nickjp/java-stub
In order to run the JNI code the class view team has developed so far, you will need to complete the following steps.

First of all, add the following lines to your .login-sgi:

set path = ( $path /usr/java/bin . )
set path = ( $path /users/projects/class/vrmidtown/<your directory> . )
This will ensure that you have the proper java path and that you can access your directory from anywhere (useful when looking at other code).

Second, add the following:

setenv LD_LIBRARY_PATH .
setenv SGI_ABI -o32
setenv THREADS_FLAG native
The LD_LIBRARY_PATH is the shared library path, libcomm.so (if you use our makefile).
The SGI_ABI is a sgi specific environment field.
The THREADS_FLAG makes sure that the java compiles with native threads, not green.

All the .c, .h, .java files will need to be copied into a directory if you want to compile this. Also, copy build and Makefile. You should only have to change the SLINK variable to your working path.

The command by command I use is:

javac Comm.java
javac Agent.java
javah Comm
javah Agent
build
and to run:
java Agent


Adding to the JNI Code
This is the location of the JNI table of contents from Suns site: http://java.sun.com/docs/books/tutorial/native1.1/TOC.html

Here are step by step instructions for compiling a helloworld JNI app: http://java.sun.com/docs/books/tutorial/native1.1/stepbystep/index.html
There is a very close example to this in the following directory: /users/projects/class/vrmidtown/nickjp/hw-java-test

In a nutshell, here are the steps for adding in a new module for JNI. Use the web pages as reference.

WRITE THE JAVA:
Decide on a name for a C shared library (libx.so, where x is the descriptive part). Write a java class which has in its constructor the following:

Static { system.load("x") }
Create any functions you want to call into C with the following syntax:
public native <returns> <function-name> ( <parameters> );
These should go before the constructor, and are actually just prototypes.

COMPILE CODE AND HEADERS:

javac .java
Use javac to compile your java code.

On all classes with a system.load call, do the following:

javah <class>
NOTE: there is no .class or .java after it, it's not a mistake. DO NOTE EDIT THIS .H FILE!!!!

WRITE THE C FILE AND CREATE A SHARED LIBRARY:
The C is standard C syntax for the most part. Be sure to include:

#include <jni.h>
#include "<class>.h"
The syntax for any function called with JNI is:
JNIEXPORT <returns> JNICALL Java_<class>_<function-name> (JNIEnv *env, jobject obj, <parameters>) { }
The rest of the module is straight C unless you are using JNI specific calls to tie into something special in the Java.

Creating the shared library varies from system to system. For the SGI version, look at the makefile in the same directory as the helloworld application from above. I would sugguest using a makefile as it gets very tedious to compile it. For other operating systems, refer to step five of the JNI tutorial or that O/S's homepage.

RUN IT:
Simply do the following:

java <class>
and watch it go.

If you get an UnsatisfiedLink error, one of 3 things happened:

  1. Your functions between Java and C don't match.
  2. You don't have your LD_LIBRARY_PATH set to the same directory as your libx.so file.
    • for ksh or sh, do a man set
    • for csh, do a man setenv
  3. You haven't set the proper flags for the o/s you are using or for any special feature of either side of the code you are using e.g. native threads.

<< Back to Course View: Fall 1998