例子

示例反应器项目

考虑一个普通的多模块反应堆构建:

my-root-project
|-- pom.xml
|-- fooUI
|   `-- pom.xml
|-- barBusinessLogic
|   `-- pom.xml
`-- bazDataAccess
    `-- pom.xml

假设项目“fooUI”依赖于项目“barBusinessLogic”,该项目依赖于项目“bazDataAccess”。

fooUI --> barBusinessLogic --> bazDataAccess

通常,当您从my-root-project运行mvn install时,您将首先构建 bazDataAccess,然后是 barBusinessLogic,然后是 fooUI。

使用 reactor:resume 恢复构建

假设您正在处理您的代码,并且您尝试使用mvn install from my-root-project构建您的代码,并且假设您在 barBusinessLogic 中遇到测试失败。在不更改 bazDataAccess 的情况下对 barBusinessLogic 进行其他更改;您知道 bazDataAccess 很好,因此无需重新构建/测试它。然后您可以使用reactor:resume,如下所示:

mvn reactor:resume -Dfrom=barBusinessLogic

这将跳过 bazDataAccess 并选择您在 barBusinessLogic 中中断的位置。如果 barBusinessLogic 成功,它将继续构建 fooUI。

在不使用 reactor:make 构建 fooUI 的情况下制作 barBusinessLogic

假设您是从事 barBusinessLogic 的开发人员;您现在不想在 fooUI 上工作,而只想获得 barBusinessLogic 的工作版本。您可以使用reactor:make,如下所示:

mvn reactor:make -Dmake.folders=barBusinessLogic

reactor:make将检查 barBusinessLogic 并沿着其依赖关系树向下走,找到它需要构建的所有项目。在这种情况下,它将自动构建 bazDataAccess 然后 barBusinessLogic,而不构建 fooUI。

使用 reactor:make-dependents 更改 barBusinessLogic 并验证您没有破坏任何内容

假设您对 barBusinessLogic 进行了更改;你想确保你没有破坏任何依赖你的项目。(在这种情况下,您要确保没有破坏 fooUI,但在可能不那么明显的更复杂的反应器中。)您还想避免重建/测试您知道自己没有更改的项目。在这种情况下,您希望避免构建 bazDataAccess。您可以使用reactor:make-dependents,如下所示:

mvn reactor:make-dependents -Dmake.folders=barBusinessLogic

reactor:make-dependents将检查您的 reactor 中的所有项目以查找依赖于 barBusinessLogic 的项目,并自动构建这些项目,仅此而已。在这种情况下,它将自动构建 barBusinessLogic,然后构建 fooUI。

使用 reactor:make-scm-changes 构建您个人更改的任何内容

假设您对 barBusinessLogic 中的某些源文件进行了更改,但您忘记了更改的内容。你想确保你可以安全地签到,并且你没有破坏任何依赖你的项目。您可以使用reactor:make-scm-changes,如下所示:

mvn reactor:make-scm-changes

reactor:make-scm-changes使用您的 SCM(源配置管理)工具(例如 Subversion、Perforce、Git 等)确定哪些文件已更改。要使用它,您需要在根项目 POM 文件中配置 SCM 连接:

<project>
  ...
  <scm>
      <connection>scm:svn:http://svn.mycompany.com/trunk/blah</connection>
      <url>http://svn.mycompany.com/trunk/blah</url>
  </scm>
  ...
</project>

reactor 插件将使用 Maven 的内置 SCM 提供程序来尝试找出您修改了哪些文件。(默认情况下,它将忽略“未知”文件:已在源目录中创建但尚未明确添加到源代码管理的文件。)

一旦 reactor 插件计算出已更改文件的列表,它将找出哪些文件对应于 reactor 中的哪些项目,并且基本上对那些包含已更改文件的项目执行reactor:make-dependents 。

在这个例子中,如果你只修改了 barBusinessLogic 中的文件,那么运行reactor:make-scm-changes相当于运行reactor:make-dependents -Dmake.folders=barBusinessLogic -- 它构建 barBusinessLogic 和任何依赖于 barBusinessLogic 的东西(在此情况下,它将构建 fooUI)。

如果你发现 reactor:make-scm-changes 正在做一些你意想不到的事情,请尝试使用--debug-X在调试模式下运行 Maven,如下所示:

mvn reactor:make-scm-changes -X

您将看到所有更改文件的日志以及我们如何计算要传递给reactor:make-dependents 的项目的描述。

使用反应器插件进行“试运行”

所有反应器插件目标都包含一个参数-Dmake.printOnly,您可以使用它来查看目标在不实际执行的情况下会做什么。例如:

> mvn reactor:make -Dmake.folders=barBusinesslogic -Dmake.printOnly
[INFO] Scanning for projects...
[...]
[INFO] [reactor:make]
[INFO] Executing: /Users/danfabulich/svn/redfin/buildtools/maven/bin/mvn -B -N -r -D maven.reactor.includes=bazDataAcecss/pom.xml,barBusinessLogic/pom.xml install
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------

运行不同的目标/生命周期(“test”、“package”、“eclipse:eclipse”、“clean”等)

默认情况下,所有反应器插件目标都将在适当的项目上运行mvn install 。这是一个相当合理的默认值,但有时您想在一堆项目上运行不同的命令。所有反应器插件目标都将接受-Dmake.goals参数,该参数将允许您运行其他目标。您可以用逗号分隔多个目标:

mvn reactor:make -Dmake.folders=barBusinessLogic -Dmake.goals=eclipse:eclipse
mvn reactor:make-dependents -Dmake.folders=barBusinessLogic -Dmake.goals=package,clean
mvn reactor:resume -Dmake.folders=barBusinessLogic -Dmake.goals=test

跳过测试并将标志传递给生成的 Maven

reactor 插件启动了 Maven 的第二个副本来发挥它的魔力。这个 Maven 副本不一定具有您传递给第一个 Maven 副本的所有标志和选项,包括 --debug 标志、系统属性和 -DskipTests。

您可以通过使用-Dmake.goals将它们视为目标来将其他参数传递给生成的 Maven ,如下所示:

mvn reactor:resume -Dmake.folders=barBusinessLogic -Dmake.goals=install,-DskipTests

换句话说,“目标”只是传递给生成的 Maven 的额外命令行参数;它们不一定是“目标”。

如果你想要真正花哨,你可能更喜欢在-Dmake.printOnly模式下干运行反应器插件,如上所述。这将打印出插件用于构建的命令,但您可以根据自己的喜好调整该命令行!

恢复“make”构建

当你使用reactor:make时,你运行的是项目的一个子集,但这并不意味着在构建过程中不会失败。您可以通过将-Dfrom传递给reactor:make目标,从停止构建的项目中恢复reactor:make build,如下所示:

mvn reactor:make -Dmake.folders=fooUI -Dfrom=barBusinessLogic

-Dfrom参数也适用于reactor :make-dependentsreactor:make-scm-changes

嵌套目录

让我们考虑一个更复杂的项目:

my-root-project
|-- pom.xml
|-- fooUI
|   `-- pom.xml
|-- barBusinessLogic
|   `-- pom.xml
|-- quz
|   |-- pom.xml
|   |-- quzAdditionalLogic
|   |   `-- pom.xml
|   `-- quzUI
|       `-- pom.xml
`-- bazDataAccess
    `-- pom.xml

再次假设项目“fooUI”依赖于项目“barBusinessLogic”,该项目依赖于项目“bazDataAccess”。

fooUI --> barBusinessLogic --> bazDataAccess

但进一步,假设“quzUI”依赖于“quzAdditionalLogic”,后者依赖于“barBusinessLogic”。

quzUI --> quzAdditionalLogic --> barBusinessLogic --> bazDataAccess

如果你尝试运行mvn reactor:make -Dmake.folders=quzUI,你会得到一个错误:

> mvn reactor:make -Dmake.folders=quzUI
[INFO] Folder doesn't exist: /home/person/svn/trunk/quzUI

当然,您必须指定 quzUI 的完整相对路径,如下所示:

> mvn reactor:make -Dmake.folders=quz/quzUI

这将在反应堆中构建除“fooUI”之外的所有内容。请注意,在这个项目中,如果您运行mvn reactor:make-dependents -Dmake.folders=barBusinessLogic,它将在反应器中构建除 bazDataAccess 之外的所有内容。

通过工件而不是文件夹名称识别项目

有时项目可以嵌套在树的很远的地方;在这种情况下,通过它们的 artifactId 而不是通过它们的完整相对路径来识别它们会更容易。假设“quzUI”的 artifactId 只是“quzUI”,您可以这样做:

mvn reactor:make -Dmake.artifacts=com.mycompany:quzUI

或者,如果您想恢复:

mvn reactor:resume -DfromArtifact=com.mycompany:quzAdditionalLogic

如果 quzUI 与根 POM 具有相同的 groupId,您甚至可以省略 "com.mycompany:" groupId 并说:

mvn reactor:make -Dmake.artifacts=quzUI