4

这似乎是一个简单的问题,但由于 maven 极其严格的生命周期和阶段范式,我发现它很困难:

假设在一个多模块的 maven 项目中,在各个阶段使用了几个插件来将 pom.xml 重写为更有效的版本,值得注意的例子是:

  • maven-shade-plugin(如果<createDependencyReducedPom>启用):当需要发布着色的 uber-jar 时,插件可以摆脱不需要包含的依赖项。始终在包阶段执行。

  • flatten-maven-plugin:允许模块发布的 pom.xml 不再依赖于父级的 pom,方法是将属性引用替换为它们的实际值。可以在任何阶段执行,但为了保持与 maven-shade-plugin 的互操作性,它也仅限于包阶段(请参阅https://issues.apache.org/jira/browse/MSHADE-323

当它们与其他模块结合使用时,maven reactor 构建引擎似乎经常摸索使用哪个版本的重写 pom 来计算传递依赖。理想情况下,应该使用打包阶段之后的最终版本。但是在最新的 maven 版本(3.6.3)中,它只能在重写之前使用 pom.xml,不会减少依赖关系并且所有属性都没有正确替换。

我的问题是:

  1. 这个设计的意义何在?为什么在所有插件都明确替换它时使用半生不熟的 pom.xml?

  2. 如何覆盖此行为,以便始终生成和使用 pom.xml 的最终版本,而不管请求的 maven 目标如何?

更新1:目前我正在使用一个简单的规避方法:

我不是 shell 脚本的忠实拥护者,我认为这背叛了 JVM 社区所珍视的与平台无关的壮举。因此,如果您有更好的解决方案,请在此处发布,我会根据受欢迎程度接受它。

非常感谢您的意见

4

1 回答 1

2

第一件事是:maven's extremely rigorous paradigm of lifecycles and phases:那些生命周期和阶段有很好的理由。

此外,您提到几个插件重写 pom.xml 文件。唯一的例子是你提到的maven-shade-pluginflatten-maven-plugin 。

除此之外,正如您提到的 maven-shade-plugin 意图:

这个插件提供了将工件打包在 uber-jar 中的能力,包括它的依赖项和遮蔽 - 即重命名 - 一些依赖项的包。

目的是隐藏依赖项(解压缩 jar 并将其重新打包到一个 jar 中)并制作一个可执行的 jar(这也可以使用maven-assembly-plugin完成)...而不是摆脱依赖。

flatten-maven-plugin 的想法是删除 pom 文件中以后使用不需要的部分(Build POM vs. Consumer POM)。目前这部分将成为 Maven 3.7.0 的 Maven Core 的一部分......这是分离构建 pom和消费者 pom的重要的第一步。

因此,让我们来看看反应堆构建引擎,它旨在根据依赖关系定义构建顺序。

理想情况下,应该使用打包阶段之后的最终版本

所以这意味着在包之前和包之后的阶段之间(对于此类插件的每次执行)具有不同的顺序和不同的依赖关系(包括传递依赖关系)。这将导致不可重复的结果。除了重新计算整个依赖树等的事情之外。

但是在最新的 maven 版本(3.6.3)中,它只能在重写之前使用 pom.xml,不会减少依赖关系并且所有属性都没有正确替换。

对于所有以前的版本也是如此。此外, pom.xml 在构建的最开始时被读取......

这个设计的意义何在?为什么在所有插件都明确替换它时使用半生不熟的 pom.xml?

你到底想知道什么?还提到了只有两个具有不同意图的插件(而不是所有插件)。

如何覆盖此行为,以便始终生成和使用 pom.xml 的最终版本,而不管请求的 maven 目标如何?

没有选项可以覆盖此行为,因为它不存在。这意味着要重写大部分 Maven 核心。

于 2020-09-06T20:41:47.927 回答