vkuzel.com

Publishing Gradle multi-project "Fat Jar" build to Artifactory

2020-04-15

I have a Gradle multi-module project with following structure.

/project <-- main project
/module1 <-- first module
/module2 <-- second module
<dependency to an external library>

My goal is to build a Fat Jar for a project and deploy it to an Artifactory repository as a library.

// settings.gradle
rootProject.name = 'factorify-gradle-postprocessors'

include 'module1', 'module2'

// Because my modules lies in a flat directory structure next to main project's
// directory I have to alter Gradle's default inclusion mechanism which expects
// module to be located in subdirectories.
rootProject.children.each { it.projectDir = new File(settingsDir, sprintf("../%s", it.name)) }
// build.gradle
plugins {
    id 'java-library'
    id 'maven-publish'
    id("com.jfrog.artifactory") version "4.15.1"
}

sourceCompatibility = JavaVersion.VERSION_1_8

repositories {
    mavenCentral()
}

dependencies {
    implementation project(':module1')
    implementation project(':module2')
}

// Artifactory-publish configuration.
String packageGroup = "com.vkuzel"
String packageName = "project"
String packageVersion = "1.0-SNAPSHOT"
String artifactoryRepoKey = "libs"
String artifactoryUsername = "username"
String artifactoryPassword = "*****"

jar {
    // To build a Fat Jar we have to alter jar task's default behaviour.
    // Following lines will iterate over runtime dependencies of this project
    // and if a dependency is a directory (for example src/) it will add it
    // directly. If a dependency is a zip or jar file it will unpack those
    // files and adds its content to the final jar file.
    from configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}

artifactory {
    publish {
        contextUrl = 'http://download.factorify.cz:8081/artifactory'
        repository {
            repoKey = artifactoryRepoKey
            username = artifactoryUsername
            password = artifactoryPassword
            maven = true
        }
        defaults {
            publications('mavenJava')
        }
    }
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId packageGroup
            artifactId packageName
            version packageVersion

            // Usually "from components.java" method call is used in this
            // place which adds compiled files or dependencies to the published
            // library. This is problematic for multi-project builds since
            // dependency to a submodule is not correcly processed by the
            // publication plugin. To avoid this we will use result of jar
            // task (Fat Jar file) as a single artifact that will be published.
            // See documentation for more details: https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html#org.gradle.api.publish.maven.MavenPublication:artifact(java.lang.Object)
            artifacts = [ jar ]
        }
    }
}