One build cache server for Gradle and Maven
If your company builds some projects with Gradle and others with Maven, you do not need two cache servers. FosterStack Cache serves both, with one login. This is a real run: a repository with a Gradle app and a Maven app, both pointed at one 0.2.1 server. Maven works through the Apache Maven Build Cache Extension.
The repository
mixed-repo/
gradle-app/ settings.gradle.kts, build.gradle.kts, gradle.properties, src/
maven-app/ pom.xml, settings.xml, src/, .mvn/extensions.xml, .mvn/maven-build-cache-config.xml
Two small Java apps, built by two different tools.
One server, one login
FSCACHE_USERNAME=build FSCACHE_PASSWORD=<a long secret> ./fscache
Both tools send that same login, each in its own way. The secret comes from one environment variable, FSCACHE_PASSWORD.
The Gradle side
gradle-app/settings.gradle.kts, with org.gradle.caching=true in gradle.properties:
rootProject.name = "gradle-app"
// FosterStack Cache — remote Gradle build cache.
// https://github.com/fosterstack/cache
buildCache {
remote<HttpBuildCache> {
url = uri("https://cache.example.com/")
isPush = true
credentials {
username = "build"
password = System.getenv("FSCACHE_PASSWORD")
}
}
}
The Maven side
maven-app/.mvn/maven-build-cache-config.xml. The remote element goes inside configuration, and saveToRemote="true" is what makes it upload:
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://maven.apache.org/BUILD-CACHE-CONFIG/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/BUILD-CACHE-CONFIG/1.2.0 https://maven.apache.org/xsd/build-cache-config-1.2.0.xsd">
<configuration>
<enabled>true</enabled>
<!-- FosterStack Cache — remote Maven build cache.
https://github.com/fosterstack/cache -->
<remote enabled="true" saveToRemote="true" id="fosterstack-cache">
<url>https://cache.example.com/</url>
</remote>
</configuration>
</cache>
And settings.xml, whose server id must match the remote's. Maven filled in the password from the same environment variable:
<settings>
<servers>
<server>
<id>fosterstack-cache</id>
<username>build</username>
<password>${env.FSCACHE_PASSWORD}</password>
</server>
</servers>
</settings>
The extension itself is added in .mvn/extensions.xml. See Maven build cache extension: remote server setup.
What happened
Each app was built twice. For Gradle, I ran gradle clean in between. For Maven, I deleted target and the extension's local cache folder, so the only copy left was on the server. (I also turned Gradle's local cache off.)
| Build | Result | Server afterwards |
|---|---|---|
| Gradle, first | :compileJava ran | 1 entry |
| Gradle, second | > Task :compileJava FROM-CACHE, "1 from cache" | 1 hit |
| Maven, first | built, then three lines of Saved to remote cache | 4 entries in all |
| Maven, second | Found cached build, restoring demo:maven-app from cache | 3 hits in all |
The counts are the server's own, from its status page. Gradle stores its work under keys of a single long hex number. The Maven extension stores its files under a path. Here is what the server held on disk afterwards:
blobs/8a/8a2fb682ab19c1d434fd2d1ee3e8b27a (Gradle)
blobs/v1.1/demo/maven-app/3aa3eaca44f8d0fa/ma/maven-app.jar (Maven)
blobs/v1.1/demo/maven-app/3aa3eaca44f8d0fa/bu/buildinfo.xml (Maven)
blobs/v1.1/demo/maven-app/e17172d0-.../bu/build-cache-report.xml (Maven)
blobs/v1.1/demo/maven-app/14c158a7-.../bu/build-cache-report.xml (Maven)
They sit side by side in one store, under one size cap, watched by one set of metrics. See server sizing and monitoring.
What this does not show
- Anything about speed. These are tiny apps, and the point is that one server handled both tools.
- Other Maven or Gradle versions: this was Gradle 9.8.0, Maven 3.10.0 and extension 1.2.3.
- That the Maven extension is ours. It is Apache's project. We maintain the server side.
Related: Gradle build cache tutorial and Maven build cache extension not restoring.