1

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 maven-publish somehow which 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 cuz 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 ?

eHayik
  • 2,981
  • 1
  • 21
  • 33
  • Why are you using two different build systems in the same project? As far as I can tell, they are the same. I would take a look at whatever the Spring Boot team did. Before their migration to Gradle, their Gradle plugin was built using Gradle, but the rest of the project was Maven. https://github.com/spring-projects/spring-boot/tree/2.2.x/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin – Cisco Feb 17 '21 at 03:48
  • Because I'm working on a presentation and I would like to show how to build the same project using maven or gradle – eHayik Feb 17 '21 at 06:18
  • Does this answer your question? [BootJar + MavenJar. Artifact wasn't produced by this build](https://stackoverflow.com/questions/61197984/bootjar-mavenjar-artifact-wasnt-produced-by-this-build) – thokuest Feb 17 '21 at 19:27
  • No, It doesn't cuz `bootJar` is disabled. I think the issue is not related with the maven build, will update my question – eHayik Feb 19 '21 at 18:35

1 Answers1

1

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 had 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 = 'eduardo.eljaiek@gmail.com'
        }
    }

    it.scm {
        connection = 'scm:git:git://github.com/eljaiek/machinery-config.git'
        developerConnection = 'scm:git:git@github.com: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
}

I had 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) }
    }
}

apply from: "$rootDir/gradle/ext/publish-common.gradle" will aplly 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 had 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 had 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

eHayik
  • 2,981
  • 1
  • 21
  • 33