Repository navigation
[CP-beta][FGP] Report the real error when applying kotlin-android fails - #195691
Conversation
…er#195080) When `android.builtInKotlin=false` and `android.newDsl=true`, the Flutter Gradle Plugin said "KGP was not found on the classpath". The real error from the Kotlin Gradle Plugin was hidden. The build then failed with an unrelated script compilation error. This change catches only the missing-plugin case, so other failures show the Kotlin Gradle Plugin's own message. Related to flutter#181557 and flutter#189236. <details><summary>Agent authored details</summary> `FlutterPluginUtils.detectApplyingKotlinGradlePlugin` wrapped `pluginManager.apply("kotlin-android")` in `catch (_: Exception)`. It now catches `org.gradle.api.plugins.UnknownPluginException`, which Gradle's `DefaultPluginManager.apply(String)` throws for an unknown plugin id. Failures inside the plugin's own `apply` are wrapped differently and now propagate. Before (AGP 9.3.1, KGP 2.4.20, template app, `builtInKotlin=false`, `newDsl=true`): ``` Applying the Kotlin Android Plugin (KGP) was unsuccessful. KGP was not found on the classpath. ... * What went wrong: Script compilation errors: Line 41: kotlin { ``` After: ``` > Failed to apply plugin 'kotlin-android'. > ⛔ Failed to apply plugin 'org.jetbrains.kotlin.android' The 'org.jetbrains.kotlin.android' plugin is not compatible with AGP's 9.0 new DSL (`android.newDsl=true` is enabled by default). Solution: Set `android.builtInKotlin=true` in `gradle.properties` and migrate to built-in Kotlin (see https://kotl.in/gradle/agp-built-in-kotlin for guidance), or set `android.newDsl=false` in `gradle.properties` to temporarily bypass this issue. ``` Tests: the two existing "KGP fails to apply" tests now throw `UnknownPluginException`. Added `propagates a KGP failure that is not a missing plugin`. No comments, docs or tests removed. Verification: `./gradlew test` (JDK 17) passed. ktlint 1.5.0 with the CI flags passed. A manual build of the template app was run before and after. Note: with AGP 9, KGP resolves through AGP even when `settings.gradle.kts` does not declare it, so the missing-plugin branch is hard to reach in practice. This applies cleanly to `flutter-3.50-candidate.0`; `FlutterPluginUtils.kt` is identical there. </details> ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant in-code documentation (doc comments with `///`). - [ ] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [AI contribution guidelines]: https://github.com/flutter/flutter/blob/main/CONTRIBUTING.ai.md [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [flutter/website]: https://github.com/flutter/website [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
|
@reidbaker please fill out the PR description above, afterwards the release team will review this request. |
|
This pull request was opened from and to a release candidate branch. This should only be done as part of the official Flutter release process. If you are attempting to make a regular contribution to the Flutter project, please close this PR and follow the instructions at Tree Hygiene for detailed instructions on contributing to Flutter. Reviewers: Use caution before merging pull requests to release branches. Ensure the proper procedure has been followed. |
There was a problem hiding this comment.
Code Review
This pull request modifies FlutterPluginUtils.kt to catch UnknownPluginException instead of a generic Exception when applying the Kotlin Android Plugin, allowing other Gradle failures to propagate. Corresponding tests in FlutterPluginUtilsTest.kt are updated, and a new test is added to verify this propagation. The reviewer suggested using the helper method executeDetectApplyingKotlinGradlePlugin in the new test for consistency with the rest of the test suite.
| val thrown = | ||
| assertThrows<GradleException> { | ||
| detectApplyingKotlinGradlePlugin(testProject.appProject) | ||
| } |
There was a problem hiding this comment.
For consistency with the other tests in this suite, please use the helper method executeDetectApplyingKotlinGradlePlugin(testProject) instead of calling detectApplyingKotlinGradlePlugin(testProject.appProject) directly. This also avoids potential compilation issues if the function is not statically imported.
| val thrown = | |
| assertThrows<GradleException> { | |
| detectApplyingKotlinGradlePlugin(testProject.appProject) | |
| } | |
| val thrown = | |
| assertThrows<GradleException> { | |
| executeDetectApplyingKotlinGradlePlugin(testProject) | |
| } |
|
autosubmit label was removed for flutter/flutter/195691, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label. |
9a813a8
into
flutter:flutter-3.50-candidate.0
This pull request is created by automatic cherry pick workflow
Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request.
Issue Link:
#181557
Impact Description:
Cherry-pick of #195080 (also tracks #189236 and #180137).
On Flutter 3.50 beta (
flutter-3.50-candidate.0), when an Android project setsandroid.newDsl=truewhileandroid.builtInKotlin=false,FlutterPluginUtils.detectApplyingKotlinGradlePlugincatches all exceptions frompluginManager.apply("kotlin-android"). Instead of surfacing the Kotlin Gradle Plugin's actual incompatibility message (The 'org.jetbrains.kotlin.android' plugin is not compatible with AGP's 9.0 new DSLalong with instructions to setandroid.builtInKotlin=trueorandroid.newDsl=false), Flutter Gradle Plugin prints"Applying the Kotlin Android Plugin (KGP) was unsuccessful. KGP was not found on the classpath."and the build fails later with an unrelated script compilation error (Unresolved reference: kotlin/compilerOptions). Narrowing the catch toUnknownPluginExceptionsurfaces KGP's real error and remediation guidance to developers adopting AGP 9's new DSL in 3.50.Changelog Description:
flutter/181557: Android builds with
android.newDsl=trueandandroid.builtInKotlin=falsemisreport a missing Kotlin Gradle Plugin instead of the actual incompatibility error.Workaround:
Set
android.builtInKotlin=true(after migrating offorg.jetbrains.kotlin.android) orandroid.newDsl=falseinandroid/gradle.properties; however, without this fix the build output misleads developers into debugging a missing KGP classpath dependency instead of thebuiltInKotlin/newDslmismatch.Risk:
What is the risk level of this cherry-pick?
Test Coverage:
Are you confident that your fix is well-tested by automated tests?
Validation Steps:
flutter create my_app) using AGP 9.x.android.builtInKotlin=falseandandroid.newDsl=trueinandroid/gradle.properties.flutter build apkand verify that Gradle reports KGP's real error (The 'org.jetbrains.kotlin.android' plugin is not compatible with AGP's 9.0 new DSLwith remediation steps) instead of"KGP was not found on the classpath."(also covered by unit tests inFlutterPluginUtilsTest.kt).