我希望将POM文件中的依赖项版本外部化为属性文件。
示例:pom.xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${externalized.junit.version}</version>
</dependency>
abc.properties
externalized.junit.version=4.8.2
可以这样做吗?如果是这样,最好的方法是什么?
答案 0 :(得分:4)
不,你做不到。
当您在项目上启动Maven命令时,首先要做的是创建项目的有效模型。这显然意味着读取您的POM文件,使用激活的配置文件进行推理,应用继承,对属性执行插值...所有这些都构建了最终的Maven模型。这项工作由Maven Model Builder组件完成,其入口点为ModelBuilder
接口,退出点为Model
类。
构建模型的过程非常复杂,许多步骤可能分为两个阶段,但问题的关键很简单:在该步骤结束时,有一个有效的有效模型可供使用由Maven。这意味着所有依赖项必须具有有效的组ID,工件ID,版本;没有重复的依赖项,没有相同ID的插件执行等。(refer to the model description)。
请注意,在模型构建过程中,interpolation正在发生,这意味着如果某个属性当时可用,并且已使用它,例如${myProperty}
,那么它将被替换为相应的值。可用的属性包括:
${project.version}
或${project.artifactId}
; ${project.basedir}
,对应于pom.xml
所在的目录; -D
开关在命令行上设置的用户属性(如-DmyProperty=myValue
); <properties>
元素内; ${maven.build.timestamp}
,表示构建开始的日期/时间,或${maven.version}
当前Maven版本; System.getProperties()
settings.xml
file。这里的关键点是,在构建有效模型时,依赖项的版本必须是有效的。这是在构建期间确保依赖图稳定且一致的唯一方法。
这正是失败的原因:你希望Maven能够读取属性文件中的版本,因此它意味着将插件绑定到生命周期的特定阶段以读取该文件并以某种方式引用属性读取使用标准的Maven属性。麻烦的是,在模型已经建成之后,这一切都会发生,所以为时已晚。所有这一过程都在build lifecycle开始之前发生;在此之前没有机会调用插件。
这也意味着如果您将属性定义为命令行属性,它将起作用(因为,如上所述,它在构建模型时的插值过程中可用)。但这不是最佳实践:将依赖项版本指定为命令行属性会使构建非常难以重现。最好将其指定为POM的<properties>
元素内的Maven属性,或者在父POM或<dependencyManagement>
中使用importing a BOM方案。
答案 1 :(得分:0)
如果真的需要这样的东西,最简单的方法是编写一个复制pom的shell脚本(或其他一些简短的命令行程序),替换pom中的指定属性。打电话给maven。
但正如之前所说:可能有更多类似Maven的方式来实现你想要达到的目标。