Skip to content

Commit d839b24

Browse files
iqqmuTfacebook-github-bot
authored andcommitted
Load jsc or hermes lib in static method (#30749)
Summary: Many have reported about the misguiding error `Fatal Exception: java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so` even though they don't use Hermes (for example issues #26075 #25923). **The current code does not handle errors correctly when loading JSC or Hermes in `ReactInstanceManagerBuilder`**. **ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java:** ```java try { return new HermesExecutorFactory(); } catch (UnsatisfiedLinkError hermesE) { // We never get here because "new HermesExecutorFactory()" does not throw an exception! hermesE.printStackTrace(); throw jscE; } ``` In Java, when an exception is thrown in static block, it will be RuntimeException and it can't be caught. For example the exception from `SoLoader.loadLibrary` can't be caught and it will crash the app. **ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.java:** ```java static { // Exception from this code block will be RuntimeException and it can't be caught! SoLoader.loadLibrary("hermes"); try { SoLoader.loadLibrary("hermes-executor-debug"); mode_ = "Debug"; } catch (UnsatisfiedLinkError e) { SoLoader.loadLibrary("hermes-executor-release"); mode_ = "Release"; } } ``` This PR fixes the code so that the original exception from failed JSC loading is not swallowed. It does not fix the original issue why JSC loading is failing with some devices, but it can be really helpful to know what the real error is. For example Firebase Crashlytics shows wrong stack trace with current code. I'm sure that this fix could have been written better. It feels wrong to import `JSCExecutor` and `HermesExecutor` in `ReactInstanceManagerBuilder.java`. However, the main point of this PR is to give the idea what is wrong with the current code. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [Android] [Fixed] - Fix error handling when loading JSC or Hermes Pull Request resolved: #30749 Test Plan: * from this PR, modify `ReactAndroid/src/main/java/com/facebook/react/jscexecutor/JSCExecutor.java` so that JSC loading will fail: ```java // original SoLoader.loadLibrary("jscexecutor"); // changed SoLoader.loadLibrary("jscexecutor-does-not-exist"); ``` * Run `rn-tester` app * Check from Logcat that the app crashed with correct exception and stacktrace. It should **not** be `java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so` Tested with Hermes ``` SoLoader.loadLibrary("hermes-executor-test"); ``` Got this one in logcat ``` 09-24 20:12:39.552 6412 6455 E AndroidRuntime: java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes-executor-test.so ``` Reviewed By: cortinico Differential Revision: D30346032 Pulled By: sota000 fbshipit-source-id: 09b032a9e471af233b7ac90b571c311952ab6342
1 parent 6acb18c commit d839b24

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed

ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.java

+14-8
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@ public class HermesExecutor extends JavaScriptExecutor {
1616
private static String mode_;
1717

1818
static {
19-
// libhermes must be loaded explicitly to invoke its JNI_OnLoad.
20-
SoLoader.loadLibrary("hermes");
21-
try {
22-
SoLoader.loadLibrary("hermes-executor-debug");
23-
mode_ = "Debug";
24-
} catch (UnsatisfiedLinkError e) {
25-
SoLoader.loadLibrary("hermes-executor-release");
26-
mode_ = "Release";
19+
loadLibrary();
20+
}
21+
22+
public static void loadLibrary() throws UnsatisfiedLinkError {
23+
if (mode_ == null) {
24+
// libhermes must be loaded explicitly to invoke its JNI_OnLoad.
25+
SoLoader.loadLibrary("hermes");
26+
try {
27+
SoLoader.loadLibrary("hermes-executor-debug");
28+
mode_ = "Debug";
29+
} catch (UnsatisfiedLinkError e) {
30+
SoLoader.loadLibrary("hermes-executor-release");
31+
mode_ = "Release";
32+
}
2733
}
2834
}
2935

ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import android.app.Application;
1515
import android.content.Context;
1616
import androidx.annotation.Nullable;
17+
import com.facebook.hermes.reactexecutor.HermesExecutor;
1718
import com.facebook.hermes.reactexecutor.HermesExecutorFactory;
1819
import com.facebook.infer.annotation.Assertions;
1920
import com.facebook.react.bridge.JSBundleLoader;
@@ -28,6 +29,7 @@
2829
import com.facebook.react.devsupport.RedBoxHandler;
2930
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
3031
import com.facebook.react.devsupport.interfaces.DevSupportManager;
32+
import com.facebook.react.jscexecutor.JSCExecutor;
3133
import com.facebook.react.jscexecutor.JSCExecutorFactory;
3234
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
3335
import com.facebook.react.packagerconnection.RequestHandler;
@@ -347,7 +349,7 @@ private JavaScriptExecutorFactory getDefaultJSExecutorFactory(
347349
try {
348350
// If JSC is included, use it as normal
349351
initializeSoLoaderIfNecessary(applicationContext);
350-
SoLoader.loadLibrary("jscexecutor");
352+
JSCExecutor.loadLibrary();
351353
return new JSCExecutorFactory(appName, deviceName);
352354
} catch (UnsatisfiedLinkError jscE) {
353355
// https://github.com/facebook/hermes/issues/78 shows that
@@ -365,6 +367,7 @@ private JavaScriptExecutorFactory getDefaultJSExecutorFactory(
365367

366368
// Otherwise use Hermes
367369
try {
370+
HermesExecutor.loadLibrary();
368371
return new HermesExecutorFactory();
369372
} catch (UnsatisfiedLinkError hermesE) {
370373
// If we get here, either this is a JSC build, and of course

ReactAndroid/src/main/java/com/facebook/react/jscexecutor/JSCExecutor.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414
import com.facebook.soloader.SoLoader;
1515

1616
@DoNotStrip
17-
/* package */ class JSCExecutor extends JavaScriptExecutor {
17+
/* package */ public class JSCExecutor extends JavaScriptExecutor {
18+
1819
static {
20+
loadLibrary();
21+
}
22+
23+
public static void loadLibrary() throws UnsatisfiedLinkError {
1924
SoLoader.loadLibrary("jscexecutor");
2025
}
2126

0 commit comments

Comments
 (0)