Maven版本插件失败:源工件被部署两次


68

我们在hudson上使用了Maven发布插件,并试图实现发布过程的自动化。发布:准备工作正常。当我们尝试执行release:perform时,它会失败,因为它尝试将源工件两次上载到存储库。

我尝试过的事情

  1. 从超级pom中删除确实包含maven源插件的配置文件(不起作用)
  2. 在hudson上将发布目标指定为-P!attach-source release:prepare release:perform。我认为这将使源插件无法执行。(不工作)。
  3. 尝试将插件阶段指定为超级pom中某个不存在的阶段。(无效)
  4. 尝试将插件配置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

任何对此的帮助将不胜感激。


Answers:


79

尝试跑步 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中而不是在子poms中进行配置。在子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>

3
类似的博客文章:blog.peterlynch.ca/2010/05/...
Vadzim

谢谢@裴 我没有意识到effective-pom目标。您的回答帮助我找到了我每天都在努力解决的问题。
罗伯·约翰森

1
我发现该attach-sources配置仍称为交换机。有人知道吗? 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)
Floresj4

4
有同样的问题。解决了。我的pom文件具有以jar-no-fork为目标的maven-source-plugin,但是maven根pom文件具有以jar为目标的相同插件。因此,生成的有效pom具有两个目标。这将导致重复尝试推送sources.jar。一旦我删除了pom中的jar-no-fork目标,默认的jar目标就是仅有的一个,构建成功。对于我的用法,它是罐子还是罐子无叉子都没关系。
codester

为了发布到联系,我在jenkins build中执行performin release:prepare release:perform时遇到问题,问题是它执行了两次,第一次是针对工件-jar,第二次是针对sources-jar。这个答案帮助了我。+1我看到有人提到恢复到Maven 3.0.5,但这会带来一些https协议错误,因此选择了此解决方案,它适用于maven 3.6.3
tibortru

31

我知道这个问题很旧,但是今天它在Google排名中排名第一,所以我将添加适用于最新版本的Maven 3的答案。

症状是,在使用某些版本的maven 3进行发布构建时,源和Javadoc jar会被部署两次。如果您正在使用maven将工件部署到Sonatype Nexus存储库,该存储库仅允许将发布工件上传一次(是完全合理的行为),当第二次上传尝试被拒绝时,构建将失败。啊!

Maven版本3.2.3至3.3.9有错误-请参阅https://issues.apache.org/jira/browse/MNG-5868https://issues.apache.org/jira/browse/MNG-5939。发行时,这些版本会两次生成并部署源代码和javadoc jar。

如果我正确阅读了Maven问题跟踪器,那么在撰写本文时,这些错误尚未计划修复(已刻录的3.4.0版本可能会影响这些错误)。

除了对pom进行复杂的调整之外,我的简单解决方法是退回到Maven 3.2.1版。


2
在头部严重撞墙后...是的,这是唯一可行的解​​决方案,THX!由于我们仍然在JDK 6上锁定了一段时间,并且Maven 3.3。+需要Java 7,回滚到Maven 3.2.2是唯一可接受的选择。
t0r0X16

似乎也是我的问题。从现在的Maven 3.6.1开始,这些问题仍未解决。
EricS

在2019年仍未修复,解决方法仍然有效。您可以在此处找到官方软件包:apache.org/dist/maven/maven-3
leondepeon

为我工作,从3.6.1降级为3.0.5。
伊戈尔·伯伯罗汀

2
2020年6月更新:应该已在Maven版本3.7.0中修复
chrisinmtown

9

遇到同样的问题,我进行了分析。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插件(或任何其他插件)如何使用此属性。

我们可以将此参数作为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添加为属性。
JRA_TLL

为我工作的版本3.6.1。
伊戈尔·伯伯罗汀

4

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

我们错过的是将源插件的执行绑定到一个阶段。通过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>

我怀疑的解决办法在于这个答案在这里; 不同的插件似乎正在调用jar目标/ attach-sources执行。通过将执行绑定到某个阶段,我们强制插件仅在此阶段运行。


它帮助我理解了问题出在maven-source插件中。我暂时将其禁用,现在可以使用
Enrico Giurin

3

跑步时发生在我身上

mvn install deploy

我通过运行来避免了这个问题

mvn deploy

(这意味着安装)。在我的情况下,仅尝试将一个工件上载两次,这是一个辅助工件(除了通过默认jar执行构建的对象之外,还设置了maven-jar-plugin来构建一个辅助jar)。


0

我不认为该探针位于发布插件中,我认为您已经获得了xxx-sources.jar两次附件-这就是重复上传的原因。为什么看不到POM很难说明重复的附件。尝试运行mvn -X并检查日志中是否xxx-source.jar还有其他人。

无论如何,在Nexus上一个不错的解决方法是拥有一个登台存储库,您可以在其中上载几次发行版本-当一切准备就绪后,您只需关闭/推广登台存储库即可。有关示例,请检查Sonatype OSS设置


0

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

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


0

父子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>

<executions>从子pom中删除该问题已解决。有效pom执行了2次执行,导致重复安装到Nexus repo。


0

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>

综上所述:

  1. 程序集插件将assemblyId用作 工件分类器,因此,它是maven术语中唯一GAV坐标的重要组成部分(实际上,它更像GAVC坐标-C是分类器)。

  2. 实际上,安装部署发布的文件的名称是根据这些坐标构建的。它与您在目标目录中看到的文件名不同。这就是为什么您的本地版本看起来不错,但是您的发布将失败的原因。

  3. 愚蠢的元素仅确定本地构建工件名称,其余部分不起作用。这是完全的红鲱鱼。

总结总结: 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的答案中获得了一些帮助:如何使用appendAssemblyId tunaki 的解释确实很有帮助。


0

TL; DR

attach-sources如果您不能修改父poms,则禁用具有id的执行可解决此问题。

-

此答案是@Bae答案的补充:

https://stackoverflow.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>

参考: 是否可以在maven pluginManagement中覆盖执行?


0

我遇到了类似的问题。工件被部署了两次,结果构建失败。

检查并发现问题出在Jenkins脚本中。settings.xml被调用了两次。喜欢:

sh“ mvn -s settings.xml干净部署-s settings.xml部署-U .....

导致问题的原因。更新了此行,它就像一个魅力:

sh“ MVN干净部署-s settings.xml -U .....


-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>

4
不赞成投票-这是大锤的方法。解决此问题实际上只需要<useReleaseProfile> false </ useReleaseProfile>,但是您将完全关闭源工件,并跳过测试-就像关闭所有编译器警告一样,因为它们会烦扰您。另外,出于完整性考虑,我想解释一下“ useReleaseProfile”的功能及其作用。
qualidafial 2011年

我也在投票。跳过测试永远不是正确的答案。以我为例,有效的POM表明我们的一个项目实际上执行了两次部署目标。解决方案是删除多余的执行。
Rob Johansen 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.