We upgraded Gradle or Maven and builds got slow
After you upgrade Gradle or Maven, the first builds on the new version can rebuild instead of restoring from the cache. FosterStack Cache stores the results of each version, and in our runs going back to the old version restored its entries.
What to do
- Upgrade CI and every laptop that shares the cache together. Our advice, not a test result: the first builds should then fill the cache for everyone.
- Expect the first builds on the new version to rebuild, unless you pin your Maven plugins (next point). They store their results for the builds after them.
- In Maven, pin your plugin versions in your
pom.xml. With all eight of our test plugins pinned (list below), Maven 3.10.0 and 3.9.9 shared entries in our test.
For Gradle, we saw this: in our three pairs of versions, each version restored only its own entries.
Pin the Maven plugin versions
Put these inside <build><plugins>. These are the eight plugins our test build used, at the versions we tested. If your build uses other plugins, pin those too. Everyone who shares the cache should use the same versions.
<plugin><artifactId>maven-resources-plugin</artifactId><version>3.5.0</version></plugin>
<plugin><artifactId>maven-compiler-plugin</artifactId><version>3.16.0</version></plugin>
<plugin><artifactId>maven-jar-plugin</artifactId><version>3.5.1</version></plugin>
<plugin><artifactId>maven-clean-plugin</artifactId><version>3.5.0</version></plugin>
<plugin><artifactId>maven-install-plugin</artifactId><version>3.2.0</version></plugin>
<plugin><artifactId>maven-deploy-plugin</artifactId><version>3.2.0</version></plugin>
<plugin><artifactId>maven-site-plugin</artifactId><version>3.22.0</version></plugin>
<plugin><artifactId>maven-surefire-plugin</artifactId><version>3.5.2</version></plugin>
Why it happens
- Gradle: the cache key includes the code of Gradle's own compile task, so a different Gradle version gives a different key. In our comparison of 9.7.1 and 9.8.0 the values from the project were identical, and the lines that differed described Gradle's own task and compiler objects.
- Maven: Maven fills in a default version for each plugin you did not pin, and some of those defaults differ between Maven versions. They end up in the cache key. In our runs the differing defaults included clean, install, deploy and site.
If the cache is still cold after you match versions, see why the Gradle hit rate is low or why the Maven cache is not restoring. The Maven setup is on Maven remote build cache setup.
How we checked
| Setup | Second build, on the other version |
|---|---|
| Gradle 9.8.0, then 9.7.1 | rebuilt |
| Gradle 9.7.1, then 9.8.0 | rebuilt |
| Gradle 9.5.1, then 9.8.0 | rebuilt |
| Maven 3.10.0 and 3.9.9, only surefire pinned (both orders) | rebuilt |
| Maven, also resources, compiler and jar pinned (both orders) | rebuilt |
| Maven, all eight pinned (both orders) | restored |
In all nine series, going back to the first version restored its own entry. One build per step. Each Maven row is two series, one per order. A new empty cache server per series, a fresh project copy for every build. Gradle: a four-module project, the :core:compileJava task, Temurin 21.0.12.1. Maven: one module with two tests, mvn verify, Build Cache Extension 1.2.3, OpenJDK 27. FosterStack Cache 0.2.1 on a Mac (arm64). Not tested: other versions, a build that uses other Maven plugins, Gradle test or jar tasks, the Gradle wrapper, a multi-module Maven build, Linux.