dalvik.system.PathClassLoader can't find jni on Intel devices

8.7k views Asked by At

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.

1

There are 1 answers

3
ph0b On BEST ANSWER

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.