31

I've tried running an application using a native library on the Nexus 9.

The application exits with an error message:

java.lang.UnsatisfiedLinkError: dlopen failed: "lib_xyz.so" is 32-bit instead of 64-bit

Is there any known workaround for this problem (except, of course, recompiling the library and making the apk bigger)?

G B
  • 2,951
  • 2
  • 28
  • 50

7 Answers7

34

Found an explanation: 64-bit Android can use 32-bit native libraries as a fallback, only if System.loadlLibrary() can't find anything better in the default search path. You get an UnsatisfiedLinkError if you force the system to load the 32-bit library using System.load() with the full library path. So the first workaround is using System.loadLibrary() instead of System.load().

An additional thing that has to be taken into account is that libraries cannot be mixed: the fallback behaviour only applies for the first library your application loads. If the first one is 64-bit, no 32-bit libraries can be loaded by the same application, and vice versa.

G B
  • 2,951
  • 2
  • 28
  • 50
  • Hey G B, is there a source for that? – orospakr Apr 09 '15 at 18:40
  • Yes. I`ve discovered it by browsing the Android source code (how library loading is implemented) – G B Apr 10 '15 at 09:08
  • 1
    @gb I know this is maybe old stuff, but we're finding that after an OS upgrade to Android 5.1.1 on a Galaxy S6 Edge this is not working anymore. Before that it was working. Do you know if this has changed? Can you point out where you found this? Thanks! – Xavier Rubio Jansana Sep 10 '15 at 14:55
  • 2
    Nevermind, the reason was other (and something to remember to check in this cases): we added a module to our project which had a dependency to a JNI library. This library has support for 64 bits, and the compatibility fallback gets disabled in this cases. – Xavier Rubio Jansana Sep 13 '15 at 11:50
  • @GB Thanks for sharing this insight! would you mind referring me to the exact location in the AOSP source code where you've found the library loading implementation (Preferably on Lollipop or higher). Thanks :) – Roi Tal Sep 21 '15 at 15:54
  • The app will try to load the lib*.so in the cpu_architecture folder first! If nothing's found, other lib*.so from other folders will be loaded, one after another. – Tim Long Nov 07 '15 at 10:48
  • 1
    How to solve this crash? Any code solution for this issue? – Anand Savjani Jan 24 '19 at 19:19
  • This does not work for me. I only loaded one 32-bit lib on a arm64-v8a phone. I used System.loadLibrary() instead of System.load(). Yet I still get the error. – Helen Cui Nov 19 '20 at 03:37
19

the point is to convert the run environment to 32 bit

  1. add the follow content in build.gradle

    defaultConfig: { ... ndk { abiFilters "armeabi", "armeabi-v7a", "x86", "mips" } }

  2. add android.useDeprecatedNdk=true into gradle.properties

  3. add new folder named armeabi under the libs, then copy a 32bit .so file into the new folder
aleksandrbel
  • 1,422
  • 3
  • 20
  • 38
vincent.song
  • 191
  • 1
  • 2
4

This work for me:

 ndk {
        abiFilters 'armeabi-v7a', 'x86'
    }
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Hassan
  • 310
  • 3
  • 7
  • 1
    ooh you are life saver buddy :) Thank you so much – iamkdblue May 01 '20 at 21:36
  • This worked for me : ndk { abiFilters "armeabi", "armeabi-v7a", "x86", "mips" } – Nabzi Dec 13 '20 at 12:32
  • 1
    This works but remember that when you upload your .apk or App bundle, Google Play Store will force you to support 64-bit architecture and you will be forced to add back variants to abiFilters and the problem will also come back – Antares Feb 23 '21 at 11:29
  • So what is the solution for this need to upload playstore. – Mani Apr 29 '21 at 07:03
1

https://source.android.com/source/64-bit-builds.html

Try this in you Android.mk

LOCAL_MULTILIB := 32
AbcAeffchen
  • 14,400
  • 15
  • 47
  • 66
AudiO
  • 79
  • 1
  • 4
0

Nop, you need to get the native library to be compatible with 64-bit for it to work.

See official documentation: JNI Tips: 64-bit Considerations

shkschneider
  • 17,833
  • 13
  • 59
  • 112
  • Actually, it doesn't say anything like that: "For the most part this isn't something that you will need to worry about when interacting with native code". After reading that paragraph, an UnsatisfiedLinkError is the last thing I'd expect. – G B Nov 28 '14 at 13:38
  • You might be right, but I think `UnsatisfiedLinkError` happened to me when I had your exact some problem once. I might be wrong, sorry if that's the case. Hope someone will help you out more. – shkschneider Nov 28 '14 at 13:41
0

I encountered the same issue, when I did the update from Android Studio 2.1 to 2.2.3 (with ndk v.13.1), and no tips found in google really helped me (like using abiFilters, exclude 'lib/x86_64/lib….so’, LOCAL_MULTILIB := 32, or TARGET_PREFER_32_BIT := true, …).

Finally, I was able to make it worked again with the latest AS v2.2.3 (without changing anything in Android.mk or in build.gradle), just by using my previous ndk compiler, i.e. android-ndk-r10e

I built the library manually with ndk-build for "armeabi-v7a" and "x86" only, and it worked like a charm on Android with arm64.

Pang
  • 9,564
  • 146
  • 81
  • 122
fjnet
  • 21
  • 4
0

For me the problem was that I enabled the advanced profiling feature under the build settings of the app