2

I'm loading my native library like this at runtime

dlopen("mylib.so", RTLD_LAZY);

This works fine on recent version of android (e.g. marshmallow, nougat, etc.). However, on older versions (e.g. Jellybean), this fails with the following message in logcat

Failed to load mylib.so. Error: Cannot load library: 
load_library[1093]: Library 'mylib.so' not found

I have ensured that mylib.so is part of the apk. I have this as part of x86 and armeabi_v7a architectures.

myapp.apk
- lib
  - armeabi-v7a
       mylib.so
  - x86
       mylib.so

As per readelf -d mylib.so | grep NEEDED the dependencies are

 0x00000001 (NEEDED)                     Shared library: [liblog.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]

I tried loading these dependencies through dlopen prior to loading mylib.so. Though loading of those dependencies succeed, loading mylib.so always fails with the same error.

As mentioned before, I see this failure only on older versions of android.

How can I get this to work? Thanks in advance for any help.

rpattabi
  • 9,984
  • 5
  • 45
  • 53
  • Try including a slash, even if it’s just `./mylib.so`. – Davis Herring Jun 23 '18 at 00:03
  • I tried that, same results. Looks like this needs something specific for the way older versions of android searches for the lib. – rpattabi Jun 24 '18 at 07:47
  • I wonder if older loaders were picky about naming. Maybe try naming your library libmylib.so instead of mylib.so. Another thing to check would be to make sure the SONAME (also part of `readelf -d` output) is correct on mylib.so. – Dan Albert Jul 09 '18 at 22:22
  • It is already in the form of libmylib.so in my case. I just gave mylib.so as a simplified example here. So, naming isn't the reason for this problem. – rpattabi Jul 23 '18 at 06:57

2 Answers2

4

Prior to Lollipop, you must supply the full path to dlopen(). This path can be obtained in Java with getApplicationInfo().nativeLibraryDir.

At any rate, you can check the contents of the /data/data/your.package/lib directory (sometimes it has -1 suffix, or starts with /data/app-lib). This directory is world-readable, so you you should see the file libmylib.so there from Android Studio or adb shell.

Another reason for the observed behavior could be that the older device does not support armeabi-v7a ABI. That's easy to check with adb shell getprop.

Also, make sure that the library is built with the correct APP_PLATFORM, which should match the minSdkVersion.

Your library luckily does not have 'private' dependencies. But for those that do, you need to take this into account, too. Prior to Lollipop, these dependencies would not be loaded automatically (because the nativeLibraryDir was not scanned for dlopen). You had to load all libraries in reverse dependency order.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • For users planning to use this solution, I accepted it without really trying it as I decided to stop supporting Jelly Bean for my app. If anyone finds that this solution does not work, I'll unaccept this answer. If it works also, please comment here. – rpattabi Oct 16 '18 at 14:33
0

Try changing the folder name from lib to jniLibs.

Mikhail Vasilyev
  • 503
  • 4
  • 11