Getting Started with JNI

Home » Getting Started with JNI » Java » Getting Started with JNI

In this post I am sharing solutions for some problems I have faced while studying Java Native Interface (JNI). Pretty much the same steps found at http://java.sun.com/docs/books/jni/html/start.html were implemented, since I needed the simplest case study possible. Although this study is a Java experiment it involves several other technologies. Moreover, we’ll be compiling platform-dependent code (the C++ part of it), which means that the the architecture of the operational system and the version of the JVM where our final JNI program will be executed definitely matters. Please take a look at the list below and keep in mind that some of the issues we’ll go through are specifically associated to this environment.

  • Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
  • Java HotSpot(TM) 64-Bit Server VM (build 11.0-b16, mixed mode)
  • Eclipse IDE for Java Developers Build id: 20100218-1602
  • Microsoft Visual Studio Professional 2010
  • Microsoft Windows Vista Ultimate 64 SP2

The program we will implement is a Hello World where the Java class will invoke a native method that prints “Hello World” out, the real implementation of the method will be done in C++, and compiled into a Windows (64-bit) binary DLL (Dynamic Link Library) file.

The Java Program

Step #1 — The Java class with a native method

I chose to use Eclipse because it helps to save time and it’s my favorite Java IDE. A Java project was created and our Java class (the one with the native method) stored under the package structure I use to organize my Java code, in this example our class is called “HelloWorld” and lives in the package com.zilotti.studies.jni.helloworld.

[java] package com.zilotti.studies.jni.helloworld;

/**
* Class with a native method.
*
* @author Ivan Zilotti Alencar
* @author $Author$
* @version $Revision$
*/
public class HelloWorld
{
/**
* Native method
*/
private native void print();

static
{
final String LIBRARY_NAME = "HelloWorld";
System.loadLibrary(LIBRARY_NAME);
}

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

Step #2 — Compile the Java class

Since I used Eclipse, the Java class was automatically compiled into the “bin” directory of the project. For example, a command line for compiling it could be javac comzilottistudiesjnihelloworldHelloWorld.java (issued from the “src” directory of the aforementioned Java project).

The compiled Java class

Figure 1 - The compiled Java class.

Step #3 — Create Native Method Header File

The most important point here is issuing the command below in Windows Command shell. Please note that the current directory is our project’s  “bin”ary output directory. It will contain only the “com” directory before the command is issued. After successfully issuing the command below, one will also find a new file, com_zilotti_studies_jni_helloworld_HelloWorld.h, created by javah.

javah -jni com.zilotti.studies.jni.helloworld.HelloWorld
Creating C header file

Figure 2 - Creating C header file.

Step #4 — Open the C header file

The C header file generated by javah contains information about the native method we will implement in C++. We are all set to start working on the C++ project!

The C header file generated by javah

Figure 3 - The C header file generated by javah.

The C++ Library

Step #1 — Create a new “Win32” Project in Microsoft Visual Studio

Choosing C++ Project Type on MS Visual Studio 2010

Figure 4 - Choosing project type in MS Visual Studio 2010.

Step #2 — Application settings and other options…

Application settings

Figure 5 - Application settings.

Application Type

Figure 6 - Choosing application type.

If you made it to this screen and pressed the “Finish” button shown on the Figure 6, you are ready to add the C header to the C++ project.

Step #3 — Add javah Generated Header to the C++ Project

Adding Existing Item...

Figure 7 - Adding existing item to the C++ project.

Finding the Header File

Figure 8 - Finding the header file.

Voilà, Here's our Header!

Figure 9 - Voilà, here's our header!

Step #4 — Add JNI headers to the C++ Project

In order for native methods implemented in C++ to be properly invoked the jni.h header file must be included, it can be found in the JDK. The command shown in the Figure 10 can help you to identify the location of your current JDK.

Figuring out the location of the current JDK.

Figure 10 - Figuring out the location of the current JDK.

Searching for the jni.h header file in the JDK…

Browsing the "include" folder of the JDK.

Figure 12 - Browsing the "include" folder of the JDK.

Project properties menu

Figure 11 - Project properties menu.

Adding the JDK's include folders to the list of include folder of the C++ project.

Figure 13 - Adding the JDK's include directory and its sub-directories to the list of include directories of the C++ project.

Step #5 — Write the Native Method

[cpp] // HelloWorld.cpp : Defines the exported functions for the DLL application.
//

#include <jni.h>
#include <stdio.h>
#include "stdafx.h"
#include "com_zilotti_studies_jni_helloworld_HelloWorld.h"

JNIEXPORT void JNICALL
Java_com_zilotti_studies_jni_helloworld_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!n");
return;
}
[/cpp]

HelloWorld.cpp

Figure 14 - HelloWorld.cpp, under "Source Files".

Step #6 — Change Target Platform to x64

Changing target platform to x64.

Figure 15 - Changing target platform to x64.

Step #7 — Building the C++ Project

Building the C++ Project

Figure 16 -- Building the C++ project.

The compiled DLL file.

Figure 17 - The compiled DLL file.

Running the Java Program

Now we have the 2 major components required to execute our project: the Java program which simply specifies the native method; and the native implementation, bundled in the DLL file we have just compiled.

Executing the Java project on Eclipse.

Figure 18 - Executing the Java project on Eclipse.

Setting the java.library.path property.

Figure 19 - Setting the java.library.path property.

The final result!

Figure 20 - Finally the final result! Now you are ready (or not) for something more profound.

One comment
  1. Camila Cândido April 7, 2011 at 1:18 pm

    Very interesting!

Leave a Comment