[0.82] Ensure legacy architecture can't be initialized (#53843)

* Ensure legacy architecture can't be initialized in Android (#53806)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53806

The Legacy architecture of React Native is not supported anymore, let's ensure nobody can initialize it anymore

changelog: [internal] internal

Reviewed By: cortinico

Differential Revision: D82465004

fbshipit-source-id: 099764fb59d906b11cf6ad0cc6208f56df029d19

* Runtime check that NewArchitecture is enabled in DefaultNewArchitectureEntryPoint (#53780)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53780

This is a commit we're going to pick in 0.82 as we want to make sure users cannot invoke `load()`
from `DefaultNewArchitectureEntryPoint` with flags that are not true,true,true.

Changelog:
[Android] [Changed] - Runtime check that NewArchitecture is enabled in DefaultNewArchitectureEntryPoint

Reviewed By: mdvacca

Differential Revision: D82456975

fbshipit-source-id: 749996a3491913cfe400173608218077c3ffbc10

* Fix DefaultNewArchitectureEntryPoint config validation (#53807)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53807

We need to read the values off feature flags before checking them.

## Changelog
[Internal]

Reviewed By: javache

Differential Revision: D82572898

fbshipit-source-id: 09fbc09570c78b41d9c25fb03c5557e390da7cae

* Fix incorrect validation of feature flags in DefaultNewArchitectureEntryPoint.loadWithFeatureFlags() method (#53863)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53863

In this diff I'm fixing an incorrect validation of feature flags in DefaultNewArchitectureEntryPoint.loadWithFeatureFlags() method.

changelog: [internal] internal

Reviewed By: cortinico

Differential Revision: D82841006

fbshipit-source-id: 6f50f2475255d7b841d9224bc8808119dcc68aec

---------

Co-authored-by: David Vacca <dvacca@meta.com>
Co-authored-by: Eric Rozell <ericroz@meta.com>
This commit is contained in:
Nicola Corti
2025-09-22 14:24:33 +01:00
committed by GitHub
co-authored by David Vacca Eric Rozell
parent 3a0a7365ff
commit 8dddde49b2
3 changed files with 52 additions and 20 deletions
@@ -328,6 +328,15 @@ public class ReactInstanceManager {
}
registerCxxErrorHandlerFunc();
// Using `if (true)` just to prevent tests / lint errors.
if (true) {
// Legacy architecture of React Native is deprecated and can't be initialized anymore.
// More details on:
// https://github.com/react-native-community/discussions-and-proposals/blob/nc/legacy-arch-removal/proposals/0929-legacy-architecture-removal.md
throw new UnsupportedOperationException(
"ReactInstanceManager.createReactContext is unsupported.");
}
}
private ReactInstanceDevHelper createDevHelperInterface() {
@@ -1446,6 +1455,7 @@ public class ReactInstanceManager {
*/
private ReactApplicationContext createReactContext(
JavaScriptExecutor jsExecutor, JSBundleLoader jsBundleLoader) {
FLog.d(ReactConstants.TAG, "ReactInstanceManager.createReactContext()");
ReactMarker.logMarker(CREATE_REACT_CONTEXT_START, jsExecutor.getName());
@@ -125,6 +125,16 @@ public object DefaultNewArchitectureEntryPoint {
privateConcurrentReactEnabled = featureFlags.enableFabricRenderer()
privateBridgelessEnabled = featureFlags.enableBridgelessArchitecture()
val (isValid, errorMessage) =
isConfigurationValid(
privateTurboModulesEnabled,
privateFabricEnabled,
privateBridgelessEnabled,
)
if (!isValid) {
error(errorMessage)
}
DefaultSoLoader.maybeLoadSoLibrary()
}
@@ -158,13 +168,13 @@ public object DefaultNewArchitectureEntryPoint {
fabricEnabled: Boolean,
bridgelessEnabled: Boolean,
): Pair<Boolean, String> =
when {
fabricEnabled && !turboModulesEnabled ->
false to
"fabricEnabled=true requires turboModulesEnabled=true (is now false) - Please update your DefaultNewArchitectureEntryPoint.load() parameters."
bridgelessEnabled && (!turboModulesEnabled || !fabricEnabled) ->
false to
"bridgelessEnabled=true requires (turboModulesEnabled=true AND fabricEnabled=true) - Please update your DefaultNewArchitectureEntryPoint.load() parameters."
else -> true to ""
if (!turboModulesEnabled || !fabricEnabled || !bridgelessEnabled) {
false to
"You cannot load React Native with the New Architecture disabled. " +
"Please use DefaultNewArchitectureEntryPoint.load() instead of " +
"DefaultNewArchitectureEntryPoint.load(turboModulesEnabled=$turboModulesEnabled, " +
"fabricEnabled=$fabricEnabled, bridgelessEnabled=$bridgelessEnabled)"
} else {
true to ""
}
}
@@ -13,36 +13,48 @@ import org.junit.Test
class DefaultNewArchitectureEntryPointTest {
@Test
fun isConfigurationValid_withEverythingOff_returnsTrue() {
val (isValid, _) =
fun isConfigurationValid_withEverythingOff_returnsFalse() {
val (isValid, errorMessage) =
DefaultNewArchitectureEntryPoint.isConfigurationValid(
turboModulesEnabled = false,
fabricEnabled = false,
bridgelessEnabled = false,
)
assertThat(isValid).isTrue()
assertThat(isValid).isFalse()
assertThat(errorMessage)
.isEqualTo(
"You cannot load React Native with the New Architecture disabled. Please use DefaultNewArchitectureEntryPoint.load() instead of DefaultNewArchitectureEntryPoint.load(turboModulesEnabled=false, fabricEnabled=false, bridgelessEnabled=false)"
)
}
@Test
fun isConfigurationValid_withNewArchOn_returnsTrue() {
val (isValid, _) =
fun isConfigurationValid_withNewArchOnlyOn_returnsFalse() {
val (isValid, errorMessage) =
DefaultNewArchitectureEntryPoint.isConfigurationValid(
turboModulesEnabled = true,
fabricEnabled = true,
bridgelessEnabled = false,
)
assertThat(isValid).isTrue()
assertThat(isValid).isFalse()
assertThat(errorMessage)
.isEqualTo(
"You cannot load React Native with the New Architecture disabled. Please use DefaultNewArchitectureEntryPoint.load() instead of DefaultNewArchitectureEntryPoint.load(turboModulesEnabled=true, fabricEnabled=true, bridgelessEnabled=false)"
)
}
@Test
fun isConfigurationValid_withTurboModulesOnlyOn_returnsTrue() {
val (isValid, _) =
fun isConfigurationValid_withTurboModulesOnlyOn_returnsFalse() {
val (isValid, errorMessage) =
DefaultNewArchitectureEntryPoint.isConfigurationValid(
turboModulesEnabled = true,
fabricEnabled = false,
bridgelessEnabled = false,
)
assertThat(isValid).isTrue()
assertThat(isValid).isFalse()
assertThat(errorMessage)
.isEqualTo(
"You cannot load React Native with the New Architecture disabled. Please use DefaultNewArchitectureEntryPoint.load() instead of DefaultNewArchitectureEntryPoint.load(turboModulesEnabled=true, fabricEnabled=false, bridgelessEnabled=false)"
)
}
@Test
@@ -67,7 +79,7 @@ class DefaultNewArchitectureEntryPointTest {
assertThat(isValid).isFalse()
assertThat(errorMessage)
.isEqualTo(
"fabricEnabled=true requires turboModulesEnabled=true (is now false) - Please update your DefaultNewArchitectureEntryPoint.load() parameters."
"You cannot load React Native with the New Architecture disabled. Please use DefaultNewArchitectureEntryPoint.load() instead of DefaultNewArchitectureEntryPoint.load(turboModulesEnabled=false, fabricEnabled=true, bridgelessEnabled=false)"
)
}
@@ -82,7 +94,7 @@ class DefaultNewArchitectureEntryPointTest {
assertThat(isValid).isFalse()
assertThat(errorMessage)
.isEqualTo(
"fabricEnabled=true requires turboModulesEnabled=true (is now false) - Please update your DefaultNewArchitectureEntryPoint.load() parameters."
"You cannot load React Native with the New Architecture disabled. Please use DefaultNewArchitectureEntryPoint.load() instead of DefaultNewArchitectureEntryPoint.load(turboModulesEnabled=false, fabricEnabled=true, bridgelessEnabled=true)"
)
}
@@ -97,7 +109,7 @@ class DefaultNewArchitectureEntryPointTest {
assertThat(isValid).isFalse()
assertThat(errorMessage)
.isEqualTo(
"bridgelessEnabled=true requires (turboModulesEnabled=true AND fabricEnabled=true) - Please update your DefaultNewArchitectureEntryPoint.load() parameters."
"You cannot load React Native with the New Architecture disabled. Please use DefaultNewArchitectureEntryPoint.load() instead of DefaultNewArchitectureEntryPoint.load(turboModulesEnabled=true, fabricEnabled=false, bridgelessEnabled=true)"
)
}
}