Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Concourse Caching for Java Maven and Gradle Builds

DZone's Guide to

Concourse Caching for Java Maven and Gradle Builds

Check out how Concourse CI now allows you to cache paths between task runs, opening the door to much faster Maven and Gradle builds.

· Java Zone
Free Resource

Managing a MongoDB deployment? Take a load off and live migrate to MongoDB Atlas, the official automated service, with little to no downtime.

Concourse CI 3.3.x has introduced the ability to cache paths between task runs. This feature helps speed up tasks which cache content in specific folders — here I will demonstrate how this feature can be used for speeding up Maven- and Gradle-based Java builds.

The code and the pipeline that I am using for this post is available at my GitHub repo here.

Let me start with the Gradle build. If I were to build the project using a Gradle wrapper using the following command...

./gradlew clean build


...then Gradle would download the dependent libraries into a ".gradle" folder in the users home folder by default. This location of this folder can be changed using a "GRADLE_USER_HOME" environment variable, which is what I will be using in a Concourse task to control the location of a cached path.

A Concourse task that builds my project looks like this:

---
platform: linux
image_resource:
  type: docker-image
  source:
    repository: openjdk
    tag: 8-jdk
inputs:
  - name: repo
outputs:
  - name: out
run:
  path: /bin/bash
  args:
    - repo/ci/tasks/build.sh
 
caches:
  - path: .gradle/
  - path: .m2/
 
params:
  PROJECT_TYPE: 


See that the cache's parameter is specified as ".gradle" above. So all I have to do now is to ensure that Gradle uses this location as its home folder, which I would do in my build script:

export ROOT_FOLDER=$( pwd )
export GRADLE_USER_HOME="${ROOT_FOLDER}/.gradle"


The process to cache Maven resources for a Maven build is along the same lines. Maven caches the dependent JARs in a location that can be specified in a variety of ways. The one I have used is to specify this location via a dynamically generated settings.xml file the following way:

M2_HOME=${HOME}/.m2
mkdir -p ${M2_HOME}
 
M2_LOCAL_REPO="${ROOT_FOLDER}/.m2"
 
mkdir -p "${M2_LOCAL_REPO}/repository"
 
cat > ${M2_HOME}/settings.xml <<EOF
 
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
      <localRepository>${M2_LOCAL_REPO}/repository</localRepository>
</settings>
 
EOF


That is quite a bit of bash scripting, but all it is doing is generating a settings.xml with a localRepository tag set to the ".m2/repository" folder, which is relative to the temporary folder created by Concourse for the build — and thus can be cached.

With these changes in place, the behavior is that the downloads happen for the first run of the task. but then get cached for subsequent runs. In my local Concourse set-up, a Gradle build takes about 2 mins for a first-time build, then takes about 20 seconds for a subsequent build!

You can try out this feature in my demo project here.

MongoDB Atlas is the easiest way to run the fastest-growing database for modern applications — no installation, setup, or configuration required. Easily live migrate an existing workload or start with 512MB of storage for free.

Topics:
java ,concourse ci ,maven ,gradle ,build cache ,tutorial

Published at DZone with permission of Biju Kunjummen, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}