如何更新子模块的版本?有很多类似这样的Stackoverflow问题,但我找不到适合这种情况的问题...如果这是重复的话会很喜欢。
考虑以下项目。
parent
--mod1
--mod2
在开发阶段开始时,我需要将父级和模块更新为相同的版本。如果父版本和模块的版本在整个版本中保持不变,那么我将只省略模块中的<version>
标记并执行versions:set -DnewVersion=1.1.1
以启动开发周期。但事实证明,模块不会以相同的版本结束循环。由于错误和修复只能实现那些带有错误的模块,因此会更新。例如,parent和mod2可能是版本1.1.1-RC1,但mod1可能是1.1.1-RC2。
因此我需要:
1)在模块中包含<version>
标记,以独立跟踪每个模块版本。
2)如果mod2需要mod1作为依赖项,我需要确保mod2引用最新版本的mod1。
这导致以下两个问题。
1)在循环开始时,如何在一个maven命令中将父模块和模块设置为相同的版本?我尝试了version:set -DnewVersion=1.1.1
,但这只更新了所有POM的父版本,而不是模块的版本。我也尝试了-N versions:update-child-modules
,但我认为我使用它是错误的,因为它什么也没做,只是跳过了所有模块。
2)这有点难,与上面的第2项相符。如何一步更新mod1的版本和mod2对mod1版本的引用?我知道如何分两步完成:
父母:
<properties>
<!-- update this manually if mod1's version no longer matches parent -->
<mod1.version>${project.version}</mod1.version>
</properties>
mod2 pom:
<dependency>
<groupId>com.xxx</groupId>
<artifactId>mod1</artifactId>
<version>${mod1.version}</version>
</dependency>
当mod1碰到1.1.1-RC2时,我更新父POM和mod1 POM以反映这一点。这是两个步骤。无论如何把它变成一步?
我的例子很小但在现实生活中有许多模块可以节省这些重要的时间,而且我很好奇。
答案 0 :(得分:5)
问题1)
管理应用程序生命周期和发布的最佳方法是使用发布插件。
正如您所知,Maven哲学是对配置的约定。 Maven约定是在开发期间使用快照版本(以-SNAPSHOT结尾的版本),并仅为版本分配非快照版本。
说你正在开发1.1.1版。在开发过程中,您只需使用1.1.1-SNAPSHOT。 Maven将负责快照的更新。如果使用工件存储库,则可以使用-U确保始终具有最新版本的快照。
当发布版准备就绪时,发布插件会生成并部署1.1.1版并使用新的开发版本更新POM,例如1.1.2-SNAPSHOT。
关于多模块项目,有两种情况:模块是相关的但是独立的(例如几个Web应用程序),或者它们是单个大型应用程序或库的模块,它们共享版本。你似乎对后者感兴趣。
在这种情况下,最好的方法是继承相同的父模块(也可能是root模块),包括其版本。您引用父组:artifact:version并且您没有为子项指定版本。通常你也会继承组,所以你的孩子pom可能看起来像:
<parent>
<groupId>com.mycompany.myproject</groupId>
<artifactId>myproject-parent</artifactId>
<version>1.1.1-SNAPSHOT</version>
<relativePath>../myproject-parent</relativePath>
</parent>
<artifactId>myproject-module1</artifactId>
现在你只需要在发布插件的帮助下照顾孩子指向正确的父版本。
为了帮助它了解孩子,您应该通过包含模块部分使您的父pom成为根pom,如下所示。
问题2) 我通常在父级中声明属性,其中包含可能引用的所有工件的所有版本。如果多个模块共享版本,则只需要一个属性。父母可以看起来像:
<groupId>com.mycompany.myproject</groupId>
<artifactId>myproject-parent</artifactId>
<version>1.1.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<myproject.version>1.1.1-SNAPSHOT</myproject.version>
</properties>
.......
<modules>
<module>../myproject-module1</module>
...
</modules>
儿童可以使用
引用其他模块<version>${myproject.version}</version>
使用LATEST声明依赖项是一种非常糟糕的做法。假设你为版本1.1.1执行此操作。现在您正在使用版本1.1.2-SNAPSHOT,并且您可能在本地仓库中安装了此版本的工件。
现在说出于某种原因你需要重建版本1.1.1,例如因为生产中的错误。您的构建将使用新版本。如果你很幸运,这将破坏构建。如果你不走运,它甚至可能不会被注意到生产。
最后但并非最不重要的是,有些人喜欢使用属性值来声明子版本。强烈建议不要这样做,并且会被maven报告为警告。我个人不会这样做。原因还与构建的可重现性以及maven假定发布版本永远不会改变这一事实有关。将模块版本外部调整并不是一个好主意。
编辑:
模块版本未对齐的情况。
实际上两种情况都可以混合使用。 例如,你可以拥有:
父
---的Component1
--- COMPONENT2
--- Component3
------ Comp3Module1
------ Como3Module2
------ Comp3Module3
父母和三个组件版本不同,组件3的三个模块共享其相同的版本。
问题1) 在这种情况下,每个模块的版本都是无关紧要的。 如前所述,使用属性指定模块版本是一个不好的方法,这也是我只能建议按字面指定版本的原因。 如前所述,要管理版本控制,最好的方法是使用发布插件,并将其与版本控制系统(如SVN)集成。 其他答案提供了如何使用它的详细信息,因此除非有要求,否则我不会进一步详细说明。
问题2) 对于共享相同版本的情况,推荐的方法是相同的,只需要您需要多个属性。 父母可以看起来像:
<properties>
<myproject.group>com.mycompany.myproject</myproject.group>
<component1.version>1.1.1-RC1</component1.version>
<component2.version>1.1.1-RC2</component2.version>
<component3.version>2.0.0</component3.version>
<properties>
然后,您可以使用依赖关系管理在父级中集中版本管理。
例如,在父pom中,
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>component1</artifactId>
<version>${component1.version}</version>
</dependency>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>component2</artifactId>
<version>${component2.version}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>comp3module1</artifactId>
<version>${component3.version}</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>comp3module1</artifactId>
<version>${component3.version}</version>
<type>ejb-client</type>
</dependency>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>comp3module2</artifactId>
<version>${component3.version}</version>
<type>war</version>
</dependency>
</dependencies>
</dependencyManagement>
现在,要引用任何其他模块中的任何模块,它就像:
一样简单<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>component1</artifactId>
</dependency>
<dependency>
<groupId>${myproject.group}</groupId>
<artifactId>comp3module1</artifactId>
<type>ejb-client</type>
</dependency>
从父级自动管理版本。你不需要将它们保存在儿童依赖中,这种依赖性也会变得不那么冗长。
答案 1 :(得分:1)
好的,这就是我想出来的。这是基于这篇continuous-releasing-of-maven-artifacts文章。
父POM:
<properties>
<!-- versions of modules -->
<main.version>1.0</main.version>
<revision>SNAPSHOT</revision> <!-- default revision -->
<Module1.revision>${revision}</Module1.revision>
<Module2.revision>${revision}</Module2.revision>
<Module3.revision>${revision}</Module3.revision>
<Module4.revision>${revision}</Module4.revision>
<Module5.revision>${revision}</Module5.revision>
<Module1.version>${main.version}-${Module1.revision}</Module1.version>
<Module2.version>${main.version}-${Module2.revision}</Module2.version>
<Module3.version>${main.version}-${Module3.revision}</Module3.version>
<Module4.version>${main.version}-${Module4.revision}</Module4.version>
<Module5.version>${main.version}-${Module5.revision}</Module5.version>
</properties>
具有项目间依赖性的子POM示例:
<groupId>com.xyz</groupId>
<artifactId>Module4</artifactId>
<packaging>jar</packaging>
<version>${Module4.version}</version>
<parent>
<groupId>com.xyz</groupId>
<artifactId>ParentProject</artifactId>
<version>1.0</version>
</parent>
<dependencies>
<dependency>
<groupId>com.xyz</groupId>
<artifactId>Module1</artifactId>
<version>${Module1.version}</version>
</dependency>
<dependency>
<groupId>com.xyz</groupId>
<artifactId>Module2</artifactId>
<version>${Module2.version}</version>
</dependency>
<dependency>
<groupId>com.xyz</groupId>
<artifactId>Module3</artifactId>
<version>${Module3.version}</version>
<type>jar</type>
</dependency>
<dependencies>
1)在循环开始时如何在一个maven命令中将父模块和模块设置为相同的版本?
你不再需要。父POM可以保持相同的版本,仅在父POM更改时才会更改。在这种情况下,您可以使用mvn version:set -DnewVersion=1.1.1
。但是你不需要采用这种方法。
相反,您可以使用属性main.version
动态设置版本。例如。 mvn clean deploy -Dmain.version=1.1.1
另外,为了强制动态传递版本号,您可以省略我在上面的父POM中包含的默认main.version
属性。
2)如何一步更新mod1的版本和mod2对mod1版本的引用?
这基本上归结为如何管理修订。如果我没有在mvn命令中设置revision
属性,那么所有模块都将使用SNAPSHOT
作为修订版。如果我将revision
属性设置为RC1
,则所有模块都将获得该修订。此外,如果我将revision
设置为RC1
但Module4.revision
设置为RC2
,则Module4将获得RC2,所有其他模块将获得RC1。这满足了客户端对每个模块进行动态修订的请求。
以下是一些例子:
mvn clean deploy -Dmain.version=1.1.1
将所有模块设置为版本1.1.1-SNAPSHOT
。 mvn clean deploy -Dmain.version=1.1.1 -Drevision=RC1
将所有模块设置为版本1.1.1-RC1
。mvn clean deploy -Dmain.version=1.1.1 -Drevision=RC1 -DModule4.revision=RC2
将所有模块设置为版本1.1.1-RC1
,但Module4除外,该模块设置为版本1.1.1-RC2
。必须提到一个警告。如果将依赖模块的版本(例如Module1)递增到RC2,则还必须递增使用它的所有模块的版本,例如,Module4也不能递增到RC2(或下一版本)。这是客户已经了解的内容,这也是我希望所有模块具有相同版本的原因。但我真的很喜欢它的动态。基本上,该版本现在通过命令行设置,不需要更新所需的POM文件。
答案 2 :(得分:0)
1)正如@rec所说,maven发布插件可以解决问题
$ mvn release:prepare -DautoVersionSubmodules=true
$ mvn release:perform
2)您可以定义从mod2到mod1的依赖关系,如:
<dependency>
<groupId>com.xxx</groupId>
<artifactId>mod1</artifactId>
<version>LATEST</version>
</dependency>
更多信息:How do I tell Maven to use the latest version of a dependency?
我测试了两种解决方案,但它确实有效!希望它可以帮助你:)