Maven 发布插件不更新依赖管理中的快照

Posted

技术标签:

【中文标题】Maven 发布插件不更新依赖管理中的快照【英文标题】:Maven Release Plugin not updating SNAPSHOTs in dependencyManagement 【发布时间】:2012-06-07 17:52:35 【问题描述】:

我有一个公司范围的父 pom,其中包含一个 <dependencyManagement> 部分,它定义了我的项目版本,应该在我的应用程序中使用,其中一些是 SNAPSHOT,有点像这样:

<dependencyManagement>
  <dependencies>
    ...
    <dependency>
      <groupId>my.group</groupId>
      <artifactId>myArtifact</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
    ...
  <dependencies>
</dependencyManagement>

当我在父 pom 上运行 release:prepare 时,这些 SNAPSHOT 不会被删除。结果是继承自父项的项目在发布时无法使用其版本。如何确保在发布时更新父 pom 的 &lt;dependencyManagement&gt; 部分?

我看到了这个问题:why does maven release plugin allow for SNAPSHOT version in dependency managment?,但提到的票声称在插件的早期版本中已修复。

Maven Release Plugin 2.3.1
Apache Maven 3.0.4 (r1232337; 2012-01-17 08:44:56+0000)
Java version: 1.6.0_31, vendor: Sun Microsystems Inc.
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"

【问题讨论】:

给定的依赖是你的reactor的一部分吗? 不,在这种情况下不是。父 pom 没有在其中声明任何模块,因为它用于许多不同的项目。这个想法是集中我们所有项目共有的东西,例如存储库、元数据等。这有什么不同吗? 那么,你真正的问题是什么? - 你不能发布你自己的项目? - 您想要 JIRA 中提到的插件条快照吗? 我可以很好地释放父级,它的&lt;dependencyManagement&gt; 部分中只有 SNAPSHOT。问题是,当我发布一个继承自它的项目时,它会继承这些 SNAPSHOT 版本——而发布插件并没有意识到这一点,导致发布不可靠。 【参考方案1】:

maven-release-plugin 只关心检查您的&lt;dependencies/&gt; 部分中是否有SNAPSHOT-s。 &lt;dependencies/&gt; 将由扩展此父级的所有模块继承。他们总是会在构建之前尝试解决这些依赖关系。

&lt;dependencies/&gt;&lt;dependencyManagement/&gt; 部分之间的区别在于后者只定义了将要使用的版本。也就是说,如果您在那里定义了SNAPSHOT-s,则发布插件根本不关心,除非该父项目是聚合器或聚合器的一部分,并且该父项目与聚合器一起作为一个整体发布。

同样,maven-release-plugin 不处理&lt;pluginManagement/&gt;。另外,我相信它仅在与 &lt;dependencies/&gt; 相关时才解决包含工件版本的 Maven 属性。

更糟糕的是——据我所知——如果依赖项/插件有SNAPSHOT 版本,如果它在&lt;*Management/&gt; 部分中,你甚至不会收到警告。

出于这个原因,我采用的方法是拥有一个带有 &lt;properties/&gt; 的父 POM,其中包含工件的版本。在发布之前,我使用 grep 扫描SNAPSHOT-s:

grep SNAPSHOT pom.xml

【讨论】:

我确实在父 pom 中的 &lt;properties&gt; 中定义了版本,然后在 &lt;dependencyManagement&gt; 部分中引用了这些版本。我希望在一个 pom 中将我们内部项目的所有版本定义为 SNAPSHOT,并将所有版本排除在我们的各种项目 pom 之外。然而,这依赖于父 pom 在 dependencyManagement 中指定发布版本,所以我想这不会起作用。我想我必须将版本信息移动到每个不同的项目中,这很遗憾。我想避免在发布过程中手动更改版本。 令我惊讶的是,当我发布一个从父级的&lt;dependencyManagement&gt; 部分继承版本的特定项目时,它不会抱怨快照。似乎如果在发布的 poms 中没有提到版本,那么发布插件只会让它们离开,而不是提示删除 SNAPSHOT。 我很遗憾&lt;dependencyManagement&gt; 的行为方式如此,但这似乎是设计使然,所以我接受了这个答案。感谢您的反馈! 不幸的是,有时,即使遵循约定的代码也有其局限性和不可预见的(在撰写本文时)用法。您可以随时在 JIRA 中提交更改请求或错误报告:jira.codehaus.org/browse/MRELEASE。【参考方案2】:

所以您正在尝试发布不属于您正在准备的构建的工件?如果你做一个 relase:perform,如果它们不存在,插件应该将哪些工件上传到存储库? (如果他们这样做,你为什么要放置快照版本?)。我认为正如@khmarbaise 所说,插件不会删除不属于你的反应器的快照(插件可能认为它们是第三方依赖项)。 这是一条评论,我将其作为答案,因为我还没有发布 cmets 的声誉...对不起,我的英语不好!

【讨论】:

是的,在这种情况下,我只发布了一个父工件,带有pom 包装。我希望此时上传的唯一工件是父 pom。在实际发布包含特定代码的项目时,它将继承自已发布的父项目,因此使用其&lt;dependencyManagement&gt; 部分中定义的版本;如果它们包含 SNAPSHOT,那么我的版本处于可疑状态,我不能依赖它在将来可以重复使用。 作为一种解决方法,如果发布的目的只是替换 dependencyManagement 上的 SNAPSHOT 并提交给 SCM,您应该尝试仅手动执行该过程(或者更好地进行批处理),不要手动更改每个项目的版本,来吧不要放弃!尝试这样的事情(在 .bat 文件中): sed -i 's/-SNAPSHOT//g' pom.xml; cvs 提交 pom.xml。您可以使用 GnuWin 来实现 sed 功能,或者更好的是,开始使用 linux!

以上是关于Maven 发布插件不更新依赖管理中的快照的主要内容,如果未能解决你的问题,请参考以下文章

依赖管理中的依赖与 Maven 版本插件中的依赖

关于maven中的快照版本(snapshot)与正式版本(release)解析。

《Maven实战》笔记-9-版本管理

maven中snapshot快照库和release发布库的区别和作用

maven正式版本和快照版本的区别

Intellij IDEA Maven 插件 - 管理依赖项