6

java.lang.UnsatisfiedLinkError

I'm using the hello-jni example, and for whatever reason, I'm getting a java.lang.UnsatisfiedLinkError when I try to call the hello-jni library. Any ideas why? Do I have to set my path somewhere?

in HelloJni.java:

public native String  stringFromJNI();

and

static {
    System.loadLibrary("hello-jni");
}

in hello-jni.c:

jstring
Java_com_bdunlay_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}

exception trace

the .so file is... project_root/libs/armeabi/libhello-jni.so

Brian D
  • 9,863
  • 18
  • 61
  • 96
  • Information is too few. where is the .so you put and what is the filename ? What is the argument of your System.loadLibrary() – qrtt1 Jan 27 '11 at 06:44
  • 1
    Hmmm. It looks good. Please show the result of 'arm-eabi-nm libhello-jni.so' and header file as well. – qrtt1 Jan 27 '11 at 07:03
  • arm-eabi-nm libhello-jni.so: no symbols. Haha, embarrassing. I didn't have a header file in my project! I'd give you checkmark if you'd answer make sure you include your header files! – Brian D Jan 27 '11 at 07:08
  • Do I need to include the jni.h file in *every* project that uses the NDK? – Brian D Jan 27 '11 at 07:11
  • you should generate the header from java class properly. – qrtt1 Jan 27 '11 at 07:16

4 Answers4

6

your native have no JNIEXPORT. It usually declares in header file with function declaration.

We will use javah -jni to generate the header

qrtt1
  • 7,746
  • 8
  • 42
  • 62
  • 2
    This may be a trivial question, but how do I manually generate this? I am writing this through eclipse and pressing the play button to compile everything the easy way :) – Brian D Jan 27 '11 at 07:18
  • javah -jni YourClassWithFullName – qrtt1 Jan 27 '11 at 07:22
  • there is a quickstart tutorial http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html#sol – qrtt1 Jan 27 '11 at 07:24
  • in root/src/com/bdunlay/hellojni I ran *javah -jni HelloJni.java* and got this response: $ javah -jni HelloJni.java / error: cannot access HelloJni.java / class file for HelloJni.java not found / javadoc: error - Class HelloJni.java not found. / Error: No classes were specified on the command line. Try -help. / I also ran it without .java and it said that the class was not found as well. – Brian D Jan 27 '11 at 07:27
  • javah will parse the bytecode, not source code. You need to compile the HelloJni.java to HelloJni.class first. – qrtt1 Jan 27 '11 at 07:28
  • Well, it's android -- I don't quite compile classes directly. What I did manage to do though was force a rebuild of everything using the android ndk's "ndk-build" tool, and that seems to have generated the proper headers. Thanks for the help. – Brian D Jan 27 '11 at 07:38
  • The header will not change frequently, if you have define the 'interface' good enough. Whatever, classes could be from other compiled, such as .jar. The javah can set classpath pointing to it. – qrtt1 Jan 27 '11 at 07:49
5

See android-ndk-r8b/documentation.html for additional details.

By default, the sample does not include an Application.mk file (in the /jni/ folder). I corrected the problem by adding this file to my project and adding the following single entry which allows the built files to build for multiple CPU types (specifically looking for x86 in my case):

APP_ABI := armeabi armeabi-v7a x86

After adding that file, you can again run ndk-build to produce the required files and then build your APK as normal.

iDurocher
  • 875
  • 9
  • 11
1

java.lang.UnsatisfiedLinkError: Native method not found exception for methods from OpenCV means that you try to use OpenCV before its initialization. You may use OpenCV objects and call methods from library only after onManagerConnected with status LoaderCallbackInterface.SUCCESS.

Lina Shyshova
  • 546
  • 5
  • 12
1

In my case the reason of error was: If you have multiple libraries loaded as

System.loadLibrary("lib1");
System.loadLibrary("lib2");

and lib1 depends on lib2, you need load lib2 first.

NoAngel
  • 1,072
  • 2
  • 18
  • 27
  • even better: ndk-depends from Android SDK may be used to get right order of loading your dynamic libraries. Just type ndk-depends --print-java – NoAngel Dec 08 '14 at 06:45