java - 如何重构Maven多模块项目?

标签 java maven multi-module maven-deploy-plugin

对于这篇文章的篇幅,我深表歉意,但在不展示图片的情况下,我很难让它更简洁。我最近继承了 maven 3.0 多模块项目的 build-master 工作。问题是项目/模块的结构是一场灾难。从当前存储在源代码管理(我们使用 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 定义构建项目所需的所有模块,以及在不同子模块中使用的 Artifact 版本号的一系列属性:

<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>

让事情变得更加困惑的是,实际的 Artifact 名称可能会或可能不会(取决于模块)与模块路径匹配。例如,module1 可能位于路径 c:\dev\MyEarProject\module1 但具有 Artifact 名称 hibernate-module。但是,由于它在 RTC 中的存储方式,该目录在 checkout 时称为 module1

当然,构建所有内容的最简单方法是进入 c:\dev\MyEarProject\parent-pom\ 并运行 mvn clean deploy。这在 SNAPSHOT 模式下工作正常,因为 SNAPSHOT 存储库允许同一 Artifact 版本的多个部署。但在 Release模式下,这会失败。

这个结构给我带来了两个问题。

  1. 每次我需要对父级中的属性进行版本更改时,我必须更新父级 pom 版本号、所有子模块父级 pom 的版本以及所有子模块版本本身(因为父级更改了).
  2. 每当我需要部署一个发布周期时,如果其中一个模块自上一个周期以来没有更改,mvn 将抛出一个错误,因此无法重新部署到同一个存储库(该存储库不允许覆盖现有 Artifact )<

所以我正在寻找重组这个项目以避免这些问题的最佳方法。对于父 pom,我知道我可以使用相对路径来指向父 pom。但是,考虑到模块的“平面”结构,这是推荐的方法吗(即:父 pom 相对路径是 ../parent-pom/pom.xml - 对我来说似乎有点奇怪)?此外,鉴于父级的版本控制独立于模块,使用相对路径不仅会带来更多的困惑(即:无法知道父 pom 的哪个版本与哪个版本相关联)子模块)。

其次,我如何构建整个耳朵而不遇到我遇到的部署错误?由于 Artifact 已经存在于 repo 协议(protocol)中,我不需要重建和重新部署它。我尝试使用 --projects,但由于涉及的模块数量众多,管理起来非常困难。

最佳答案

我真正推荐的第一件事是重组项目文件夹...这意味着让项目文件夹代表结构,这意味着不要展平结构。

  +-- parent-pom (pom.xml)
       +--- module1 (pom.xml)
       +--- module2 (pom.xml)
       +--- module3 (pom.xml)

因此,您的父级模块部分将被简化为:

<modules>
  <module>module1</module>
  <module>module2</module>
  <module>module3</module>
</modules>

此外,您的模块中的父条目也可以像这样简化:

<parent>
  <groupId>com.cws.cs.lendingsimulationservice</groupId>
  <artifactId>parent-pom</artifactId>
  <version>1.0.6</version>
</parent>

...这让我想到了下一点:

如果您当前的所有项目都像上面那样定义它们的父级,这是完全错误的,因为将尝试在存储库中而不是在上层文件夹中找到父级。换句话说,这会导致您在发布等方面出现很多问题。

如果我们要解决这个问题,它必须看起来像我不推荐的那样:

<parent>
  <groupId>com.cws.cs.lendingsimulationservice</groupId>
  <artifactId>parent-pom</artifactId>
  <version>1.0.6</version>
  <relativePath>../parent-pom/pom.xml</relativePath>
</parent>

我观察到的另一件事是您没有使用 SNAPTSHOT,它会在发布阶段被发布插件替换。与此相关的是,它会自动更改相应父项中的所有版本等。

在理想情况下,您的模块应如下所示:

<parent>
  <groupId>com.cws.cs.lendingsimulationservice</groupId>
  <artifactId>parent-pom</artifactId>
  <version>1.0.6</version>
</parent>

<artifactId>module-1</artifactId>
<!-- No Version or groupId -->

因为所有模块都将继承其父模块的版本和 groupId。有时更改模块 groupId 很有用或需要,但这是一个异常(exception)。

我重读的是关于父版本的单独版本控制。这根本没有意义,因为它是它们模块的父级,所以将它放在相同的结构中,当然还有相同的 VCS。

如果你想制作一些配置/插件版本,应该用于其他项目的依赖项以及制作单独的公司 pom.xml 这是一个单独的项目并将单独发布等.

完成结构更改后,您只需进入 parent-pom 目录并从该文件夹执行 mvn clean packagemvn release:prepare release:perform,然后一切都会变得简单。

关于java - 如何重构Maven多模块项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10452444/

相关文章:

maven - 使用 gpg 验证签名后如何比较主 key 指纹?

java - 如何在 NetBeans 中实现部署保存多模块 Maven 项目?

多模块多语言项目的 Travis-ci 文件

java - 使用修订属性构建一个模块的 Maven 问题

java - 我将如何跨多行搜索一串单词

spring - java.lang.ClassNotFoundException : org. hibernate.annotations.common.reflection.ClassLoadingException

java - Eclipse RCP - SelectionService - 历史?

scala - 为什么 sbt 构建失败并显示 "MissingRequirementError: object scala.runtime in compiler mirror not found."?

java - EJB 3.0 TimerService - 在每个月的第一天运行计时器

java - 使用反射从列表中获取对象