很抱歉这篇文章有点长,但我很难在不附上图片的情况下让它更加简洁。最近我接手了一个maven 3.0多模块项目的构建工作。问题是,项目/模块的结构很混乱。从源代码控制中的存储方式(我们使用RTC)到模块的pom结构,每次都要尝试让整个构建周期完成,我都快被搞疯了。
就项目层次结构而言,所有模块都是"平面"存储的;即:所有东西都在同一级别。我有一个父POM文件,所有模块都依赖于该父文件。然而,该父文件与我的其他所有模块处于同一级别。
例如:
c:\dev\MyEarProject
+ parent-pom
- pom.xml
+ module1
- pom.xml (depends on parent-pom)
- src
- main
- ...
+ module2
- pom.xml (depends on parent-pom)
- src
- main
- ...
+ module3
- pom.xml (depends on parent-pom)
- src
- main
- ...
父pom定义了构建项目所需的所有模块,以及在不同子模块中使用的一堆构件版本号的属性:
<modules>
<module>../module1</module>
<module>../module2</module>
<module>../module3</module>
</modules>
<properties>
<org.springframework.version>3.0.5.RELEASE</org.springframework.version>
<slf4j.version>1.6.4</slf4j.version>
<repositoryAddress>${snapshots.repo.url}</repositoryAddress>
<my.hibernate-module.dao.impl>1.2.3</my.hibernate-module.dao.impl>
<my.hibernate-module.dao.api>1.2.3</my.hibernate-module.dao.api>
</properties>
每个模块的pom依次通过pom的artifact编号依赖于父pom:
<parent>
<groupId>com.cws.cs.lendingsimulationservice</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.6</version>
</parent>
为了让事情更加混乱,实际构件的名称可能与模块路径匹配,也可能不匹配(这取决于模块)。例如,module1 可能位于路径 c:\dev\MyEarProject\module1 中,但具有 artifact 名称 hibernate-module。但是,由于它在 RTC 中存储的方式,当它被签出时,目录名为 module1。当然,最简单的构建方式是进入 c:\dev\MyEarProject\parent-pom\ 并运行 mvn clean deploy。在 SNAPSHOT 模式下,这可以正常工作,因为 SNAPSHOT 存储库允许多次部署同一构件版本。但在 release 模式下,会失败。
这种结构给我带来了两个问题:
1.每次需要更改父级属性的版本时,我都必须更新 parent-pom 版本号以及所有子模块的 parent pom 版本号和子模块版本号(因为父级已更改)。
2.每当我需要部署一个 release cycle 时,如果其中一个模块自上一个周期以来没有更改,并且因此无法重新部署到同一个 repo (该 repo 不允许覆盖现有构件),则 mvn 将抛出错误。
所以我正在寻找重新组织此项目以避免这些问题的最佳方法。对于 parent pom,我知道可以使用相对路径指向父级。然而,鉴于模块的“平面”结构,这是否是推荐的方法(例如:parent pom 相对路径将是 ../parent-pom/pom.xml-对我来说似乎有点奇怪)。此外,考虑到父级的版本控制独立于模块,使用相对路径是否只会开启另一种混乱的方式(例如:没有办法知道父级 pom 的哪个版本与子模块的哪个版本相关联)。
其次,我如何构建整个 ear 而不遇到我遇到的部署错误?由于 artifact 已经存在于存储库中,所以我不需要重建和重新部署它。我尝试使用 --projects,但涉及的模块数量非常大,管理起来非常困难。