In this tutorial I will use Eclipse with CDT (using MinGW/gcc) to create a simple hello world example. Therefore we will create a Java program, that calls native code from a shared library. Settings for linux and windows differ in some details, so these differences will be explicitely marked.
Source code for this tutorial is available on github as a single zip archive, as a Team Project Set or you can browse the files online.
Step 1: Creating a Java Project
First create a new Java Project called "com.codeandme.jni". Create a class "com.codeandme.jni.JNITest" with following content:
package com.codeandme.jni;
public class JNITest {
static {
// load library
if (System.getProperty("os.name").startsWith("Windows"))
// windows
System.loadLibrary("libJNI_Library_windows");
else
// linux
System.loadLibrary("JNI_Library_linux");
}
public static void main(final String[] args) {
new JNITest().hello("world");
}
// native method signature
public native void hello(String name);
}
Line 9/13 will trigger loading of the shared library.Line 21 declares an external method which is implemented in the native library.
Create a new folder called resources under your project root. This will be the location for our JNI library.
Step 2: Create C++ Project
Now we need to create the library code. Therefore create a new C++ Project called "JNI_Library". As Project Type select Shared Library/Empty Project. This will provide reasonable defaults for our build. Create a source folder src within that project.
The header file for the shared functions needs to follow a very specific coding. This is generated by javah, a helper program of your JDK. We will do this by using an external tool helper.
Use Run -> External Tools -> External Tools Configurations... and create a new Program launcher:
Location: C:\Program Files\Java\jdk1.8.0_31\bin\javah.exe
Working Directory: ${workspace_loc:/com.codeandme.jni/bin}
Arguments: -jni -d "${workspace_loc:/JNI_Library_windows/src}" com.codeandme.jni.JNITest
This launcher will create a header file within the src folder of our C++ Project. On linux you will have to change the Location to /usr/bin/javah. On the refresh tab you can enable refreshing of the target folder. Otherwise refresh manually after file creation.
Open the project properties of JNI_Library and go to C/C++ General/Paths and Symbols. Select [All Configurations] from the Configuration combo at the top of the dialog.
On the Includes tab add following folders from your JDK to the include paths for GNU C++.
Windows:
- include
- include/win32
- include
- include/linux
Now we can add our implementation in C++.
Create a new source file within src folder named com_codeandme_jni_JNITest.cpp. Add following content to the file
#include <iostream>
#include "com_codeandme_jni_JNITest.h"
using namespace std;
JNIEXPORT void JNICALL Java_com_codeandme_jni_JNITest_hello
(JNIEnv *env, jobject jthis, jstring data) {
jboolean iscopy;
const char *charData = env->GetStringUTFChars(data, &iscopy);
cout << "Hello " << charData << endl;
env->ReleaseStringUTFChars(data, charData);
}
Finally we need to adjust our build settings a bit. Open the project properties and go to C/C++ Build/Settings. Switch to the Tool Settings tab:
Windows:
- GCC C++ Compiler/Miscellaneous: enable Position independent code (-fPIC)
- GCC C++ Linker/Shared Library Settings: enable Shared (-shared)
- MinGW C++ Linker/Miscellaneous: add -Wl,--add-stdcall-alias
- GCC C++ Compiler/Miscellaneous: enable Position independent code (-fPIC)
- GCC C++ Linker/Shared Library Settings: enable Shared (-shared)
Windows:
- xcopy "${BuildArtifactFilePrefix}${BuildArtifactFileName}" "${workspace_loc:/com.codeandme.jni/resources/}" /Y
- cp "${BuildArtifactFilePrefix}${BuildArtifactFileName}" "${workspace_loc:/com.codeandme.jni/resources/}"
This will automatically copy our build product to the Java Project we created at step 1.
Save all settings and build your library. It should be copied over to your Java Project. Refresh your workspace (F5) to see the newly created file.
Step 3: Put it all together
We are almost done. As a final step we need to add the resource folder to the library path of our run target.
Launch your Java program to create a launch target for it. You will get an Exception, don't worry, we'll fix that immediately. Go to Run -> Run Configurations... and find your Java run target (typically named JNITest). On the Arguments tab add
-Djava.library.path="${workspace_loc:/com.codeandme.jni/resources/}"to VM arguments.
Now launch your Java program and you should get a "Hello world" on your console view.
Further reading
It is also possible to have asynchronous callbacks from C to Java. An example how to do this is available on github.

