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

Get the Edge with a Professional Java IDE. 30-day free trial.

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 Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.

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 }}