Saturday, 4 July 2015

Maven to gradle Migration


I am not a big fan of gradle but still this time i am taking this topic.

Maven pom file is xml based build file and Gradle is groovy based system. There are many logic involve to make one to one comparison of generic features. I would like take some generic logic and try to detail out on converting those from maven pom file to gradle build file.


  • Setup Modules
  • define repositories
  • upload of artifacts to maven repository
  • Profiling
    • jacoco test report
  • use of release plugin




Setup Modules

A multi-project build can have an arbitrary directory structure, Which can be configured in settings.gradle. The information in settings.gradle tells Gradle which subprojects are part of this build, what their logical and physical paths are, how their build scripts are named, etc. It does not, and cannot, tell Gradle what the dependencies between the subprojects are.
Like
include 'abc'
include 'xyz'
include 'pqr'

Define Repositories


allprojects {

    afterEvaluate { project ->

        def javaProject = project.plugins.hasPlugin('java')
        repositories {
            maven {
                name "public"
                url "https://apache.maven.com/public/"
            }
            maven {
                name "release"
                url "https://your-maven-repo.com/releases/"
            }
            maven {
                name "snapshot"
                url "https://your-maven-repo.com/snapshots/"
            }
            mavenLocal()
            mavenCentral()


        }

}


upload of artifacts to maven repository


Maven reads the pom.xml to identify the groupID, artifactId and version number. You need to specify these values explicitly to gradle.
Create a file called gradle.properties. This file contains the information about your project metadata like groupid, version etc.. Here are the entries (values are just example).
version=0.1.5
group=com.xyz
packaging=jar
artifactid=abc
gradle build file entry

allprojects {

apply plugin: 'maven'


afterEvaluate {

  uploadArchives {
    repositories {
        mavenDeployer {
            pom.packaging = project.packaging
            pom.groupId = project.group
            pom.version = project.version
            pom.artifactId = project.artifactid
             if(project.version.endsWith('-SNAPSHOT')) {
                repository(url: 'https://your-maven-repo.com//snapshots') {
                authentication(userName: repoUsernameProp, password: repoPasswordProp);
            }
            }
            else {
                repository(url: 'https://your-maven-repo.com//releases') {
                authentication(userName: repoUsernameProp, password: repoPasswordProp);
            }
            }
        }
      }

    }

}
}

Either your can directly provide the username and password of the maven repo to upload the file or use the variable and store it in gradle.properties in ~/.gradle folder. Values for this file would be simple key=value parameter.

Use "upload" as task to upload artifact to maven repo with above configuration.


Profile

If you want to activate some profile with the gradle build, You can add the profile check with following option for java project

allprojects {

        if (project.hasProperty("dev-profile")) {

   <Do your stuff>
        }
     }
}

You can call the profile with -Pdev-profile.

lets take example, If you want to activate jacoco coverage with the profile.


  if (project.hasProperty("dev-profile")) {

                project.apply plugin: 'jacoco'


                jacoco {


                    ext.version = "0.8"

                }

                jacocoTestReport {


                    sourceDirectories = files('src/java')

                    classDirectories = files('build/classes/main')
                }

            }




M2 Release plugin


If you are using maven release plugin to perform release build like "mvn release:prepare release:perform". This is very handy and easy to use plugin to perform release job which takes care of tagging, increment version etc.

You may want to use similar way for gradle build too. Here is the way you can achieve it.

I would suggest to use researchgate plugin for same purposes. There are few alteration but it is most closer to the m2 release plugin.

Plugin source - https://github.com/researchgate/gradle-release
Plugin documentation is very much clear and detail, I would still like to provide some information which can be useful.

Add following entry in your build.gradle to support release plugin
plugins {
id 'net.researchgate.release' version '2.0.2'
}

apply plugin: 'net.researchgate.release'
apply plugin: 'maven'
createReleaseTag.dependsOn allprojects.uploadArchives
Add these configurations too

allprojects {

    apply plugin: 'maven'


  afterEvaluate {

    uploadArchives {
        repositories {
            mavenDeployer {
                pom.packaging = project.packaging
                pom.groupId = project.group
                pom.version = project.version
                pom.artifactId = project.artifactid
                repository(url: 'http://your-repo/releases') {
                    authentication(userName: repoUsernameProp, password: repoPasswordProp);
                }

            }

        }
    }
  }
}

Create a file called gradle.properties. This file contains the information about your project metadata like groupid, version etc.. Here are the entries (values are just example).
version=1.0
group=com.xyz
packaging=jar
artifactid=abc
This file will be used by the plugin to identify the group id, artifact id, version etc to upload it to maven repo.

Difference between M2 plugin and this plugin are



  • Only the root|parent project is applying the plugin
  • Only one version is used for root and sub projects
  • Snapshot is not needed in gradle release plugin.


  • The ultimate command which you may need to run for the release job may be

    gradle release -Pgradle.release.useAutomaticVersion

    gradle wrapper v/s gradle executable

    To use gradle for your project you can download the Gradle distribution and install it on our machine. But maybe you want to share our project with other people or want to run on various systems that don't have Gradle installed. Then we can use the Gradle wrapper. The wrapper is responsible for downloading the Gradle distribution and making it available for our project.


    Auto Mavne to gradle conversion


    There a tool available to convert your pom.xml to builod.gradle
    https://github.com/jbaruch/maven2gradle

    There is build init project within gradle is going on to take care of this migration
    https://docs.gradle.org/current/userguide/build_init_plugin.html