【问题标题】:Build order of Maven multimodule project?Maven多模块项目的构建顺序?
【发布时间】:2012-06-23 07:10:40
【问题描述】:

情况是,我有两个结构相同的Maven多模块项目:

家长 - 模块 1 - 模块 2

当我构建项目 1 时,我看到先构建父级(顺序为 parent->module1->module2)。但是对于项目 2,最后构建父级(顺序为 module1->module2->parent)。为什么这两个项目有不同的构建顺序?另外,如何手动控制构建顺序?

更新 1:
两个父项目都是简单的POM项目,没有源代码,所以无法按照依赖图解释构建顺序。

更新 2:
除了 GAV 和子模块名称之外,父 POM 相同:

4.0.0父组IDparent-artifact-id父版本pom包装> 父名module-1module-2模块> 项目>

【问题讨论】:

标签: java maven build multi-module


【解决方案1】:

构建顺序由 Maven 反应器确定,这是一种通过对项目进行排序来自动确保多模块构建的正确构建顺序的机制。

请参阅 the official documentation 了解其工作原理。

上面写着:

在对项目进行排序时遵循以下关系:

  • 项目依赖于构建中的另一个模块
  • 插件声明,其中插件是构建中的另一个模块
  • 插件依赖于构建中的另一个模块
  • 构建中另一个模块的构建扩展声明
  • 元素中声明的顺序(如果没有其他规则适用)

您无法手动控制构建顺序。如果您想更改顺序,您必须对您的项目做出影响反应堆排序顺序的更改。

【讨论】:

  • 但这并不能解释为什么两个项目有不同的构建顺序。
  • 应该没有什么不同。没有更多的不同了吗?孩子们有同一个父母吗?
  • 检查子模块中的父版本
【解决方案2】:

在高层次上,构建顺序基于模块依赖关系图的topological sort

编辑:问你一个问题。我知道项目 1 包含两个模块,项目 2 也是如此。但是项目 2 中的模块是否明确将“父”pom 声明为父项?我在想也许你的项目 1 模块明确声明了父 pom,而项目 2 模块没有。这意味着项目 2“父级”根本不是真正的父级,因此不必在模块之前构建。反正这是我的猜测。

【讨论】:

  • 但是两个父项目都是简单的POM项目,没有任何源代码。依赖关系图在这里没有意义。
  • 引用父 POM 也是一个依赖。
【解决方案3】:

我最近在使用 CentOS 7 时遇到了这个问题。我将 Maven 从 3.0.5 更新到 3.5.3,问题已经解决。如果有人也有这个问题,你可以先试试。

【讨论】:

  • 欢迎来到 SO。对于这样一个老问题,这似乎不太可能回答。有关如何回答问题的帮助,请参阅 stackoverflow.com/help/how-to-answer
  • 我是为像我这样的人写的。我有这个问题,找不到任何东西。然后我自己解决并写到这里,所以如果人们遇到这个问题并谷歌它,他们可以找到一些东西。
【解决方案4】:

总结

为什么?

Maven 使用<module> 声明来确定要包含在当前运行中的模块列表。 Maven 使用<parent> 声明为每个包含的模块 生成有效的 POM,然后用于执行该模块的构建。

项目1中,module1module2 中的每一个都在<parent> 部分指定parent 模块。 在项目 2 中,module1module2 均未在 <parent> 部分中指定 parent 模块。

如何手动控制构建顺序?

通过更改模块之间的依赖关系,包括<parent><dependencies>、插件依赖关系等,如the official documentation中所述。

请查看Introduction to the POM 以了解有关聚合和继承的讨论。


详情

在 Maven 中模块关系有 4 种可能的场景,聚合(<module> 声明)和继承(<parent> 声明)。

让我们假设一个模块A 带有包装pom 和一个模块B(包装无关紧要)。模块A 可以是父模块或聚合器。模块B 可以将A 引用为父级,也可以不引用。

案例 1:

AB 都不会相互引用 - 模块是独立的。 Maven无法控制构建顺序,每个模块独立构建,手动构建顺序控制。

案例 2:

模块A包含模块B<modules>中。 B 模块 不声明 A 为父模块。在这种情况下,模块 A 是模块 B 的聚合器。

  • Maven 调用 mvn -f A/pom.xml 将首先构建 B,然后是 A
  • Maven 调用 mvn -f B/pom.xml 将仅构建 B

案例 3:

模块A包含模块B<modules>中。模块 B 声明 A 为父模块。在这种情况下,A 模块 既是 模块 B 的父级和聚合器(反应器)。

  • Maven 调用 mvn -f A/pom.xml 将首先构建 A,然后是 B
  • Maven 调用 mvn -f B/pom.xml 将仅构建 B,但将使用 A 的 POM 生成有效的 B 的 POM,方法是从本地存储库或关注 /project/parent/relativePath

案例 4:

模块A 不包含模块B 中的<modules>。模块 B 声明 A 为父模块。在这种情况下,模块 A 是模块 B 的父模块。

  • Maven 调用 mvn -f A/pom.xml 将仅构建 A
  • Maven 调用 mvn -f B/pom.xml 将仅构建 B,但将使用 A 的 POM 生成有效的 B 的 POM,方法是从本地存储库或关注 /project/parent/relativePath

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-08
    • 2013-09-08
    • 2014-05-22
    • 2016-10-30
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 2014-03-03
    相关资源
    最近更新 更多