2

I'm having an issue where the dalvik.system.PathClassLoader can't find my jni file on Intel devices. I think it has to do with the structure of an aar dependency I have because once I removed that dependency, the jni file is found without issue. My aar dependency has x86 and arm libraries and my project only has arm libraries.

The folder structure is:

My Project

  • src
    • jniLibs
      • armeabi
        • libLibraryA.so

My AAR dependency Project has:

  • src
    • jniLibs
      • armeabi
        • libLibraryB.so
      • x86
        • libLibraryB.so

With that structure, libLibraryA.so will not be found on x86 devices. I'm not sure if this is a gradle packaging issue or if this is a dalvik/runtime issue. I'm at a loss of where to go next. The error I get is:

  FATAL EXCEPTION: main 
  Process: com.project, PID: 10850 
 java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/base.apk"],nativeLibraryDirectories=[/lib/x86, /vendor/lib, /system/lib]]] couldn't find "libLibraryA.so" 
 at java.lang.Runtime.loadLibrary(Runtime.java:366) 
 at java.lang.System.loadLibrary(System.java:989)`

I know the issue can be 'fixed' by creating an x86 folder in my project and copying libLibraryA.so into it. Does anyone know if gradle can/should be handling this for me? Is it safe to put an arm compiled library into the x86 folder for use on intel devices or would that mess up the runtime translation? I've seen issues on the Nexus Player where it can't read our arm compiled library.

Hemina
  • 375
  • 1
  • 11
Bryan
  • 367
  • 3
  • 11

1 Answers1

2

You can mix libs compiled for x86 and for arm only if they don't depend on each other (ie. if they don't call each other directly without going through Java).

So gradle will not mix libs targeting different architectures, it's really your responsibility to do that and the most simple way is indeed to copy your libLibraryA.so to an x86 folder.

But doing this is a workaround that will work only on retail Intel-based devices. I don't recommend that: the right thing to do would still be getting a version of libLibraryA.so compiled for x86 and putting it inside the x86 folder.

update: as said in my comment below, loading an arm lib from the app's x86 folder isn't supported anymore with Android 5.0.

ph0b
  • 14,353
  • 4
  • 43
  • 41
  • Thanks for clearing that up. Do you have any any thoughts on why Nexus Player isn't reading our libLibraryA even when its inside the x86 folder? – Bryan Dec 08 '14 at 16:17
  • usually the translation works fine, can you provide more information on which library is failing and/or what is the exact behavior/error ? sometimes, libs fail with Lollipop because ART is more strict than Dalvik on JNI use, not necessarily because of the cpu architecture. – ph0b Dec 10 '14 at 08:54
  • I've made further testing on x86 devices running Lollipop: loading an arm lib from the app's x86 folder isn't supported anymore on these platforms. – ph0b Dec 11 '14 at 11:23