Maven:多模块项目和版本控制

25

在使用Maven创建多模块项目时,软件版本控制和最佳实践是什么?

我的意思是,在多模块项目中,版本控制的最佳方法是什么?使用单个版本来管理所有模块(在顶层项目中定义),还是为每个模块使用一个版本(在每个模块的POM文件中定义)?还有其他我可能忽略的方法吗?每种方法的优缺点是什么?

一般来说,不同的模块会一起发布(可能共享相同的版本号)吗?

谢谢


嗨,Mickel,我在多模块项目中遇到了一些问题,你能帮我解决一下吗? - Subodh Joshi
@subodh 你好,你可以在StackOverflow上提出问题并发布,我会尽力帮助你。 - manash
嗨,我在这里添加了一个问题:http://stackoverflow.com/questions/13392915/maven-web-module-not-running-from-inside-eclipse/13392978#13392978 - Subodh Joshi
4个回答

7
说实话,这取决于你想做什么。多模块项目有多种创建原因之一是你只需要部署已更改的模块,而不是所有模块。
可以这样想:如果你有一个非多模块项目,而且你只需要改变服务层中的一行代码,你必须重新构建整个项目并重新部署所有代码...即使只有你的服务层发生了改变。
使用多模块项目,您可以重新生成项目并仅部署更改的服务层,从而降低风险,并确保只有您的服务模块发生了更改。
使用多模块项目还有许多好处,但我在此没有列出,不过不将模块的版本号保持同步肯定是有巨大好处的。构建项目时,请考虑将其部署到存储所有兼容的JAR文件的存储库中(每次构建都会创建具有父级POM版本号的新文件夹)。这样,您就不需要保留有关哪些JAR文件兼容的文档,它们只是带有构建编号一起部署的所有文件。

1
是的,但我也可以为每个模块定义一个独立的Maven项目,而不使用Maven的多模块功能。这有什么区别? - manash
一个非常有效的问题。其他人在StackOverflow上也提出了同样的问题,并且有一些不错的答案(链接在末尾)。请记住,Maven是完成工作的许多方式之一(在Maven中做同样的事情有很多方法...只取决于哪种方法适合您)。链接:https://dev59.com/gVnUa4cB1Zd3GeqPYC97 - vinnybad
@MickaelMarrache:区别在于这些模块彼此依赖,如果我重构某个依赖项中的内容,我只需要提交一个更改。同样适用于发布 - 构建服务器可以测试每个提交是否像这样一起工作(我承认,我还没有集成测试,但我也会将其作为模块添加)。因此,我的代码始终保持一致。 - rudi

5

我自己也曾经为这个问题寻找解决方案,versions-maven-plugin正是我需要的。我不喜欢release插件与SCM系统的交互。versions插件正好满足我们的需求:它在项目的所有pom文件中设置了一个新的版本号:

mvn versions:set -DnewVersion=2.0.0

然后我可以进行提交、标记和官方构建服务器的构建...
编辑:
版本插件取决于maven多模块项目的组织方式:因此,在复杂的多模块项目中,它通常不会更新所有POM文件。我发现使用sed和find更加可靠。
sed -i 's/1.0.0-SNAPSHOT/1.0.0-RC1/g' `find . -name 'pom.xml'`

4
通常情况下,您会创建一个多模块项目,因为您认为各个模块是整体的一部分。也许是客户端、控制器和服务模块,或者是带有服务的UI模块。
无论如何,让各个模块的版本号保持同步是有意义的。但是,Maven并没有强制执行这一规则。
至于您的问题:
“不同的模块是否一起发布(可能共享相同的版本号)?”
我想应该是这样的。这就是将其作为多模块项目的原因之一。否则,您可以将模块作为独立的项目。
当然,这种情况充满了边缘案例和例外。

1
如果只修改了一个模块怎么办?以一个包含 GUI 层、控制器层和数据访问层的三层项目为例,这三个层次是单个项目的模块。但在某些情况下,仅更改数据访问层(因为使用了抽象),而没有更改控制器。在这种情况下,为什么要发布所有三个模块呢?另外,即使两个模块没有被更改,也为什么要给所有模块一个新版本呢? - manash
2
@MickaelMarrache,让我从我的回复的最后一行开始引用:“......这是充满边缘情况和异常的东西。”我们可以就此话题进行无休止的辩论。我考虑的事情是,我是否可以轻松地为我的产品的任何发布版本重新创建开发环境。为什么?这样我就可以重现任何错误并修复它们。 - Sri Sankaran
1
@Michael 这种推理很容易变得荒谬:你总是可以争论一个特定的代码包应该被进一步拆分“因为其中一部分可能会改变,但另一部分可能不会”。即使只修改了一个子项目:它们所有的版本号都会增加。在我看来,多模块项目非常有用,因为你可以构建仅包含你正在进行更改的最小实用代码单元,但当到达发布时间时,你可以使用顶级项目来生成可安装的二进制文件。 - Tomislav Nakic-Alfirevic

0

我在我正在工作的项目中遇到了同样的问题。我决定使用单独的版本,即使只有父POM的依赖关系需要更新,如果一些受管理的依赖项发生更改。(大多数情况下就像@vinnybad描述的那样)

两个补充

exists-maven-plugin

通过使用"org.honton.chas.exists-maven-plugin",只有实际更改的模块才会被部署到存储库中,这真的很棒,因为仅当某个服务发生更改时,相应的Docker镜像才会被发布。这避免了将不同但未更改的版本“污染”镜像存储库。

版本控制

"分离版本"方法的一个主要缺点是版本控制方面的问题:

  • 我的项目当前版本是什么?
  • 哪些模块版本彼此兼容?(即使它们没有直接依赖于彼此,一个模块确实依赖于另一个模块所做的事情,例如它们共享数据库架构)
为了解决这个问题,我将所有模块版本都放入父POM的依赖管理部分,即使没有其他模块依赖它们。一个“集成测试”模块可以通过依赖于所有模块来解决这个问题 - 当然还要一起测试它们。
这样一来,我就会被“强制”更新父POM,因为它引用了发布的模块版本。这样,父POM将具有“领先”的版本,并在依赖管理块状态下列出所有兼容的模块版本(这将由集成测试确保)。

如果您有新的问题,请点击提问按钮进行提问。如果需要提供背景信息,请包含此问题的链接。- 从审查中返回 - tgdavies
1
对我来说,这是同一个问题,只是基于@vinnybad的答案提供了一个扩展解决方案。 - rudi
@tgdavies 好的,我已经更新了它,使其成为一个没有任何问题的替代答案。 - rudi
@rudi,关于你的版本控制策略,当你对子模块进行更改、发布新版本并使用新版本时,你是如何处理的?看起来你没有使用SNAPSHOT构建,所以你是否只是手动递增子模块版本,并手动递增父POM中相应模块的版本,然后在父级运行mvn release - Daniel
@Daniel 是的,手动版本号到处都是。对于通过“develop”分支进行的较大发布,我会在那里准备所有版本号并在之后合并(一个干净的方式是发布分支)。对于错误修复和小更改,版本号直接与修复一起进行。哦,我根本不使用mvn release - rudi

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