Skip to content

fix(android): skip kotlin-android plugin when AGP 9 built-in Kotlin is enabled - #1100

Open
kimchi-developer wants to merge 1 commit into
callstack:masterfrom
kimchi-developer:fix/agp9-builtin-kotlin
Open

fix(android): skip kotlin-android plugin when AGP 9 built-in Kotlin is enabled#1100
kimchi-developer wants to merge 1 commit into
callstack:masterfrom
kimchi-developer:fix/agp9-builtin-kotlin

Conversation

@kimchi-developer

Copy link
Copy Markdown

Summary

android/build.gradle applies kotlin-android unconditionally:

https://github.com/callstack/react-native-pager-view/blob/cf75cb9/android/build.gradle#L23

Android Gradle Plugin 9.0 ships built-in Kotlin support and enables it by default, so the Kotlin
Android plugin is no longer needed — and applying it anyway is a hard failure. Any app on AGP 9 fails
at configuration time on this module with:

* What went wrong:
A problem occurred configuring project ':react-native-pager-view'.
> Failed to apply plugin 'org.jetbrains.kotlin.android'.
   > The 'org.jetbrains.kotlin.android' plugin is no longer required for Kotlin support since AGP 9.0.

(depending on the AGP/KGP combination the same conflict can also surface as
Cannot add extension with name 'kotlin', as there is an extension already registered with that name).

Because the failure happens while configuring a dependency, an app author cannot fix it on their side
other than by pinning AGP 8 or setting android.builtInKotlin=false project-wide — which is only a
stopgap, as that opt-out is documented to be removed in AGP 10.

The change

Apply kotlin-android only when built-in Kotlin is not in effect:

def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger()

def builtInKotlinProperty = findProperty('android.builtInKotlin')
def hasBuiltInKotlin = agpVersion >= 9 &&
    (builtInKotlinProperty == null || builtInKotlinProperty.toString().toBoolean())

if (!hasBuiltInKotlin) {
  apply plugin: 'kotlin-android'
}

Why the condition has this shape:

  • agpVersion >= 9 — built-in Kotlin only exists from AGP 9. On AGP 8 and below the plugin must
    still be applied explicitly, so the guard has to be version-gated rather than unconditional.
  • builtInKotlinProperty == null || …toBoolean() — built-in Kotlin is on by default on AGP 9,
    so an unset android.builtInKotlin means "enabled". Consumers who opt out with
    android.builtInKotlin=false still need the explicit plugin, and this keeps working for them.
  • com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION is already used a few lines below for the
    shouldUseNameSpace (AGP 8 namespace) check, so it is a pattern this file already relies on and adds
    no new compatibility requirement. That existing parse is hoisted above the plugin block so both
    checks share one agpVersion instead of parsing it twice — the only other line the diff touches.

No behaviour change on older AGP. For AGP < 9, agpVersion >= 9 is false, hasBuiltInKotlin is
false, and apply plugin: 'kotlin-android' runs exactly as before. Same for AGP 9 consumers that set
android.builtInKotlin=false.

org.jetbrains.kotlin.plugin.compose is deliberately left applied unconditionally — the Compose
compiler Gradle plugin is still required (and still applied separately) under AGP 9 built-in Kotlin;
only org.jetbrains.kotlin.android conflicts with it. The kotlin-gradle-plugin buildscript classpath
entry is likewise kept: putting KGP on the classpath is harmless, it is only applying it that fails.

Test Plan

What's required for testing (prerequisites)?

An app (or the example app) building against AGP 9.x.

What are the steps to reproduce (after prerequisites)?

  1. Build a project that depends on react-native-pager-view with AGP 9 and default
    android.builtInKotlin (i.e. unset).
  2. Before this change: configuration fails with the Failed to apply plugin 'org.jetbrains.kotlin.android'
    error above.
  3. After this change: the module configures and compiles, with AGP compiling the module's Kotlin sources.
  4. Regression check: build the same project with AGP 8 — unchanged, kotlin-android is still applied.
  5. Regression check: build with AGP 9 and android.builtInKotlin=false in gradle.properties
    kotlin-android is applied, as it must be.

Compatibility

OS Implemented
iOS N/A
Android

Checklist

  • I have tested this on a device and a simulator
  • I added the documentation in README.md
  • I updated the typed files (TS and Flow)

Build-configuration-only change: no JS/TS surface, no native source, and nothing to document in
README.md or the typed files.

…s enabled

AGP 9 compiles Kotlin sources itself and refuses to have the Kotlin Android
plugin applied on top, so consumers on AGP 9 fail to configure this module with
"The 'org.jetbrains.kotlin.android' plugin is no longer required for Kotlin
support since AGP 9.0".

Apply 'kotlin-android' only when built-in Kotlin is not in effect, i.e. on AGP 8
and below, or when the consumer opted out with android.builtInKotlin=false.
Behaviour is unchanged on older AGP versions. The Compose compiler plugin is
still applied unconditionally, since it stays required under built-in Kotlin.

The AGP major version is already parsed further down for the namespace check;
that parse is hoisted so both checks share it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant