2

In my java class I have this:

static
{
    System.loadLibrary("c++_shared");

    System.loadLibrary("com.testandroid.LibAndroidBridge");
}

And my Application.mk has this:

NDK_TOOLCHAIN_VERSION:=4.8
APP_STL := c++_shared
APP_ABI := x86

Things build fine, but when I run the app (on emulator or device, so x85 and arm) I get this in LogCat:

02-13 12:00:32.174: D/dalvikvm(2142): Trying to load lib /data/app-lib/com.testandroid-1/libc++_shared.so 0xb0fcfc60
02-13 12:00:32.174: D/dalvikvm(2142): Added shared lib /data/app-lib/com.testandroid-1/libc++_shared.so 0xb0fcfc60
02-13 12:00:32.174: D/dalvikvm(2142): No JNI_OnLoad found in /data/app-lib/com.testandroid-1/libc++_shared.so 0xb0fcfc60, skipping init
02-13 12:00:32.174: D/dalvikvm(2142): Trying to load lib /data/app-lib/com.testandroid-1/libcom.testandroid.LibAndroidBridge.so 0xb0fcfc60
02-13 12:00:32.174: E/dalvikvm(2142): dlopen("/data/app-lib/com.testandroid-1/libcom.testandroid.LibAndroidBridge.so") failed: dlopen failed: cannot locate symbol "rand" referenced by "libcom.testandroid.LibAndroidBridge.so"...
02-13 12:00:32.174: W/dalvikvm(2142): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/testandroid/AriesLib;
02-13 12:00:32.174: D/AndroidRuntime(2142): Shutting down VM
02-13 12:00:32.174: W/dalvikvm(2142): threadid=1: thread exiting with uncaught exception (group=0xb0cb0b20)
02-13 12:00:32.174: E/AndroidRuntime(2142): FATAL EXCEPTION: main
02-13 12:00:32.174: E/AndroidRuntime(2142): Process: com.testandroid, PID: 2142
02-13 12:00:32.174: E/AndroidRuntime(2142): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "rand" referenced by "libcom.testandroid.LibAndroidBridge.so"...
02-13 12:00:32.174: E/AndroidRuntime(2142):     at java.lang.Runtime.loadLibrary(Runtime.java:364)

Would anyone know why this is failing to import the c++_shared.so library?

TooManyEduardos
  • 4,206
  • 7
  • 35
  • 66

3 Answers3

3

The real error is something else: rand() is not present, because of Android-21 incompatibilities.

java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "rand" referenced by

See this thread for more info.

The recommended fix is to downgrade your API in jni/Application.mk and set it to something lower than Android-21. If you need Android-21 then Google actually recommends shipping multiple APK files. Ugh.

Community
  • 1
  • 1
Bram
  • 7,440
  • 3
  • 52
  • 94
0

Problem is entirely on native side. Java has no any clue on what's happening past the JNI boundary. You cannot make two native libraries go along this way. Especially, C++ standard library (it has no any symbols easily and reliably accessible by JNI).

You should resolve all the symbols on the native side, i.e. you should correctly link C++ Standard Library to your libcom.testandroid.LibAndroidBridge.so.

I'd advised against mixing { gcc toolchain (4.8 in your case) + libc++ ("c++_shared") } or { clang + libstdc++ } on Android. It should work theoretically on desktop Linux or OSX, but there are still portability issues and some quirks persist on Android, depending on NDK version, target, and some "random" factors. So it doesn't always work.

Unfortunately you did not provide the code where you are using rand (maybe it's even non Standard Library rand, but some custom code?), but you can still try:

  • to use GCC's GNU Standard Library, leaving GCC 4.8 as toolchain

OR

  • to use Clang compiler, leaving libc++ as Standard library

AND/OR

  • to use static linking for "debugging purposes" (it won't link until something is missing, allowing you to find the cause without messing with Java and JNI)
Ivan Aksamentov - Drop
  • 12,860
  • 3
  • 34
  • 61
  • Fair enough. I'm not importing the c++_shared library in Java now, and I have commented out the NDK_TOOLCHAIN_VERSION:=4.8. The plan is to compile with llvm, or as close as possible. According to the docs c++_shared is LLVM, right? The rand is a called as rand(); in the C++ code, and it comes from stdlib.h as int rand(void); – TooManyEduardos Feb 13 '15 at 18:25
  • With these changes, I still get the dlopen("/data/app-lib/com.testandroid-1/libcom.testandroid.LibAndroidBridge.so") failed: dlopen failed: cannot locate symbol "rand" referenced by "libcom.testandroid.LibAndroidBridge.so"... – TooManyEduardos Feb 13 '15 at 18:27
  • Yes, libc++ is a part of LLVM project, same as Clang compiler. Removing `NDK_TOOLCHAIN_VERSION:=4.8` will change nothing. NDK uses GCC by default (version being used depends on NDK version). To get your lib compiled with clang, use `NDK_TOOLCHAIN_VERSION := clang`. If it won't help, try also `APP_STL := c++_static` as for third point in my answer. In all cases, double check that you are properly cleaning up all the old binaries (*.o, *.so, *.a) before rebuild, as well as final APK. Use verbose build output (`-V` option) to verify that your project builds with desired toolchain and library. – Ivan Aksamentov - Drop Feb 13 '15 at 19:44
  • The problem with using clang is that I get compile errors on several .c files, and I dont get these issues with toolchain 4.8. Should I use clang and try to fix these compile issues, or should I keep 4.8 and try to solve this rand() issue some other way? – TooManyEduardos Feb 13 '15 at 19:47
  • 1
    Let's try another thing: set `APP_PLATFORM=android-19` in `Application.mk` – Ivan Aksamentov - Drop Feb 13 '15 at 19:52
  • With APP_PLATFORM=android-19, NDK_TOOLCHAIN_VERSION:=4.8 and APP_STL := c++_static, I now get "No JNI_OnLoad found", and then a "UnsatisfiedLinkError: Native method not found" com.testandroid.AriesLib.Process:(Ljava/lang/String;Ljava/lang/String;JZI)I – TooManyEduardos Feb 13 '15 at 20:00
  • Looks like it works. The problem now in in how you are calling native code from Java. But you don't show this code, so I don't know what's wrong. – Ivan Aksamentov - Drop Feb 13 '15 at 21:22
  • Yeah I got to that conclusion a couple of minutes ago. Thank you for your help! – TooManyEduardos Feb 13 '15 at 21:23
0

You don't have to write

System.loadLibrary("c++_shared");

just include :-

APP_STL := c++_shared 

in your Application.mk That should make it work and now libc++_shared.so will be bundled

Sumit Kumar Saha
  • 799
  • 1
  • 12
  • 25