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

Created on 7 Feb 2017  Â·  17Comments  Â·  Source: facebook/react-native

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

Stale

Most helpful comment

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.

All 17 comments

the same issue, i have this problem with RN 0.42. how can we solve it?

是是是

the same issue, i have this problem with RN 0.43.4. how can we solve it?

@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

thinks @krunalsshah

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.

@lyahdav Precisely React Native core library needs to be fixed at the point where houdini fails to compile. This would avoid all of the above points mentioned above. Please let us know if you were able to find any alternative solution or if you happen to fix the source. Thanks.

Thanks for the additional details, @lyahdav. I'll try to find a point of contact that can help out here.

I've marked #5773 as a duplicate of this issue. If you're investigating this issue, I recommend reading through the comments in #5773 for additional details.

Specifically, @lyahdav has posted some findings here, and here

@hramos Thanks for taking a look at this. You'd want to take a look from the start as all the bullets captured are summarized in the previous steps. Also the original post summarizes the steps to reproduce etc. Please let us know if you have any questions.

@krunalsshah I've shared this issue internally and am looking for a point of contact who can help provide more context.

Can anybody help?

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.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.

I had to solve it a few months back as we didn't have x86 libraries yet and need to support Intel devices anyway.

There are two problems:

  1. There is a bug in the JSC library react-native using. You'd rather need to recompile it with JIT turned off which will reduce startup time but will hurt runtime performance or upgrade to the newer version of JSC to mitigate it.
  2. On Android L devices there is a bug in libhoudini dlclose implementation. You need to remove the dlclose ASSERT to fix it. You need it only in case you are using Cxx modules though.

@lyahdav I am sorry, I also have this problem with 0.51.0?Is there a solution to this problem?

See the alternatives listed here: https://github.com/facebook/react-native/issues/12246#issuecomment-324706053. They should be fine in most cases.

Was this page helpful?
0 / 5 - 0 ratings