ChatGPT解决这个技术问题 Extra ChatGPT

React-Native :java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so

I have just updated my project to use react-native version 0.60.2 . But when I am trying to run an application on Android device it gets crashed after launch screen. I got the following error logs :

E/AndroidRuntime: FATAL EXCEPTION: create_react_context
    Process: com.tjspeed, PID: 3909
    java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so
        at com.facebook.soloader.SoLoader.doLoadLibraryBySoName(SoLoader.java:738)
        at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:591)
        at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:529)
        at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:484)
        at com.facebook.hermes.reactexecutor.HermesExecutor.<clinit>(HermesExecutor.java:20)
        at com.facebook.hermes.reactexecutor.HermesExecutorFactory.create(HermesExecutorFactory.java:27)
        at com.facebook.react.ReactInstanceManager$5.run(ReactInstanceManager.java:949)
        at java.lang.Thread.run(Thread.java:760)

Few suggestions available here : https://github.com/facebook/react-native/issues/25601 but unfortunately none of them worked for me. Please suggest the workaround.

From v0.60 changelog/blog: With this change, React Native apps will need to begin using AndroidX themselves. They cannot be used side-by-side in one app, so all of the app code and dependency code needs to be using one or the other. This might be a case for you?

V
Vinzzz

I had the same issue after upgrading from 0.59.8 to 0.60.4

Make sure you have added all these lines in your app/build.gradle, especially the dependencies part as this makes sure you have JSC binary

project.ext.react = [

...
    // your index js if not default, other settings
  // Hermes JSC ?
 enableHermes: false,

...
]

def jscFlavor = 'org.webkit:android-jsc:+'

def enableHermes = project.ext.react.get("enableHermes", false);

dependencies {

    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.facebook.react:react-native:+"  // From node_modules

    if (enableHermes) {
      // For RN 0.60.x
      def hermesPath = "../../node_modules/hermesvm/android/"

      // --- OR ----          

      // for RN 0.61+
      def hermesPath = "../../node_modules/hermes-engine/android/";


      debugImplementation files(hermesPath + "hermes-debug.aar")
      releaseImplementation files(hermesPath + "hermes-release.aar")
    } else {
      implementation jscFlavor
    }

EDIT

Also, make sure the Hermes Maven repo is in your root build.gradle

maven {
        // Android JSC is installed from npm
        url("$rootDir/../node_modules/jsc-android/dist")
    }

This did not work for me after upgrade to 0.60.4. I tried clean multiple times. I cannot seem to disable hermes. I get crash on start "couldn't find DSO to load: libhermes.so"
Make sure in the src/android/build.gradle, you've also added the maven repo for hermes libs (like the other answer proposes). It might be related to JavaScriptCore & not Hermes specifically
Thank you! I was missing "maven { url("$rootDir/../node_modules/jsc-android/dist") }
Thank !! Its working form me but don't forget to add this block in project build.gradle maven { // Android JSC is installed from npm url("$rootDir/../node_modules/jsc-android/dist") }
In react-native 0.61 the hermesvm part in android/app/build.gradle has moved to hermes-engine: github.com/facebook/react-native/blob/0.61-stable/template/…
s
samernady

I've just cleaned the build folder for android and after that, it worked fine. Hope that helps mate.

cd android
./gradlew clean 

hours of debugging and searched and it was fixed by a clean...
yeah it was very disappointing to find it was this absurd fix
I always have this error when I create a bundle release, need to run clean every time
I think this problem started when I upgraded nodejs version. Anyway this fixed my problem!
s
skang

I added this block in allProject block in project_dir/build.gradle and the crash went away.

    maven {
        // Android JSC is installed from npm
        url("$rootDir/../node_modules/jsc-android/dist")
    }

What I did is to create new project with react-native init and went through the android build files. Fortunately this one was the first difference I noticed and fixed my issue. I guess you could do the same if this doesn't work.


@msqar same here
Adding that line caused the following error during build: error: package com.facebook.react.module.annotations does not exist
Verifying the changes here might be a good idea react-native-community.github.io/upgrade-helper
A
Andru

In case you're facing this error while updating to React Native version 0.62.2:

Add the following to your android/app/build.gradle file:

dependencies {
   implementation 'com.facebook.soloader:soloader:0.9.0+'

as one of the first implementation entries.

Solution taken from here


After implement still have this issue---> couldn't find DSO to load: libhermes.so SoSource 0: com.facebook.soloader.ApkSoSource[root = /data/data/com.tootitoo.tootitoo/lib-main flags = 1] SoSource 1: com.facebook.soloader.DirectorySoSource[root = /data/app/com.tootitoo.tootitoo-1/lib/arm flags = 0] SoSource 2: com.facebook.soloader.DirectorySoSource[root = /system/vendor/lib flags = 2] SoSource 3: com.facebook.soloader.DirectorySoSource[root = /system/lib flags = 2] Native lib dir: /data/app/com.tootitoo.tootitoo-1/lib/arm result: 0
S
Starryi

open node_modules/jsc-android/README.md find section 'How to use it with my react Native app'

for example:

modify android/build.gradle

allprojects {
    repositories {
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        maven {
            // Local Maven repo containing AARs with JSC library built for Android
            url "$rootDir/../node_modules/jsc-android/dist"
        }
        google()
        jcenter()

    }
}

modify android/app/build.gradle

android {
    packagingOptions {
        pickFirst '**/libjsc.so'
        pickFirst '**/libc++_shared.so'
    }
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation "org.webkit:android-jsc:+"
    implementation "com.facebook.react:react-native:+" // From node_modules
}

i have performed above way without using packagingOptions and that's enough. Thanks.
For me, I just needed to add pickFirst '**/libjsc.so' pickFirst '**/libc++_shared.so'
Long time research to find the answer. Thanks for the solution.
OMFG I would upvote this answer a billion @#$%ing times if I could!! I thought I was losing my mind for hours; tried all the above answers' suggestions and adding the second maven repo link finally solved it! Having just one or the other is not enough. TYSM! :D
This is my only solution.
d
dasl

i have solved this by adding

 configurations.all {
    resolutionStrategy {
        force "com.facebook.soloader:soloader:0.8.2"
    }
}

Where exactly did you add this and in which file?
app/build.gradle inside end of dependencies { } dependencies { implementation project(':react-native-permissions') configurations.all { resolutionStrategy { force "com.facebook.soloader:soloader:0.8.2" } } }
E
Eliezer Steinbock

For others that run into this issue, there are 2 sections that look similar. You need to update the bottom repositories section in android/build.gradle!

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        buildToolsVersion = "28.0.3"
        minSdkVersion = 16
        compileSdkVersion = 28
        targetSdkVersion = 28
        supportLibVersion = "28.0.0"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:3.4.1")

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }

        google()
        jcenter()
    }
}

i just added url("$rootDir/../node_modules/jsc-android/dist") in project gradle. thank you Eliezer Steinbock
J
Jack Ou

I did nothing more. ./gradlew clean solved my problem.


ince you are formally posting an answer to an older question. It would be most helpful that you support your purported answer with some code and the output that results from using your code. You can support your answer with a copy and paste or even a screen print if the result from your code cannot be copied.
m
michael_vons

This is because SOLoader is absent.

Ensure

implementation'com.facebook.soloader:soloader:0.9.0+'

is added under dependencies in android/app/build.gradlle

clean your build

cd android

./gradlew clean

Try bundling ./gradlew bundleRelease

Exit android folder cd ../

Try running npx react-native run-android --variant=release


In my case I was missing a releaseImplementation 'com.facebook.soloader:soloader:0.9.0+'
@michael_vons Thank you for the solution. For anyone where it seems it stops working out of nowhere, it would build in Android studio no problem, and react-native run-android will work for API's below 30, but for 30 and up I needed to add the implementation'com.facebook.soloader:soloader:0.9.0+' like Michael said and follow the rest of his instructions to get it to build with react-native. Also, having logcat open in Android studio while building/launching a react-native app allowed me to find the issue since metro wasn't spitting out any errors and the app was crashing on build immediately.
A
Abhinav Saxena

Add this in your project level gradle

allprojects {
    repositories {
        maven {
            url "$rootDir/../node_modules/react-native/android"
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }
        mavenLocal()
        google()
        jcenter()
    }
}

H
Henrik

After following all advise without success I built an *.apk instead of an *.aab. The APK is 16 MB as opposed to the 8 MB AAB, but I finally got rid of the UnsatisfiedLinkError.

To build an AAB (crashed with UnsatisfiedLinkError):

cd android && ./gradlew clean && ./gradlew bundleRelease

To build an APK (no crash and hermes works fine too):

cd android && ./gradlew clean && ./gradlew assembleRelease

Although this is not a permanent solution, it's a temporary work-around that fixed the issue for me for now. Thanks!
P
Piotr Badura

In my case I needed to add hermes path for each android flavour

    if (enableHermes) {
        def hermesPath = "../../node_modules/hermes-engine/android/";
        debugImplementation files(hermesPath + "hermes-debug.aar")
        releaseImplementation files(hermesPath + "hermes-release.aar")
        qaImplementation files(hermesPath + "hermes-release.aar")
        stageImplementation files(hermesPath + "hermes-release.aar")
        prodImplementation files(hermesPath + "hermes-release.aar")
    } else {
        implementation jscFlavor
    }

I
Isaac Overacker

In my case, Hermes was never enabled and yet I encountered this error. Cleaning (via Android Studio) and rebuilding resolved the error.


Does cleaning via Android Studio vs. via ./gradlew clean make a difference?
u
user3571779

Try to replace your ndk object inside app/build.gradle

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

S
Sir Codesalot

I had this error when I was trying to run with an older version of React Native, prior to 0.60 while in the package.json had a newer version defined (post 0.60).


E
Elan

It happens to me after I updated my android studio, then I clean and build again, it doesn't crash any more.


D
Dhaval Panchani
 maven {
        // Android JSC is installed from npm
        url("$rootDir/../node_modules/jsc-android/dist")
    }

&

Make sure you've installed this - https://www.npmjs.com/package/jsc-android

In my case, it was not there because of some reason.


t
tryp

To avoid this kind of unexpected behavior I've made the choice to use fastlane for all my projects (pretty easy to implement and use). I've created a short lane to clear the project every time I'm looking for a new release.

lane :clean do
    gradle(
      task: "clean"
    )
end

I'm then using this lane on my production lane command

lane :release do
  check_env
  bump
  ...
  clean
  gradle(
    task: 'bundle',
    build_type: 'Release'
  ) 
end

l
lfree

In my case, just turn the enableHermes on in app/build.gradle:

project.ext.react = [
    entryFile   : "index.js",
    enableHermes: true,  // HERE!
]

If you turn on Hermes you just change builds options and it will replace SoLoader to Hermes and make build via Hermes... but it is not fixed
M
Moaz Khan

If any one is still facing the issue even after applying trying all the steps above then here is the solution

In the MainApplication.java, add this import:

import com.facebook.react.BuildConfig;

Warning! Don't add that import in case you're using the Expo bare workflow. It will mess up the BuildConfig.DEBUG value and make your debug builds not work anymore.
BuildConfig is a file generated automatically for your project, you shouldn't import the one from facebook.
P
Pmpr.ir

Solve this problem in a simple way.

apply plugin: "com.android.application"
// def useIntlJsc = false

import com.android.build.OutputFile
project.ext.react = [
    entryFile: "index.js",
    bundleInStaging: true,       // Add this
    bundleInInternalTest: true,  // Add this
    bundleInRelease: true
]

apply from: "../../node_modules/react-native/react.gradle"

def enableSeparateBuildPerCPUArchitecture = false

def enableProguardInReleaseBuilds = false

def jscFlavor = 'org.webkit:android-jsc:+'

def enableHermes = project.ext.react.get("enableHermes", false);

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {
        applicationId "com.inbox.clean.free.gmail.unsubscribe.smart.email.fresh.mailbox"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 2597205 //4242929
        versionName "1.6.3"
        multiDexEnabled true
        ndk {
            //  abiFilters "armeabi-v7a", "x86"
                //   abiFilters.clear()

        }

    }

    signingConfigs {
        release {
            if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
                storeFile file(MYAPP_RELEASE_STORE_FILE)
                storePassword MYAPP_RELEASE_STORE_PASSWORD
                keyAlias MYAPP_RELEASE_KEY_ALIAS
                keyPassword MYAPP_RELEASE_KEY_PASSWORD
            }
        }
    }
    buildTypes {

        release {
            minifyEnabled enableProguardInReleaseBuilds
            shrinkResources enableSeparateBuildPerCPUArchitecture
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
    }



    project.ext.sentryCli = [
        logLevel: "debug",
        flavorAware: false,
        //add
         enableHermes: false
    ]




    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }


    splits {
        abi {
            reset()
            enable true
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a","arm64-v8a","x86","x86_64"
            //"armeabi-v7a" "arm64-v8a" "x86" "x86_64"
            // include "armeabi-v7a", "x86"
            exclude "ldpi", "xxhdpi", "xxxhdpi"
        }
    }

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
            def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a":3,"x86_64":4]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }
        }
    }
}

dependencies {
    implementation project(':react-native-linear-gradient')
    implementation fileTree(dir: "libs", include: ["*.jar"])

    if (enableHermes) {
      def hermesPath = "../../node_modules/hermesvm/android/";
      debugImplementation files(hermesPath + "hermes-debug.aar")
      releaseImplementation files(hermesPath + "hermes-release.aar")
    } else {
      implementation jscFlavor
    }

}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

apply plugin: 'com.google.gms.google-services'

It is too simple I think!!
@Chaurasia what did you do to solve this problem? what are the lines that solved this?
@Kruupös I'm showing only my file instruction. this file is working a good way. can user match own files to my file? so simple.
@Chaurasia not really, I have some specific config that wouldn't match your requirements.A real answer would be to understand what precise line are causing or solving the issue. I don't even know your React version, so not that simple.