Maven发布插件失败:源代码文件被部署两次。

77
我们正在hudson上使用maven release插件来自动化发布过程。 release:prepare 已经正常工作。 当我们尝试执行 release:perform 时,它由于试图将源代码上传两次到仓库而失败。
我尝试过以下的解决方法:
  1. 从super pom中删除包含maven源代码插件的profile (没有起作用)
  2. 在Hudson上指定release的goals为 -P!attach-source release:prepare release:perform. 我认为这将排除执行源插件。(没有起作用).
  3. 尝试在super 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
任何关于此事的帮助都将不胜感激。

投票问题:http://jira.codehaus.org/browse/MSOURCES-8 - Vadzim
13个回答

93

尝试运行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" 是 attach-sources,这样它就与发布配置文件相同。然后这些部分将被合并。
最佳实践是要获得一致性,您需要在项目的根 POM 中配置此项,即在 build > pluginManagement 中进行配置,而不是在您的子 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>

3
类似博客文章:http://blog.peterlynch.ca/2010/05/maven-how-to-prevent-generate-sources.html请问您需要什么具体帮助? - Vadzim
谢谢,@Bae。我之前不知道effective-pom目标。你的回答帮助我找到了一整天都在解决的问题。 - Rob Johansen
3
我发现即使使用相同的配置,attach-sources 仍然被调用。有人知道原因吗?第640行: [INFO] [DEBUG] Goal: org.apache.maven.plugins:maven-source-plugin:3.0.1:jar (attach-sources)第660行: [INFO] [DEBUG] Goal: org.apache.maven.plugins:maven-source-plugin:3.0.1:jar-no-fork (attach-sources) - Floresj4
5
遇到了同样的问题,已经解决。我的pom文件中有一个使用目标为jar-no-fork的maven-source-plugin插件。但是,maven根pom文件也有相同目标的插件,只不过目标为jar。因此生成的effective-pom中包含了这两个目标,导致源码jar文件被重复尝试推送。一旦我在自己的pom中删除了jar-no-fork目标,只剩下默认的jar目标,构建就成功了。对于我的使用情况来说,无论是jar还是jar-no-fork都没有关系。 - codester
我在Jenkins构建中执行release:prepare release:perform时遇到了问题,以便发布到Nexus和问题是它做了两次,首先是artifact,第二个是sources-jar。这个答案帮助了我。+1 我看到有人提到回退到maven 3.0.5,但会出现一些https协议错误,所以选择了这个解决方案,并且在maven 3.6.3上运行良好。 - tibortru

37

我知道这个问题已经很老了,但它在今天的谷歌搜索中排名第一,所以我会提供适用于最近版本的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
在严肃地撞墙之后......是的,这是唯一可行的解决方案,谢谢!由于我们仍然使用JDK 6相当长的一段时间,并且Maven 3.3.+需要Java 7,所以回滚到Maven 3.2.2是唯一可以接受的选择。 - t0r0X
似乎这也是我的问题。自从Maven 3.6.1发布以来,这些问题仍未得到解决。 - EricS
对我来说有效,从3.6.1降级到3.0.5。 - Igor Baiborodine
3
2020年6月更新:应该在Maven 3.7.0版本中修复。 - chrisinmtown
1
2021年6月更新:应该在Maven 3.8.2版本中得到修复。顺便说一句,你能相信这个问题已经存在了多久吗? - chrisinmtown
显示剩余3条评论

11

我也碰到了类似的问题,仔细分析了一下。mvn release:perform 命令会读取 release.properties 文件, 然后在一个临时目录检出标签(tag),并在那里执行类似以下的操作:














/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,这对我起作用了。 - Igor Baiborodine

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>

我怀疑解决方案在这个答案。不同的插件似乎会调用jar目标或attach-sources执行。通过将我们的执行绑定到特定阶段,我们强制该插件仅在该阶段运行。

它帮助我理解问题出在maven-source插件上。我已经暂时禁用了它,现在它可以工作了。 - Enrico Giurin

5

当我运行时,这种情况发生在我身上。

mvn install deploy

我通过运行其他程序来避免这个问题。
mvn deploy

(这意味着安装)。在我的情况下,只有一个构件被尝试上传两次,那就是一个辅助构件(maven-jar-plugin被设置为在默认的构建过程中额外构建了一个辅助jar包)。


1

简述:

如果您无法修改父POM,禁用ID为attach-sources的执行即可解决此问题。

--

这个答案是对@Bae的回答的补充:

https://dev59.com/x2855IYBdhLWcg3wm1i3#10794985

我遇到了同样的问题,当运行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插件管理中覆盖执行?


我认为它可以工作。因为插件配置将默认合并。 目标将被合并,因此根据第一个答案的描述,将具有多个目标。 但是“phase”配置将被覆盖。最后,在执行部分中命名为“attach-sources”的配置将被新命名为“none”的阶段覆盖。因此,具有ID“attach-sources”的配置将不会绑定到任何构建生命周期。 - user3033075

0

我认为问题不在发布插件上,而是你将xxx-sources.jar附加了两次 - 这就是重复上传的原因。如果没有看到POM,很难说为什么会有重复的附件。尝试运行mvn -X并检查日志,看看谁又附加了xxx-source.jar

无论如何,在Nexus上一个好的解决方法是拥有一个分阶段存储库,您可以在其中多次上传发布 - 当一切准备就绪时,只需关闭/推广分阶段存储库即可。请参考Sonatype OSS setup进行示例。


0

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

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


0

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

检查后发现问题出在Jenkins脚本中。settings.xml被调用了两次,如下:

sh "mvn -s settings.xml clean deploy -s settings.xml deploy -U .....

这就导致了问题。更新了这一行代码,问题迎刃而解:

sh "mvn clean deploy -s settings.xml -U .....


0
父POM和子POM中的Maven插件不应该有执行。根据标准惯例,在插件管理部分定义所有带有执行/目标的插件。子POM不应重新定义上述细节,但只提到需要执行的插件(具有artifactId和version)。
我在具有以下父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>

而子 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 repo中重复安装。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接