Migrating from Maven to Gradle

Milan Brich
Sep 5, 2018 · 4 min read

Environment:

gradle 4.9, IntelliJ IDEA 2018.2.2

Describes migrating from existing maven project to gradle project with Gradle DSL.

Initial configuration

Initialize gradle project in directory where is pom.xml:

gradle init

It creates build.gradle file which is equivalent to pom.xml and settings.gradle file.

Below configuration uses Gradle DSL which is in Groovy. Prefer using double apostrophes ex.: “mapstruct:$mapstructVersion”. It’s String when no variable (marked with ‘$’) is present or GString when variable is present in Groovy. In GString are variables replaced with it’s values.

Setting artifactory

build.gradle:

repositories {
maven { url "http://artifactory/repo" }
}

settings.gradle:

pluginManagement {
repositories {
maven {
url "http://artifactory/repo"
}
gradlePluginPortal()
}
}

UTF-8 Encoding

tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}

Create gradle.properties file which will contain configuration setting and library versions.

org.gradle.jvmargs="-Dfile.encoding=UTF-8"

Build project

Build project using gradle wrapper:

gradlew assemble

When problem with downloading from https://services.gradle.org/… (you’re behind proxy). Either change distributionUrl in gradle-wrapper.properties to your internal artifactory or create gradle.properties in your ${userHome}/.gradle or in project directory with:

systemProp.https.proxyHost=localhost
systemProp.https.proxyPort=3128

Assuming that on localhost:3128 runs cnltm: http://cntlm.sourceforge.net


Replacing maven plugins

Below is described how can be replaced plugins in pom.xml with plugins in build.gradle.

Generating build-info.properties

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>

replace with:

plugins {
id "org.springframework.boot" version "1.5.12.RELEASE"
}
springBoot {
buildInfo()
}

Generating git.properties

<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
</plugin>

replace with:

plugins {
id "com.gorylenko.gradle-git-properties" version "1.5.2"
}

!!! It’s incompatible with plugin: id(“nebula.release”).version(“6.3.5”)

Git.properties plugin uses older version of https://github.com/ajoberstar/grgit.

Cucumber reporting

<plugin>
<groupId>net.masterthought</groupId>
<artifactId>maven-cucumber-reporting</artifactId>
<executions>
<execution>
<id>execution</id>
<phase>verify</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<projectName>prjName</projectName>
<outputDirectory>${project.build.directory}/site/cucumber-reports</outputDirectory>
<cucumberOutput>${project.build.directory}/cucumber.json</cucumberOutput>
</configuration>
</execution>
</executions>
</plugin>

replace with:

plugins {
id "com.github.spacialcircumstances.gradle-cucumber-reporting" version "0.0.14"
}
cucumberReports {
outputDir = file("target/cucumber-reports")
buildName = "0"
reports = files("target/cucumber.json")
}

where cucumberReports.reports references cucumber.json configured in @CucumberOptions:

@CucumberOptions(...,
plugin = [ "pretty", "json:target/cucumber.json", "html:target/site/cucumber-pretty" ])

In @CucumberOptions set generating files with correct names:

@CucumberOptions(junit = ["--filename-compatible-names"])

Kotlin

<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
...
</plugin>

replace with:

plugins {
id "org.jetbrains.kotlin.jvm" version "1.2.60"
id "org.jetbrains.kotlin.kapt" version "1.2.60"
id "org.jetbrains.kotlin.plugin.allopen" version "1.2.60"
id "org.jetbrains.kotlin.plugin.spring" version "1.2.60"
}

Mapstruct processor

<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<executions>
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal>
</goals>
<configuration>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</annotationProcessorPath>
</annotationProcessorPaths>
...
</plugin>

replace with:

dependencies {
kapt "org.mapstruct:mapstruct-processor:$mapstructVersion"
}

Sonarqube

<sonar.host.url>http://...</sonar.host.url><plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>${sonar-maven-plugin.version}</version>
</plugin>

replace with:

plugins {
id "org.sonarqube" version "2.6.2"
}

gradle.properties

systemProp.sonar.host.url=https://

Jacoco

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>target/jacoco.exec</dataFile>
<outputDirectory>target/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

replace with:

plugins {
id "jacoco"
}

War plugin

<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>WEB-INF/classes/db/**,WEB-INF/classes/configuration/**</packagingExcludes>
</configuration>
</plugin>

replace with:

plugins {
id "war"
}
war {
exclude "WEB-INF/classes/db/**,WEB-INF/classes/configuration/**"
}

Release plugin

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
</plugin>

replace with:

plugins {
id "pl.allegro.tech.build.axion-release" version "1.9.3"
}
project.version = scmVersion.version

https://github.com/allegro/axion-release-plugin


Final version

plugins {
id "java"
id "war"
id "jacoco"

id "org.springframework.boot" version "1.5.12.RELEASE"
id "com.gorylenko.gradle-git-properties" version "1.4.17"

id "org.jetbrains.kotlin.jvm" version "1.2.60"
id "org.jetbrains.kotlin.kapt" version "1.2.60"
id "org.jetbrains.kotlin.plugin.allopen" version "1.2.60"
id "org.jetbrains.kotlin.plugin.spring" version "1.2.60"

id "com.github.spacialcircumstances.gradle-cucumber-reporting" version "0.0.14"
id "org.sonarqube" version "2.6.2"
}

version = "1.0"
group = "group"
description = "desc"

kapt {
useBuildCache = true
}

springBoot {
buildInfo()
}

cucumberReports {
outputDir = file("target/cucumber-reports")
buildName = "0"
reports = files("target/cucumber.json")
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}

repositories {
maven { url "http://.../repo" }
}

dependencies {
implementation "org.springframework.boot:spring-boot-dependencies:$springbootVersion"

compile "org.springframework.boot:spring-boot-starter-actuator"
...
kapt "org.mapstruct:mapstruct-processor:$mapstructVersion"
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlinVersion"
providedCompile "org.springframework.boot:spring-boot-starter-tomcat"
}

gradle.properties

org.gradle.caching=true
org.gradle.parallel
=true
kotlin.incremental
=true
org.gradle.console
=verbose
org.gradle.jvmargs
="-Dfile.encoding=UTF-8"
mapstructVersion=1.2.0.Final
...

Run with:

gradlew clean assemble // build without tests
gradlew test // build with tests
gradlew sonarqube // build, tests and sonarqube
gradlew bootRun // run springBoot app
gradlew dependencies --configuration default // dependency tree

IntelliJ IDEA

In Build, Execution, Deployment > Build Tools > Gradle > Runner check Delegate IDE build/run actions to gradle.

Otherwise Idea doesn’t find file git.properties.

Milan Brich

Written by

Java full stack developer