Skip to content

Commit 6d7e6ec

Browse files
committed
fix(android): restore namespace fallback for libraries not applying the React plugin
#57038 narrowed configureNamespaceForLibraries from a rootProject-wide sweep to only the project applying `com.facebook.react`. That was necessary because the old code re-ran the sweep from every library, and AGP 9 errors when `finalizeDsl` is registered after a project's DSL has been finalized. The narrowing has a side effect: third-party Android libraries that do NOT apply `com.facebook.react` and still rely on the manifest `package` attribute (e.g. older react-native-linear-gradient) no longer receive a namespace, so they fail under AGP 9 with "Namespace not specified". Restore the broad coverage by sweeping all `com.android.library` subprojects once, from the application project (which applies the plugin a single time, avoiding the repeated-traversal finalizeDsl error from #57038). Guard configureNamespaceForLibraries so it registers its finalizeDsl callback at most once per project, since libraries that DO apply the React plugin are now reachable from both the per-library hook and the app-level sweep.
1 parent ad2cf4d commit 6d7e6ec

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,20 @@ class ReactPlugin : Plugin<Project> {
113113
configureCodegen(project, extension, rootExtension, isLibrary = false)
114114
configureResources(project, extension)
115115
configureBuildTypesForApp(project)
116+
117+
// Apply the namespace fallback to every Android library in the build, including third-party
118+
// libraries that don't apply the `com.facebook.react` plugin and still rely on the manifest
119+
// `package` attribute (which AGP 9 no longer accepts as a namespace). The per-library hook
120+
// below only covers libraries that apply our plugin, so we additionally sweep all library
121+
// subprojects from the app. We do this once, from the application project, because re-running
122+
// a rootProject-wide traversal from every library breaks on AGP 9, which errors when
123+
// `finalizeDsl` is registered after a project's DSL has been finalized.
124+
// See https://github.com/facebook/react-native/pull/57038.
125+
project.rootProject.allprojects { subproject ->
126+
subproject.pluginManager.withPlugin("com.android.library") {
127+
configureNamespaceForLibraries(subproject)
128+
}
129+
}
116130
}
117131

118132
// Library Only Configuration

packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/AgpConfiguratorUtils.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ internal object AgpConfiguratorUtils {
106106
}
107107

108108
fun configureNamespaceForLibraries(project: Project) {
109+
// This helper can be reached both from a library's own application of the React plugin and
110+
// from the app-level sweep in ReactPlugin (which also covers libraries that don't apply
111+
// `com.facebook.react`). A project's `finalizeDsl` callback must be registered before AGP
112+
// finalizes its DSL — registering it twice (or after finalization) is a hard error on AGP 9+ —
113+
// so we guard to register the namespace fallback at most once per project.
114+
if (project.extensions.extraProperties.has(NAMESPACE_CONFIGURED_PROPERTY)) {
115+
return
116+
}
117+
project.extensions.extraProperties.set(NAMESPACE_CONFIGURED_PROPERTY, true)
109118
project.extensions.getByType(LibraryAndroidComponentsExtension::class.java).finalizeDsl { ext ->
110119
if (ext.namespace == null) {
111120
val manifestFile =
@@ -122,6 +131,8 @@ internal object AgpConfiguratorUtils {
122131
}
123132
}
124133

134+
private const val NAMESPACE_CONFIGURED_PROPERTY = "com.facebook.react.internal.namespaceConfigured"
135+
125136
const val DEFAULT_DEV_SERVER_PORT = "8081"
126137

127138
fun getPackageNameFromManifest(manifest: File): String? {

0 commit comments

Comments
 (0)