Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.loadLibrary(...) couldn't find native library in my case

I want to use a existing native library from another Android project, so I just copied the NDK built library (libcalculate.so) to my new Android project. In my new Android project I created a folder libs/armeabi/ and put libcalculate.so there. There is no jni/ folder. My testing device has ARM architecture.

In my java code I load the library by:

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

When I run my new android project, I got error:

java.lang.UnsatisfiedLinkError:  ... nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so" 

So, as error says, the copied native library is not in /verdor/lib or /system/lib , how to resolve this problem in my case?

(I unziped the apk package, under lib/ there is libcalculate.so)

====UPDATE=====

I also tried to create a jni/ folder under project root, and add an Android.mk file under jni/. The content of Android.mk is:

LOCAL_PATH := $(call my-dir)  include $(CLEAR_VARS) LOCAL_MODULE    := libcalculate LOCAL_SRC_FILES := libcalculate.so include $(PREBUILT_SHARED_LIBRARY) 

Then, under project root, I executed ndk-build . After that, the armeabi/ and armeabi-v7a/ directories are generated by ndk-build (with libcalculate.so inside the folder).

Then I run my maven build the project successfully. In the final apk package, there are:

lib/armeabi/libcalculate.so lib/armeabi-v7a/libcalculate.so 

But when I run my app, the same error throw:

java.lang.UnsatisfiedLinkError:  ... nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so" 
like image 656
user842225 Avatar asked Dec 11 '14 10:12

user842225


People also ask

What is System loadLibrary?

loadLibrary(String filename) method loads the dynamic library with the specified library name. A file containing native code is loaded from the local file system from a place where library files are conventionally obtained. The details of this process are implementation-dependent.

How do I install native library on Android?

Or: you could try putting your library into /res in the project and use System. load() instead of System. loadLibrary() to load it.

How do I load a native library in Tomcat?

So you need to ensure that your native library is loaded by Tomcat's common class loader: the referring class (that does the loadlibrary) must be in common/lib (not your webapp's WEB-INF/lib), and (of course) your native lib needs to in PATH or LD_LIBRARY_PATH as appropriate for the platform. separate classloaders for each web application.

How do I get the native library path of an APK?

Build your APK and open it as a zip file, to check that your libcalculate.so file is inside lib/ (armeabi|armeabi-v7a|x86|...). Run dumpsys package packages | grep yourpackagename to get the nativeLibraryPath or legacyNativeLibraryDir of your application.

How to check step 5-7 of the native libs monitor?

In order to check step 5-7, you can use my application instead of command lines and readelf: Native Libs Monitor PS: It's easy to get confused on where .so files should be put or generated by default, here is a summary: inside the app's nativeLibraryPath on a <5.0 device, and inside the app's legacyNativeLibraryDir/CPU_ARCH on a >=5.0 device.

Why can't I open a libcalculate file?

Check that libcalculate.so actually gets picked up by the packaging process - try e.g. unzip -l package.apk, or rename the apk to .zip and open it with some application. If it isn't there, something is wrong with packaging it (did your IDE notice the folder is there, do you need to refresh the project?).


2 Answers

To root cause (and maybe solve your issue in the same time), here is what you can do:

  1. Remove the jni folder and all the .mk files. You don't need these nor the NDK if you aren't compiling anything.

  2. Copy your libcalculate.so file inside <project>/libs/(armeabi|armeabi-v7a|x86|...) . When using Android Studio, it's <project>/app/src/main/jniLibs/(armeabi|armeabi-v7a|x86|...), but I see you're using eclipse.

  3. Build your APK and open it as a zip file, to check that your libcalculate.so file is inside lib/(armeabi|armeabi-v7a|x86|...).

  4. Remove and install your application

  5. Run dumpsys package packages | grep yourpackagename to get the nativeLibraryPath or legacyNativeLibraryDir of your application.

  6. Run ls on the nativeLibraryPath you had or on legacyNativeLibraryDir/armeabi, to check if your libcalculate.so is indeed there.

  7. If it's there, check if it hasn't been altered from your original libcalculate.so file: is it compiled against the right architecture, does it contain the expected symbols, are there any missing dependencies. You can analyze libcalculate.so using readelf.

In order to check step 5-7, you can use my application instead of command lines and readelf: Native Libs Monitor

PS: It's easy to get confused on where .so files should be put or generated by default, here is a summary:

  • libs/CPU_ABI inside an eclipse project

  • jniLibs/CPU_ABI inside an Android Studio project

  • jni/CPU_ABI inside an AAR

  • lib/CPU_ABI inside the final APK

  • inside the app's nativeLibraryPath on a <5.0 device, and inside the app's legacyNativeLibraryDir/CPU_ARCH on a >=5.0 device.

Where CPU_ABI is any of: armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips, mips64. Depending on which architectures you're targeting and your libs have been compiled for.

Note also that libs aren't mixed between CPU_ABI directories: you need the full set of what you're using, a lib that is inside the armeabi folder will not be installed on a armeabi-v7a device if there are any libs inside the armeabi-v7a folder from the APK.

like image 168
ph0b Avatar answered Sep 21 '22 04:09

ph0b


In gradle, after copying all files folders to libs/

jniLibs.srcDirs = ['libs'] 

Adding the above line to sourceSets in build.gradle file worked. Nothing else worked whatsoever.

like image 35
Mukund Muralikrishnan Avatar answered Sep 25 '22 04:09

Mukund Muralikrishnan