ReLinker icon indicating copy to clipboard operation
ReLinker copied to clipboard

Can't load .so file stored in a library (aar) from an application project

Open MichaelCaraccio opened this issue 5 years ago • 2 comments
trafficstars

TLDR : ReLinker is looking in /lib folder of my android project and not also in the /jni folder of my aar file (which contains some so files) which result with a java.lang.UnsatisfiedLinkError

Create the aar file including so files I created an aar library which contains a few shared-objects. Those so files are stored in the /jni folder according to Android documentation. So the compilation of the aar library is not a problem.

Screenshot 2020-01-29 at 20 46 30

Import aar in Android project Then when I import the aar file in an android project, I use relinker.recursive() to get my so file. But it seems that relinker is looking only in the /lib folder of the android project, and not also in the /jni folder of the aar library.

V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Loading the library normally failed: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk"],nativeLibraryDirectories=[/data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/lib/x86, /system/lib]]] couldn't find "libnanolcms.so"
        at java.lang.Runtime.loadLibrary0(Runtime.java:1012)
        at java.lang.System.loadLibrary(System.java:1669)
        at com.getkeepsafe.relinker.SystemLibraryLoader.loadLibrary(SystemLibraryLoader.java:24)
        at com.getkeepsafe.relinker.ReLinkerInstance.loadLibraryInternal(ReLinkerInstance.java:163)
        at com.getkeepsafe.relinker.ReLinkerInstance.access$000(ReLinkerInstance.java:31)
        at com.getkeepsafe.relinker.ReLinkerInstance$1.run(ReLinkerInstance.java:142)
        at java.lang.Thread.run(Thread.java:764)
    [LibraryLoadingTask.log()-32]: nanolcms (null) was not loaded normally, re-linking...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/x86/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi-v7a/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/x86/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi-v7a/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/x86/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi-v7a/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/x86/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi-v7a/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
    [LibraryLoadingTask.log()-32]: Looking for lib/armeabi/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/x86/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi-v7a/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
V/ReLinkerInstance: [LibraryLoadingTask.log()-32]: Looking for lib/armeabi/libnanolcms.so in APK /data/app/com.colorix.spike.nano-KLziZmxzMy8HpQoBCkOsAA==/base.apk...
W/orix.spike.nan: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
W/orix.spike.nan: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
I/orix.spike.nan: Background concurrent copying GC freed 21210(7MB) AllocSpace objects, 0(0B) LOS objects, 49% free, 1727KB/3MB, paused 10.482ms total 300.249ms
W/orix.spike.nan: Accessing hidden method Landroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic; (light greylist, linking)
I/MainActivity: onResume()
    nanoUsbDevice = com.colorix.cxcolorcatch.CXColorcatchManager@e92abb4
V/MainActivity: [CXColorcatchManager.getInstance()-59]: getInstance
I/MainActivity: nano = null
D/OpenGLRenderer: Skia GL Pipeline
V/ReLinkerInstance: [LibraryLoadingTask.failure()-54]: Unable to load nanolcms library 

Of course if I copy/paste those .so files in the android project those library will be loaded using ReLinker. But that's not what I try to achieve.

For more information about my problem, I posted on Stackoverflow

MichaelCaraccio avatar Jan 30 '20 08:01 MichaelCaraccio

Shared libraries are always stored in lib directory in the APK. That's where the system looks for them. There's no reason for ReLinker to look anywhere else, i.e. this is not ReLinker's problem.

AARs from Maven repos and other modules are processed correctly. Perhaps there's an issue with how raw AAR files get processed by Android Gradle Plugin. In which case create a small repro project and open an issue in Google Issue Tracker.

If the library and the application are in the same root project, you can have the application module depend on the library module:

implementation(project(":my_library"))

If they're in separate root project, publish the library to a maven repo (you can use mavenLocal() for testing).

Avoid manually working with AARs. AAR does not contain metadata required to resolve dependencies. You would have to duplicate dependency specifications between the library and the application. That means the person who writes application would also need to have access to the library's build.gradle... and even if you do, good luck keeping them in sync.

consp1racy avatar Jul 02 '20 08:07 consp1racy

Your remote library needs the shared native libs in src/main/jniLibs/<abi>/ directory. Upon building & publishing of your Library as an aar, it will be packaged in the aar's jni directory. When imported to your project, the .so files will be included in the apk's lib/ directory when building the app.

Placing the .so files in the jni dir of your library, they won't be included in the published aar. Must be in the src/main/jniLibs/<abi>/ dir.

05nelsonm avatar Jul 13 '20 14:07 05nelsonm