Error when using JNI on ubuntu: java.lang.Unsatisf

2019-09-09 12:10发布

问题:

I know there are similar questions on this topic but none of the answers could solve my problem:

I have a java file:

class hjni {

     static {
         System.loadLibrary("hjni");
     }

     private native void print();

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

I use the following to compile and generate header files:

javac hjni.java
javah -jni hjni

Here is the C++ file:

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

 JNIEXPORT void JNICALL 
 Java_hjni_print(JNIEnv *env, jobject obj)
 {
     printf("Hello World!\n");
     return;
 }

I compile the C++ file:

g++ -fPIC -shared -I/usr/lib/jvm/java-7-openjdk-amd64/include -I/usr/lib/jvm/java-7-openjdk-amd64/include/linux hjni.cpp -o hjni.so

The files hjni.class, hjni.h, and hjni.so are all created.

I run the java file:

java -Djava.library.path=. hjni

Here is the error I get:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no hjni in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1889)
    at java.lang.Runtime.loadLibrary0(Runtime.java:849)
    at java.lang.System.loadLibrary(System.java:1088)
    at hjni.<clinit>(hjni.java:4)

I use java -XshowSettings:properties to check java.library.path:

java.library.path = /usr/java/packages/lib/amd64
        /usr/lib/x86_64-linux-gnu/jni
        /lib/x86_64-linux-gnu
        /usr/lib/x86_64-linux-gnu
        /usr/lib/jni
        /lib
        /usr/lib

Interestingly, the folder

/usr/java/packages/lib/amd64

does not exist:

cd /usr/java/packages/lib/amd64
bash: cd: /usr/java/packages/lib/amd64: No such file or directory

I could find a shared library (libjli.so) here:

/usr/lib/jvm/java-7-openjdk-amd64/lib/amd64/jli

when I add the above path by

export LD_LIBRARY_PATH=/usr/lib/jvm/java-7-openjdk-amd64/lib/amd64/jli

the path is successfully added as long as the terminal is open. If I close the terminal and reopen it, then the added path is no longer there. I also copied hjni.so to the jli folder but I got the same linking error.

回答1:

When you do System.loadLibrary("hjni") Java will look for a file called libhjni.so. Call System.mapLibraryName(libname) to find out what the file name for a given lib should be. Unfortunately the Javadoc for mapLibraryName only states the name will be mapped to a platform dependent name but not what the rules for building this file name are. It's <name>.dll for Windows, lib<name>.so for Linux and lib<name>.jnilib for Mac OS X, but I can't find a reference for that right now.

If you rename your file, everything will work.