BootJar + MavenJar。工件不是由这个构建产生的
Posted
技术标签:
【中文标题】BootJar + MavenJar。工件不是由这个构建产生的【英文标题】:BootJar + MavenJar. Artifact wasn't produced by this build 【发布时间】:2020-07-26 14:35:26 【问题描述】:我有一个具有以下层次结构的示例项目:
Sample (root)
-- model (simple jar)
-- api (springboot jar)
我想将两个生成的 jar:plain jar 和 bootJar 发布到我的 localRepository。
gradlew clean build -xTest publishToMavenLocal
但是,出现以下错误:
* What went wrong:
Execution failed for task ':api:publishMavenJavaPublicationToMavenLocal'.
> Failed to publish publication 'mavenJava' to repository 'mavenLocal'
> Artifact api.jar wasn't produced by this build.
根 build.gradle 如下:
plugins
id 'java'
id "org.springframework.boot" version "2.2.5.RELEASE" apply false
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
group 'sample'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories
mavenCentral()
ext
artifactVersion = version
springBootVersion = "2.2.5.RELEASE"
allprojects
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'maven'
tasks.withType(JavaCompile)
options.encoding = 'UTF-8'
repositories
mavenCentral()
jcenter()
subprojects
apply plugin: "io.spring.dependency-management"
apply plugin: "maven-publish"
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencyManagement
imports
mavenBom "org.springframework.boot:spring-boot-dependencies:$springBootVersion"
dependencies
implementation "org.springframework.boot:spring-boot-dependencies:$springBootVersion"
publishing
publications
mavenJava(MavenPublication)
groupId project.group
artifactId project.name
version project.version
from components.java
api build.gradle
apply plugin: 'org.springframework.boot'
dependencies
compile project(":model")
implementation "org.springframework.boot:spring-boot-starter-web"
bootJar
将 bootJava 任务添加到 api build.gradle 允许直接从 api 模块发布 bootJar,但根发布任务仍然中断。
publishing
publications
bootJava(MavenPublication)
artifact bootJar
我已经尝试了几乎所有来自 docs 和 google 的解决方案,但似乎没有一个有效。 谁能解释一下,什么配置错误?
Gradle 版本:6.3
【问题讨论】:
适用于 Gradle 5.3。 :-( 【参考方案1】:正如 gradle 文档 here 所述:
从 Gradle 6.2 开始,Gradle 在上传前会执行完整性检查,以确保您不会上传过时的文件(由另一个构建生成的文件)。这引入了使用 components.java 组件上传的 Spring Boot 应用程序的问题
更多解释可在上面的链接中找到。 他们提出了以下我个人尝试并为我工作的解决方法:
配置传出配置
configurations
[apiElements, runtimeElements].each
it.outgoing.artifacts.removeIf it.buildDependencies.getDependencies(null).contains(jar)
it.outgoing.artifact(bootJar)
在我的 build.gradle 配置之后:
....
apply plugin: 'maven-publish'
...
configurations
[apiElements, runtimeElements].each
it.outgoing.artifacts.removeIf it.buildDependencies.getDependencies(null).contains(jar)
it.outgoing.artifact(bootJar)
....
publishing
publications
myPublication(MavenPublication)
groupId groupId
artifactId artifactId
version version
from components.java
versionMapping
usage('java-api')
fromResolutionOf('runtimeClasspath')
usage('java-runtime')
fromResolutionResult()
repositories
maven
url azureRepoUrl
name azureRepoName
credentials
username azureRepoUserName
password azureRepoAccessToken
【讨论】:
您能分享更多信息吗?它放在哪里?我收到无法将提供的表示法转换为 ConfigurablePublishArtifact 类型的对象 注意:在多模块项目中的“配置”块应该在带有 bootjar 任务的模块中 没有一种解决方案适用于 bootWar 任务。有什么想法吗?configurations
中的附加行对我有用,在我的情况下是 Gradle v6.5。【参考方案2】:
摘录from
从 Gradle 6.2 开始,主 jar
任务被 Spring Boot 应用程序禁用,component
期望它存在。因为 bootJar
任务默认使用与主 jar
任务相同的文件,所以之前版本的 Gradle 会:
bootJar
工件
如果之前没有调用过 bootJar 任务,则失败
简单的解决方法是配置传出配置。对于多模块 Gradle 项目,将以下配置放在服务模块(spring boot 模块)中。
dependencies
.....
configurations
[apiElements, runtimeElements].each
it.outgoing.artifacts.removeIf
it.buildDependencies.getDependencies(null).contains(jar)
it.outgoing.artifact(bootJar)
注意:如果配置正确,则无需更改 artifactory
任务的任何内容。此工作解决方案已通过 Gradle 6.4.1
测试。
不要尝试他们提供的替代建议,因为 classifier
属性在最近的版本中已被弃用,使用自定义配置更改 bootJar
任务也会导致不正确的 uber jar 构建,如果您提取生成的 jar 分发包,您可以找到缺少的 BOOT-INF
目录和必要的 META-INF/MANIFEST.MF
值。
jar
enabled = true
bootJar
classifier = 'application'
更新:
来自 Spring Boot 2.5.0
,jar
任务会生成一个以-plain.jar
结尾的附加 jar 存档。如果有人使用*.jar
之类的模式来复制构建存档,可能会破坏他们的构建,因此,为了限制额外的 jar 创建,应使用以下jar
任务配置代码 sn-p。
jar
enabled = false
【讨论】:
【参考方案3】:我可以通过在发布任务中添加artifact bootJar
来完成这项工作,如下所示,而无需按照 gradle 文档中的建议添加任何配置。我相信这可能与他们在文档中的第一个解决方法相同。用gradle测试6.5.1
publishing
publications
mavenJava(MavenPublication)
artifact bootJar
artifact sourceJar
classifier "sources"
project.tasks.publish.dependsOn bootJar
【讨论】:
【参考方案4】:根据下面的“Gradle”文档,
https://docs.gradle.org/current/userguide/upgrading_version_6.html#publishing_spring_boot_applications
只需将以下内容添加到build.gradle
文件中
jar
enabled = true
bootJar
classifier = 'application'
【讨论】:
【参考方案5】:如果您使用的是 gradle kotlin dsl,请在 build.gradle 中添加等效项。它对我有用
configurations
val elements = listOf(apiElements, runtimeElements)
elements.forEach element ->
element.get().outgoing.artifacts.removeIf it -> it.buildDependencies.getDependencies(null).contains(tasks.jar.get())
element.get().outgoing.artifact(tasks.bootJar.get())
【讨论】:
【参考方案6】:对于 Spring Boot 2.5.0+,此配置适用于发布嵌入式 jar、其源代码和 javadoc:
plugins
id 'maven-publish'
id 'java-library'
jar
enabled = false
java
withSourcesJar()
withJavadocJar()
publishing
publications
publication(MavenPublication)
artifact bootJar
from components.java
【讨论】:
以上是关于BootJar + MavenJar。工件不是由这个构建产生的的主要内容,如果未能解决你的问题,请参考以下文章
如何让 Teamcity Artifactory 插件在 Gradle 中调用 bootJar 而不是 Jar?