问题描述
这似乎是一个简单的问题,但是由于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反应堆构建引擎经常摸索着哪个版本的重写pom用于计算传递相关性。理想情况下,应使用打包阶段之后的最终版本。但是在最新的maven版本(3.6.3)中,它只能在两次重写之前使用pom.xml,并且没有减少的依赖关系并且所有属性都不能正确替换。
我的问题是:
更新1 :目前,我正在通过以下一种简单的规避方法:
-
将第一个模块拆分为一个独立的maven项目,在软件包阶段同时调用maven-shade和flatten-maven插件。 (我没有直接的证据,但是我怀疑这是经过重新打包的依赖项,例如
spark-project.hive
https://mvnrepository.com/artifact/org.spark-project.hive/hive-common的产生,相关讨论请参见https://issues.apache.org/jira/browse/SPARK-20202) -
使用shell脚本按顺序编译/发布上述项目和主要的多模块项目。
我不是shell脚本的忠实拥护者,我认为这背叛了JVM社区所珍视的与平台无关的壮举。因此,如果您有更好的解决方案,请在此处发布,我会根据受欢迎程度接受它。
非常感谢您的意见
解决方法
第一件事是:maven's extremely rigorous paradigm of lifecycles and phases:
这些生命周期和阶段有很好的理由。
此外,您提到了几个插件重写pom.xml文件。正如您提到的,只有maven-shade-plugin和flatten-maven-plugin这样的例子。
除了您提到的maven-shade-plugin意图之外,
此插件提供了将工件打包(包括其依赖项)并阴影化(即重命名)某些依赖项的软件包的功能。
目的是隐藏依赖项(解压缩jar并将其重新打包到单个jar中),并使其成为可执行的jar(也可以使用maven-assembly-plugin完成)...而不是摆脱依赖关系
flatten-maven-plugin的想法是删除pom文件中以后不需要的部分(Build POM vs. Consumer POM)。目前,这部分将与Maven 3.7.0一起成为Maven Core的一部分...这是将build pom和使用者pom分开的重要第一步。
因此,让我们来看一下反应堆构建引擎,该引擎旨在根据依赖关系定义构建顺序。
理想情况下,应使用打包阶段之后的最终版本
因此,这意味着在打包之前和打包之后(对于此类插件的每次执行)阶段之间,具有不同的顺序和不同的依赖关系(包括传递依赖关系)。这将导致不可重复的结果。除了重新计算整个依赖树之类的东西之外。
但是在最新的maven版本(3.6.3)中,它只能在两次重写之前使用pom.xml,并且没有减少的依赖关系并且所有属性都没有正确替换。
所有以前的版本也是如此。此外,pom.xml是在构建的开始时读取的。
此设计的重点是什么?当所有插件都显式替换掉pom.xml时,为什么要使用它呢?
您到底想知道什么?还只提到了两个意图不同的插件(并非所有插件)。
如何忽略此行为,以便始终生成和使用pom.xml的最终版本,而不管是否要求maven目标?
由于它不存在,因此无法覆盖此行为。这将意味着重写Maven核心的大部分内容。