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>

【讨论】:

被否决-这是一种大锤方法。实际上,只有 false 是解决问题所必需的,但是您完全关闭了源工件,并跳过了测试——这就像关闭所有编译器警告一样,因为它们会惹恼您。另外,为了完整起见,我想看看“useReleaseProfile”的作用以及它为什么有用的解释。 我也反对。跳过测试永远不是正确的答案。在我的例子中,有效的 POM 表明我们的一个项目实际上有两次部署目标的执行。解决方案是删除无关的执行。【参考方案3】:

尝试运行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>

我现在将 &lt;useReleaseProfile&gt;false&lt;/useReleaseProfile&gt; 行添加到所有 POM 中,看起来现在发布工作没有错误消息。

【讨论】:

或者,添加 useReleaseProfile=false 作为属性。 为我工作了 3.6.1 版。【参考方案5】:

我遇到了同样的问题。基本上,当工件被发送到 Nexus 两次时,就会发出错误消息。这可能是同一个 Nexus 存储库的两次,甚至是同一个 Nexus 中不同的存储库。

但是,这种错误配置的原因可能会有所不同。在我的情况下,工件在 Jenkins 的 mvn clean deploy 构建步骤中正确上传,但在尝试第二次部署时失败。第二次部署是在 Jenkins 后期构建步骤“在 Maven 存储库中发布工件”中配置的。

【讨论】:

【参考方案6】:

我已经为这个问题苦苦挣扎了一段时间,终于能够在我们的基础架构中解决它。这里的答案对我没有帮助,因为我们没有多次执行源插件目标并且配置对我们来说似乎很好。

我们确实错过了将源插件的执行绑定到一个阶段。扩展 Bae 的示例,包括行 &lt;phase&gt;install&lt;/phase&gt; 到执行解决了我们的问题:

<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 中删除 &lt;executions&gt; 解决了这个问题。 有效的 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 是分类器)。

    installeddeployedreleased 文件的名称实际上是根据这些坐标构建的。它与您在目标目录中看到的文件名不同。这就是为什么您的本地构建看起来不错,但您的发布会失败。

    愚蠢的元素只决定本地构建工件的名称,不参与其余部分。这是一个完全的红鲱鱼。

总结总结: 来自 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 发布插件执行两次测试

Jenkins部署Spring boot项目失败

maven deploy 400失败,二次上传maven source.jar包

maven deploy 400失败,二次上传maven source.jar包

maven deploy 400失败,二次上传maven source.jar包

maven deploy 400失败,二次上传maven source.jar包