Maven 发布插件失败:源工件被部署两次
Posted
技术标签:
【中文标题】Maven 发布插件失败:源工件被部署两次【英文标题】:Maven release plugin fails : source artifacts getting deployed twice 【发布时间】:2011-05-14 04:23:17 【问题描述】:我们正在使用 hudson 上的 maven 发布插件并尝试自动化发布过程。 发布:准备工作正常。当我们尝试执行 release:perform 时,它失败了,因为它尝试将源构件两次上传到存储库。
我尝试过的事情,
-
从超级 pom 中删除包含 maven 源插件的配置文件(不起作用)
将 hudson 上的发布目标指定为 -P!attach-source release:prepare release:perform。我认为这会将源插件排除在执行之外。 (没用)。
尝试将插件阶段指定为超级 pom 中某个不存在的阶段。(无效)
尝试指定插件配置,forReleaseProfile 为 false。 (你猜怎么着??也没有用)
它仍然会吐出这个错误。
[INFO] [DEBUG] Using Wagon implementation lightweight from default mapping for protocol http
[INFO] [DEBUG] Using Wagon implementation lightweight from default mapping for protocol http
[INFO] [DEBUG] Checking for pre-existing User-Agent configuration.
[INFO] [DEBUG] Adding User-Agent configuration.
[INFO] [DEBUG] not adding permissions to wagon connection
[INFO] Uploading: http://xx.xx.xx.xx:8081/nexus/content/repositories/releases//com/yyy/xxx/hhh/hhh-hhh/1.9.40/hhh-hhh-1.9.40-sources.jar
[INFO] 57K uploaded (xxx-xxx-1.9.40-sources.jar)
[INFO] [DEBUG] Using Wagon implementation lightweight from default mapping for protocol http
[INFO] [DEBUG] Using Wagon implementation lightweight from default mapping for protocol http
[INFO] [DEBUG] Checking for pre-existing User-Agent configuration.
[INFO] [DEBUG] Adding User-Agent configuration.
[INFO] [DEBUG] not adding permissions to wagon connection
[INFO] Uploading: http://xx.xxx.xx.xx:8081/nexus/content/repositories/releases//com/xxx/xxxx/xxx/xxx-xxx/1.9.40/xxx-xxx-1.9.40-sources.jar
[INFO] [DEBUG] Using Wagon implementation lightweight from default mapping for protocol http
[INFO] [INFO] ------------------------------------------------------------------------
[INFO] [ERROR] BUILD ERROR
[INFO] [INFO] ------------------------------------------------------------------------
[INFO] [INFO] Error deploying artifact: Authorization failed: Access denied to: http://xx.xxx.xx.xx:8081/nexus/content/repositories/releases/com/xxx/xxx/xxx/xxx-config/1.9.40/xxx-xxx-1.9.40-sources.jar
我们将非常感谢任何有关此方面的帮助。
【问题讨论】:
问题投票:jira.codehaus.org/browse/MSOURCES-8 【参考方案1】:我认为问题不在发布插件中,我认为您已将xxx-sources.jar
附加了两次 - 这就是重复上传的原因。没有看到 POM 就很难判断为什么会有重复的附件。尝试运行mvn -X
并再次检查日志以了解谁附加了xxx-source.jar
。
无论如何,在 Nexus 上一个很好的解决方法是拥有一个临时存储库,您可以在其中多次上传版本 - 当一切准备就绪时,您只需关闭/升级临时存储库。以Sonatype OSS setup 为例。
【讨论】:
【参考方案2】:我使用 releaseProfile=false 配置了 maven 发布插件,并且不执行源工件配置文件。哪个成功了。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.1</version>
<configuration>
<arguments>-P!source-artifacts</arguments>
<useReleaseProfile>false</useReleaseProfile>
<goals>-Dmaven.test.skip=true deploy</goals>
</configuration>
</plugin>
</plugins>
</build>
【讨论】:
被否决-这是一种大锤方法。实际上,只有尝试运行mvn -Prelease-profile help:effective-pom
。
你会发现maven-source-plugin
有两个执行部分
输出将如下所示:
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.0.4</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
要解决此问题,请查找您使用过maven-source-plugin
的所有位置,并确保使用“id”附加源,使其与发布配置文件相同。然后这些部分将被合并。
最佳实践表明,要获得一致性,您需要在项目的根 POM 中的 build > pluginManagement 和 NOT 的子 pom 中进行配置。在子 pom 中,您只需在 build > plugins 中指定要使用 maven-source-plugin 但您不提供任何执行。
在根 pom.xml 中:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<!-- This id must match the -Prelease-profile id value or else sources will be "uploaded" twice, which causes Nexus to fail -->
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
在子 pom.xml 中:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
</plugins>
</build>
【讨论】:
类似博文:blog.peterlynch.ca/2010/05/… 谢谢,@Bae。我不知道effective-pom
目标。您的回答帮助我找到了一个我整天都在努力解决的问题。
我发现 attach-sources
仍然被称为 switch 具有相同的配置。有人有线索吗? Line 640: [INFO] [DEBUG] Goal: org.apache.maven.plugins:maven-source-plugin:3.0.1:jar (attach-sources)
Line 660: [INFO] [DEBUG] Goal: org.apache.maven.plugins:maven-source-plugin:3.0.1:jar-no-fork (attach-sources)
遇到了同样的问题。解决了。我的 pom 文件有 maven-source-plugin,目标是 jar-no-fork。但是 maven root pom 文件具有相同的插件,目标是 jar。因此,生成的有效 pom 具有两个目标。这会导致重复尝试推送 sources.jar。一旦我在我的 pom 中删除了 jar-no-fork 目标,默认的 jar 目标是唯一剩下的,并且构建成功。对于我的使用来说,它是 jar 还是 jar-no-fork 并不重要。
我在执行发布时遇到问题:准备发布:从 jenkins 构建执行以发布到 nexus,问题是它执行了两次,第一次是工件,第二次是源 jar。这个答案帮助了我。 +1 我看到人们提到恢复到 maven 3.0.5 但这会带来一些 https 协议错误,所以选择了这个解决方案,它适用于 maven 3.6.3【参考方案4】:
刚遇到同样的问题,我稍微分析了一下。 mvn release:perform
评估 release.properties 文件,然后在临时目录中检出标签并在那里调用类似
/usr/bin/mvn -D maven.repo.local=... -s /tmp/release-settings5747060794.xml
-D performRelease=true -P set-envs,maven,set-envs deploy
我试图重现这个——手动检查了release:prepare
产生的标签并调用了这个:
mvn -D performRelease=true -P set-envs,maven,set-envs deploy
我得到了相同的结果:它试图上传 -sources.jar 两次。
正如qualidafial 在评论中指出的那样,设置performRelease=false
会省略同一文件的两个附件之一。
我真的不知道deploy plugin(或任何其他插件)如何使用此属性。
我们可以将此参数作为配置提供给 maven-relase-plugin:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<useReleaseProfile>false</useReleaseProfile>
</configuration>
</plugin>
</plugins>
</build>
我现在将 <useReleaseProfile>false</useReleaseProfile>
行添加到所有 POM 中,看起来现在发布工作没有错误消息。
【讨论】:
或者,添加 useReleaseProfile=false 作为属性。 为我工作了 3.6.1 版。【参考方案5】:我遇到了同样的问题。基本上,当工件被发送到 Nexus 两次时,就会发出错误消息。这可能是同一个 Nexus 存储库的两次,甚至是同一个 Nexus 中不同的存储库。
但是,这种错误配置的原因可能会有所不同。在我的情况下,工件在 Jenkins 的 mvn clean deploy 构建步骤中正确上传,但在尝试第二次部署时失败。第二次部署是在 Jenkins 后期构建步骤“在 Maven 存储库中发布工件”中配置的。
【讨论】:
【参考方案6】:我已经为这个问题苦苦挣扎了一段时间,终于能够在我们的基础架构中解决它。这里的答案对我没有帮助,因为我们没有多次执行源插件目标并且配置对我们来说似乎很好。
我们确实错过了将源插件的执行绑定到一个阶段。扩展 Bae 的示例,包括行 <phase>install</phase>
到执行解决了我们的问题:
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.0.4</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>install</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
我怀疑解决方案在于这个答案here;不同的插件似乎正在调用 jar 目标/附加源执行。通过将我们的执行绑定到某个阶段,我们强制我们的插件只在这个阶段运行。
【讨论】:
它帮助我了解问题出在 maven-source 插件中。我暂时禁用了它,现在它可以工作了【参考方案7】:父和子 pom 中的 Maven 插件不应执行。根据标准约定,在插件管理部分的父 pom 中定义所有具有执行/目标的插件。子 pom 不应重新定义上述细节,而仅提及需要执行的插件(带有 artifactId 和版本)。
我在父 pom 的 maven-assembly-plugin 上遇到了类似的问题,如下所示:
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptors>
<descriptor>src/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
而 Child pom 的 maven-assembly-plugin 如下:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<finalName>xyz</finalName>
<descriptors>
<descriptor>src/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>xyz-distribution</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
从子 pom 中删除 <executions>
解决了这个问题。
有效的 pom 执行了 2 次,导致重复安装到 Nexus 存储库。
【讨论】:
【参考方案8】:我知道这个问题很老,但它是谷歌今天的第一名,所以我会添加适合最新版本 maven 3 的答案。
症状是在使用某些版本的 maven 3 进行发布构建时,源代码和 javadoc jar 被部署了两次。如果您使用 maven 将工件部署到仅允许上传发布工件的 Sonatype Nexus 存储库一次(这是完全合理的行为),当第二次上传尝试被拒绝时构建失败。啊!
Maven 版本 3.2.3 至 3.3.9 存在错误 - 请参阅 https://issues.apache.org/jira/browse/MNG-5868 和 https://issues.apache.org/jira/browse/MNG-5939。这些版本在发布时会生成和部署源代码和 javadoc jar 两次。
如果我正确阅读了 Maven 问题跟踪器,那么在撰写本文时,这些错误还没有计划修复(烧毁的 3.4.0 版本可能影响了这些)。
我的简单解决方法是回退到 Maven 版本 3.2.1,而不是对我的 pom 进行复杂的调整。
【讨论】:
在严重的头部撞到墙上之后......是的,这是唯一可行的解决方案,THX!由于我们仍然锁定 JDK 6 一段时间,而 Maven 3.3.+ 需要 Java 7,回滚到 Maven 3.2.2 是唯一可接受的选择。 似乎也是我的问题。从 Maven 3.6.1 开始,这些问题仍未解决。 2019 年仍未修复,解决方法仍然有效。你可以在这里找到官方包:apache.org/dist/maven/maven-3 为我工作,从 3.6.1 降级到 3.0.5。 2020 年 6 月更新:应该在 Maven 版本 3.7.0 中修复【参考方案9】:FWIW 这个问题在一段时间内破坏了我们的构建,而答案并非如此。 相反,我愚蠢地在 maven-assembly-plugin 中将看似无害的 appendAssemblyId 设置为 false,以用于与我们的主要工件附加(读取部署、发布)的工件。例如:
<execution>
<id>ci-groovy-distrib</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>my-extra-assembly</descriptorRef>
</descriptorRefs>
<!-- This is the BUG: the assemblyID MUST be appended
because it is the classifier that distinguishes
this attached artifact from the main one!
-->
<appendAssemblyId>false</appendAssemblyId>
<!-- NOTE: Changes the name of the zip in the build target directory
but NOT the artifact that gets installed, deployed, releaseed -->
<finalName>my-extra-assembly-$project.version</finalName>
</configuration>
</execution>
总结:
程序集插件使用 assemblyId 作为工件的 分类器,因此它是 maven 术语中唯一 GAV 坐标的重要部分(实际上它更像 GAVC 坐标 - C 是分类器)。
installed、deployed 或 released 文件的名称实际上是根据这些坐标构建的。它与您在目标目录中看到的文件名不同。这就是为什么您的本地构建看起来不错,但您的发布会失败。
愚蠢的元素只决定本地构建工件的名称,不参与其余部分。这是一个完全的红鲱鱼。
总结总结: 来自 Nexus 的 400 错误是因为我们额外附加的工件被上传到主工件之上,因为它与主工件具有相同的名称,因为它与主工件具有相同的 GAVC 坐标,因为我删除了唯一的区别坐标:从 assemblyId 自动派生的分类器。
调查发现这是一条漫长而曲折的道路,答案一直在 maven-assembly 的文档中:
appendAssemblyId
布尔值
设置为 false 以排除程序集 ID 从程序集最终名称,并创建结果程序集 没有分类器的工件。 因此,装配工件具有 与当前Maven项目的打包格式相同将替换 此主要项目工件的文件。
默认值为:true。 用户属性为:assembly.appendAssemblyId。
来自http://maven.apache.org/plugins/maven-assembly-plugin/single-mojo.html#attach
加粗的是我的。文档应该在此处有一个大的闪烁警告:“将此设置为 false 并放弃所有希望”
我从这个答案中得到了一些关于另一个问题的帮助maven-assembly-plugin: How to use appendAssemblyId tunaki 那里的解释确实很有帮助。
【讨论】:
【参考方案10】:跑步时发生在我身上
mvn install deploy
我通过运行避免了这个问题
mvn deploy
(这意味着安装)。在我的情况下,只有一个工件被尝试上传两次,这是一个辅助工件(maven-jar-plugin 被设置为构建一个辅助 jar,除了由 default-jar 执行构建的那个)。
【讨论】:
【参考方案11】:TL;DR
如果您无法修改父 pom,则使用 id attach-sources
禁用执行可以解决此问题。
--
此答案是对@Bae 答案的补充:
https://***.com/a/10794985/3395456
我的问题也是一样,运行mvn -Prelease-profile help:effective-pom
时,maven-source-plugin有两个执行部分
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.0.4</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
投票最多的答案只是推荐了一个最佳实践来删除未命名(匿名)execution
,以避免重复绑定。但是如果我无法删除它,因为我无法更改父 pom 怎么办?
有一种方法可以禁用execution
,不是匿名的,而是id 为attach-source
的。它也适用于两次上传xx-javadoc.jar
。
所以在我的pom.xml
下,我可以通过禁用 id attach-source
的执行来明确覆盖插件设置。
<!-- Fix uploading xx-source.jar and xx-javadoc.jar twice to Nexus -->
<!-- try to disable attach-sources, attach-javadocs execution (bind its phase to none) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>none</phase>
</execution>
</executions>
<inherited>true</inherited>
</plugin>
参考资料: Is it possible to override executions in maven pluginManagement?
【讨论】:
我认为它有效。因为插件配置默认会被合并。目标将被合并,因此如第一个答案所述,将有多个目标。但是phase
配置将被覆盖。最后,执行部分中名为 attach-sources
的配置将被名为 none
的新阶段覆盖。因此 ID 为 attach-sources
的配置不会绑定到任何构建生活方式。【参考方案12】:
我遇到了类似的问题。工件被部署了两次,结果构建失败。
检查并发现问题出在 Jenkins 脚本中。 settings.xml 被调用了两次。喜欢:
sh "mvn -s settings.xml clean deploy -s settings.xml deploy -U .....
导致问题的原因。 更新了这一行,它就像一个魅力:
sh "mvn clean deploy -s settings.xml -U .....
【讨论】:
【参考方案13】:nexus thix 配置为我工作
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<useReleaseProfile>false</useReleaseProfile>
</configuration>
</plugin>
【讨论】:
以上是关于Maven 发布插件失败:源工件被部署两次的主要内容,如果未能解决你的问题,请参考以下文章
maven deploy 400失败,二次上传maven source.jar包
maven deploy 400失败,二次上传maven source.jar包