facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
119.23k stars 24.33k forks source link

Upgrading to 0.71.7 causes build to fail when Hermes is disabled #37190

Closed denissb closed 1 year ago

denissb commented 1 year ago

New Version

0.71.7

Old Version

0.66.5

Build Target(s)

Google Pixel 7 device

Output of react-native info

System: OS: macOS 12.6 CPU: (10) arm64 Apple M1 Max Memory: 70.83 MB / 32.00 GB Shell: 3.2.57 - /bin/bash Binaries: Node: 16.16.0 - /var/folders/ds/frkzsx3s2pncyxrps39c47z5q5v2bz/T/yarn--1683009508109-0.6950868209952468/node Yarn: 1.19.1 - /var/folders/ds/frkzsx3s2pncyxrps39c47z5q5v2bz/T/yarn--1683009508109-0.6950868209952468/yarn npm: 8.19.3 - ~/.nvm/versions/node/v16.16.0/bin/npm Watchman: 2023.02.20.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.12.0 - /Users/denissb/.rvm/gems/ruby-2.7.3/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1 Android SDK: API Levels: 28, 29, 31, 32, 33 Build Tools: 30.0.2, 30.0.3, 33.0.0, 33.0.1, 33.0.2 System Images: android-29 | Google APIs ARM 64 v8a, android-31 | Google APIs ARM 64 v8a, android-33 | Google APIs ARM 64 v8a Android NDK: Not Found IDEs: Android Studio: 2022.2 AI-222.4459.24.2221.9862592 Xcode: 14.2/14C18 - /usr/bin/xcodebuild Languages: Java: 11.0.17 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.2.0 => 18.2.0 react-native: 0.71.7 => 0.71.7 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Issue and Reproduction Steps

Hello dear RN support team

I have a problem with the Android app crashing when trying to disable Hermes on RN version 0.71+, with Hermes enabled the app builds and works fine. My Android app is using multiple build flavours, so maybe the cause is related. iOS builds and works fine both with and without Hermes enabled.

I would like to disable Hermes because I am relying on toString implementation on functions.

build.gradle

apply plugin: "com.android.application"
apply plugin: "com.facebook.react"

project.ext.envConfigFiles = [
        testapp1: ".env.testapp1",
        testapp2: ".env.testapp2",
        testapp3: ".env.testapp3",
]

apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"

import com.android.build.OutputFile

/**
 * This is the configuration block to customize your React Native Android app.
 * By default you don't need to apply any configuration, just uncomment the lines you need.
 */

react {
    /* Folders */
    //   The root of your project, i.e. where "package.json" lives. Default is '..'
    // root = file("../")
    //   The folder where the react-native NPM package is. Default is ../node_modules/react-native
    // reactNativeDir = file("../node_modules/react-native")
    //   The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen
    // codegenDir = file("../node_modules/react-native-codegen")
    //   The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
    // cliFile = file("../node_modules/react-native/cli.js")
    /* Variants */
    //   The list of variants to that are debuggable. For those we're going to
    //   skip the bundling of the JS bundle and the assets. By default is just 'debug'.
    //   If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
    debuggableVariants = [
        "testapp1",
        "testapp2",
        "testapp3",
    ]
    /* Bundling */
    //   A list containing the node command and its flags. Default is just 'node'.
    // nodeExecutableAndArgs = ["node"]
    //
    //   The command to run when bundling. By default is 'bundle'
    // bundleCommand = "ram-bundle"
    //
    //   The path to the CLI configuration file. Default is empty.
    // bundleConfig = file(../rn-cli.config.js)
    //
    //   The name of the generated asset file containing your JS bundle
    // bundleAssetName = "MyApplication.android.bundle"
    //
    //   The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
    // entryFile = file("../js/MyApplication.android.js")
    //
    //   A list of extra flags to pass to the 'bundle' commands.
    //   See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
    // extraPackagerArgs = []
    /* Hermes Commands */
    //   The hermes compiler command to run. By default it is 'hermesc'
    // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
    //
    //   The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
    // hermesFlags = ["-O", "-output-source-map"]
}

/**
* Set this to true to create four separate APKs instead of one,
* one for each native architecture. This is useful if you don't
* use App Bundles (https://developer.android.com/guide/app-bundle/)
* and want to have separate APKs to upload to the Play Store.
*/
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
 */
def enableProguardInReleaseBuilds = System.getenv("MINIFY_ENABLED")?.toBoolean() ?: false

/**
 * The preferred build flavor of JavaScriptCore (JSC)
 *
 * For example, to use the international variant, you can use:
 * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
 *
 * The international variant includes ICU i18n library and necessary data
 * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
 * give correct results when using with locales other than en-US. Note that
 * this variant is about 6MiB larger per architecture than default.
 */
def jscFlavor = 'org.webkit:android-jsc:+'

/**
 * Private function to get the list of Native Architectures you want to build.
 * This reads the value from reactNativeArchitectures in your gradle.properties
 * file and works together with the --active-arch-only flag of react-native run-android.
 */
def reactNativeArchitectures() {
    def value = project.getProperties().get("reactNativeArchitectures")
    return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
}

def enableGoogleServices = project.env.get("PUSH_NOTIFICATIONS_ENABLED", "false") == "true";

android {
    ndkVersion rootProject.ext.ndkVersion // "23.1.7779620"

    compileSdkVersion rootProject.ext.compileSdkVersion // 33
    flavorDimensions "default"
    namespace 'com.mobile'

    sourceSets {
        testapp1 {
          manifest.srcFile 'src/testapp1/AndroidManifest.xml'
        }

        testapp2 {
          manifest.srcFile 'src/testapp2/AndroidManifest.xml'
        }

        testapp3 {
          manifest.srcFile 'src/testapp3/AndroidManifest.xml'
        }
    }

    productFlavors {
        testapp1 {
          applicationId "com.testapp1"

            resValue 'string', 'ASSET_STATEMENTS', '[{ \"include\": \"https://testapp1/.well-known/assetlinks.json\" }]'
        }

        testapp2 {
          applicationId "com.testapp2"

            resValue 'string', 'ASSET_STATEMENTS', '[{ \"include\": \"https://www.testapp2.com/.well-known/assetlinks.json\" }, { \"include\": \"https://www.saxotrader.com/.well-known/assetlinks.json\" }]'
        }

        testapp3 {
          applicationId "com.testapp3"

            resValue 'string', 'ASSET_STATEMENTS', '[{ \"include\": \"https://www.testapp3.com/.well-known/assetlinks.json\" }]'
        }

        all { flavor ->
            task("${flavor.name}AppConfig", type: Copy) {
                description = 'Copy variant configuration'
                from "../../.env.${flavor.name}"
                into "./src/${flavor.name}/assets"
                rename(".env.${flavor.name}", 'app.env')
            }
        }
    }

    defaultConfig {
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        compileSdkVersion rootProject.ext.compileSdkVersion
        versionCode 1
        versionName '3.3.1'
        resValue 'string', 'build_config_package', 'com.mobile'
        resValue 'string', 'SEND_CRASHES', System.getenv('APPCENTER_CRASHES_ENABLED')?.toBoolean() ? 'ASK_JAVASCRIPT' : ''
        resValue 'string', 'SEND_ANALYTICS', System.getenv('APPCENTER_ANALYTICS_ENABLED')?.toBoolean() ? 'ALWAYS_SEND' : ''
        resValue 'string', 'RUNTIME_VERSION', '3.3'
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include (*reactNativeArchitectures())
        }
    }
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see // see https://reactnative.dev/docs/signed-apk-android.
            signingConfig signingConfigs.debug

            // Enables code shrinking, obfuscation, and optimization for only
            // your project's release build type.
            minifyEnabled enableProguardInReleaseBuilds

            // Enables resource shrinking, which is performed by the
            // Android Gradle plugin.
            // shrinkResources enableProguardInReleaseBuilds

            // Includes the default ProGuard rules files that are packaged with
            // the Android Gradle plugin. To learn more, go to the section about
            // R8 configuration files.
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"

            ndk {
                debugSymbolLevel 'SYMBOL_TABLE'
            }
        }
    }

    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // https://developer.android.com/studio/build/configure-apk-splits.html
            // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
            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 =
                    defaultConfig.versionCode * 1000 + versionCodes.get(abi)
            }

        }
    }
}

dependencies {
    // The version of react-native is set by the React Native Gradle Plugin
    implementation("com.facebook.react:react-android")

    implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")

    debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
    debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.squareup.okhttp3', module:'okhttp'
    }

    debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")

    if (hermesEnabled) {
        implementation("com.facebook.react:hermes-android")
    } else {
        implementation jscFlavor
    }
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

if(enableGoogleServices) {
    apply plugin: 'com.google.gms.google-services'
}

afterEvaluate {
    android {
      productFlavors.all {
        flavor ->
          tasks."pre${flavor.name.capitalize()}DebugBuild".dependsOn "${flavor.name}AppConfig"
          tasks."pre${flavor.name.capitalize()}ReleaseBuild".dependsOn "${flavor.name}AppConfig"
      }
    }
}

Error log:

E  couldn't find DSO to load: libjsc.so
        SoSource 0: com.facebook.soloader.DirectorySoSource[root = /data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/lib/arm64 flags = 0]
        SoSource 1: com.facebook.soloader.DirectApkSoSource[root = (/data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/base.apk!/lib/arm64-v8a, )]
        SoSource 2: com.facebook.soloader.DirectorySoSource[root = /system/lib64 flags = 2]
        SoSource 3: com.facebook.soloader.DirectorySoSource[root = /vendor/lib64 flags = 2]
        Native lib dir: /data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/lib/arm64
            result: 0
E  couldn't find DSO to load: libjscexecutor.so caused by: couldn't find DSO to load: libjsc.so
        SoSource 0: com.facebook.soloader.DirectorySoSource[root = /data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/lib/arm64 flags = 0]
        SoSource 1: com.facebook.soloader.DirectApkSoSource[root = (/data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/base.apk!/lib/arm64-v8a, )]
        SoSource 2: com.facebook.soloader.DirectorySoSource[root = /system/lib64 flags = 2]
        SoSource 3: com.facebook.soloader.DirectorySoSource[root = /vendor/lib64 flags = 2]
        Native lib dir: /data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/lib/arm64
            result: 0 result: 0
E  couldn't find DSO to load: libhermes.so
        SoSource 0: com.facebook.soloader.DirectorySoSource[root = /data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/lib/arm64 flags = 0]
        SoSource 1: com.facebook.soloader.DirectApkSoSource[root = (/data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/base.apk!/lib/arm64-v8a, )]
        SoSource 2: com.facebook.soloader.DirectorySoSource[root = /system/lib64 flags = 2]
        SoSource 3: com.facebook.soloader.DirectorySoSource[root = /vendor/lib64 flags = 2]
        Native lib dir: /data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/lib/arm64
            result: 0
E  FATAL EXCEPTION: main
        Process: com.testapp.go.test, PID: 17234
        java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so
            SoSource 0: com.facebook.soloader.DirectorySoSource[root = /data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/lib/arm64 flags = 0]
            SoSource 1: com.facebook.soloader.DirectApkSoSource[root = (/data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/base.apk!/lib/arm64-v8a, )]
            SoSource 2: com.facebook.soloader.DirectorySoSource[root = /system/lib64 flags = 2]
            SoSource 3: com.facebook.soloader.DirectorySoSource[root = /vendor/lib64 flags = 2]
            Native lib dir: /data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/lib/arm64
                result: 0
            at com.facebook.soloader.SoLoader.doLoadLibraryBySoName(SoLoader.java:1127)
            at com.facebook.soloader.SoLoader.loadLibraryBySoNameImpl(SoLoader.java:943)
            at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:855)
            at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:802)
            at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:772)
            at com.facebook.hermes.reactexecutor.HermesExecutor.loadLibrary(HermesExecutor.java:26)
            at com.facebook.hermes.reactexecutor.HermesExecutor.<clinit>(HermesExecutor.java:20)
            at com.facebook.hermes.reactexecutor.HermesExecutor.loadLibrary(HermesExecutor.java:24)
            at com.facebook.react.ReactInstanceManagerBuilder.getDefaultJSExecutorFactory(ReactInstanceManagerBuilder.java:369)
            at com.facebook.react.ReactInstanceManagerBuilder.build(ReactInstanceManagerBuilder.java:316)
            at com.facebook.react.ReactNativeHost.createReactInstanceManager(ReactNativeHost.java:94)
            at expo.modules.ReactNativeHostWrapperBase.createReactInstanceManager(ReactNativeHostWrapperBase.kt:32)
            at com.facebook.react.ReactNativeHost.getReactInstanceManager(ReactNativeHost.java:41)
            at com.mobile.MainApplication.onCreate(MainApplication.java:71)
            at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1211)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6728)
            at android.app.ActivityThread.access$1500(ActivityThread.java:247)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2057)
            at android.os.Handler.dispatchMessage(Handler.java:106)
            at android.os.Looper.loopOnce(Looper.java:201)
            at android.os.Looper.loop(Looper.java:288)
            at android.app.ActivityThread.main(ActivityThread.java:7842)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
2023-05-02 08:31:51.842  2833-4043  FrameEvents             com...le.android.apps.nexuslauncher  E  updateAcquireFence: Did not find frame.
2023-05-02 08:31:53.740   697-697   libnos_datagram         citadeld                             E  can't send spi message: Try again
2023-05-02 08:31:53.747   697-697   libnos_datagram         citadeld                             E  can't send spi message: Try again
2023-05-02 08:31:53.753   697-697   libnos_datagram         citadeld                             E  can't send spi message: Try again
2023-05-02 08:31:53.759   697-697   libnos_datagram         citadeld                             E  can't send spi message: Try again
2023-05-02 08:31:53.765   697-697   libnos_datagram         citadeld                             E  can't send spi message: Try again
2023-05-02 08:31:54.201  9920-9984  android.vendin          com.android.vending                  E  Failed to open APK '/data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/base.apk': I/O error
2023-05-02 08:31:54.202  9920-9984  android.vendin          com.android.vending                  E  Failed to open APK '/data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/base.apk': I/O error
2023-05-02 08:31:54.203  9920-9984  ResourcesManager        com.android.vending                  E  failed to add asset path '/data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/base.apk'
            java.io.IOException: Failed to load asset path /data/app/~~DtufW25xRfmWYTj0ODv7SQ==/com.testapp.go.test-UwnuiAwKjGBU9EpNouWY3g==/base.apk
                at android.content.res.ApkAssets.nativeLoad(Native Method)
                at android.content.res.ApkAssets.<init>(ApkAssets.java:295)
                at android.content.res.ApkAssets.loadFromPath(ApkAssets.java:144)
                at android.app.ResourcesManager.loadApkAssets(ResourcesManager.java:454)
                at android.app.ResourcesManager.access$000(ResourcesManager.java:72)
                at android.app.ResourcesManager$ApkAssetsSupplier.load(ResourcesManager.java:168)
                at android.app.ResourcesManager.createAssetManager(ResourcesManager.java:530)
                at android.app.ResourcesManager.createResourcesImpl(ResourcesManager.java:612)
                at android.app.ResourcesManager.findOrCreateResourcesImplForKeyLocked(ResourcesManager.java:664)
                at android.app.ResourcesManager.createResources(ResourcesManager.java:1011)
                at android.app.ResourcesManager.getResources(ResourcesManager.java:1114)
                at android.app.ActivityThread.getTopLevelResources(ActivityThread.java:2376)
                at android.app.ApplicationPackageManager.getResourcesForApplication(ApplicationPackageManager.java:1751)
                at android.app.ApplicationPackageManager.getResourcesForApplication(ApplicationPackageManager.java:1737)
                at android.app.ApplicationPackageManager.getDrawable(ApplicationPackageManager.java:1506)
                at android.app.ApplicationPackageManager.loadUnbadgedItemIcon(ApplicationPackageManager.java:3029)
                at android.app.ApplicationPackageManager.loadItemIcon(ApplicationPackageManager.java:3008)
                at android.content.pm.PackageItemInfo.loadIcon(PackageItemInfo.java:273)
                at android.app.ApplicationPackageManager.getApplicationIcon(ApplicationPackageManager.java:1570)
                at jel.a(PG:5)
                at jer.l(PG:1)
                at re.ajn(PG:61)
                at jdw.k(PG:3)
                at jdn.f(PG:3)
                at jdn.i(PG:3)
                at jep.i(Unknown Source:0)
                at jes.d(Unknown Source:10)
                at jes.e(PG:3)
                at jdd.apply(PG:165)
                at anyp.e(PG:2)
                at anyq.run(PG:9)
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
                at ksz.run(PG:12)
                at java.lang.Thread.run(Thread.java:1012)
cortinico commented 1 year ago

I have a problem with the Android app crashing when trying to disable Hermes on RN version 0.71+, with Hermes enabled the app builds and works fine. My Android app is using multiple build flavours, so maybe the cause is related. iOS builds and works fine both with and without Hermes enabled.

Hi @denissb Thanks for sharing your build files.

Could you try on a fresh 0.71.x project, add custom flavors, disable hermes, and verify if the crash is still happening.

You can use this template to create a small repro: https://github.com/react-native-community/reproducer-react-native

If the crash is happening also in that scenario, we can look into fixing it.

github-actions[bot] commented 1 year ago

This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

github-actions[bot] commented 1 year ago

This issue was closed because it has been stalled for 7 days with no activity.

AndresHB commented 1 year ago

I have the same problem after updating to RN 0.72.6 I need to disable Hermes because the debugging tools are not working and I found a solution that recommends to disable Hermes: https://github.com/facebook/react-native/issues/34615#issuecomment-1238913946