在多模块Maven项目中更新模块版本号

427

我有一个多模块的Maven项目。我们打算将所有这些模块一起进行版本控制。但目前我在每个模块的pom.xml中硬编码了版本号,如下所示

<parent>
    <artifactId>xyz-application</artifactId>
    <groupId>com.xyz</groupId>
    <version>2.50.0.g</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.xyz</groupId>
<artifactId>xyz-Library</artifactId>
<version>2.50.0.g</version>

而主父模块具有以下配置

<modelVersion>4.0.0</modelVersion>
<groupId>com.xyz</groupId>
<artifactId>xyz-application</artifactId>
<version>2.50.0.g</version>
<packaging>pom</packaging>

3
你的问题陈述有误,会让真正使用多模块(“聚合”)POM的人感到困惑。从你的示例和答案中可以看出,你实际上是在谈论父POM,而不是多模块、聚合POM。请参阅https://maven.apache.org/pom.html#Aggregation。 - Garret Wilson
12个回答

812

使用versions:set命令来自versions-maven插件

mvn versions:set -DnewVersion=2.50.1-SNAPSHOT

它将调整多模块项目中的所有pom版本、父版本和依赖版本。

如果您犯了一个错误,请执行以下操作

mvn versions:revert

之后,或者

mvn versions:commit

如果你对结果满意,请注意:此解决方案假定所有模块都将聚合pom作为父pom使用,这在回答时被认为是标准情况。如果不是这种情况,请参考Garret Wilson的答案


7
如果有一种解决方案不需要你实际改变每个模块,那将会非常好。我唯一能想到的替代方法是始终使用父POM的快照版本。 - AmanicA
73
除了使用 versions:set 命令外,还可以通过指定 -DgenerateBackupPoms=false 参数来关闭该插件默认备份原始pom文件的功能。 - Maksim Sorokin
30
versions:commit的目的在于:“删除pom的初始备份,从而接受更改。” - Michael Laffargue
2
一个新的插件以不同的方式解决了这个问题:http://mojo.codehaus.org/flatten-maven-plugin/examples/example-multiple-versions.html - Stephan
1
@MichaelLaffargue mvn versions:commit 似乎会删除之前 pom.xml 生成的备份文件。 - Cris Rockwell
显示剩余17条评论

100

假设所讨论的项目不仅使用模块聚合,还使用了项目继承。实际上,这两个概念是不同的:

https://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Project_Inheritance_vs_Project_Aggregation

一些项目可能是模块的聚合,但聚合POM和被聚合模块之间没有父子关系。(可能根本没有父子关系,或者子模块可能使用单独的POM作为“父级”。)在这些情况下,给出的答案将不起作用。
经过阅读和实验,发现可以使用Versions Maven Plugin来更新聚合POM以及所有被聚合的模块;它是processAllModules选项。必须在聚合项目的目录中执行以下命令:
mvn versions:set -DnewVersion=2.50.1-SNAPSHOT -DprocessAllModules

Versions Maven插件不仅会更新所有包含模块的版本,还会更新模块间的依赖关系!这是一个巨大的胜利,将节省大量时间并防止各种问题。

当然,不要忘记提交所有模块的更改,您也可以使用相同的开关完成此操作:

mvn versions:commit -DprocessAllModules

你可以决定完全放弃备用POMS并在一个命令中完成所有操作:
mvn versions:set -DnewVersion=2.50.1-SNAPSHOT -DprocessAllModules -DgenerateBackupPoms=false

3
找到了秘密的开关:父级pom文件和模块的起始版本必须相同!我的父级pom文件以“1-SNAPSHOT”开头,而模块则以“1.0.0-SNAPSHOT”开头。 :) - SiKing
5
使用聚合工程时,聚合器的版本和子模块的版本不需要相同。(例如,聚合器的pom文件可能很少更改并可以保持特定版本,而各个子模块可以有自己的发布周期)。在使用versions:set插件时,需要指定的关键属性是-DoldVersion='*',在https://www.mojohaus.org/versions-maven-plugin/set-mojo.html上明确说明了在处理聚合项目时应该指定此属性。 - Matthew Wise
3
-DprocessAllModules 参数在什么情况下才会生效?它对我来说没有生效。 - Alex R
1
@Garret,你甚至假设聚合POM和子模块POM的版本必须相同! - Number945
1
实际上,它似乎只有在聚合器 POM 中的版本和所有子模块中的版本完全相同的情况下才能正常工作,否则它将无法更新它们。 - Kris
显示剩余3条评论

50

如果你想要完全自动化这个过程(即你想增加版本号而不需要知道当前版本号是什么),你可以这样做:

mvn build-helper:parse-version versions:set -DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.nextIncrementalVersion} versions:commit

7
谢谢,@Crummy,你救了我一天。 - Maksim Kostromin
2
https://www.mojohaus.org/build-helper-maven-plugin/parse-version-mojo.html - Se Song
或者您可以使用-DoldVersion='*' - Matthew Wise
2
很酷,谢谢!!带有 SNAPSHOT 的示例: mvn build-helper:parse-version versions:set -DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.nextIncrementalVersion}-SNAPSHOT versions:commit - oikonomopo

31

你可能需要查看Maven发布插件的release:update-versions目标。它将更新父级的版本以及其下所有模块的版本。


更新:请注意,上述是发布插件。如果您不打算发布,则可以使用versions:set

mvn versions:set -DnewVersion=1.2.3-SNAPSHOT

1
mvn version:set 不会影响模块。 - 9ilsdx 9rvj 0lo
可以的,我使用它。设置当前项目的版本,并基于该更改将其传播到任何必要的子模块。 - Nishant
好的,当反应堆构建在同一时间父级中时,它是有效的。当结构看起来不同的时候,这会让人感到困惑... - 9ilsdx 9rvj 0lo
1
mvn release:update-versions -DautoVersionSubmodules 对我来说很好用,即使我不进行发布 :-) - msa

11

我鼓励你阅读关于多模块(反应堆)构建的Maven 书籍

我特别指的是以下内容:

<parent>
    <artifactId>xyz-application</artifactId>
    <groupId>com.xyz</groupId>
    <version>2.50.0.g</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.xyz</groupId>
<artifactId>xyz-Library</artifactId>
<version>2.50.0.g</version>

应该进行更改。在此,要注意只有在父部分中定义的未定义版本。

<modelVersion>4.0.0</modelVersion>

<parent>
    <artifactId>xyz-application</artifactId>
    <groupId>com.xyz</groupId>
    <version>2.50.0.g</version>
</parent>
<groupId>com.xyz</groupId>
<artifactId>xyz-Library</artifactId>

这个链接更好了


11
找什么具体的东西? - Thorbjørn Ravn Andersen
2
赞同对于pom.xml文件的正确格式化提出建议,但我也同意(@ThorbjørnRavnAndersen)为此阅读整本书是过度杀伤力了。 :p - Priidu Neemre
12
遗憾的是,从父项目继承版本信息并不能减轻修改项目中所有pom文件的负担,因为它们都通过版本号引用父项目。 - Steven the Easily Amused
1
你可以使用versions-maven-plugin来处理所有这些事情,或者你可以使用maven-release-plugin,这样你就不需要手动处理了... - khmarbaise
仍然让我感到困惑的是,人们仍然会毫不考虑链接是否过期就在这里发布链接。这使得这个答案基本上没有用处。 - TheRealChx101

7

上面提供的解决方案对我们也有效,长时间以来一直起作用:

mvn versions:set -DnewVersion=2.50.1-SNAPSHOT

然而,它在昨天停止工作,我们发现它是由于versions-maven-plugin的最新bug引起的。

我们(临时)采用了更改parent/pom.xml文件的解决方法,如下所示:

--- jackrabbit/oak/trunk/oak-parent/pom.xml 2020/08/13 13:43:11 1880829
+++ jackrabbit/oak/trunk/oak-parent/pom.xml 2020/08/13 15:17:59 1880830
@@ -329,6 +329,13 @@
           <artifactId>spotbugs-maven-plugin</artifactId>
           <version>3.1.11</version>
         </plugin>
+        
+        <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>versions-maven-plugin</artifactId>
+          <version>2.7</version>
+        </plugin>
+        

5
更新主pom.xml和子模块的父版本:
要更新主pom.xml以及子模块的父版本:
mvn versions:set -DnewVersion=1.3.0-SNAPSHOT -N versions:update-child-modules -DgenerateBackupPoms=false

4

提示:
如果您的多模块Maven项目在主POM文件中使用项目版本作为属性,例如

<properties>
        <revision>1.0.0</revision> <!-- project version/revision -->
        ...
</properties>

在这种情况下,您可以使用set-property而不是set来提高项目版本:
示例:
mvn versions:set-property -Dproperty=revision -DnewVersion="2.0.0"  

mvn versions:commit

4

versions:update-child-modules听起来像是你需要的。你可以像之前提到的那样使用versions:set,但这是一种轻量级的方式来更新父模块的版本号。对于子模块,我认为你应该删除<version>定义,因为它们将继承父模块的版本号。


让子模块继承父模块的版本号是一个好的方法吗?如果只有子模块发生变化呢? - TheRealChx101
这假设根模块是父模块,但并非必须如此。 - Tinman

4

最好的方式是,由于你打算将模块捆绑在一起,所以可以在外层最顶级的pom.xml(父模块)中直接在<project>标签下指定<dependencyManagement>标签。它控制版本和组名。在你的单独模块中,只需要在你的pom.xml中指定<artifactId>标签即可。它会从父文件中获取版本。


我在pom.xml中找不到标签dependencyManagement。你是不是想要查看其他内容 - ArturoTena

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