Saturday, November 26, 2016

Unable to find native library / findLibrary returned null

Ever since doing Android development in 2012, I've been getting crash reports that showed my game was failing to load the shared object library that contains my native code.

This could manifest itself as a:

Unable to load native library: /data/data/com.sample.teapot/lib/
or sometimes a findLibrary returned null:
E/AndroidRuntime( 7344): java.lang.UnsatisfiedLinkError:
  Couldn't load /data/data/com.sample.teapot/lib/ findLibrary returned null

It turns out there is a trick to have android give up more information about it. What you do, is load the library yourself in onCreate() of your native activity class. For this you use the System.load() call (and not the System.loadLibrary() call that the stackoverflow answer suggests.) Unfortunately, you need to know where your test device has actually placed the .so file, but if you do something like this:

public class TeapotNativeActivity extends NativeActivity {
    protected void onCreate(Bundle savedInstanceState) {
You will get a proper error in the logs:
W/native-activity( 7426): onCreate
D/dalvikvm( 7426): Trying to load lib /data/data/com.sample.teapot/lib/ 0x410d97a8
W/dalvikvm( 7426): threadid=1: thread exiting with uncaught exception (group=0x40a741f8)
E/AndroidRuntime( 7426): FATAL EXCEPTION: main
E/AndroidRuntime( 7426): java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1936]:
  81 could not load needed library '' for '' (load_library[1091]: Library '' not found)

Hooray! Now we know which dependency is missing. Note that in this specific example, it is of course an issue of not specifying the ES3 requirement in the manifest. But this example is for illustration purposes only.

Originally, I was convinced that these errors were a case of not finding the library, because Android decided to append a "-1" or "-2" to the library name. But this was a red herring. The library is there all right. The thing is, it has dependencies that are not met, and are not reported when it fails loading.

By the way, to check if your library is really there, you could issue a command like:

$ adb shell run-as com.sample.teapot /system/bin/sh -c "ls\ -al\ /data/data/com.sample.teapot/lib/"
-rwxr-xr-x system   system     424232 2016-12-26 08:53

1 comment:

  1. Also, did the installation directory for shared library files change when going 64-bit? It seems so: