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

使用maven-pl选项和从模块级运行maven有什么区别?,maven,maven-3,pom.xml,multi-module,maven-reactor,Maven,Maven 3,Pom.xml,Multi Module,Maven Reactor,两者之间有什么区别吗 C:/dev/path/to/Project> mvn package -pl MyModule -am -s settings.xml 及 就我而言,这两种行为的结果应该是一样的 然而,每种情况下的行为似乎不同:前者似乎更广泛;后者结束得更快——我正试图理解这是为什么。首先让我们澄清一下多模块(聚合器)构建(即,从聚合器/父项目调用构建)和构建单个模块 让我们使用以下示例: -+ modules-project |- module-a |- module-b

两者之间有什么区别吗

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

就我而言,这两种行为的结果应该是一样的


然而,每种情况下的行为似乎不同:前者似乎更广泛;后者结束得更快——我正试图理解这是为什么。

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

让我们使用以下示例:

-+ modules-project
 |- module-a
 |- module-b (depends on module-a)
因此,模块项目将具有以下内容作为其pom的一部分:

<modules>
    <module>module-a</module>
    <module>module-b</module>
</modules>
将创建所声明模块的依赖关系图并相应地构建它们,因此模块a将在模块b之前构建,因为模块b依赖于模块a

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

如果我们没有在模块项目上调用
clean install
,而是调用了
clean package
,那么Maven就不会在本地Maven缓存中安装任何东西,因此无法解决模块b项目中对模块a的依赖性。澄清:

module-project> mvn clean package
仍将构建整个项目(及其所有子模块)并创建包(即jar文件)

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

这就是为什么只有在您已经构建了整个多模块项目并至少在本地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将根据请求尝试构建模块b,但同样,会将模块a作为依赖项而不是模块查找,因此在本地Maven缓存或配置的Maven存储库中找不到它

modules-project> mvn clean package -pl module-b -am
最终可以正常工作,因为现在Maven也在构建依赖模块(多亏了
-am
),并且知道在哪里可以找到它们(作为多模块信息的一部分,即
模块
部分)

让我们看最后一个案例:

module-b> mvn clean package -am
如果我们从未安装整个多模块项目(即,我们总是运行
干净的包
),那么
-am
选项将被忽略,如果它不是反应堆构建的一部分(因为它是的一个选项,而不是普通构建的一个选项),Maven仍然会尝试在本地缓存或存储库中查找模块-a

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

  • 使用正确的依赖项和模块信息正确构建
  • 您可以根据最新版本的代码/依赖项进行构建,而不是根据之前在maven缓存中安装的可能与其模块代码不一致的内容进行构建
这也是为什么您的观察是正确的,您提到的第一次调用(从聚合器项目构建子模块)需要稍长的时间,因为它不仅仅是子模块的构建,而是更多的东西(因为有更多的信息要处理,而且它是一种不同类型的构建,一种反应器构建,也可能构建依赖于它的模块),而直接构建子模块(从它的目录)是一种更简单的Maven构建,因此也更快(但由于缺少一些信息,更容易出错)


可以找到关于反应堆建造这些选项的更多信息。

第二个选项将解析由
-am
间接提供的模块(列表要求的建造项目)来自远程存储库,其中作为第一个
mvn-pl…-am
。将从反应器中解析它们…并从远程存储库中解析nto…我建议nevery使用第二个表单。。。
modules-project> mvn clean package -pl module-b
modules-project> mvn clean package -pl module-b -am
module-b> mvn clean package -am