Monday, January 12, 2015

The Hello World JNI example

The Hello World JNI example

A simple example to use native code (C/C++ in this tutorial) via JNI (Java Native Interface). The Java program will take the input from user, and then pass the value to native code to print out on console.

Setup

  • Linux Mint - a modern, elegant and comfortable Linux distro
  • OpenJDK - the JDK on Linux Mint
  • gcc - the c compiler

Installation

Make usre the software is installed properly

$ javac -version
javac 1.7.0_75
$ gcc --version
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
...

Development

Demo.java

package com.example.jni;

public class Demo {

    // load native library at runtime
    static {
        System.loadLibrary("myNative");
    }

    // declare a native method
    public native void helloNative(String message);

    public static void main(String[] args) {
        new Demo().helloNative(args[0]);
    }
}

generate the header file com_example_jni_Demo.h

path/to/java/src $ javah com.example.jni.Demo

no need to modify the header file, but it declares the method to implement

JNIEXPORT void JNICALL Java_com_example_jni_Demo_helloNative
  (JNIEnv *, jobject, jstring);

myNative.c

#include 
#include "com_example_jni_Demo.h"

JNIEXPORT void JNICALL Java_com_example_jni_Demo_helloNative(JNIEnv *env, jobject obj, jstring javaString)
{
    const char *message;
    message = (*env)->GetStringUTFChars(env, javaString, 0);
    printf("native echo: %s\n", message);
}

generate the Shared Library which will be libmyNative.so

path/to/java/src $ gcc -shared -fPIC -o libmyNative.so -I /usr/lib/jvm/java-7-openjdk-amd64/include -I /usr/lib/jvm/java-7-openjdk-amd64/include/linux myNative.cdino

compile and run the program

path/to/java/src $ javac com/example/jni/Demo.java
path/to/java/src $ java -Djava.library.path=path/to/java/src Demo

To run the Java program on Eclipse, add -Djava.library.path=path/to/shared/library to Run configurations -> Arguments -> VM arguments