1. 概述
在这个教程中,我们将学习如何在Maven构建失败后恢复它。我们将了解如何跳过已经成功构建的模块,从而直接定位到问题出现的地方。
2. 示例设置
让我们构建一个多模块Maven项目。父项目称为resume-from
,子项目有两个:lib
和business
。为了演示,我们暂时让lib
项目为空。然而,business
项目包含一个名为src/main/java/Main.java
的文件,里面只有一个简单的Hello World
程序。现在,我们在business
模块中添加对lib
的依赖:
<dependency>
<groupId>com.baeldung</groupId>
<artifactId>lib</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
目前,项目的结构是正确的,所以我们可以成功构建它:
$ mvn clean install
[...]
[INFO] Reactor Summary for resume-from 1.0-SNAPSHOT:
[INFO]
[INFO] resume-from ........................................ SUCCESS [ 1.749 s]
[INFO] lib ................................................ SUCCESS [ 2.021 s]
[INFO] business ........................................... SUCCESS [ 0.991 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[...]
3. 在运行install
阶段时
现在,我们去掉Main.java
文件中的分号。这会导致business
子模块的构建失败:
$ mvn clean install
[...]
[INFO] Reactor Summary for resume-from 1.0-SNAPSHOT:
[INFO]
[INFO] resume-from ........................................ SUCCESS [ 1.186 s]
[INFO] lib ................................................ SUCCESS [ 0.984 s]
[INFO] business ........................................... FAILURE [ 0.334 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.809 s
[INFO] Finished at: 2023-06-20T16:15:13+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project business: Compilation failure
[ERROR] [...]/resume-from/business/src/main/java/Main.java:[4,43] ';' expected
[...]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <args> -rf :business
由于lib
子模块已经成功构建,修复问题后希望跳过它的构建就很有意义。正如Maven错误消息所说,我们可以使用-rf
选项从给定模块恢复反应器构建。现在,我们修复Main.java
文件并尝试这样做:
$ mvn clean install -rf :business
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< com.baeldung:business >------------------------
[INFO] Building business 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[...]
------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.318 s
[INFO] Finished at: 2023-06-20T17:21:07+02:00
[INFO] ------------------------------------------------------------------------
如预期,这次只构建了business
子模块。实际上,-rf
是--resume-from
的简写形式,所以我们也可以这样写:
$ mvn clean install --resume-from :business
4. 当不运行install
时
假设我们现在没有运行Maven的install
,而是在早期的阶段停止构建。为了展示这一点,我们可以回到Main.java
文件损坏的情况。同时,我们清空本地仓库并运行package
阶段:
$ mvn clean package
[...]
[INFO] Reactor Summary for resume-from 1.0-SNAPSHOT:
[INFO]
[INFO] resume-from ........................................ SUCCESS [ 0.108 s]
[INFO] lib ................................................ SUCCESS [ 0.709 s]
[INFO] business ........................................... FAILURE [ 0.316 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.216 s
[INFO] Finished at: 2023-06-20T17:49:59+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project business: Compilation failure
[ERROR] [...]/resume-from/business/src/main/java/Main.java:[4,43] ';' expected
[...]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <args> -rf :business
不出所料,我们得到了相同的编译错误。错误信息给出同样的提示,即修复问题后使用-rf
选项。于是,我们修复问题并运行命令:
$ mvn clean package -rf :business
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< com.baeldung:business >------------------------
[INFO] Building business 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[WARNING] The POM for com.baeldung:lib:jar:1.0-SNAPSHOT is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.187 s
[INFO] Finished at: 2023-06-20T17:56:34+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project business: Could not resolve dependencies for project com.baeldung:business:jar:1.0-SNAPSHOT: Could not find artifact com.baeldung:lib:jar:1.0-SNAPSHOT -> [Help 1]
由于我们没有运行install
阶段,在第一次构建时lib
子模块并没有安装到本地仓库。因此,当Maven尝试恢复构建时,找不到lib
模块的 artefact。理论上,我们可以通过在命令行中添加--also-make
选项来解决这个问题。--also-make
应该会构建business
依赖的所有项目。然而,Maven 3存在一个bug,当与--resume-from
一起使用时,--also-make
被忽略【参见MNG-6863】。
这个bug将在即将发布的Maven 4中修复。然而,在此期间,我们无法在这种情况下从特定模块恢复反应器。不幸的是,我们需要重新构建整个项目:
$ mvn clean package
[...]
[INFO] Reactor Summary for resume-from 1.0-SNAPSHOT:
[INFO]
[INFO] resume-from ........................................ SUCCESS [ 0.109 s]
[INFO] lib ................................................ SUCCESS [ 0.660 s]
[INFO] business ........................................... SUCCESS [ 0.436 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[...]
5. 总结
在这篇文章中,我们了解了如何在Maven构建失败后跳过部分构建。当我们将子模块安装到本地仓库时,可以使用-rf
选项。另一方面,如果不安装它们,由于Maven的一个bug,我们需要重新构建整个项目。代码示例可在GitHub上找到。