From 3ee058cb45c6309d71cdaa110a47546d1082001e Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Wed, 4 Nov 2026 07:56:31 -0800 Subject: [PATCH] Disable legacy Hermes executor creation (#59753) Summary: Keep `HermesExecutor.loadLibrary()` as a compatibility no-op and reject `HermesExecutorFactory.create()` with New Architecture migration guidance. Changelog: [Android][Breaking] - Disable legacy Hermes executor creation. Differential Revision: D129045580 --- .../hermes/reactexecutor/HermesExecutor.kt | 23 ++----------- .../reactexecutor/HermesExecutorFactory.kt | 12 ++++++- .../HermesExecutorFactoryTest.kt | 34 +++++++++++++++++++ 3 files changed, 48 insertions(+), 21 deletions(-) create mode 100644 packages/react-native/ReactAndroid/src/test/java/com/facebook/hermes/reactexecutor/HermesExecutorFactoryTest.kt diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.kt index efeb06a9e793..9491038c6add 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutor.kt @@ -10,32 +10,15 @@ package com.facebook.hermes.reactexecutor import com.facebook.jni.HybridData import com.facebook.jni.annotations.DoNotStrip import com.facebook.react.bridge.JavaScriptExecutor -import com.facebook.react.common.build.ReactBuildConfig -import com.facebook.soloader.SoLoader public class HermesExecutor internal constructor(enableDebugger: Boolean, debuggerName: String) : JavaScriptExecutor(initHybridDefaultConfig(enableDebugger, debuggerName)) { - override fun getName(): String = "HermesExecutor$mode" + override fun getName(): String = "HermesExecutor" public companion object { - private var mode: String? = null - - init { - loadLibrary() - } - - @JvmStatic - @Throws(UnsatisfiedLinkError::class) - public fun loadLibrary() { - if (mode == null) { - // libhermesvm must be loaded explicitly to invoke its JNI_OnLoad. - SoLoader.loadLibrary("hermesvm") - SoLoader.loadLibrary("hermes_executor") - // libhermes_executor is built differently for Debug & Release so we load the proper mode. - mode = if (ReactBuildConfig.DEBUG) "Debug" else "Release" - } - } + /** Retained for compatibility; this method no longer loads native libraries. */ + @JvmStatic public fun loadLibrary() {} @DoNotStrip @JvmStatic diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutorFactory.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutorFactory.kt index 5c31fdbb7aa3..52a415a872eb 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutorFactory.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/HermesExecutorFactory.kt @@ -25,7 +25,17 @@ public class HermesExecutorFactory : JavaScriptExecutorFactory { this.debuggerName = debuggerName } - override fun create(): JavaScriptExecutor = HermesExecutor(enableDebugger, debuggerName) + /** + * Compatibility factory for the unsupported legacy Hermes executor. + * + * @throws UnsupportedOperationException when creating an executor; use the New Architecture + * runtime instead. + */ + override fun create(): JavaScriptExecutor { + throw UnsupportedOperationException( + "HermesExecutorFactory is no longer supported. Use the New Architecture runtime instead.", + ) + } override fun startSamplingProfiler() { enable() diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/hermes/reactexecutor/HermesExecutorFactoryTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/hermes/reactexecutor/HermesExecutorFactoryTest.kt new file mode 100644 index 000000000000..d0e5501e6963 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/hermes/reactexecutor/HermesExecutorFactoryTest.kt @@ -0,0 +1,34 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.hermes.reactexecutor + +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.Test + +class HermesExecutorFactoryTest { + @Test + fun loadLibraryIsNoOp() { + HermesExecutor.loadLibrary() + HermesExecutor.loadLibrary() + } + + @Test + fun createIsUnsupported() { + val factory = HermesExecutorFactory() + factory.setEnableDebugger(false) + factory.setDebuggerName("test") + + repeat(2) { + assertThatThrownBy { factory.create() } + .isInstanceOf(UnsupportedOperationException::class.java) + .hasMessage( + "HermesExecutorFactory is no longer supported. Use the New Architecture runtime instead.", + ) + } + } +}