This repository is a minimal reproducible project for a bug related to AGP 9 and Gradle Cache.
A library built with AGP 8 that contains an invalid ProGuard/R8 rule (-printmapping) in its consumer-rules.pro will:
- Build successfully when consumed by an application using AGP 8
- Break the Gradle build cache on the second run when consumed by an application using AGP 9
The root cause is the -printmapping consumer ProGuard rule bundled inside the AAR. AGP 8 silently ignores or accepts this rule in the consuming app's context. AGP 9 processes it differently, causing a cache invalidation or error on incremental/cached builds.
agp-9-issue/
├── test.sh # Reproduction script
├── lib-agp-8/ # Android library built with AGP 8.13.2 / Gradle 8.14.4
│ └── lib/
│ └── consumer-rules.pro # Contains the problematic rule: -printmapping out.map
├── app-agp-8/ # Android app (AGP 8.13.2 / Gradle 8.14.4) — consumes lib-agp-8 AAR
└── app-agp-9/ # Android app (AGP 9.0.1 / Gradle 9.3.1) — consumes lib-agp-8 AAR
| Project | AGP Version | Gradle Version |
|---|---|---|
| lib-agp-8 | 8.13.2 | 8.14.4 |
| app-agp-8 | 8.13.2 | 8.14.4 |
| app-agp-9 | 9.0.1 | 9.3.1 |
lib-agp-8/lib/consumer-rules.pro:
-printmapping out.map
This consumer rule is bundled into lib-release.aar when the library is built with AGP 8. The rule is valid in AGP 8's context but causes a Gradle cache problem in AGP 9 when the AAR is consumed by an application.
Run the test script from the repository root:
./test.shThe script performs the following steps:
- Build the library (
lib-agp-8) with AGP 8 — produceslib-release.aarcontaining the-printmapping out.mapconsumer rule. - Build the AGP 8 app (
app-agp-8) twice:- Gradle cache is cleared and the project is cleaned beforehand
- First run: cold build
- Second run: incremental/cached build
- Expected result: both runs succeed.
- Build the AGP 9 app (
app-agp-9) twice:- Gradle cache is cleared and the project is cleaned beforehand
- First run: cold build
- Second run: incremental/cached build
- Expected result: first run succeeds, second run fails.
Each app project uses an isolated Gradle home (-g .gradle-home) to avoid cross-project cache interference.