使用 maven -pl 选项和从模块级别运行 maven 有啥区别?

Posted

技术标签:

【中文标题】使用 maven -pl 选项和从模块级别运行 maven 有啥区别?【英文标题】:What is the difference between using maven -pl option and running maven from module level?使用 maven -pl 选项和从模块级别运行 maven 有什么区别? 【发布时间】:2016-06-06 20:09:22 【问题描述】:

有什么区别

C:/dev/path/to/Project> mvn package -pl MyModule -am -s settings.xml

C:/dev/path/to/Project/MyModule> mvn package -am -s ../settings.xml

在我看来,这两个动作的结果应该是一样的。

但是,每种情况下的行为似乎都不同:前一种似乎更广泛;后者结束得更快 - 我试图理解为什么会这样。

【问题讨论】:

第二个将从远程存储库中解析由-am(列表所需的构建项目)间接提供的模块,而第一个mvn -pl ...-am ..将从反应器中解析它们...和来自远程存储库的 nto...我建议永远不要使用第二种形式... 【参考方案1】:

让我们首先澄清一下多模块(聚合器)构建(即从聚合器/父项目调用构建)和构建单个模块。

让我们使用以下示例:

-+ modules-project
 |- module-a
 |- module-b (depends on module-a)

因此 modules-project 将在其 pom 中包含以下内容:

<modules>
    <module>module-a</module>
    <module>module-b</module>
</modules>

从模块项目文件夹构建时:

module-project> mvn clean install

Maven Reactor 将创建已声明模块的依赖关系图并相应地构建它们,因此模块-a 将在模块-b 之前构建,因为模块-b 依赖于模块-a

module-b> mvn clean install

可以正常工作,只构建 module-b,将 module-a 解析为依赖项(我们之前安装过),并在需要时将其用作构建类路径的一部分。

如果不是在模块项目上调用clean install,而是调用clean package,Maven 就不会在我们的本地 Maven 缓存中安装任何东西,因此在模块 b 项目中对模块 a 的依赖可以不能解决。澄清一下:

module-project> mvn clean package

仍将构建整个项目(及其所有子模块)并创建包(即 jar 文件)。

module-b> mvn clean package

现在会失败,因为对 module-a 的依赖既不存在于本地 Maven 缓存中,也不存在于任何 Maven 存储库中,也就是说,它不作为依赖存在而 Maven 不存在对其他模块一无所知,它正在构建一个简单的项目(一个模块),而不了解其他模块(由 modules-project 提供)。相反,当构建 modules-project 时,Maven 正在构建具有更多信息的每个模块,因为知道一个模块对另一个模块有依赖关系,它不会在本地缓存或任何 Maven 存储库中查找模块间依赖关系。同样,它是reactor build。

这就是为什么只有当您已经构建了整个多模块项目并至少在本地 Maven 缓存中安装了它的工件时,您才能将子模块构建为单独的构建。这就是为什么最佳实践始终是从多模块项目开始工作,以便 Maven 拥有所有必需的信息,您可以:

构建整个多模块项目 (mvn clean install) 通过-pl 选项构建一个或一组模块(但仍从多模块项目开始) 通过-pl-am 选项构建单个或一组模块它们的依赖项(仍然来自多模块项目)

现在让我们澄清最后一点,这也将回答您的问题。

modules-project> mvn clean package -pl module-a

运行良好,仅构建模块 a 作为反应堆构建的一部分。不过

modules-project> mvn clean package -pl module-b

失败,因为 Maven 会根据请求尝试构建 module-b,但同样会查找 module-a 作为依赖项而不是模块,因此在本地 Maven 缓存中或在配置的 Maven 存储库中,没有找到它。

modules-project> mvn clean package -pl module-b -am

最终会正常工作,因为现在 Maven 也在构建依赖模块(感谢 -am)并且知道在哪里可以找到它们(作为多模块信息的一部分,即 modules 部分) .

让我们看最后一个案例:

module-b> mvn clean package -am

如果我们从未安装过整个多模块项目(即我们总是运行clean package)会失败,如果不是反应堆构建的一部分,-am 选项将被忽略(因为它是reactor 的一个选项,而不是正常构建的选项),Maven 仍会尝试在本地缓存或存储库中查找模块-a。

这就是为什么您应该始终从其聚合器/父级并通过 -pl-am 选项构建子模块,以确保:

使用正确的依赖项和模块信息正确构建 您针对最新版本的代码/依赖项进行构建,而不是针对您之前在 maven 缓存中安装的可能与其模块代码不一致的内容进行构建

这也是为什么您的观察是正确的,您提到的第一次调用(从聚合器项目构建子模块)需要稍长一些,因为它不仅仅是子模块的构建,而是更多(因为有更多信息需要处理和它是一种不同类型的构建,一个反应器,也可能构建依赖模块),而直接构建一个子模块(从其目录)是一个更简单的 Maven 构建,因此也更快(但更容易出错,因为缺少一些信息)。

有关反应堆构建的这些选项的更多信息,请访问:

Maven Tips and Tricks: Advanced Reactor Options

【讨论】:

您也可以看看这个吗?谢谢***.com/questions/69925811/…

以上是关于使用 maven -pl 选项和从模块级别运行 maven 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

如何使一个 Maven 模块依赖于另一个?

使用 maven 碰撞模块版本

maven相关说明,以及使用Testng相关

Maven 多模块发布

如何在驻留在不同路径的包上运行带有mod选项“-m”的Python3?

python----日志模块loggin的使用,按日志级别分类写入文件