phone

adesso blog

Build caching helps you reduce your local or remote build time! Building a project with Maven or Gradle will save your artifacts to a (remote) cache. The second build will get the artifacts from the cache if nothing changes. It sounds great, right? But why was nobody aware of the feature when I asked about it during our presentation at JFall? Only two people in the room (of 100) knew what it was. This is an excellent opportunity to tell you more about this feature. So say goodbye to your extra coffee breaks, and let’s go back to work and code!

Maven

is one of the most used build tools within Java, Kotlin, Scala, or other languages. Within your project, you could enable build caching. Let’s go on a Maven Journey together.

- To enable local caching

To enable caching for your project, you need to add the extension in listing 1 to your:

  • pom.xml file. Add an extension within the project / build tag and enjoy faster build times. With this approach, every developer can enjoy a quicker build because it’s also committed to the version control system.
  • .mvn/extensions.xml file. Add the extension to the extensions tag. The feature will be only available for you, as it is mostly not committed to the version control system.

From a sustainability point of view, the first approach is more powerful as it prevents code duplication.

	
	<extension>
	    <groupId>org.apache.maven.extensions</groupId>
	    <artifactId>maven-build-cache-extension</artifactId>
	    <version>1.0.1</version
	</extension>
	

Listing 1: Enjoy caching with the following extension

To check if (local) caching is enabled, an additional line in your logging will be added, like:

	
		INFO] Loading cache configuration from <project dir>/.mvn/maven-build-cache-config.xml
	

In the .m2/ directory, the build will add a build-cache directory with the cached artifacts. In the buildinfo.xml file, you find the artifacts that are built.

- To enable shared caching [1]

If you want to use a caching server, you can enable a remote server by entering the URL. You need to set this information in the .mvn/maven-build-cache-config.xml (together with other build configurations).

	
		<!--Default @id is 'cache'-->
		<remote enabled="true" id="my-cache">
		    <url>http://your-buildcache-url</url>
		</remote>
	

Listing 2: A way to enable remote caching in your cache config

Or add your remote server in your settings.xml file.

	
		<servers>
		    <server>
		        <!-- Should match id attribute from the 'remote' tag in cache config or should be 'cache' by default -->
		        <id>my-cache</id>
		        <username>[cache user]</username>
		        <password>[cache password]</password>
		    </server>
		</servers>
	

Listing 3: A way to enable remote caching in your Maven settings file

If you want to add the caching in your CI, please add the following to your JVM properties:

	
		-Dmaven.build.cache.remote.save.enabled=true
	

You will see the following line in your logging:

	
		[INFO] [CACHE] Saved to remote cache https://your-cache-url/<...>/915296a3-4596-4eb5-bf37-f6e13ebe087e/build-cache-report.xml
	

You can also compare your local build with the one from the CI. For that, you must use the “build-cache-report.xml” file. With the following command, you can check if you have some cache misses:

	
		mvn verify -Dmaven.build.cache.failFast=true -Dmaven.build.cache.baselineUrl=https://your-cache-url/<...>/915296a3-4596-4eb5-bf37-f6e13ebe087e/build-cache-report.xml
	

As you can read, the Maven build can fail fast, but what does it mean? It means that the build will fail if the build cache comparison fails. So, there are differences in caching your local build and the build from the remote server. As that happens, it creates a buildsdiff.xml file in a new folder called target/incremental-maven.

Check the differences and try to solve them, as it gives you some more performance when building your project.

Gradle

The younger brother of Maven is Gradle, and you can also use build caching there. Gradle is helping to make your build even faster. Caching is supported for Java, Groovy, and Scala. [2]

- To enable local caching [3]

Add the following snippet (Kotlin) in your project's settings file to enable the build caching within Gradle.

	
		buildCache {
		    local {
		        directory = File(rootDir, "build-cache")
		        removeUnusedEntriesAfterDays = 30
		    }
		}
	

Listing 4: A way to enable remote caching in your Gradle settings file.

When you’re running your second build, it will show you that you’re using the cache, an example in Listing 5.

	
		> gradle --build-cache assemble
		:compileJava FROM-CACHE
		:processResources
		:classes
		:jar
		:assemble
	
	
		BUILD SUCCESSFUL
	

Listing 5: A Gradle build will show you’re using the FROM-CACHE.

If you want to build your project by default with the cache, you can add the following property to your gradle.properties:

	
		org.gradle.caching=true
	

Eventually your cache will be saved in your home folder (or user profile) like .gradle\caches

You can also think of a task you don’t want to cache. For that, you can add the annotation “@DisableCachingByDefault”

- To enable shared caching[4]

Use the following snippet to use the build cache and replace the URI, username, and password.

	
		buildCache {
		    remote<HttpBuildCache> {
		        url = uri("https://example.com:8123/cache/")
		        credentials {
		            username = "build-cache-user"
		            password = "some-complicated-password"
		        }
		    }
		}
	

Listing 6: A way to enable remote caching in your Gradle properties file

Conclusion

Maven and Gradle are both supporting build caching, and are extremely useful if you want to improve the build time of your project. Easy to implement is the solution to add it to your local project (in your pom or gradle file). A simple change can already save you a lot of precious time.

It can be difficult to use it in your pipeline because builds are mostly executed in a separate container in a virtual machine. So you need to add a cache server where you can save your artifacts on disk. A solution for this is that you can run the docker image “build cache node” and save the URL to your project. Don’t want that? You can also acquire the developer productivity platform from Gradle Enterprise. Here you can cache your artifacts, and it gives some interesting facts on how to improve your build.

What to do next? Simple! Implement caching in your project.

Picture Ko Turk

Author Ko Turk

As Senior Java Developer Ko Turk is part of the growing team Blue4IT of adesso Netherlands.

Save this page. Remove this page.