eHayik
eHayik

Reputation: 3262

Gradle maven publish plugin fails in a multi-module project with error "Artifact wasn't produced by this build"

I have a multi-module project which supports maven and gradle builds hence it contains pom.xml files along side with build.gradle. I'm working on a demo and I would like to show how to build and deploy to nexus the same project using either gradle or maven. That's why I have two different build systems in case you wonder why.

You may see the project structure below.

project structure

You may look into the code here.

I've configured the gradle maven-publish plugin in order to publish all modules to my local nexus repository however when I run gradle publish I hit this error:

Execution failed for task ':publishMavenJavaPublicationToMavenRepository'.
> Failed to publish publication 'mavenJava' to repository 'maven'
   > Artifact machinery-config-0.0.1.jar wasn't produced by this build.

The issue is related with having the publishing section within $rootDir/build.gradle.

It's confusing, the maven-publish somehow is trying to publish an artifact that doesn't exist machinery-config-0.0.1.jar, machinery-config is the name of the rootProject.

One workaround could be to remove the publishing section from the rootProject and duplicate it in the sub-projects. I don't like that approach, since I will end up with a lot of duplicated code.

Could you point me out a better way to use maven-publish within a multi-module project ?

Upvotes: 3

Views: 3672

Answers (1)

eHayik
eHayik

Reputation: 3262

After some digging I realized that I had two issues:

  1. publishing section was outside of subprojects section, then gradle tried to deploy an artifact using rootProject.name ignoring the included modules.

  2. group & version properties were outside subprojects therefore deployed artifacts had undefined as version number, e.g machinery-config-core-undefined.jar

In order to fix issue number two, I moved group & version into subprojects section.

My build also produces a BOM artifact, hence I need two publications from components.java and from components.javaPlatform, so I wrote this script gradle/ext/publish-common.gradle which exports two functions, I will use later on both publications to keep code duplication at bay.

def pom(it) {
    it.licenses {
        license {
            name = 'The Apache License, Version 2.0'
            url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
        }
    }

    it.developers {
        developer {
            id = 'eljaiek'
            name = 'Eduardo Eljaiek'
            email = '[email protected]'
        }
    }

    it.scm {
        connection = 'scm:git:git://github.com/eljaiek/machinery-config.git'
        developerConnection = 'scm:git:[email protected]:eljaiek/machinery-config.git'
        url = 'https://github.com/eljaiek/machinery-config'
    }
}

def nexusRepository(it) {
    it.url = version.endsWith('SNAPSHOT') ? project.nexusSnapshotsUrl : project.nexusReleasesUrl
    it.credentials {
        username project.nexusUser
        password project.nexusPasswd
    }
}

ext {
    pom = this.&pom
    nexusRepository = this.&nexusRepository
}

Additionally, I added from components.javaPlatform publication into machinery-config-dependencies/build.gradle in order to deploy the BOM artifact:


apply plugin: 'maven-publish'
apply from: "$rootDir/gradle/ext/publish-common.gradle"


publishing {
    publications {
        mavenBom(MavenPublication) {
            from components.javaPlatform

            pom { x -> pom(x)}
        }
    }

    repositories {
        maven { x -> nexusRepository(x) }
    }
}

The apply from: "$rootDir/gradle/ext/publish-common.gradle" will apply the script I wrote, this is required in order to import pom() and nexusRepository() functions into my build script.

To deploy from components.java artifacts, I added a publishing section in subprojects under if (it.name != 'machinery-config-dependencies') statement into $rootDir/build.gradle

apply plugin: 'ru.vyarus.pom'
apply from: "$rootDir/gradle/ext/publish-common.gradle"

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
                pom { x -> pom(x)}
            }
        }

        repositories {
           maven { x -> nexusRepository(x) }
        }
}

I used Gradle POM plugin instead of maven-publish. It provides maven's dependencies declaration simplicity and implicitly applies maven-publish plugin.

See the code here

References

Extract common methods from Gradle build script

The Java Platform Plugin

Upvotes: 1

Related Questions