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

Gradle: Upload a List of JARs Into Nexus/Artifactory

DZone's Guide to

Gradle: Upload a List of JARs Into Nexus/Artifactory

Want to see the beauty of Gradle in action? Here we'll learn how to build a custom task that uploads a list of JARs to Nexus or Artifactory.

· Java Zone ·
Free Resource

Atomist automates your software deliver experience. It's how modern teams deliver modern software.

More and more Java projects are starting to use Gradle as their build tool. As a coder, you'll find the power back in your hands again after using it. Because Gradle itself is a Groovy script, a custom task can be easily and concisely created. Here is an example of loading a list of libraries into a Nexus or Artifactory server. Before trying to load it, let's start with a custom task.

configurations {
    oneLib
}

artifacts {
    oneLib file("path-to/one-lib.jar")
}

apply plugin: 'maven'

project.tasks.create('uploadOneLib', Upload.class) {
    configuration = configurations.oneLib
    repositories {
        mavenDeployer {
            repository(url: "${protReleaseUrl}") {
                authentication(userName: "${protReleaseUser}", password: "${protReleasePswd}")
            }
            pom.version = "0.0.1"
            pom.artifactId = "one-lib"
            pom.groupId = "com.onelib"
        }
    }
}


The above Gradle DSL defines an "uploadOneLib" task to load one-lib.jar into the release repository as com.onelib:one-lib-0.0.1.jar (URL and credentials are provided by gradle.properties under ${user.home}/.gradle or the current folder). It extends the built-in task "Upload" to use Maven Deploy. If one-lib-0.0.1.jar has 5 dependent JARs, to load all of them, we can simply duplicate it for each one with slight modifications. But since Gradle has a loop construct, it would be nice to just list the libraries to be uploaded, the target URLs/credentials, some consideration to allow different URLs/credentials for different libraries, and some different classifiers for some libraries. The meta-data structure will look like:

{
    "libs": [
        {
          "cfgName": "uploadInternal1"
          , "groupId": "com.prot.zbank.client"
          , "artifactId": "client-model"
          , "version": "0.0.8"
          , "jarLocation": "client/client-model.jar"
        }
        , {
          "cfgName": "uploadInternal2"
          , "groupId": "com.prot.zbank.client"
          , "artifactId": "client-model"
          , "classifier": "test"
          , "version": "0.0.8"
          , "jarLocation": "client/unit-test.jar"
        }
        , {
          "cfgName": "uploadInternal3"
          , "groupId": "com.prot.zbank.client"
          , "artifactId": "client-service"
          , "version": "0.0.9"
          , "jarLocation": "client/rest-api.jar"
        }
        , {
          "cfgName": "uploadOracleDriver"
          , "groupId": "com.oracle"
          , "artifactId": "ojdbc8"
          , "version": "0.2b"
          , "jarLocation": "3rd/ojdbc8.jar"
          , "repoUrl": "http://a.b.com/repository/third-party/"
          , "repoUser": "david"
          , "repoPswd": "Passw0rd888"
        }
    ]
    , "repoUrl": "http://a.b.com/repository/zbank-project-release/"
    , "repoUser": "george"
    , "repoPswd": "Passw0rd999"
}


The model says to:

  1. Upload from client/client-model.jar to com.prot.zbank.client:client-model-0.0.8.jar

  2. Upload from client/unit-test.jar to com.prot.zbank.client:client-model-0.0.8-test.jar

  3. Upload from client/rest-api.jar to com.prot.zbank.client:client-service-0.0.9.jar

  4. Upload from 3rd/ojdbc8.jar to com.oracle:ojdbc8-0.2b.jar

The first 3 JARs are uploaded to http://a.b.com/repository/zbank-project-release/, and the last one will be uploaded to http://a.b.com/repository/third-party/.

Gradle shines for this kind of task. In about 50 lines of code, a custom task — "batchUpload" — is created for our needs.

apply plugin: 'maven'

def f = file("upload-list.json")
def m = f.exists() ? new groovy.json.JsonSlurper().parse(f) : null

task batchUpload() {
}

if (m == null || m.libs == null || m.libs.isEmpty()) {
    batchUpload.doLast {
        println "WARNING: no file to upload"
    }
} else {
    m.libs.each { lib ->
        configurations.create( "${lib.cfgName}" )
        if (lib.classifier == null) {
            artifacts.add("${lib.cfgName}", file("${lib.jarLocation}"))
        } else {
            artifacts.add("${lib.cfgName}", file("${lib.jarLocation}")) {
                setClassifier( "${lib.classifier}" )
            }
        }

        def repoUrl = lib.repoUrl != null ? lib.repoUrl : m.repoUrl;
        def repoUser = lib.repoUser != null ? lib.repoUser : m.repoUser;
        def repoPswd = lib.repoPswd != null ? lib.repoPswd : m.repoPswd;
        def classifier = lib.classifier == null ? "" : ("-" + lib.classifier)
        println "define task '${lib.cfgName}' to upload ${lib.jarLocation} to ${repoUrl} as ${lib.groupId}:${lib.artifactId}-${lib.version}${classifier}.jar"

        project.tasks.create("${lib.cfgName}", Upload.class) {
            configuration = configurations[lib.cfgName]
            repositories {
                mavenDeployer {
                    repository(url: "${repoUrl}") {
                        authentication(userName: "${repoUser}", password: "${repoPswd}")
                    }
                    pom.version = "${lib.version}"
                    pom.artifactId = "${lib.artifactId}"
                    pom.groupId = "${lib.groupId}"
                }
            }
        }

        batchUpload.dependsOn "${lib.cfgName}"
    }
}


It loops through each lib from the JSON model, creates a custom task to perform the upload, then tells the "batchUpload" task to depend on this task, so running "gradle batchUpload" will try to upload all libraries. Running "gradle ${lib.cfgName}" will just upload that ${lib} only. I can feel the beauty of this simplicity after using Gradle for one year. 

Get the open source Atomist Software Delivery Machine and start automating your delivery right there on your own laptop, today!

Topics:
gradle ,artifact repositories ,java ,nexus ,artifactory ,tutorial

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}