react-native: [x86][houdini] UnsatisfiedLinkError when running on Android devices with x86 processors

SoLoader$WrongAbiError: APK was built for a different platform

Description

For app that supports only armeabi-v7a libraries on playstore (running on Intel Z2560 and other chip sets with dual ABI support) causes error java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app-lib/com.app.android-4/libreactnativejni.so" has unexpected e_machine: 40

Ideally houdini ARM translator should do the trick by allowing NDK binaries to run on x86 hardware.

D/houdini: [12822] Loading library(version: 4.0.8.45720 RELEASE)... successfully.
[12822] Unsupported feature (ID:0x10600cae).
[12822] Open Native Library /data/app-lib/com.walmart.android-4/libreactnativejni.so failed.

The logs above clearly suggest that libhoudini failed to openlibreactnativejni.so. I am aware by including x86 support for react binaries the problem can be solved, however we currently aren’t considering the option (including split apk option). Does react-native team have any other alternative solution?

The related Issue can be found here

Reproduction

Please find the steps HERE In a nut shell , create a new React native project and remove “x86” from the abiFilters property in the build.gradle file.

Additional Information

  • React Native version: 0.40
  • Platform: Android, Tablets with Intel Z2560 and other chip sets with dual ABI support
  • Operating System: Linux
  • On running adb shell getprop | grep ro.product.cpu the device properties are rightly configured.
[ro.product.cpu.abi2]: [armeabi-v7a]
[ro.product.cpu.abi]: [x86]
  • On stepping into the code to check the abi values programmatically, the abi values are returning values identical to lib folder of apk , Please check the png file. Any idea?
        final String cpuAbi = Build.CPU_ABI; // value = armeabi-v7a
        final String cpuAbi2 = Build.CPU_ABI2; // value = armeabi
apk

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 14
  • Comments: 17 (7 by maintainers)

Most upvoted comments

I have made some progress on investigating this issue. I found that when I change the APP_STL value in Application.mk from gnustl_shared to gnustl_static I no longer get the “Unsupported feature” error when loading libreactnativejni.so. It still gives the “Unsupported feature” error on the other libraries, which I haven’t had time investigate. I’m a bit concerned with changing APP_ STL to static because of the C++ One Definition Rule, as mentioned here.

If anyone wants to investigate in parallel:

  1. Clone the RN repo.
  2. Follow Android prerequisites here.
  3. Open RN project in Android Studio, remove “x86” from abiFilters in RNTester/android/app/build.gradle.
  4. Run RNTester app in BlueStacks emulator (which has Houdini).
  5. Start making changes to files like Application.mk, Android.mk, etc. and see if it fixes anything.

One gotcha at least with Android Studio 2.2, when you change the Application.mk file and run the project, it doesn’t rebuild the app. You have to go to Build menu > Rebuild Project to force a rebuild.

Just to be clear, this may be a roadblock for some apps to integrate React Native because there is some small percentage of Android devices that run x86 processors. We end up with a few non-ideal options:

  1. Don’t support x86 devices. This isn’t feasible for some apps, as our native (Java) code runs fine on these devices and we don’t want to drop support for those users.
  2. Include x86 in ABI filters (mentioned above here), which increases the binary size a lot (10 MB in our case), which is prohibitive.
  3. Switch to a Split APK, which for some teams is a prohibitively large amount of work because of assumptions in our build and release tooling about app versions.

It’s not clear to me why other libraries with native dependencies work fine with the houdini ARM translator but React Native’s dependencies don’t. It seems this is something that should be fixable.

@matthewfang @yaxin3690 @wj495175289 At this point the solution is to include abiFilters as below in defaultConfig of your applications build.gradle.

ndk {
  abiFilters "armeabi-v7a", "x86"
}

Yes this will increase the size of the .apk file. If you want to reduce the apk file size you should go with split APKs Please note universal .apk will not work as dual ABI support devices will still try to load arm .so files and still fail with java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app-lib/com.app.android-4/libreactnativejni.so" has unexpected e_machine: 40