If you’re planning to migrate your Maven project to Gradle, you’ll be looking for the path of least resistance to get the job done as easily as possible. In this article you’ll discover the 8 recommended steps to migrate your Java Spring Boot project from Maven to Gradle.

Why do a migration to Gradle?

If you’re reading this article you probably know why you want to move to Gradle, but some of the reasons probably include:

  • Gradle’s Groovy syntax is less verbose than Maven’s xml

  • easier to configure thanks to its graph based task hierarchy

  • features incremental builds to avoid rerunning tasks

  • 2-10 times faster than Maven (according to the Grade docs)

If you’re still deciding whether to migrate, check this Maven vs. Gradle comparison for more help.

When running your migration, it’s important to run through a pre-determined list of steps and commit your code after each one. With a Spring Boot project, these steps should end up with having the same (or very similar) built jar file, the application running exactly as before, and with the same tests running.

Starting point: a Maven project

We’ll be using an example Maven project which you can download from this GitHub repository. We’ll go back to the initial commit containing the original Maven project:

git clone https://github.com/tkgregory/maven-to-gradle.git
cd maven-to-gradle
git checkout d5fa646871b28a622cca10fb1ca5a52573566fc1

To build and run the Spring Boot application, use the included Maven wrapper script:

./mvnw spring-boot:run

The application includes the following functionality:

  • creates a git.properties file at build time containing the git commit hash

  • exposes this information on http://localhost:8080/actuator/info (Spring Boot does this automatically when git.properties is provided)

  • has a @SpringBootTest test to check that the application starts up

  • depends on Spring Boot web, data-jpa, actuator, and test libraries

Running the migration

Follow each stage of the migration process using the steps below.

1) Generate a build scan

The Gradle build scan can run against a Maven or Gradle project, and publishes useful build information to gradle.com for you to access. We’ll use it to get an insight into the Maven build, and later on to compare to the Gradle version.

Add the file .mvn/extensions.xml with the following contents:

com.gradle gradle-enterprise-maven-extension 1.3.6

Then run mvn install and accept the terms of service when prompted.

Click on the link provided, enter your email address, then click the link in the email in your inbox to see the scan results.

Total build time

Select Performance on the left hand menu, and you’ll see our build took 12 seconds in total:

Plugins

The Plugins area will be useful to us later to make sure our Gradle build has all the required plugins:

2) Run an automatic conversion

Thankfully Gradle can do a share of the heavy lifting and automatically generate the build.gradle file based on the pom.xml. It will even convert dependencies, but unfortunately not plugins.

Install or update Gradle

Make sure you’re on the latest version of Gradle. At the time of writing this was 6.1.1.

gradle --version

Run gradle init

Navigate to the project root and run:

gradle init

Type yes when prompted if you want to generate a Gradle build.

The following Gradle resources have now been created:

  • build.gradle file - the pom.xml file equivalent

  • settings.gradle file - sets your project name

  • gradlew and gradlew.bat wrapper scripts - you should use these whenever you run Gradle tasks to ensure you’re using the correct version of Gradle

  • a gradle directory - this contains the wrapper jar file

Edit your .gitignore file and add the following entries for directories that shouldn’t be added to version control:

.gradle/
build/

3) Build your project and work through any errors

Now we can try to build using Gradle, although we may get errors since the automatic conversion is just a ‘best-effort’ attempt:

./gradlew build

Here’s an example of an error you might see when using certain versions of Gradle.

Gradle can’t find the required repositories. We need to declare mavenCentral() in the list of repositories in build.gradle so that Gradle knows where to look.

repositories {
    mavenLocal()
    mavenCentral()
    maven {
        url = 'http://repo.maven.apache.org/maven2'
    }
}

Try ./gradlew build again and you’ll get a success:

4) Compare the built artifacts

Add the following script to compareArtifacts.sh. It will compare the size of the built artifacts in Maven’s target and Gradle’s build directories.

#!/bin/sh
MAVEN=target/maven-to-gradle-0.0.1-SNAPSHOT.jar
GRADLE=build/libs/maven-to-gradle-0.0.1-SNAPSHOT.jar

ls -hl $MAVEN  | awk '{print $9, $5}'
ls -hl $GRADLE  | awk '{print $9, $5}'

Now run it:

./compareArtifacts.sh

We’re missing 40MB of code here. Could be important? ⚠️

What’s happened is that Gradle isn’t building the full executable ‘fat’ Spring Boot jar since we don’t have the correct plugin. Add the Spring Boot plugins to the plugins section:

    id 'org.springframework.boot' version '2.2.4.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'

Now build again with ./gradlew build, then run ./compareArtifacts.sh again:

Much better! Of course this verification method is by no means bulletproof, but it gives us a good indication that we’re on the right track.

5) Run a build scan on the Gradle build to see which plugins are missing

Now let’s run a scan on our Gradle build using ./gradlew build --scan and compare with the Maven build scan:

Maven

Gradle

Both Maven and Gradle add a lot of plugins by default. Ignoring all the org.apache.maven.plugins plugins, we can see that we should include:

  • spring-boot-maven-plugin - we already added this one

  • git-commit-id-plugin - we don’t have this one yet, meaning our http://localhost:8080/actuator/info endpoint won’t work. You can see this by running ./gradlew bootRun:

Missing git.properties file

Missing git.properties file

6) Convert plugins

At this point we need to convert any remaining plugins to Gradle. Usually there’s a direct equivalent or very similar plugin.

For generating the git.properties file we’ll add this plugin to plugins block:

id "com.gorylenko.gradle-git-properties" version "2.4.1"

And add it’s configuration:

gitProperties {
    keys = ['git.commit.id']
}

Let’s run ./gradlew build and we can see the git.properties file has been generated in build/classes:

git.commit.id=eea1a128...'

7) Ensure tests are running

Run ./gradlew test and you’ll see from the test report in build/reports/tests/test/index.html that our test is not running:

Enable JUnit 5 tests by adding the following test configuration to the end of build.gradle:

test {
    useJUnitPlatform()
}

Run ./gradlew test again and the test report should now look much better:

8) Manually test the application (if applicable)

If you have a full automated test suite then this step might not be required, but in our case we’re going to manually start the application and verify it has the expected behaviour.

Start the application in Gradle:

./gradlew bootRun

Does http://localhost:8080/actuator/info return us what we expect?

Looks good! ✅ How about http://localhost:8080/vegetables?

Yup, two of your five-a-day. 🍆

Conclusion

Converting your project from Maven to Gradle doesn’t have to be difficult if you follow these steps carefully, ensuring you commit at each stage in case you need to go back to a previous point.

Once your conversion is complete, if you’re working in a team I recommend keeping the Maven build files for a few weeks until your teammates have moved across to Gradle. Don’t forget to also update your CI server.

Then it’s time for the fun part, deleting the pom.xml files and enjoying your more powerful Gradle build.

Resources

CODE See the code for this example in this GitHub repository

DOCUMENTATION Checkout out Gradle’s own useful guide to migrations

Watch this video demonstrating the ideas from this article.

Stop reading Gradle articles like these

This article helps you fix a specific problem, but it doesn't teach you the Gradle fundamentals you need to actually help your team succeed.

Instead, follow a step-by-step process that makes getting started with Gradle easy.

Download this Free Quick-Start Guide to building simple Java projects with Gradle.

  • Learn to create and build Java projects in Gradle.
  • Understand the Gradle fundamentals.