使用maven -pl选项和从模块级别运行maven有什么区别? [英] What is the difference between using maven -pl option and running maven from module level?

查看:1675
本文介绍了使用maven -pl选项和从模块级别运行maven有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两者之间是否有任何区别

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

就我而言,这两个动作的结果应该是相同的.

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

解决方案

首先让我们澄清有关多模块(聚合器)构建的一些内容(即,从聚合器/父项目中调用该构建)并构建一个模块. /p>

让我们使用以下示例:

-+ 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文件夹构建时:

module-project> mvn clean install

Maven Reactor 将创建声明的模块并进行相应的构建,因此,模块a将在模块b之前构建,因为模块b依赖于模块a

module-b> mvn clean install

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

如果不是在modules-project上调用clean install,而是调用clean package,则Maven不会在本地Maven缓存中安装任何东西,因此,module-b项目中对module-a的依赖关系可以无法解决.要澄清:

module-project> mvn clean package

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

module-b> mvn clean package

现在将失败,因为对模块-a的依赖关系在本地Maven缓存或任何Maven存储库中都不存在,也就是说,它不作为依赖项存在,而Maven则不存在.对其他模块一无所知,它正在构建一个简单的项目(一个模块),而对其他模块(如由modules-project提供)一无所知.当构建模块项目时,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清洁软件包-pl module-b -am

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

让我们看一下最后一种情况:

module-b> mvn清洁软件包-am

如果失败,如果我们从不安装整个多模块项目(即,我们始终运行clean package),则-am选项将被忽略(如果它不是反应堆构建的一部分)(因为它是反应器的选项,而不是常规版本)而且Maven仍会尝试在本地缓存或存储库中找到模块-a.

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

  • 您使用正确的依赖项和模块信息正确构建了
  • 您是根据最新版本的代码/依赖关系构建的,而不是根据您先前在maven缓存中安装的,可能与其模块代码不一致的内容构建的

这也是您的观察正确的原因,您提到的第一个调用(从聚合器项目构建子模块)花费的时间稍长一些,因为它不仅是子模块的构建,而且还更多(因为有更多信息要处理和处理).它是一种不同的构建,一个反应堆,也可能构建依赖模块),而直接构建一个子模块(从其目录)是一个更简单的Maven构建,因此也更快(但由于缺少一些,所以更容易出错)信息).

有关反应堆构建的这些选项的更多信息,请参见 解决方案

Let's first clarify something about multi-module (aggregator) build (that is, invoking the build from the aggregator/parent project) and building a single module.

Let's use the following example:

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

Hence modules-project will have as part of its pom the following:

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

When building from the module-project folder:

module-project> mvn clean install

The Maven Reactor will create the dependency graph of the declared modules and build them accordingly, hence module-a will be built before module-b because module-b depends on module-a

module-b> mvn clean install

Would work correctly, only building module-b, resolving module-a as a dependency (which we installed previously) and using it as part of the build classpath where required.

If instead of invoking a clean install on modules-project we would have invoked a clean package, Maven would not have installed anything in our local Maven cache, hence the dependency to module-a in the module-b project could not be resolved. To clarify:

module-project> mvn clean package

Will still build the whole project (with all of its submodules) and create the packages (that is, the jar files).

module-b> mvn clean package

Would now fail, because the dependency to module-a is not present in the local Maven cache nor in any Maven repository, that is, it doesn't exist as a dependency and Maven doesn't know anything about other modules, it is building a simple project (a module) without any knowledge about other modules (as provided by modules-project). When building modules-project instead, Maven is building each module with much more information, knowing that a module has a dependency to another module it will not look on the local cache or on any Maven repository for inter-modules dependencies. Again, it's a reactor build.

That's why you can build a sub-module as a separate build only if you already built the whole multi-module project and installed its artifacts at least in the local Maven cache. And that's why the best practice is always to work from the multi-module project, so that Maven has all the required information and you could:

  • Build the whole multi-module project (mvn clean install)
  • Build a single or a set of modules via the -pl option (but still starting from the multi-module project)
  • Build a single or a set modules and their dependencies via the -pl and -am options (still from the multi-module project)

Let's clarify now the last point, which will also answer your question.

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

Would run fine, building only module-a as part of the reactor build. However

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

Would fail, because Maven will try as requested to build module-b, but, again, would look for module-a as a dependency and not a module, hence in the local Maven cache or in the configured Maven repository, not finding it.

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

Would eventually work fine, because now Maven is also building the dependent modules (thanks to -am) and knows exactly where to find them (as part of the multi-module information, that is, the modules section).

Let's look at a last case:

module-b> mvn clean package -am

Would fail if we never installed the whole multi-module project (i.e. we always run clean package), the -am option would be ignored if not part of a reactor build (because it is an option of the reactor, not of the normal build) and Maven would still try to find module-a in local cache or in repositories.

That's why you should always build a sub-module from its aggregator/parent and via the -pl and -am options, to make sure that:

  • You build correctly, using the right dependencies and modules information
  • You build against the latest version of your code/dependency and not against something you installed previously in your maven cache which may not be aligned with its module's code

That's also why your observation is right, the first invocation you mentioned (building a submodule from the aggregator project) takes slightly longer because it is not simply the build of a submodule but something more (because there are more information to process and it is a different type of build, a reactor one, potentially building dependent modules also), while building directly a submodule (from its directory) is a simpler Maven build and as such also quicker (but more error prone because of the lack of some information).

More information on these options for a reactor build could be found here.

这篇关于使用maven -pl选项和从模块级别运行maven有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆