Converting a maven project to gradle

Updated:  13 July 2014

With gradle 2.0 released on 1st July 2014, it was time to relook and update this write-up suitably.  gradle is in active development and has evolved a lot.  It is now the new android build tool.

I had tried using Gradle a few months back without much success.

Last week, I decided to give another shot, after seeing that many popular open source projects (hibernatespring security to name two) were using gradle.

I downloaded the latest version as of date (0.9-rc-3). (2.0 as on 13th July 2014).

Installation is straightforward, since it is just extracting the zip file and updating the PATH to refer to the bin folder of the unzipped contents.

gradle -version

ran without errors, indicating that installation went off fine.

Downloading and installing gradle is straight-forward.  Unzip the binaries to a folder of your choice, set GRADLE_HOME to this folder and add the bin subfolder of GRADLE_PATH to your PATH variable.

On Windows, it would be something like below:

set GRADLE_HOME=C:\software\gradle-2.0 

set PATH=%GRADLE_HOME%\bin;%PATH% 

gradle -v 

------------------------------------------------------------ 
Gradle 2.0 
------------------------------------------------------------ 

Build time: 2014-07-01 07:45:34 UTC 
Build number: none Revision: b6ead6fa452dfdadec484059191eb641d817226c 

Groovy: 2.3.3 
Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013 
JVM: 1.7.0_60 (Oracle Corporation 24.60-b09) 
OS: Windows 8.1 6.3 amd64

So far so good.

Now the idea was to create a gradle build script for an existing maven project. The best way to start off was by looking at the documentation.

There is no shortage of information, but my idea was not to learn gradle from a to z, but to see how quickly I could create a build script for my maven project.  I looked around but could find nothing like a one-to-one mapping of maven pom.xml to build.gradle.

There is a gradle build init plugin, which can be applied on a maven pom to bootstrap a gradle script.  It does a simple one-to-one conversion of maven dependencies to gradle, but not much beyond.  For instance, it did not automatically apply 'war' plugin. It also did not detect I was using testNG.

I did find some examples for maven in samples folder of gradle installation.  However, the best resource that I hit upon was the build script of spring security itself [build.gradle, javaprojects.gradle].

Here is what I did to enable a gradle build for my maven project.  Remember, we are looking at a simple typical maven project and this is not an exhaustive guide.

We start by specifying to gradle that we need to build java, maven project

apply plugin: 'java'
apply plugin: 'maven'


In addition, if we need to build a war (as in my case),

apply plugin: 'war'

Gradle uses build folder by convention to do the build and generate artifacts.  To use maven's target folder,

// Change default directory to target from build

buildDir = 'target'

Specifying versions of libraries (or other properties)

In Maven, it would be something like...

<properties> <
    <spring.version>4.0.5.RELEASE</spring.version>
    <spring.security.version>3.2.4.RELEASE</spring.security.version>
    <slf4j.version>1.7.7</slf4j.version>
    <logback.version>1.1.2</logback.version>
</properties>

In gradle:

ext {
    springVersion = '4.0.5.RELEASE'
    securityVersion = '3.2.4.RELEASE'
    slf4jVersion = '1.7.7'
    logbackVersion = '1.1.2'
}

Specifying the version and group of the project artifact

Maven:

<groupId>net.sourceforge.jukebox</groupId>
<version>1.1-SNAPSHOT</version>


Gradle:

group = 'net.sourceforge.jukebox'
version = '1.0-SNAPSHOT'


Specifying location of repository (holding 3rd party dependencies)

Maven gathers this from settings.xml

Gradle (assuming Maven local repository is in the default location):

repositories {
    // First check local cache before accessing central repository
    mavenRepo name:'Local', urls: "file://" + System.properties['user.home'] + "/.m2/repository"
    mavenCentral()
}


Specifying the 3rd party dependencies.

In Maven, a dependency can have the following scope
  • compile (the default)
  • test
  • runtime
  • provided
Also, by default maven dependencies are transitive

To make it similar in gradle,

configurations {
    providedCompile
    testCompile.extendsFrom provided
    compile.transitive = true
}


dependencies {

    compile(
        [group: 'ch.qos.logback', name : 'logback-classic', version : logbackVersion],
        [group: 'ch.qos.logback', name : 'logback-core', version : logbackVersion],
        [group: 'commons-configuration', name : 'commons-configuration', version : '1.6']
        ...
    )

    providedCompile group: 'javax.servlet', name : 'servlet-api', version : '2.5'

    testCompile(
        [group: 'org.mockito', name : 'mockito-core', version : '1.8.5'],
        [group: 'org.springframework', name : 'spring-test', version : springVersion],
        [group: 'org.testng', name : 'testng', version : '5.14.2']
    )
    runtime(
        ...
        [group: 'org.slf4j', name : 'log4j-over-slf4j', version : slf4jVersion],
        [group: 'org.springframework.security', name : 'spring-security-config', version : securityVersion],
        [group: 'org.springframework.security', name : 'spring-security-web', version : securityVersion]
    )
}

Now to ensure that the dependencies in the provided scope are available in compile classpath  Dependencies in providedCompile group are available in compile classpath.

// Added the provided dependency to compile classpath
sourceSets.main.compileClasspath += configurations.provided



Now, if you use testNG instead of junit for unit testing, then

// Use TestNG instead of the default JUnit
test {
    useTestNG()
}


That is it!  With these configuration,  the following command does the equivalent of maven clean package

gradle clean test war

In case you are interested, you can compare the pom.xml and the equivalent build.gradle here

Comments

  1. I have had success on several project with this simple converter.

    http://www.nofluffjuststuff.com/blog/baruch_sadogursky/2010/10/maven2_to_gradle_convertor__take_ii

    Cheers
    -bob

    ReplyDelete
  2. Instead of

    // First check local cache before accessing central repository
    maven {
    url "file:///" + localRepoDir + "/.m2/repository"
    }

    you can just use mavenLocal()

    ReplyDelete
  3. Nice article to write gradle file from beginning. I tried to come up with one more article to convert pom file to gradle build file
    AND
    converting parent pom to gradle init file

    http://www.scmtechblog.net/2015/12/how-to-migrate-parent-pom-from-maven-to.html

    Let me know your feedback.

    ReplyDelete

Post a Comment

Popular posts from this blog

Opening a safe deposit locker in SBI

Opening a Kannada Word document

Automating a cordova ios build