Search code examples
javac++cubuntujava-native-interface

java.lang.UnsatisfiedLinkError: TestJni.print(LA;)V error on Ubuntu


I know this is an often-seen problem and after search on the web, problem still not solved. -Djava.library.path is already added to the command.

Here is my java file

public class TestJni
{
        public native void print(A a);

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

        public static void main(String []args){
                new TestJni().print(new A());
        }
}
class A{
        void show(){
                System.out.println("In a show function");

        }
}

I am trying to create an instance 'a' which is A class. Pass it to native method print and let native method to invoke show() method. Compile .java into .class

javac TestJni.java

Now I have three files: A.class TestJni.class TestJni.java

Use

javah -classpath . TestJni

to get .h file which is like:

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

#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     TestJni
 * Method:    print
 * Signature: (LA;)V
 */
JNIEXPORT void JNICALL Java_TestJni_print
  (JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif

Rename it to MyJni.h by

mv TestJni.h MyJni.h

Create MyJni.c by

vim MyJni.c

the content of MyJni.c is:

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

#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     TestJni
 * Method:    print
 * Signature: (LA;)V
 */
JNIEXPORT void JNICALL Java_TestJni_print
  (JNIEnv *env, jobject obj, jobject o){
    jclass cls = (*env)->GetObjectClass(env, o);
    jmethodID mid = (*env)->GetMethodID(env, cls, "show", "()V");
    (*env)->CallVoidMethod(env, o, mid);

}

#ifdef __cplusplus
}
#endif
#endif

Build .so file by

gcc -fPIC -shared -o libMyJni.so MyJni.c -I. -I$JAVA_HOME/include -I$JAVA_HOME/include/linux

And now I have 5 files [A.class libMyJni.so MyJni.c MyJni.h TestJni.class TestJni.java] in my directory: /home/grid/code/tmp

Run java program:

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

Now I get the Error which is

Exception in thread "main" java.lang.UnsatisfiedLinkError: TestJni.print(LA;)V
    at TestJni.print(Native Method)
    at TestJni.main(TestJni.java:10)

I am coding under Ubuntu 14.10 and gcc program is the default one. I really not able to figure out what is wrong. Please help me to correct the program. Thank you very much in advance!!!


Solution

  • Remove the

    #ifndef _Included_TestJni
    #define _Included_TestJni
    
    ...
    
    #endif
    

    from the source file. You've already #defined the include guard in the header, so this effectively comments out the code.