Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle, SpringBoot, MavenPublish - Publication only contains dependencies and/or constraints without a version

I'm using maven-publish plugin in Gradle to publish my Spring Boot application jar. I run the usual task: ./gradlew artifactorypublish. However, the following error appeared, which I could understand the meaning of:

> Task :assembleArtifact
> Task :application-jar:compileJava UP-TO-DATE
> Task :application-jar:processResources UP-TO-DATE
> Task :application-jar:classes UP-TO-DATE
> Task :application-jar:jar SKIPPED
> Task :generateMetadataFileForMavenJavaPublication FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':generateMetadataFileForMavenJavaPublication'.
> Invalid publication 'mavenJava':
    - Publication only contains dependencies and/or constraints without a version. You need to add minimal version information, publish resolved versions (https://docs.gradle.org/6.1/userguide/publishing_maven.html#publishing_maven:resolved_dependencies) or reference a platform (https://docs.gradle.org/6.1/userguide/platforms.html)

My build.gradle:

plugins {
    id 'org.springframework.boot' version '2.2.6.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
    id 'maven-publish'
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

publishing {
    publications {
        mavenJava(MavenPublication){
            components.java
        }
    }
}

...

Versions:
Gradle 6.1
Spring Boot 2.2.6 (mostly generated from Spring Boot Initializr)

like image 761
Nakamura Avatar asked Apr 29 '20 11:04

Nakamura


3 Answers

The problem that you're facing is actually the desired behavior because of the change - https://github.com/gradle/gradle/pull/11388 that came along with Gradle 6.0.1

The thing is that Gradle requires you to provide a proper version of dependencies so as to disallow users from publishing an invalid Gradle Module Metadata. The discussions on the issues below will help you to get a deeper insight into this

https://github.com/gradle/gradle/issues/11862

https://github.com/spring-gradle-plugins/dependency-management-plugin/issues/262

Now, in your case, there are two solutions that you can choose from

publishing {
    publications {
        mavenJava(MavenPublication){
            // bootJar is the default build task configured by Spring Boot
            artifact bootJar
        }
    }
}

or

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java

            versionMapping {
                usage('java-api') {
                    fromResolutionOf('runtimeClasspath')
                }
                usage('java-runtime') {
                    fromResolutionResult()
                }
            }
        }
    }
}

More information on the second option can be found on this link - https://docs.gradle.org/6.6.1/userguide/publishing_maven.html

like image 160
Isank Avatar answered Nov 11 '22 09:11

Isank


Extend the answer by @Nakamura, If you make a project to be Springboot Library and need to set:

bootJar {
    enabled=false
}

jar {
    enabled=true
}

You can set :

publishing {
    publications {
        mavenJava(MavenPublication){
            // jar is the default build task configured by Spring Boot if bootJar=false
            artifact jar
        }
    }
}
like image 7
Chayne P. S. Avatar answered Nov 11 '22 07:11

Chayne P. S.


After messing around for a while, I found the solution:

publishing {
    publications {
        mavenJava(MavenPublication){
            // bootJar is the default build task configured by Spring Boot
            artifact bootJar
        }
    }
}

Detailed Explanation

This is because components.java is configured for default java plugin task: jar or war. However for Spring Boot, after applying plugin org.springframework.boot, the default task become bootJar or bootWar.

(For your reference) From Spring Boot doc:

Executable jars can be built using the bootJar task. The task is automatically created when the java plugin is applied and is an instance of BootJar. The assemble task is automatically configured to depend upon the bootJar task so running assemble (or build) will also run the bootJar task.

Therefore, the artifact could not be correctly identified by components.java. We should point to bootJar or bootWar instead.

Reference: https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#publishing-your-application-maven-publish

like image 4
Nakamura Avatar answered Nov 11 '22 08:11

Nakamura