Gradle、SpringBoot、MavenPublish - 发布仅包含没有版本的依赖项和/或约束

Nak*_*ura 7 java spring gradle spring-boot maven-publish

我在 Gradle 中使用 maven-publish 插件来发布我的 Spring Boot 应用程序 jar。我运行通常的任务:./gradlew artifactorypublish. 但是,出现了以下错误,我可以理解其含义:

> 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)
Run Code Online (Sandbox Code Playgroud)

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

...
Run Code Online (Sandbox Code Playgroud)

版本:
Gradle 6.1
Spring Boot 2.2.6(主要由 Spring Boot Initializr 生成)

Nak*_*ura 6

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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.

因此,该工件无法被正确识别components.java。我们应该指向bootJarorbootWar来代替。

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


Isa*_*ank 6

您面临的问题实际上是由于更改而导致的所需行为 - Gradle 6.0.1 附带的https://github.com/gradle/gradle/pull/11388

问题是 Gradle 要求您提供正确版本的依赖项,以禁止用户发布无效的 Gradle 模块元数据。关于以下问题的讨论将帮助您更深入地了解这一点

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

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

现在,在您的情况下,您可以选择两种解决方案

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

或者

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

            versionMapping {
                usage('java-api') {
                    fromResolutionOf('runtimeClasspath')
                }
                usage('java-runtime') {
                    fromResolutionResult()
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

可以在此链接上找到有关第二个选项的更多信息 - https://docs.gradle.org/6.6.1/userguide/publishing_maven.html

  • 仅供参考,`artifact bootJar` 会为我跳过 .module 元数据的生成,并且查看 *DefaultMavenPublication.java* 的源代码,它总是会的。@Isank你能详细说明一下使用“versionMapping”的解决方案吗?您对来源的链接非常出色,但让我问如何获得解决方案,而不是解决方案如何工作。例如,我在哪里可以找到有关字符串 *java-api* 和 *java-runtime* 的信息? (2认同)

Cha*_* S. 5

扩展@Nakamura的答案,如果您将项目设为Springboot Library并需要设置:

bootJar {
    enabled=false
}

jar {
    enabled=true
}
Run Code Online (Sandbox Code Playgroud)

您可以设置:

publishing {
    publications {
        mavenJava(MavenPublication){
            // jar is the default build task configured by Spring Boot if bootJar=false
            artifact jar
        }
    }
}
Run Code Online (Sandbox Code Playgroud)