Skip to content

Instantly share code, notes, and snippets.

@DmitrySoshnikov
Last active May 1, 2024 05:02
Show Gist options
  • Save DmitrySoshnikov/8b1599a5197b5469c8cc07025f600fdb to your computer and use it in GitHub Desktop.
Save DmitrySoshnikov/8b1599a5197b5469c8cc07025f600fdb to your computer and use it in GitHub Desktop.

JNI Example (Mac OS)

JNI (Java Native Interface) allows implementing methods in C/C++, and use them in Java.

1. Create JNIExample.java file

class JNIExample {

  // Native method, no body.
  public native void sayHello(int length);

  public static void main (String args[]) {
    String str = "Hello, world!";

    (new JNIExample()).sayHello(str.length());
  }

  // This loads the library at runtime. NOTICE: on *nix/Mac the extension of the
  // lib should exactly be `.jnilib`, not `.so`, and have `lib` prefix, i.e.
  // the library file should be `libjniexample.jnilib`.
  static {
    System.loadLibrary("jniexample");
  }
}

2. Compile the JNIExample.java file

This gives you JNIExample.class:

javac JNIExample.java

3. Codegen .h file for JNI

javah -jni JNIExample

This gives you JNIExample.h (do not edit it manually!):

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNIExample */

#ifndef _Included_JNIExample
#define _Included_JNIExample
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JNIExample
 * Method:    sayHello
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_JNIExample_sayHello
  (JNIEnv *, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif

4. Create JNIExample.c

Native implementation:

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

JNIEXPORT void JNICALL Java_JNIExample_sayHello
  (JNIEnv *env, jobject object, jint len) {
  printf("\nThe length of your string is %d.\n\n", len);
}

5. Compile C library

IMPORTANT: library extension should exactly be .jnilib (not .so!), and should have lib prefix, i.e. libjniexample.jnilib:

gcc -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin/" -o libjniexample.jnilib -shared JNIExample.c

NOTICE: the $JAVA_HOME can be taken from (for 1.8 version in this case):

export JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"

6. Execute the java class

Notice, we set java.library.path to current directory, where the libjniexample.jnilib was compiled to:

java -Djava.library.path=. JNIExample

Result:

The length of your string is 13.
@MrWangFeiHu
Copy link

Hello, When I run the command:
java -Djava.library.path=. JNIExample

I got the error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no jniexample in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1863)
	at java.lang.Runtime.loadLibrary0(Runtime.java:843)
	at java.lang.System.loadLibrary(System.java:1134)
	at JNIExample.<clinit>(JNIExample.java:16)

env: MacOS Monterey 12.3

$gcc -v
Apple clang version 13.1.6 (clang-1316.0.21.2.5)
Target: arm64-apple-darwin21.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$java -version
java version "1.8.0_351"
Java(TM) SE Runtime Environment (build 1.8.0_351-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.351-b10, mixed mode)

Do yo know how to solve this error? thank you very much.

@midhunadarvin
Copy link

midhunadarvin commented May 1, 2024

Hello, When I run the command: java -Djava.library.path=. JNIExample

I got the error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no jniexample in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1863)
	at java.lang.Runtime.loadLibrary0(Runtime.java:843)
	at java.lang.System.loadLibrary(System.java:1134)
	at JNIExample.<clinit>(JNIExample.java:16)

env: MacOS Monterey 12.3

$gcc -v
Apple clang version 13.1.6 (clang-1316.0.21.2.5)
Target: arm64-apple-darwin21.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$java -version
java version "1.8.0_351"
Java(TM) SE Runtime Environment (build 1.8.0_351-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.351-b10, mixed mode)

Do yo know how to solve this error? thank you very much.

Getting the same error in MacOS M1 . .so and .jnilib doesn't work for me.

EDIT :

Figured it out by referring this : https://www.baeldung.com/jni

Compile ( MacOS ) :

g++ -c -fPIC -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/darwin" JNIExample.c -o JNIExample.o

Link ( MacOS ) :

g++ -dynamiclib -o libjniexample.dylib JNIExample.o -lc

Run :

java -cp . -Djava.library.path=. JNIExample

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment