Skip to content

Revert file naming convention of .aar files to support fuzzy matching in build.gradle - #112149

Merged
auto-submit[bot] merged 7 commits into
flutter:masterfrom
JunhuaLin:master
Oct 4, 2022
Merged

auto-submit[bot] merged 7 commits into
flutter:masterfrom
JunhuaLin:master

Conversation

@JunhuaLin

@JunhuaLin JunhuaLin commented Sep 22, 2022 •

Copy link
Copy Markdown
Contributor

Revert file naming convention of .aar files to support fuzzy matching in build.gradle on using maven-publish

Fix #111643
Fix #108000

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard flutter-dashboard Bot added c: contributor-productivity Team-specific productivity, code health, technical debt. tool Affects the "flutter" command-line tool. See also t: labels. labels Sep 22, 2022
@google-cla

google-cla Bot commented Sep 22, 2022

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@JunhuaLin JunhuaLin changed the title Revert file naming convention of .aar files to support fuzzy matching in build.gradle #111643 Revert file naming convention of .aar files to support fuzzy matching in build.gradle Sep 22, 2022
@JunhuaLin

Copy link
Copy Markdown
Contributor Author

build result:
image

image

@JunhuaLin

Copy link
Copy Markdown
Contributor Author

image

@Jasguerrero

Copy link
Copy Markdown
Contributor

Could you take a look? @GaryQian

1 similar comment
@JunhuaLin

Copy link
Copy Markdown
Contributor Author

Could you take a look? @GaryQian

@GaryQian GaryQian left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR seems to be missing some of the testing code removed in the original PR. Can you make sure this PR fully reverts the original PR? Tests that have comments "mimic the AGP plugin" seem to be missing. Things like the JDK bump can stay unless it causes incompatibility issues. This way we have more guarantees we are not introducing new bugs.

@JunhuaLin

JunhuaLin commented Sep 25, 2022 •

Copy link
Copy Markdown
Contributor Author

This PR seems to be missing some of the testing code removed in the original PR. Can you make sure this PR fully reverts the original PR? Tests that have comments "mimic the AGP plugin" seem to be missing. Things like the JDK bump can stay unless it causes incompatibility issues. This way we have more guarantees we are not introducing new bugs.

This PR is not intended to restore all the original PR1 changes

This PR modifies the use of Maven-Publish to produce the correct AAR based on #101276

The Maven-Publish part of the code has been tested in #101276

This PR ensures that the code is correct without having to adjust the Maven-Publish-related test code

@JunhuaLin

Copy link
Copy Markdown
Contributor Author

This PR seems to be missing some of the testing code removed in the original PR. Can you make sure this PR fully reverts the original PR? Tests that have comments "mimic the AGP plugin" seem to be missing. Things like the JDK bump can stay unless it causes incompatibility issues. This way we have more guarantees we are not introducing new bugs.

The JDK version configuration in the CI file is not concerned, the latest flutter:master branch has been adjusted

@JunhuaLin

Copy link
Copy Markdown
Contributor Author

@GaryQian
When can this PR be merged to the master branch?

@GaryQian GaryQian added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 27, 2022
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Sep 27, 2022
@auto-submit

auto-submit Bot commented Sep 27, 2022

Copy link
Copy Markdown
Contributor

auto label is removed for flutter/flutter, pr: 112149, due to - Please get at least one approved review if you are already a member or two member reviews if you are not a member before re-applying this label. Reviewers: If you left a comment approving, please use the "approve" review action instead.

@auto-submit

auto-submit Bot commented Sep 27, 2022

Copy link
Copy Markdown
Contributor

auto label is removed for flutter/flutter, pr: 112149, due to Validations Fail.

@GaryQian

Copy link
Copy Markdown
Contributor

This still needs one more review to be landable! I've tagged a few others.

@GaryQian
GaryQian requested a review from camsim99 September 27, 2022 06:54
@JunhuaLin

Copy link
Copy Markdown
Contributor Author

auto label is removed for flutter/flutter, pr: 112149, due to Validations Fail.

This still needs one more review to be landable! I've tagged a few others.

There seems to be a need for approving comments LGTM

@JunhuaLin

JunhuaLin commented Sep 28, 2022 •

Copy link
Copy Markdown
Contributor Author

Could you take a look? @christopherfujino @stuartmorgan @camsim99

@JunhuaLin

Copy link
Copy Markdown
Contributor Author

Hope to deal with as soon as possible, affect the upgrade to the latest version!
We don't want to stay at 3.0.5 for too long!
This problem is holding up the build flutter.

@christopherfujino christopherfujino left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RSLGTM

@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Sep 28, 2022
@JunhuaLin

JunhuaLin commented Sep 29, 2022 •

Copy link
Copy Markdown
Contributor Author

@JunhuaLin it looks like you have a test failure, however:

02:08 +13 -1: test\integration.shard\gradle_non_android_plugin_test.dart: Flutter app that depends on a non-Android plugin can still build for Android [E]
  Expected: a file system entity that exists
    Actual: LocalFile:<LocalFile: 'C:\b\s\w\ir\x\t\flutter_flutter_plugin_test.5951ddc1\ios_only\example\build\app\outputs\apk\release\app-release.apk'>
     Which: does not exist
  
  package:test_api                                                 expect
  test\integration.shard\gradle_non_android_plugin_test.dart 90:5  main.<fn>
  dart:async                                                       runZoned
  test\src\common.dart 197:14                                      testWithoutContext.<fn>
  test\src\common.dart 166:18                                      test.<fn>

This test failure has nothing to do with my PR
Let me merge the flutter:master code again

@JunhuaLin

Copy link
Copy Markdown
Contributor Author

image

Should I not merge the master code?
Should I just keep my commit?

@JunhuaLin

Copy link
Copy Markdown
Contributor Author

Now,it‘s fine~
@christopherfujino @GaryQian

@AesSedai101

Copy link
Copy Markdown
Contributor

this change is going to cause add to app modules with multiple native dependencies to fail because of how gradle 7 does dependency resolution. Please test that case as well

@JunhuaLin

JunhuaLin commented Sep 29, 2022 •

Copy link
Copy Markdown
Contributor Author

this change is going to cause add to app modules with multiple native dependencies to fail because of how gradle 7 does dependency resolution. Please test that case as well

Can you give a detailed description demo?

OR

Does this mean that there are multiple flutter plugin dependencies?

this case:it's ok

module dependency:

app --> module_test --> flutterboost
                 |
                  --> shared_preferences_android

build aar file tree:

flutter build aar --no-debug --no-profile --build-number 1.0.0

└── host
    └── outputs
        └── repo
            ├── com
            │   ├── example
            │   │   └── module_test
            │   │       └── flutter_release
            │   │           ├── 1.0.0
            │   │           │   ├── flutter_release-1.0.0.aar
            │   │           │   ├── flutter_release-1.0.0.aar.md5
            │   │           │   ├── flutter_release-1.0.0.aar.sha1
            │   │           │   ├── flutter_release-1.0.0.aar.sha256
            │   │           │   ├── flutter_release-1.0.0.aar.sha512
            │   │           │   ├── flutter_release-1.0.0.module
            │   │           │   ├── flutter_release-1.0.0.module.md5
            │   │           │   ├── flutter_release-1.0.0.module.sha1
            │   │           │   ├── flutter_release-1.0.0.module.sha256
            │   │           │   ├── flutter_release-1.0.0.module.sha512
            │   │           │   ├── flutter_release-1.0.0.pom
            │   │           │   ├── flutter_release-1.0.0.pom.md5
            │   │           │   ├── flutter_release-1.0.0.pom.sha1
            │   │           │   ├── flutter_release-1.0.0.pom.sha256
            │   │           │   └── flutter_release-1.0.0.pom.sha512
            │   │           ├── maven-metadata.xml
            │   │           ├── maven-metadata.xml.md5
            │   │           ├── maven-metadata.xml.sha1
            │   │           ├── maven-metadata.xml.sha256
            │   │           └── maven-metadata.xml.sha512
            │   └── idlefish
            │       └── flutterboost
            │           └── flutter_boost_release
            │               ├── 1.0.0
            │               │   ├── flutter_boost_release-1.0.0.aar
            │               │   ├── flutter_boost_release-1.0.0.aar.md5
            │               │   ├── flutter_boost_release-1.0.0.aar.sha1
            │               │   ├── flutter_boost_release-1.0.0.aar.sha256
            │               │   ├── flutter_boost_release-1.0.0.aar.sha512
            │               │   ├── flutter_boost_release-1.0.0.module
            │               │   ├── flutter_boost_release-1.0.0.module.md5
            │               │   ├── flutter_boost_release-1.0.0.module.sha1
            │               │   ├── flutter_boost_release-1.0.0.module.sha256
            │               │   ├── flutter_boost_release-1.0.0.module.sha512
            │               │   ├── flutter_boost_release-1.0.0.pom
            │               │   ├── flutter_boost_release-1.0.0.pom.md5
            │               │   ├── flutter_boost_release-1.0.0.pom.sha1
            │               │   ├── flutter_boost_release-1.0.0.pom.sha256
            │               │   └── flutter_boost_release-1.0.0.pom.sha512
            │               ├── maven-metadata.xml
            │               ├── maven-metadata.xml.md5
            │               ├── maven-metadata.xml.sha1
            │               ├── maven-metadata.xml.sha256
            │               └── maven-metadata.xml.sha512
            └── io
                └── flutter
                    └── plugins
                        └── sharedpreferences
                            └── shared_preferences_android_release
                                ├── 1.0.0
                                │   ├── shared_preferences_android_release-1.0.0.aar
                                │   ├── shared_preferences_android_release-1.0.0.aar.md5
                                │   ├── shared_preferences_android_release-1.0.0.aar.sha1
                                │   ├── shared_preferences_android_release-1.0.0.aar.sha256
                                │   ├── shared_preferences_android_release-1.0.0.aar.sha512
                                │   ├── shared_preferences_android_release-1.0.0.module
                                │   ├── shared_preferences_android_release-1.0.0.module.md5
                                │   ├── shared_preferences_android_release-1.0.0.module.sha1
                                │   ├── shared_preferences_android_release-1.0.0.module.sha256
                                │   ├── shared_preferences_android_release-1.0.0.module.sha512
                                │   ├── shared_preferences_android_release-1.0.0.pom
                                │   ├── shared_preferences_android_release-1.0.0.pom.md5
                                │   ├── shared_preferences_android_release-1.0.0.pom.sha1
                                │   ├── shared_preferences_android_release-1.0.0.pom.sha256
                                │   └── shared_preferences_android_release-1.0.0.pom.sha512
                                ├── maven-metadata.xml
                                ├── maven-metadata.xml.md5
                                ├── maven-metadata.xml.sha1
                                ├── maven-metadata.xml.sha256
                                └── maven-metadata.xml.sha512

pom dependencies:

module_test pom file:

<project ...>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.module_test</groupId>
  <artifactId>flutter_release</artifactId>
  <version>1.0.0</version>
  <packaging>aar</packaging>

  <dependencies>
    <dependency>
      <groupId>io.flutter</groupId>
      <artifactId>flutter_embedding_release</artifactId>
      <version>1.0.0-4b591e17d288447f118300754073c9f1d9a4393a</version>
      <scope>compile</scope>
    </dependency>
  
 ......

    <dependency>
      <groupId>io.flutter.plugins.sharedpreferences</groupId>
      <artifactId>shared_preferences_android_release</artifactId>
      <version>1.0.0</version>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>com.idlefish.flutterboost</groupId>
      <artifactId>flutter_boost_release</artifactId>
      <version>1.0.0</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

flutterboost pom file:

<project ...>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.idlefish.flutterboost</groupId>
  <artifactId>flutter_boost_release</artifactId>
  <version>1.0.0</version>
  <packaging>aar</packaging>
  <dependencies>
    <dependency>
      <groupId>io.flutter</groupId>
      <artifactId>flutter_embedding_release</artifactId>
      <version>1.0.0-4b591e17d288447f118300754073c9f1d9a4393a</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

shared_preferences_android pom file:

<project ...>
  <modelVersion>4.0.0</modelVersion>
  <groupId>io.flutter.plugins.sharedpreferences</groupId>
  <artifactId>shared_preferences_android_release</artifactId>
  <version>1.0.0</version>
  <packaging>aar</packaging>
  <dependencies>
    <dependency>
      <groupId>io.flutter</groupId>
      <artifactId>flutter_embedding_release</artifactId>
      <version>1.0.0-4b591e17d288447f118300754073c9f1d9a4393a</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

The dependencies in the POM are complete

@AesSedai101

AesSedai101 commented Sep 29, 2022 •

Copy link
Copy Markdown
Contributor

If you have your add to app project depending on another plugin with a native dependency (in your case, flutterboost depending on shared_preferences) via the pubspec, the dependencies in the POM uses the new classifier mechanism.

For example., in my main add to app module, I use logging_to_logcat, which gets included like this:

   <dependency>
      <groupId>com.logger.logging_to_logcat</groupId>
      <artifactId>logging_to_logcat</artifactId>
      <version>1.0.0</version>
      <scope>compile</scope>
    </dependency>

with the -debug and -release classifiers mapping to the flavours.

so, if you don't publish the artifacts in the new way with the classifiers, you will need to declare all Flutter dependencies with a native component manually in the gradle file of your native project.

@JunhuaLin

JunhuaLin commented Sep 29, 2022 •

Copy link
Copy Markdown
Contributor Author

If you have your add to app project depending on another plugin with a native dependency (in your case, flutterboost depending on shared_preferences) via the pubspec, the dependencies in the POM uses the new classifier mechanism.

For example., in my main add to app module, I use logging_to_logcat, which gets included like this:

   <dependency>
      <groupId>com.logger.logging_to_logcat</groupId>
      <artifactId>logging_to_logcat</artifactId>
      <version>1.0.0</version>
      <scope>compile</scope>
    </dependency>

with the -debug and -release classifiers mapping to the flavours.

so, if you don't publish the artifacts in the new way with the classifiers, you will need to declare all Flutter dependencies with a native component manually in the gradle file of your native project.

I created the following dependency structure:

app --> module_test --> flutterboost --> okhttp
                             |
                              --> logging_to_logcat

flutterboost depending on logging_to_logcat and okhttp

flutterboost pubspec file:

name: flutter_boost
description: A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.
version: 3.0.0

homepage: https://github.com/alibaba/flutter_boost

environment:
  sdk: '>=2.12.0 <3.0.0'

dependencies:
  flutter:
    sdk: flutter
  collection: ^1.16.0
  logging_to_logcat: ^0.1.1               <---- plugin

dev_dependencies:
  flutter_lints: ^2.0.1
  flutter_test:
    sdk: flutter
  pigeon: ^3.2.9

flutter:
  plugin:
    platforms:
      android:
        package: com.idlefish.flutterboost
        pluginClass: FlutterBoostPlugin
      ios:
        pluginClass: FlutterBoostPlugin

flutterboost gradle file:

group 'com.idlefish.flutterboost'
version '1.0-SNAPSHOT'

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.4'
    }
}

rootProject.allprojects {
    repositories {
        google()
        jcenter()
    }
}

apply plugin: 'com.android.library'

android {
    compileSdkVersion 31
    buildToolsVersion '30.0.2'
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 31
        testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
    }
    lintOptions {
        disable 'InvalidPackage'
        abortOnError false
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    compileOnly 'com.google.android.material:material:1.0.0'
    compileOnly 'com.alibaba:fastjson:1.2.41'
    implementation 'com.squareup.okhttp3:okhttp:3.5.0'                  <------ native
}

ext {
    groupId = 'com.taobao.fleamarket'
    artifactId = "FlutterBoost"
}


.flutter-plugins-dependencies file:Plugin dependent plugins also compile normally,look this:

image

build aar file tree:

└── host
    └── outputs
        └── repo
            └── com
                ├── example
                │   └── module_test
                │       └── flutter_release
                │           ├── 1.0
                │           │   ├── flutter_release-1.0.aar
                │           │   ├── flutter_release-1.0.aar.md5
                │           │   ├── flutter_release-1.0.aar.sha1
                │           │   ├── flutter_release-1.0.pom
                │           │   ├── flutter_release-1.0.pom.md5
                │           │   └── flutter_release-1.0.pom.sha1
                │           ├── maven-metadata.xml
                │           ├── maven-metadata.xml.md5
                │           └── maven-metadata.xml.sha1
                ├── idlefish
                │   └── flutterboost
                │       └── flutter_boost_release
                │           ├── 1.0
                │           │   ├── flutter_boost_release-1.0.aar
                │           │   ├── flutter_boost_release-1.0.aar.md5
                │           │   ├── flutter_boost_release-1.0.aar.sha1
                │           │   ├── flutter_boost_release-1.0.pom
                │           │   ├── flutter_boost_release-1.0.pom.md5
                │           │   └── flutter_boost_release-1.0.pom.sha1
                │           ├── maven-metadata.xml
                │           ├── maven-metadata.xml.md5
                │           └── maven-metadata.xml.sha1
                └── logger
                    └── logging_to_logcat
                        └── logging_to_logcat_release
                            ├── 1.0
                            │   ├── logging_to_logcat_release-1.0.aar
                            │   ├── logging_to_logcat_release-1.0.aar.md5
                            │   ├── logging_to_logcat_release-1.0.aar.sha1
                            │   ├── logging_to_logcat_release-1.0.pom
                            │   ├── logging_to_logcat_release-1.0.pom.md5
                            │   └── logging_to_logcat_release-1.0.pom.sha1
                            ├── maven-metadata.xml
                            ├── maven-metadata.xml.md5
                            └── maven-metadata.xml.sha1

module_test pom file:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.module_test</groupId>
  <artifactId>flutter_release</artifactId>
  <version>1.0</version>
  <packaging>aar</packaging>
  <dependencies>
    <dependency>
      <groupId>com.logger.logging_to_logcat</groupId>
      <artifactId>logging_to_logcat_release</artifactId>
      <version>1.0</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.idlefish.flutterboost</groupId>
      <artifactId>flutter_boost_release</artifactId>
      <version>1.0</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.flutter</groupId>
      <artifactId>flutter_embedding_release</artifactId>
      <version>1.0.0-d3ea636dc5d16b56819f3266241e1f708979c233</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.flutter</groupId>
      <artifactId>armeabi_v7a_release</artifactId>
      <version>1.0.0-d3ea636dc5d16b56819f3266241e1f708979c233</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.flutter</groupId>
      <artifactId>arm64_v8a_release</artifactId>
      <version>1.0.0-d3ea636dc5d16b56819f3266241e1f708979c233</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.flutter</groupId>
      <artifactId>x86_64_release</artifactId>
      <version>1.0.0-d3ea636dc5d16b56819f3266241e1f708979c233</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

flutterboost pom file:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!-- This module was also published with a richer model, Gradle metadata,  -->
  <!-- which should be used instead. Do not delete the following line which  -->
  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
  <!-- that they should prefer consuming it instead. -->
  <!-- do_not_remove: published-with-gradle-metadata -->
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.idlefish.flutterboost</groupId>
  <artifactId>flutter_boost_release</artifactId>
  <version>1.0</version>
  <packaging>aar</packaging>
  <dependencies>
    <dependency>
      <groupId>io.flutter</groupId>
      <artifactId>flutter_embedding_release</artifactId>
      <version>1.0.0-4b591e17d288447f118300754073c9f1d9a4393a</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>okhttp</artifactId>
      <version>3.5.0</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>com.logger.logging_to_logcat</groupId>
      <artifactId>logging_to_logcat_release</artifactId>
      <version>1.0</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>

logging_to_logcat pom file:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!-- This module was also published with a richer model, Gradle metadata,  -->
  <!-- which should be used instead. Do not delete the following line which  -->
  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
  <!-- that they should prefer consuming it instead. -->
  <!-- do_not_remove: published-with-gradle-metadata -->
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.logger.logging_to_logcat</groupId>
  <artifactId>logging_to_logcat_release</artifactId>
  <version>1.0</version>
  <packaging>aar</packaging>
  <dependencies>
    <dependency>
      <groupId>io.flutter</groupId>
      <artifactId>flutter_embedding_release</artifactId>
      <version>1.0.0-4b591e17d288447f118300754073c9f1d9a4393a</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-stdlib-jdk7</artifactId>
      <version>1.6.10</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>

This case is fine~

@GaryQian

Copy link
Copy Markdown
Contributor

@AesSedai101 Can you confirm that @JunhuaLin 's explanation here resolves your concern?

@JunhuaLin

JunhuaLin commented Sep 30, 2022 •

Copy link
Copy Markdown
Contributor Author

image

Why tree is currently broken?
I shouldn't merge the master, I should use Rebase, right?

@GaryQian

Copy link
Copy Markdown
Contributor

Yes, you should use rebase, but don't worry about the tree being broken, it is not your fault, it should become green again soon (it is green now). That check simply reflects the build status of tip-of-tree.

@JunhuaLin

JunhuaLin commented Sep 30, 2022 •

Copy link
Copy Markdown
Contributor Author

Yes, you should use rebase, but don't worry about the tree being broken, it is not your fault, it should become green again soon (it is green now). That check simply reflects the build status of tip-of-tree.

Ok, I see~

Can my PR be merged in this case?

We want to use the latest version as soon as possible

@AesSedai101

Copy link
Copy Markdown
Contributor

Can you confirm that @JunhuaLin 's explanation here resolves your concern?

That is not the behaviour I saw on my side, but it's possible that my environment is in a broken state

@JunhuaLin

JunhuaLin commented Sep 30, 2022 •

Copy link
Copy Markdown
Contributor Author

Can you confirm that @JunhuaLin 's explanation here resolves your concern?

That is not the behaviour I saw on my side, but it's possible that my environment is in a broken state

I'm not sure I understand your situation.
My changes are consistent with 3.0.5 and earlier features for build aar,so there should be no negative effect!

You can use my branch master version to verify your problem
or:
Can you reproduce your problem in 3.0.5 or earlier?
Can you provide a complete minimum reproducible code example ?

@GaryQian

GaryQian commented Oct 2, 2022

Copy link
Copy Markdown
Contributor

@AesSedai101 Ping on @JunhuaLin 's questions

@JunhuaLin

Copy link
Copy Markdown
Contributor Author

Can my PR be released with 3.4.0 @GaryQian

@GaryQian GaryQian added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 4, 2022
@auto-submit
auto-submit Bot merged commit 8e30cc9 into flutter:master Oct 4, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Oct 4, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Oct 4, 2022
flutter-kim-json added a commit to flutter-kim-json/flutter that referenced this pull request Feb 20, 2023
gmackall pushed a commit to gmackall/flutter that referenced this pull request Oct 20, 2026
…Is (flutter#193962)

PR 7 (flutter#193693) merged to master as `ecd1ab06865` and PR 8 (flutter#193717) as
`4249ccbc18a`. This branch merges master at `4521d8d6634`, so the Files
tab shows only PR 9's changes.

PR 9 commits:
- `86523c549fc` Move aar_init_script to public AGP APIs
- `3edc95d1fa0` Check requested AAR variants in the module and each
plugin
- `da9646aad53` Address review: derive requested variants from
components, register AAR tasks lazily
- `94a29907065` Clarify aar_init_script comments from the adversarial
review
- `ea08280d886` Merge commit '23ddd6b74e6' into agp-aar-init-script (PR
8's head with master at `ecd1ab06865`; no conflicts, no change to PR 9's
files)
- `a17fafcc35e` Merge commit '5ba8961b517' into agp-aar-init-script
(master with PR 8 at `4249ccbc18a`; no conflicts, no change to PR 9's
files)
- `77ba449ea4a` Filter requested AAR components before adding tasks
- `adbfb9cd640` Drop the AGP version list from the duplicate-variant
comment
- `f2b7111c51e` Docs: state the AAR variant requirement in plain words
- `cd10f766b5b` Register an AAR task for every variant, publish only
requested ones
- `b9493299916` Merge commit '4521d8d6634' into agp-aar-init-script
(master, including flutter#193649; no conflicts, no change to PR 9's files)

## Description

This is PR 9 of 11 in the AGP 9.1.0 / public `gradle-api` migration
stack ([flutter#180137](flutter#180137),
[flutter#166550](flutter#166550)).

`flutter build aar` passes
`packages/flutter_tools/gradle/aar_init_script.gradle` to Gradle with
`-I`. The script read `android.libraryVariants` and AGP's internal
`publishing.singleVariants`. With AGP 9's `android.newDsl=true`,
`flutter build aar` on a module fails on `5ba8961b517` with `Can't
generate AAR on a non Android library project.` (script line 13), and
then at line 178 (`Could not get unknown property 'libraryVariants'`).
With this PR the script uses only `pluginManager.hasPlugin`,
`Publishing.singleVariant`, software `components` and `tasks.register`,
and the build succeeds with `newDsl` on and off, on AGP 9.3.1 and on
master's minimum AGP 9.1.1, and on AGP 8.11.1 when FGP's version check
is skipped.

**Breaking:** no. Builds that succeed on `5ba8961b517` succeed with the
same artifacts. Two failing cases change: a module or plugin build file
that declares `singleVariant` for only some variants builds, and a
variant mismatch between the module and a plugin fails with a Flutter
error instead of `Task with name … not found`.

**Base:** `master` at `4521d8d6634`. `aar_init_script.gradle`,
`build_aar_module_test.dart` and both docs are the same at `4521d8d6634`
and `5ba8961b517`, so the comparisons below against `5ba8961b517` hold
for `4521d8d6634`.

<details>
<summary>Agent authored details</summary>

### Changes

All in `aar_init_script.gradle` unless noted. Line numbers are at
`b9493299916`.

1. **Library check** (`:13`):
`project.pluginManager.hasPlugin("com.android.library")` replaces
`android.hasProperty("libraryVariants")`. The error text is unchanged.
2. **Publishing declarations** (`afterProject`, `:185-219`): Flutter
calls `android.publishing.singleVariant(<variant>) { withSourcesJar();
withJavadocJar() }` for each variant, one variant at a time. If the
project's build file already declared that variant, AGP throws, and
`isDuplicateSingleVariantError` (`:125-134`) matches AGP's exact
message, so the build file's declaration is kept. Its comment links the
AGP source of the message ([`AbstractPublishing.kt` at
`studio-2025.3.2`, AGP
9.1.0](https://android.googlesource.com/platform/tools/base/+/refs/tags/studio-2025.3.2/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dsl/AbstractPublishing.kt#38)).
Any other exception is rethrown (`:201-203`). The guard that read
`publishing.singleVariants` and skipped every Flutter declaration once
the build file declared any variant is deleted.
3. **No module-to-plugin `dependsOn`** (`projectsEvaluated`): the loop
over `moduleProject.android.libraryVariants` that made each module
`assembleAar<Variant>` depend on the plugin's task (with eager
`tasks.named(...).get()`) is deleted. The tool requests
`assembleAar<Variant>` without a project path (`gradle.dart`
`buildGradleAar`, `command.add(aarTask)`), and Gradle runs a task
selector that is only a task name in every project that has the task
([Gradle
docs](https://docs.gradle.org/current/userguide/command_line_interface.html#executing_tasks_in_multi_project_builds):
"You can also run a task for all subprojects using a task selector that
consists of only the task name."). Each plugin publishes from its own
task. The comment at `:247-248` says this.
4. **Tasks, publications and task name** (`configureProject` `:27-37`;
`aarTaskName` `:93-97`; `requestedAarComponents` `:99-103`): AGP adds
one software component for each `singleVariant` declaration, with the
variant's name. `registerAarTask` (`:105-110`) registers
`assembleAar<Variant>` for every component, so a misspelled `--flavor`
gets Gradle's candidate list (`Some candidates are: 'assembleAarDebug',
...`). `requestedAarComponents` returns the components whose
`assembleAar<Variant>` name is in `startParameter.taskNames`; only those
get a publication (`addAarPublication`, `:112-123`), because `publish`
publishes every publication in the project. The check uses the same
function. `aarTaskName` is the only place that builds
`assembleAar<Variant>`; its comment points to the tool's `getAarTaskFor`
(`gradle.dart`). Nothing parses a task name back into a variant. The
`component.name != "all"` filter from `5ba8961b517` is deleted (see "Why
removing the deleted code is safe").
5. **Lazy task registration** (`registerAarTask`):
`project.tasks.register` replaces `project.tasks.create(name:)`. The
configuration action only adds `finalizedBy "publish"`.
`publications.create` runs in `addAarPublication`, not in the action,
because maven-publish registers tasks for each publication and Gradle
rejects that while it realizes a task
(`DefaultTaskContainer#register(String, Class, Action) on task set
cannot be executed in the current context.`, seen when
`publications.create` was inside the action).
6. **Requested-variant check** (`checkProjectsHaveRequestedVariants`,
`:136-175`, called at `:252`): Gradle skips projects that lack the
requested task, so the script checks the module and each Android plugin.
The requested variants are the names of the components that
`requestedAarComponents` returns for those projects. A project without a
requested variant fails the build with a `GradleException` that names
the variant and the project:
- module: `Flutter can't build the AAR for variant 'debug' because
module project ':flutter' has no variant with that name. Its variants
are: demoDebug, demoProfile, demoRelease, fullDebug, fullProfile,
fullRelease. Pass the module's product flavor with --flavor, or omit
--flavor if the module has no product flavors.`
- plugin: `Flutter can't build the AAR for variant 'demoDebug' because
plugin project ':plugin_a' has no variant with that name, so the plugin
AAR that the module depends on can't be published. `flutter build aar`
requires the module and each of its Android plugins to declare the same
product flavors.`
- A requested task that matches no project's variant (for example
`--flavor foo`) is left to Gradle: `Task 'assembleAarFooDebug' not found
in root project 'android_generated' and its subprojects. Some candidates
are: 'assembleAarDebug', 'assembleAarDemoDebug',
'assembleAarFullDebug'.` That is the same error as on `5ba8961b517`. The
check's doc says so. (`3edc95d1fa0` parsed the task-name prefix and
reported a Flutter module error in this case; `da9646aad53` drops the
parsing per review.)
7. **Docs.** Both docs describe behavior only.
- `Migrating-Flutter-Gradle-Plugin-to-AGP-public-API.md`: the P8 row of
the phase table and "Features that must break" item 8 are rewritten. The
"Why" starting-state list (L38-39) is unchanged, as in other PRs of the
stack.
-
[`website-page-draft.md`](https://github.com/flutter/flutter/blob/master/docs/platforms/android/website-page-draft.md)
(publishing tracked in
[flutter#193713](flutter#193713)): the
`flutter build aar` section is rewritten. It said Flutter "detects the
overlap and reports it with an actionable error". The code keeps the
build file's declaration instead, so the docs were changed to match the
code. It says (L234-237) that when a build file declares `singleVariant`
for a variant, Flutter keeps that declaration and declares the other
variants, and (L238-241) that the module and each Android plugin need a
variant with the built name.
8. **Tests.** devicelab `build_aar_module_test` gets two final sections:
- With `android.newDsl=true` and `android.builtInKotlin=true` in
`.android/gradle.properties`, and
`android.publishing.singleVariant("release") { withSourcesJar() }` in
`.android/Flutter/build.gradle`, it runs `flutter build aar
--no-profile`. It checks that the edits survive, that release has the
AAR and sources jar and no javadoc jar, that debug has the javadoc jar,
and that the plugin AARs exist for release and debug.
- It replaces that declaration with a `demo` product flavor and checks
both errors: `flutter build aar --no-profile --no-release` fails with
the module error, and the same with `--flavor demo` fails with the
plugin error.

`da9646aad53`'s commit message says the check's doc "says when it
returns and when it throws". That doc sentence was added in
`94a29907065`.

### Bug history (moved out of the docs)

The docs describe behavior only, so the history that `3edc95d1fa0` put
in them is here:
- On `5ba8961b517`, the `afterProject` guard skipped all of Flutter's
`singleVariant` declarations for a project whose build file declared any
variant. For a module with at least one Android plugin that declared
only `release`, every `flutter build aar` failed with `Task with name
'assembleAarDebug' not found in project ':flutter'`. With this PR that
build succeeds (table 1 below).
- On `5ba8961b517`, the `dependsOn` loop failed with `Task with name
'assembleAar<Variant>' not found in project ':<plugin>'` whenever a
plugin lacked any module variant, requested or not, and nothing checked
that the module had the requested variant. With this PR only requested
variants are checked, in the module and in each plugin (table 2 below).

### Audit resolution

[PR 9 draft
audit](reidbaker-agent#9 (comment)),
and stack audit items M4 and L8:

| Item | Resolution |
| --- | --- |
| 1. Eager `.get()` and cross-project task lookup by name | The wiring
is deleted, not made lazy: it was redundant (Changes 3). No `.get()` or
`tasks.named` in the script. The check reads software components, and
`registerAarTask` uses `tasks.register`. |
| 2. Broad `catch (Exception)`; overstated `multipleVariants` warning |
Only AGP's exact duplicate message is ignored (`:130-134`); everything
else is rethrown (`:201-203`). No warning is logged, so there is no
`multipleVariants` claim. |
| 3. Ext property without `flutter.internal.` | No ext property.
`afterProject` fires once per project (instrumented: count 1 for `:`,
`:app`, `:flutter`, `:plugin_a` and the included FGP build), and a
second call would only hit ignored duplicates. The "fires more than once
in composite settings" claim is dropped. |

Why the message match and not the type: AGP reports the duplicate from
`AbstractPublishing.checkSingleVariantUniqueness` through
`SyncIssueReporterImpl`, which throws
`com.android.builder.errors.EvalIssueException` in STANDARD mode. That
class is in `com.android.tools.build:builder`, not in `gradle-api`, and
is not on the init script's classpath. `javap -v` on
`AbstractPublishing` shows the same text in AGP 8.11.1, 9.1.0 and 9.3.1.
AGP checks before it adds the component (8.11.1
`AbstractPublishing.kt:27-35`), so the build file's declaration stays.
If AGP changes the text, the exception is rethrown and the build fails
loudly; devicelab `build_aar_module_test` exercises the path on the
template AGP.

Why not declare first or query: the public `Publishing` DSL in
`gradle-api-9.1.0.jar` has only `singleVariant(String)` and
`singleVariant(String, Function1)`, and `LibraryPublishing` adds only
`multipleVariants(...)` (`javap`), so there is no public way to list
declared variants. Declaring Flutter's variants in `beforeProject` +
`pluginManager.withPlugin("com.android.library")` makes the build file
fail at its own `singleVariant("release")` line with the duplicate error
(probe).

Why not AGP types in the init script: `import
com.android.build.api.dsl.LibraryExtension` fails with `unable to
resolve class`. With `gradle-api:9.3.1` on the `initscript` classpath,
the init script gets its own copy of the class from a different
classloader, so `instanceof` is `false` and
`extensions.getByType(LibraryExtension)` throws `Extension of type
'LibraryExtension' does not exist. Currently registered extension types:
[..., LibraryExtension, ...]` (probes).

`multipleVariants`: `PublishingUtil.ensureComponentNameUniqueness`
errors only when a `multipleVariants` component name equals a
`singleVariant` name. Flutter declares the same `singleVariant`s on
`5ba8961b517` when the build file declares none, so that behavior is
unchanged. It is not tested here.

### Why removing the deleted code is safe

- `android.libraryVariants` does not exist with `newDsl=true`
(reproduced above). AGP 9.1.0 marks its class,
`com.android.build.gradle.LibraryExtension`, `@Deprecated` ("This class
is not used for the public extensions in AGP when android.newDsl=true,
which is the default in AGP 9.0, and will be removed in AGP 10.0."), and
the class is not in `gradle-api-9.1.0.jar`. `singleVariants` is an
internal property (`getSingleVariants()` on
`com.android.build.gradle.internal.dsl.AbstractPublishing`, `javap`). It
resolves from Groovy with `newDsl=true`, so it was not a failure, only
internal API.
- The `dependsOn`: with it removed, the task graph for
`assembleAarRelease` on case (a) has `:plugin_a:assembleAarRelease`,
`:plugin_a:bundleReleaseAar`,
`:plugin_a:publishReleasePublicationToMavenRepository` and
`:plugin_a:publish`. `:flutter:generatePomFileForReleasePublication`
depends on no `:plugin_a` task, and
`:flutter:publishReleasePublicationToMavenRepository` depends only on
the plugin's compile-classpath tasks, so the order between the module's
and the plugin's publishing doesn't matter. The module POM refers to the
plugin by coordinates (`plugin_a_release`). devicelab
`build_aar_module_test`, `build_android_host_app_with_module_aar` and
`android_java17_build_android_host_app_with_module_aar` pass (they check
the plugin AAR/POM and that the module POM depends on
`plugin_with_android_release`).
- The `all` filter (`component.name != "all"`, added in flutter#101891
`606e91ad63d`): AGP 7.x created an automatic multi-variant component
named `all` when a project used no publishing DSL ([`PublishingUtil.kt`
at
`studio-2021.3.1`](https://android.googlesource.com/platform/tools/base/+/refs/tags/studio-2021.3.1/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/utils/PublishingUtil.kt),
`createPublishingInfoForLibrary` and `publishingFeatureOptIn`; same in
the AGP 7.3.1 jar). flutter#101891 published it separately with classifiers and
skipped it for the `_<variant>` publications; flutter#112149 (`8e30cc9c56b`)
removed that publication and kept the skip. AGP 8.0 disabled automatic
components by default ([AGP 8.0.0 release
notes](https://developer.android.com/build/releases/past-releases/agp-8-0-0-release-notes)),
and the AGP 8.11.1, 9.1.1 and 9.3.1 jars list
`android.disableAutomaticComponentCreation` as removed, with no `all`
component code. This script declares `singleVariant` for every variant,
which also turns automatic components off on AGP 7.x. A probe that
prints `project.components` after `projectsEvaluated` on all four matrix
configurations shows only per-variant names (`[debug, profile, release]`
for `:flutter`, `:app` and each plugin, `[demoDebug, …, fullRelease]`
for the flavored module, `[freeDebug, freeProfile, freeRelease]` for
`plugin_flavored`, `[debug, release]` for the root), never `all`.
- `tasks.register`: the publication is created at configuration time
only for a requested task name, as with `tasks.create`, whose
configuration closure ran immediately. Only the task object is created
lazily. Table rows below and the devicelab runs show the same artifacts.

### Removed comments, assertions and code

| Removed | Reason |
| --- | --- |
| `afterProject` comment item 2, "The project has already defined which
variants to publish…", and the `singleVariants.size()` guard it
described | The guard read internal API and skipped all of Flutter's
declarations once a build file declared any. Item 1 of that comment
became "Exit early if the project doesn't have the Android Gradle plugin
applied." |
| The `projectsEvaluated` comment "Configure the
`assembleAar<variantName>` task for each plugin's projects and make the
module's equivalent task depend on the plugin's task.", with the
`libraryVariants.all` loop, both `tasks.named(...).get()` calls, both
`assert(... != null)` and the `dependsOn` | The dependency is redundant
(see above). `tasks.named(...).get()` throws before the asserts could
fail, so they never checked anything. |
| `addAarTask` and its `variantName` local | Split into
`registerAarTask` (every component) and `addAarPublication` (requested
components). The task name comes from `aarTaskName`, which the check
also uses. |
| `addAarTask` comment "This check is required to be able to configure
the archives before `publish` runs.", with the check | The check is
`requestedAarComponents`, applied by the caller before
`addAarPublication`. Its reason is the comment on `addAarPublication`:
"`publish` publishes every publication in the project, so only requested
components get one." |
| The `component.name != "all"` filter in `configureProject`, and the
fragment "(except "all" since that is used to publish artifacts in the
new way)" from "Create a default MavenPublication for the variant" |
Nothing creates an `all` component where this script runs (see "Why
removing the deleted code is safe"). |
| From the migration doc item 8 and the website page draft: the
sentences about the deleted guard, the `Task with name … not found`
failures, and what the deleted code did and did not check | The docs
describe behavior only. The history is in "Bug history" above. |

### Behavioral and compatibility notes

Matrix projects (local scratch): (a) module + Android plugin `plugin_a`;
(b) module with flavors `demo`/`full` + `plugin_a`; (c) module +
`plugin_a` + `plugin_flavored` (flavor `free`); (d) module declaring
`singleVariant("release") { withSourcesJar() }` + `plugin_a`.

1. **A build file that declares `singleVariant` for some variants
builds.** Case (d), `flutter build aar`:

   | Script | Result |
   | --- | --- |
| `5ba8961b517` (AGP 9.3.1 `newDsl=false`) | exit 1: `Task with name
'assembleAarDebug' not found in project ':flutter'.` |
| This PR (all four configurations below) | exit 0. Release has the AAR,
POM and sources jar, and no javadoc jar (the build file's declaration).
Debug and profile have sources and javadoc jars. Plugin AAR/POM for all
three. |

2. **Variant mismatches fail with a Flutter error that names the
project.** Only requested variants are checked. The `5ba8961b517` column
is AGP 9.3.1 with `newDsl=false`.

   | Case | `5ba8961b517` | This PR (all four configurations) |
   | --- | --- | --- |
| (b) `--flavor demo` | `Task with name 'assembleAarDemoDebug' not found
in project ':plugin_a'.` | plugin error for `demoDebug` and `:plugin_a`
|
| (c) default | `Task with name 'assembleAarDebug' not found in project
':plugin_flavored'.` | plugin error for `debug` and `:plugin_flavored` |
| (b) no `--flavor`, `--no-profile --no-release` | `Task with name
'assembleAarDemoDebug' not found in project ':plugin_a'.` | module error
for `debug`, listing the module's variants |
| (c) `--flavor free`, `--no-profile --no-release` | `Task with name
'assembleAarDebug' not found in project ':plugin_flavored'.` | module
error for `freeDebug` |
| (b) `--flavor foo` | Gradle `Task 'assembleAarFooDebug' not found in
root project …` | same Gradle error |

Without the module check (`86523c549fc`), the module-error cases exit 0
with "✓ Built" and a repo that has only the plugin AAR.
3. **Path-qualified requests.** `./gradlew -I aar_init_script.gradle …
:flutter:assembleAarRelease` exits 0 and publishes nothing, on
`5ba8961b517` and on this PR: a publication is created only when
`startParameter.taskNames` contains the bare name. The tool sends only
the bare name (`gradle.dart` `command.add(aarTask)`). Not changed here.
4. **No warnings.** `flutter build aar` hides Gradle output on success
unless `-v` (`ProcessUtils.run` buffers it; `gradle.dart` prints it only
on failure, and verified with a `logger.error` probe). Keeping a build
file's declaration needs no action, so nothing is logged. Errors are
shown.
5. **Configuration cache:** with `org.gradle.configuration-cache=true`
in case (a)'s `.android/gradle.properties` (AGP 9.3.1 / Gradle 9.5.0),
`flutter build aar` reports the same single problem with the
`5ba8961b517` script and with this PR: ``Task
`:flutter:compileFlutterBuildDebug` of type
`com.flutter.gradle.tasks.FlutterTask`: invocation of 'Task.project' at
execution time is unsupported with the configuration cache.`` None comes
from the init script.
6. `newDsl=true` with `builtInKotlin=false` fails before the script with
any Kotlin plugin (`The 'org.jetbrains.kotlin.android' plugin is not
compatible with AGP's 9.0 new DSL`). The devicelab section and matrix
set `builtInKotlin=true`.
7. Related open work: no overlap with
[flutter#191681](flutter#191681)
(`gradle.dart`, `gradle_errors.dart` and tests). No open PR touches
`aar_init_script.gradle`.

### Follow-up candidates (pre-existing, not changed here)

- `allprojects { apply plugin: "maven-publish" }` applies maven-publish
to every project, including ones that never publish.
- The `afterProject` and `projectsEvaluated` hooks reach across
projects, which Gradle Isolated Projects does not allow.
- The `-SNAPSHOT` rewrite of `project.version` in `configureProject`.
- The `engine.realm` and `engine.stamp` file reads at configuration time
in `configureProject`.
- The `is-plugin` branch of `projectsEvaluated` looks unreachable from
the tool.
- The configuration cache problem in FGP `FlutterTask` (note 5).
- `newDsl=true` with KGP (`builtInKotlin=false`), for PR 10.
- Mapping between flavored module variants and plugin variants (for
example, plugin `release` for module `demoRelease`).
- `singleVariant` is declared on the root project and `:app`, which
never publish.
- Gradle output is hidden on success, so nothing the script logs at info
or warn level reaches the user without `-v`.

### Integration test coverage of the changed paths

Searched `dev/devicelab/bin/tasks` and
`packages/flutter_tools/test/integration.shard` for `build aar` and
`assembleAar`.

| Path | Tests |
| --- | --- |
| Library check, publishing declarations, lazy task registration, plugin
publishing without `dependsOn` (`newDsl=false`) | devicelab
`build_aar_module_test`, `build_android_host_app_with_module_aar`,
`android_java17_build_android_host_app_with_module_aar`;
`android_obfuscate_test` |
| `newDsl=true`, a build file's `singleVariant` declaration kept |
devicelab `build_aar_module_test`, `newDsl=true` section |
| Module and plugin variant mismatch errors | devicelab
`build_aar_module_test`, product flavor section |
| AGP 9.1.1 and 8.11.1; a variant that no project has | Manual matrix
only |

`Linux build_aar_module_test` runs in presubmit for this PR: in
`.ci.yaml` its `runIf` includes `dev/**` and
`packages/flutter_tools/**`, and it sets neither `presubmit: false` nor
`bringup`. It also ran locally on the head (below) with `cd
dev/devicelab && ../../bin/dart bin/test_runner.dart test -t
build_aar_module_test --exit`.

### Tests run locally (macOS, JDK 17)

On the head (`b9493299916`; master merged at `4521d8d6634`):

- `gradle test --rerun-tasks` in `packages/flutter_tools/gradle`, with
the engine's `third_party/gradle` binary that the README names: 33
suites, 277 tests, 0 failures.
- `dart format` and `dart analyze --fatal-infos` on
`build_aar_module_test.dart`: clean (unchanged since `3edc95d1fa0`).
- Tool tests: `test/commands.shard/hermetic/build_aar_test.dart`,
`test/commands.shard/permeable/build_aar_test.dart` and
`test/general.shard/android/android_gradle_builder_test.dart`: 56 tests,
all pass.
- `test/integration.shard/android_obfuscate_test.dart`: 2 tests pass.
- devicelab via `bin/test_runner.dart test --exit`, one at a time:
`build_aar_module_test` (including both added sections),
`build_android_host_app_with_module_aar`,
`android_java17_build_android_host_app_with_module_aar`,
`build_android_host_app_with_module_source`,
`module_host_with_custom_build_test`, all `success`.
- The configuration cache comparison (note 5).

Manual matrix on `b9493299916`, four configurations:
- **9.3.1 off:** AGP 9.3.1 / Gradle 9.5.0, `newDsl=false`,
`builtInKotlin=false`.
- **9.3.1 on:** AGP 9.3.1 / Gradle 9.5.0, `newDsl=true`,
`builtInKotlin=true`.
- **9.1.1 on:** AGP 9.1.1 / Gradle 9.3.1 (FGP's minimums on master since
flutter#193813), `newDsl=true`, `builtInKotlin=true`.
- **8.11.1:** AGP 8.11.1 / Gradle 8.14.3, `newDsl=false`, with
`skipDependencyChecks=true` in `.android/gradle.properties`. Without it,
FGP stops before the init script runs: `Your project's Gradle version
(8.14.3) is lower than Flutter's minimum supported version of 9.3.1.`

| Case | 9.3.1 off | 9.3.1 on | 9.1.1 on | 8.11.1 |
| --- | --- | --- | --- | --- |
| (a) | exit 0, AAR, POM, sources and javadoc jars for
`flutter_{debug,profile,release}` and `plugin_a_{debug,profile,release}`
| same | same | same |
| (b) `--flavor demo` | exit 1, plugin error | same | same | same |
| (b) no `--flavor` | exit 1, module error | same | same | same |
| (b) `--flavor foo` | exit 1, Gradle `Task 'assembleAarFooDebug' not
found in root project` | same | same | same |
| (c) | exit 1, plugin error | same | same | same |
| (c) `--flavor free` | exit 1, module error | same | same | same |
| (d) | exit 0, as (a), except module release has the sources jar and no
javadoc jar | same | same | same |

Case (a)'s `flutter_release-1.0.pom` depends on
`dev.pr9.plugin_a:plugin_a_release:1.0` (checked on `b9493299916`, AGP
9.1.1).

Negative control, the master script (same at `5ba8961b517` and
`4521d8d6634`), on `b9493299916`: with `newDsl=true` (AGP 9.3.1 and AGP
9.1.1), (a)-(d) all fail with `Can't generate AAR on a non Android
library project.`; with `newDsl=false` on AGP 9.3.1, (a) passes and
(b)-(d) fail with Gradle's `Task with name 'assembleAar<V>' not found in
project ':<p>'.` On `a17fafcc35e`, with only line 13 changed to
`hasPlugin`, `newDsl=true` fails at line 178 with `Could not get unknown
property 'libraryVariants' for object of type
com.android.build.gradle.internal.dsl.LibraryExtensionImpl$AgpDecorated.`
devicelab `build_aar_module_test` with that script fails at the
`newDsl=true` section with the same error.

</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
`///`).
- [x] 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.

<!-- 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/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[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
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
…Is (flutter#193962)

PR 7 (flutter#193693) merged to master as `ecd1ab06865` and PR 8 (flutter#193717) as
`4249ccbc18a`. This branch merges master at `4521d8d6634`, so the Files
tab shows only PR 9's changes.

PR 9 commits:
- `86523c549fc` Move aar_init_script to public AGP APIs
- `3edc95d1fa0` Check requested AAR variants in the module and each
plugin
- `da9646aad53` Address review: derive requested variants from
components, register AAR tasks lazily
- `94a29907065` Clarify aar_init_script comments from the adversarial
review
- `ea08280d886` Merge commit '23ddd6b74e6' into agp-aar-init-script (PR
8's head with master at `ecd1ab06865`; no conflicts, no change to PR 9's
files)
- `a17fafcc35e` Merge commit '5ba8961b517' into agp-aar-init-script
(master with PR 8 at `4249ccbc18a`; no conflicts, no change to PR 9's
files)
- `77ba449ea4a` Filter requested AAR components before adding tasks
- `adbfb9cd640` Drop the AGP version list from the duplicate-variant
comment
- `f2b7111c51e` Docs: state the AAR variant requirement in plain words
- `cd10f766b5b` Register an AAR task for every variant, publish only
requested ones
- `b9493299916` Merge commit '4521d8d6634' into agp-aar-init-script
(master, including flutter#193649; no conflicts, no change to PR 9's files)

## Description

This is PR 9 of 11 in the AGP 9.1.0 / public `gradle-api` migration
stack ([flutter#180137](flutter#180137),
[flutter#166550](flutter#166550)).

`flutter build aar` passes
`packages/flutter_tools/gradle/aar_init_script.gradle` to Gradle with
`-I`. The script read `android.libraryVariants` and AGP's internal
`publishing.singleVariants`. With AGP 9's `android.newDsl=true`,
`flutter build aar` on a module fails on `5ba8961b517` with `Can't
generate AAR on a non Android library project.` (script line 13), and
then at line 178 (`Could not get unknown property 'libraryVariants'`).
With this PR the script uses only `pluginManager.hasPlugin`,
`Publishing.singleVariant`, software `components` and `tasks.register`,
and the build succeeds with `newDsl` on and off, on AGP 9.3.1 and on
master's minimum AGP 9.1.1, and on AGP 8.11.1 when FGP's version check
is skipped.

**Breaking:** no. Builds that succeed on `5ba8961b517` succeed with the
same artifacts. Two failing cases change: a module or plugin build file
that declares `singleVariant` for only some variants builds, and a
variant mismatch between the module and a plugin fails with a Flutter
error instead of `Task with name … not found`.

**Base:** `master` at `4521d8d6634`. `aar_init_script.gradle`,
`build_aar_module_test.dart` and both docs are the same at `4521d8d6634`
and `5ba8961b517`, so the comparisons below against `5ba8961b517` hold
for `4521d8d6634`.

<details>
<summary>Agent authored details</summary>

### Changes

All in `aar_init_script.gradle` unless noted. Line numbers are at
`b9493299916`.

1. **Library check** (`:13`):
`project.pluginManager.hasPlugin("com.android.library")` replaces
`android.hasProperty("libraryVariants")`. The error text is unchanged.
2. **Publishing declarations** (`afterProject`, `:185-219`): Flutter
calls `android.publishing.singleVariant(<variant>) { withSourcesJar();
withJavadocJar() }` for each variant, one variant at a time. If the
project's build file already declared that variant, AGP throws, and
`isDuplicateSingleVariantError` (`:125-134`) matches AGP's exact
message, so the build file's declaration is kept. Its comment links the
AGP source of the message ([`AbstractPublishing.kt` at
`studio-2025.3.2`, AGP
9.1.0](https://android.googlesource.com/platform/tools/base/+/refs/tags/studio-2025.3.2/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/dsl/AbstractPublishing.kt#38)).
Any other exception is rethrown (`:201-203`). The guard that read
`publishing.singleVariants` and skipped every Flutter declaration once
the build file declared any variant is deleted.
3. **No module-to-plugin `dependsOn`** (`projectsEvaluated`): the loop
over `moduleProject.android.libraryVariants` that made each module
`assembleAar<Variant>` depend on the plugin's task (with eager
`tasks.named(...).get()`) is deleted. The tool requests
`assembleAar<Variant>` without a project path (`gradle.dart`
`buildGradleAar`, `command.add(aarTask)`), and Gradle runs a task
selector that is only a task name in every project that has the task
([Gradle
docs](https://docs.gradle.org/current/userguide/command_line_interface.html#executing_tasks_in_multi_project_builds):
"You can also run a task for all subprojects using a task selector that
consists of only the task name."). Each plugin publishes from its own
task. The comment at `:247-248` says this.
4. **Tasks, publications and task name** (`configureProject` `:27-37`;
`aarTaskName` `:93-97`; `requestedAarComponents` `:99-103`): AGP adds
one software component for each `singleVariant` declaration, with the
variant's name. `registerAarTask` (`:105-110`) registers
`assembleAar<Variant>` for every component, so a misspelled `--flavor`
gets Gradle's candidate list (`Some candidates are: 'assembleAarDebug',
...`). `requestedAarComponents` returns the components whose
`assembleAar<Variant>` name is in `startParameter.taskNames`; only those
get a publication (`addAarPublication`, `:112-123`), because `publish`
publishes every publication in the project. The check uses the same
function. `aarTaskName` is the only place that builds
`assembleAar<Variant>`; its comment points to the tool's `getAarTaskFor`
(`gradle.dart`). Nothing parses a task name back into a variant. The
`component.name != "all"` filter from `5ba8961b517` is deleted (see "Why
removing the deleted code is safe").
5. **Lazy task registration** (`registerAarTask`):
`project.tasks.register` replaces `project.tasks.create(name:)`. The
configuration action only adds `finalizedBy "publish"`.
`publications.create` runs in `addAarPublication`, not in the action,
because maven-publish registers tasks for each publication and Gradle
rejects that while it realizes a task
(`DefaultTaskContainer#register(String, Class, Action) on task set
cannot be executed in the current context.`, seen when
`publications.create` was inside the action).
6. **Requested-variant check** (`checkProjectsHaveRequestedVariants`,
`:136-175`, called at `:252`): Gradle skips projects that lack the
requested task, so the script checks the module and each Android plugin.
The requested variants are the names of the components that
`requestedAarComponents` returns for those projects. A project without a
requested variant fails the build with a `GradleException` that names
the variant and the project:
- module: `Flutter can't build the AAR for variant 'debug' because
module project ':flutter' has no variant with that name. Its variants
are: demoDebug, demoProfile, demoRelease, fullDebug, fullProfile,
fullRelease. Pass the module's product flavor with --flavor, or omit
--flavor if the module has no product flavors.`
- plugin: `Flutter can't build the AAR for variant 'demoDebug' because
plugin project ':plugin_a' has no variant with that name, so the plugin
AAR that the module depends on can't be published. `flutter build aar`
requires the module and each of its Android plugins to declare the same
product flavors.`
- A requested task that matches no project's variant (for example
`--flavor foo`) is left to Gradle: `Task 'assembleAarFooDebug' not found
in root project 'android_generated' and its subprojects. Some candidates
are: 'assembleAarDebug', 'assembleAarDemoDebug',
'assembleAarFullDebug'.` That is the same error as on `5ba8961b517`. The
check's doc says so. (`3edc95d1fa0` parsed the task-name prefix and
reported a Flutter module error in this case; `da9646aad53` drops the
parsing per review.)
7. **Docs.** Both docs describe behavior only.
- `Migrating-Flutter-Gradle-Plugin-to-AGP-public-API.md`: the P8 row of
the phase table and "Features that must break" item 8 are rewritten. The
"Why" starting-state list (L38-39) is unchanged, as in other PRs of the
stack.
-
[`website-page-draft.md`](https://github.com/flutter/flutter/blob/master/docs/platforms/android/website-page-draft.md)
(publishing tracked in
[flutter#193713](flutter#193713)): the
`flutter build aar` section is rewritten. It said Flutter "detects the
overlap and reports it with an actionable error". The code keeps the
build file's declaration instead, so the docs were changed to match the
code. It says (L234-237) that when a build file declares `singleVariant`
for a variant, Flutter keeps that declaration and declares the other
variants, and (L238-241) that the module and each Android plugin need a
variant with the built name.
8. **Tests.** devicelab `build_aar_module_test` gets two final sections:
- With `android.newDsl=true` and `android.builtInKotlin=true` in
`.android/gradle.properties`, and
`android.publishing.singleVariant("release") { withSourcesJar() }` in
`.android/Flutter/build.gradle`, it runs `flutter build aar
--no-profile`. It checks that the edits survive, that release has the
AAR and sources jar and no javadoc jar, that debug has the javadoc jar,
and that the plugin AARs exist for release and debug.
- It replaces that declaration with a `demo` product flavor and checks
both errors: `flutter build aar --no-profile --no-release` fails with
the module error, and the same with `--flavor demo` fails with the
plugin error.

`da9646aad53`'s commit message says the check's doc "says when it
returns and when it throws". That doc sentence was added in
`94a29907065`.

### Bug history (moved out of the docs)

The docs describe behavior only, so the history that `3edc95d1fa0` put
in them is here:
- On `5ba8961b517`, the `afterProject` guard skipped all of Flutter's
`singleVariant` declarations for a project whose build file declared any
variant. For a module with at least one Android plugin that declared
only `release`, every `flutter build aar` failed with `Task with name
'assembleAarDebug' not found in project ':flutter'`. With this PR that
build succeeds (table 1 below).
- On `5ba8961b517`, the `dependsOn` loop failed with `Task with name
'assembleAar<Variant>' not found in project ':<plugin>'` whenever a
plugin lacked any module variant, requested or not, and nothing checked
that the module had the requested variant. With this PR only requested
variants are checked, in the module and in each plugin (table 2 below).

### Audit resolution

[PR 9 draft
audit](reidbaker-agent#9 (comment)),
and stack audit items M4 and L8:

| Item | Resolution |
| --- | --- |
| 1. Eager `.get()` and cross-project task lookup by name | The wiring
is deleted, not made lazy: it was redundant (Changes 3). No `.get()` or
`tasks.named` in the script. The check reads software components, and
`registerAarTask` uses `tasks.register`. |
| 2. Broad `catch (Exception)`; overstated `multipleVariants` warning |
Only AGP's exact duplicate message is ignored (`:130-134`); everything
else is rethrown (`:201-203`). No warning is logged, so there is no
`multipleVariants` claim. |
| 3. Ext property without `flutter.internal.` | No ext property.
`afterProject` fires once per project (instrumented: count 1 for `:`,
`:app`, `:flutter`, `:plugin_a` and the included FGP build), and a
second call would only hit ignored duplicates. The "fires more than once
in composite settings" claim is dropped. |

Why the message match and not the type: AGP reports the duplicate from
`AbstractPublishing.checkSingleVariantUniqueness` through
`SyncIssueReporterImpl`, which throws
`com.android.builder.errors.EvalIssueException` in STANDARD mode. That
class is in `com.android.tools.build:builder`, not in `gradle-api`, and
is not on the init script's classpath. `javap -v` on
`AbstractPublishing` shows the same text in AGP 8.11.1, 9.1.0 and 9.3.1.
AGP checks before it adds the component (8.11.1
`AbstractPublishing.kt:27-35`), so the build file's declaration stays.
If AGP changes the text, the exception is rethrown and the build fails
loudly; devicelab `build_aar_module_test` exercises the path on the
template AGP.

Why not declare first or query: the public `Publishing` DSL in
`gradle-api-9.1.0.jar` has only `singleVariant(String)` and
`singleVariant(String, Function1)`, and `LibraryPublishing` adds only
`multipleVariants(...)` (`javap`), so there is no public way to list
declared variants. Declaring Flutter's variants in `beforeProject` +
`pluginManager.withPlugin("com.android.library")` makes the build file
fail at its own `singleVariant("release")` line with the duplicate error
(probe).

Why not AGP types in the init script: `import
com.android.build.api.dsl.LibraryExtension` fails with `unable to
resolve class`. With `gradle-api:9.3.1` on the `initscript` classpath,
the init script gets its own copy of the class from a different
classloader, so `instanceof` is `false` and
`extensions.getByType(LibraryExtension)` throws `Extension of type
'LibraryExtension' does not exist. Currently registered extension types:
[..., LibraryExtension, ...]` (probes).

`multipleVariants`: `PublishingUtil.ensureComponentNameUniqueness`
errors only when a `multipleVariants` component name equals a
`singleVariant` name. Flutter declares the same `singleVariant`s on
`5ba8961b517` when the build file declares none, so that behavior is
unchanged. It is not tested here.

### Why removing the deleted code is safe

- `android.libraryVariants` does not exist with `newDsl=true`
(reproduced above). AGP 9.1.0 marks its class,
`com.android.build.gradle.LibraryExtension`, `@Deprecated` ("This class
is not used for the public extensions in AGP when android.newDsl=true,
which is the default in AGP 9.0, and will be removed in AGP 10.0."), and
the class is not in `gradle-api-9.1.0.jar`. `singleVariants` is an
internal property (`getSingleVariants()` on
`com.android.build.gradle.internal.dsl.AbstractPublishing`, `javap`). It
resolves from Groovy with `newDsl=true`, so it was not a failure, only
internal API.
- The `dependsOn`: with it removed, the task graph for
`assembleAarRelease` on case (a) has `:plugin_a:assembleAarRelease`,
`:plugin_a:bundleReleaseAar`,
`:plugin_a:publishReleasePublicationToMavenRepository` and
`:plugin_a:publish`. `:flutter:generatePomFileForReleasePublication`
depends on no `:plugin_a` task, and
`:flutter:publishReleasePublicationToMavenRepository` depends only on
the plugin's compile-classpath tasks, so the order between the module's
and the plugin's publishing doesn't matter. The module POM refers to the
plugin by coordinates (`plugin_a_release`). devicelab
`build_aar_module_test`, `build_android_host_app_with_module_aar` and
`android_java17_build_android_host_app_with_module_aar` pass (they check
the plugin AAR/POM and that the module POM depends on
`plugin_with_android_release`).
- The `all` filter (`component.name != "all"`, added in flutter#101891
`606e91ad63d`): AGP 7.x created an automatic multi-variant component
named `all` when a project used no publishing DSL ([`PublishingUtil.kt`
at
`studio-2021.3.1`](https://android.googlesource.com/platform/tools/base/+/refs/tags/studio-2021.3.1/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/utils/PublishingUtil.kt),
`createPublishingInfoForLibrary` and `publishingFeatureOptIn`; same in
the AGP 7.3.1 jar). flutter#101891 published it separately with classifiers and
skipped it for the `_<variant>` publications; flutter#112149 (`8e30cc9c56b`)
removed that publication and kept the skip. AGP 8.0 disabled automatic
components by default ([AGP 8.0.0 release
notes](https://developer.android.com/build/releases/past-releases/agp-8-0-0-release-notes)),
and the AGP 8.11.1, 9.1.1 and 9.3.1 jars list
`android.disableAutomaticComponentCreation` as removed, with no `all`
component code. This script declares `singleVariant` for every variant,
which also turns automatic components off on AGP 7.x. A probe that
prints `project.components` after `projectsEvaluated` on all four matrix
configurations shows only per-variant names (`[debug, profile, release]`
for `:flutter`, `:app` and each plugin, `[demoDebug, …, fullRelease]`
for the flavored module, `[freeDebug, freeProfile, freeRelease]` for
`plugin_flavored`, `[debug, release]` for the root), never `all`.
- `tasks.register`: the publication is created at configuration time
only for a requested task name, as with `tasks.create`, whose
configuration closure ran immediately. Only the task object is created
lazily. Table rows below and the devicelab runs show the same artifacts.

### Removed comments, assertions and code

| Removed | Reason |
| --- | --- |
| `afterProject` comment item 2, "The project has already defined which
variants to publish…", and the `singleVariants.size()` guard it
described | The guard read internal API and skipped all of Flutter's
declarations once a build file declared any. Item 1 of that comment
became "Exit early if the project doesn't have the Android Gradle plugin
applied." |
| The `projectsEvaluated` comment "Configure the
`assembleAar<variantName>` task for each plugin's projects and make the
module's equivalent task depend on the plugin's task.", with the
`libraryVariants.all` loop, both `tasks.named(...).get()` calls, both
`assert(... != null)` and the `dependsOn` | The dependency is redundant
(see above). `tasks.named(...).get()` throws before the asserts could
fail, so they never checked anything. |
| `addAarTask` and its `variantName` local | Split into
`registerAarTask` (every component) and `addAarPublication` (requested
components). The task name comes from `aarTaskName`, which the check
also uses. |
| `addAarTask` comment "This check is required to be able to configure
the archives before `publish` runs.", with the check | The check is
`requestedAarComponents`, applied by the caller before
`addAarPublication`. Its reason is the comment on `addAarPublication`:
"`publish` publishes every publication in the project, so only requested
components get one." |
| The `component.name != "all"` filter in `configureProject`, and the
fragment "(except "all" since that is used to publish artifacts in the
new way)" from "Create a default MavenPublication for the variant" |
Nothing creates an `all` component where this script runs (see "Why
removing the deleted code is safe"). |
| From the migration doc item 8 and the website page draft: the
sentences about the deleted guard, the `Task with name … not found`
failures, and what the deleted code did and did not check | The docs
describe behavior only. The history is in "Bug history" above. |

### Behavioral and compatibility notes

Matrix projects (local scratch): (a) module + Android plugin `plugin_a`;
(b) module with flavors `demo`/`full` + `plugin_a`; (c) module +
`plugin_a` + `plugin_flavored` (flavor `free`); (d) module declaring
`singleVariant("release") { withSourcesJar() }` + `plugin_a`.

1. **A build file that declares `singleVariant` for some variants
builds.** Case (d), `flutter build aar`:

   | Script | Result |
   | --- | --- |
| `5ba8961b517` (AGP 9.3.1 `newDsl=false`) | exit 1: `Task with name
'assembleAarDebug' not found in project ':flutter'.` |
| This PR (all four configurations below) | exit 0. Release has the AAR,
POM and sources jar, and no javadoc jar (the build file's declaration).
Debug and profile have sources and javadoc jars. Plugin AAR/POM for all
three. |

2. **Variant mismatches fail with a Flutter error that names the
project.** Only requested variants are checked. The `5ba8961b517` column
is AGP 9.3.1 with `newDsl=false`.

   | Case | `5ba8961b517` | This PR (all four configurations) |
   | --- | --- | --- |
| (b) `--flavor demo` | `Task with name 'assembleAarDemoDebug' not found
in project ':plugin_a'.` | plugin error for `demoDebug` and `:plugin_a`
|
| (c) default | `Task with name 'assembleAarDebug' not found in project
':plugin_flavored'.` | plugin error for `debug` and `:plugin_flavored` |
| (b) no `--flavor`, `--no-profile --no-release` | `Task with name
'assembleAarDemoDebug' not found in project ':plugin_a'.` | module error
for `debug`, listing the module's variants |
| (c) `--flavor free`, `--no-profile --no-release` | `Task with name
'assembleAarDebug' not found in project ':plugin_flavored'.` | module
error for `freeDebug` |
| (b) `--flavor foo` | Gradle `Task 'assembleAarFooDebug' not found in
root project …` | same Gradle error |

Without the module check (`86523c549fc`), the module-error cases exit 0
with "✓ Built" and a repo that has only the plugin AAR.
3. **Path-qualified requests.** `./gradlew -I aar_init_script.gradle …
:flutter:assembleAarRelease` exits 0 and publishes nothing, on
`5ba8961b517` and on this PR: a publication is created only when
`startParameter.taskNames` contains the bare name. The tool sends only
the bare name (`gradle.dart` `command.add(aarTask)`). Not changed here.
4. **No warnings.** `flutter build aar` hides Gradle output on success
unless `-v` (`ProcessUtils.run` buffers it; `gradle.dart` prints it only
on failure, and verified with a `logger.error` probe). Keeping a build
file's declaration needs no action, so nothing is logged. Errors are
shown.
5. **Configuration cache:** with `org.gradle.configuration-cache=true`
in case (a)'s `.android/gradle.properties` (AGP 9.3.1 / Gradle 9.5.0),
`flutter build aar` reports the same single problem with the
`5ba8961b517` script and with this PR: ``Task
`:flutter:compileFlutterBuildDebug` of type
`com.flutter.gradle.tasks.FlutterTask`: invocation of 'Task.project' at
execution time is unsupported with the configuration cache.`` None comes
from the init script.
6. `newDsl=true` with `builtInKotlin=false` fails before the script with
any Kotlin plugin (`The 'org.jetbrains.kotlin.android' plugin is not
compatible with AGP's 9.0 new DSL`). The devicelab section and matrix
set `builtInKotlin=true`.
7. Related open work: no overlap with
[flutter#191681](flutter#191681)
(`gradle.dart`, `gradle_errors.dart` and tests). No open PR touches
`aar_init_script.gradle`.

### Follow-up candidates (pre-existing, not changed here)

- `allprojects { apply plugin: "maven-publish" }` applies maven-publish
to every project, including ones that never publish.
- The `afterProject` and `projectsEvaluated` hooks reach across
projects, which Gradle Isolated Projects does not allow.
- The `-SNAPSHOT` rewrite of `project.version` in `configureProject`.
- The `engine.realm` and `engine.stamp` file reads at configuration time
in `configureProject`.
- The `is-plugin` branch of `projectsEvaluated` looks unreachable from
the tool.
- The configuration cache problem in FGP `FlutterTask` (note 5).
- `newDsl=true` with KGP (`builtInKotlin=false`), for PR 10.
- Mapping between flavored module variants and plugin variants (for
example, plugin `release` for module `demoRelease`).
- `singleVariant` is declared on the root project and `:app`, which
never publish.
- Gradle output is hidden on success, so nothing the script logs at info
or warn level reaches the user without `-v`.

### Integration test coverage of the changed paths

Searched `dev/devicelab/bin/tasks` and
`packages/flutter_tools/test/integration.shard` for `build aar` and
`assembleAar`.

| Path | Tests |
| --- | --- |
| Library check, publishing declarations, lazy task registration, plugin
publishing without `dependsOn` (`newDsl=false`) | devicelab
`build_aar_module_test`, `build_android_host_app_with_module_aar`,
`android_java17_build_android_host_app_with_module_aar`;
`android_obfuscate_test` |
| `newDsl=true`, a build file's `singleVariant` declaration kept |
devicelab `build_aar_module_test`, `newDsl=true` section |
| Module and plugin variant mismatch errors | devicelab
`build_aar_module_test`, product flavor section |
| AGP 9.1.1 and 8.11.1; a variant that no project has | Manual matrix
only |

`Linux build_aar_module_test` runs in presubmit for this PR: in
`.ci.yaml` its `runIf` includes `dev/**` and
`packages/flutter_tools/**`, and it sets neither `presubmit: false` nor
`bringup`. It also ran locally on the head (below) with `cd
dev/devicelab && ../../bin/dart bin/test_runner.dart test -t
build_aar_module_test --exit`.

### Tests run locally (macOS, JDK 17)

On the head (`b9493299916`; master merged at `4521d8d6634`):

- `gradle test --rerun-tasks` in `packages/flutter_tools/gradle`, with
the engine's `third_party/gradle` binary that the README names: 33
suites, 277 tests, 0 failures.
- `dart format` and `dart analyze --fatal-infos` on
`build_aar_module_test.dart`: clean (unchanged since `3edc95d1fa0`).
- Tool tests: `test/commands.shard/hermetic/build_aar_test.dart`,
`test/commands.shard/permeable/build_aar_test.dart` and
`test/general.shard/android/android_gradle_builder_test.dart`: 56 tests,
all pass.
- `test/integration.shard/android_obfuscate_test.dart`: 2 tests pass.
- devicelab via `bin/test_runner.dart test --exit`, one at a time:
`build_aar_module_test` (including both added sections),
`build_android_host_app_with_module_aar`,
`android_java17_build_android_host_app_with_module_aar`,
`build_android_host_app_with_module_source`,
`module_host_with_custom_build_test`, all `success`.
- The configuration cache comparison (note 5).

Manual matrix on `b9493299916`, four configurations:
- **9.3.1 off:** AGP 9.3.1 / Gradle 9.5.0, `newDsl=false`,
`builtInKotlin=false`.
- **9.3.1 on:** AGP 9.3.1 / Gradle 9.5.0, `newDsl=true`,
`builtInKotlin=true`.
- **9.1.1 on:** AGP 9.1.1 / Gradle 9.3.1 (FGP's minimums on master since
flutter#193813), `newDsl=true`, `builtInKotlin=true`.
- **8.11.1:** AGP 8.11.1 / Gradle 8.14.3, `newDsl=false`, with
`skipDependencyChecks=true` in `.android/gradle.properties`. Without it,
FGP stops before the init script runs: `Your project's Gradle version
(8.14.3) is lower than Flutter's minimum supported version of 9.3.1.`

| Case | 9.3.1 off | 9.3.1 on | 9.1.1 on | 8.11.1 |
| --- | --- | --- | --- | --- |
| (a) | exit 0, AAR, POM, sources and javadoc jars for
`flutter_{debug,profile,release}` and `plugin_a_{debug,profile,release}`
| same | same | same |
| (b) `--flavor demo` | exit 1, plugin error | same | same | same |
| (b) no `--flavor` | exit 1, module error | same | same | same |
| (b) `--flavor foo` | exit 1, Gradle `Task 'assembleAarFooDebug' not
found in root project` | same | same | same |
| (c) | exit 1, plugin error | same | same | same |
| (c) `--flavor free` | exit 1, module error | same | same | same |
| (d) | exit 0, as (a), except module release has the sources jar and no
javadoc jar | same | same | same |

Case (a)'s `flutter_release-1.0.pom` depends on
`dev.pr9.plugin_a:plugin_a_release:1.0` (checked on `b9493299916`, AGP
9.1.1).

Negative control, the master script (same at `5ba8961b517` and
`4521d8d6634`), on `b9493299916`: with `newDsl=true` (AGP 9.3.1 and AGP
9.1.1), (a)-(d) all fail with `Can't generate AAR on a non Android
library project.`; with `newDsl=false` on AGP 9.3.1, (a) passes and
(b)-(d) fail with Gradle's `Task with name 'assembleAar<V>' not found in
project ':<p>'.` On `a17fafcc35e`, with only line 13 changed to
`hasPlugin`, `newDsl=true` fails at line 178 with `Could not get unknown
property 'libraryVariants' for object of type
com.android.build.gradle.internal.dsl.LibraryExtensionImpl$AgpDecorated.`
devicelab `build_aar_module_test` with that script fails at the
`newDsl=true` section with the same error.

</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
`///`).
- [x] 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.

<!-- 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/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App c: contributor-productivity Team-specific productivity, code health, technical debt. tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

5 participants