javac++cjava-native-interfacejnienv

Java, C++ JNI - java.lang.UnsatisfiedLinkError : No .dylib in java.library.path


I was trying to link java and c++ code using java JNI but when I ran the java file using dylib path, getting an error that no file was available. However, my lib file is available in the current working directory.

Also, I tried moving same dylib to /Library/Java/Extensions but still the same error.

Java File: JNIJava.java

public class JNIJava {
    static {
        System.loadLibrary("JNI_CPP");
    }
    public native void printString(String name);
   
    public static void main(final String[] args) {
        JNIJava jniJava = new JNIJava();
        jniJava.printString("Invoked C++ 'printString' from Java");
    }
}

Header file : JNIJava.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/include/jni.h"
/* Header for class JNIJava */

#ifndef _Included_JNIJava
#define _Included_JNIJava
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JNIJava
 * Method:    printString
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_JNIJava_printString
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

C++ file : JNIJava.cpp

#include <iostream>
#include "JNIJava.h"

using namespace std;

JNIEXPORT void JNICALL Java_JNIJava_printString(JNIEnv *env, jobject jthis, jstring string) {
    const char *stringInC = env->GetStringUTFChars(string, NULL);
    if (NULL == stringInC)
        return;
    cout << stringInC << endl;
    env->ReleaseStringUTFChars(string, stringInC);
}

Used the below commands to link and run the code :

javac JNIJava.java -h .

g++ -dynamiclib -O3 \
    -I/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/include \
    -I/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/include \
    JNIJava.cpp -o JNI_CPP.dylib

java -cp . -Djava.library.path=$(pwd) JNIJava

When I Do ls :

JNIJava.class           JNIJava.cpp             JNIJava.h               JNIJava.java            JNI_CPP.dylib

Error :

Exception in thread "main" java.lang.UnsatisfiedLinkError: no JNI_CPP in java.library.path: /Users/tkapadn/Documents/Documents_Data/Lens-Eclipse-Workspace/Java_JNI/CPP
        at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2447)
        at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:809)
        at java.base/java.lang.System.loadLibrary(System.java:1893)
        at JNIJava.<clinit>(JNIJava.java:3)

Here is the screenshot of the error :

enter image description here

Note - I tried linking c with java using JNI and I was successfully able to run the java file.

Java Version - jdk1.8.0_261, System - macOS Big Sur (11.6.1)

Please provide your suggestions.


Solution

  • instead of using 'System.loadLibrary("")' use 'System.load("lib path")' and check if the library is working.then you can move it to the java library path.

    for example : (tested and working)

    try { 
    
    String libPath = System.getProperty("user.dir") + System.getProperty("file.separator") + System.mapLibraryName("JNI_CPP"); 
    System.load(libPath); 
    
    } catch (Exception e) {
     System.out.println(e.toString());
    }