1. flatten-maven-plugin 介绍
1.1 环境
- IntelliJ IDEA 2021.3
- JDK 1.8.0_301
- Apache Maven 3.8.1
- org.codehaus.mojo:versions-maven-plugin 1.2.7
- https://www.mojohaus.org/flatten-maven-plugin/
1.2 版本占位符
自 Maven 3.5.0-beta-1 开始,可以使用 ${revision}, ${sha1} and/or ${changelist} 这样的变量作为版本占位符。
- 像这样:
<project> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.maven.ci</groupId> <artifactId>ci-parent</artifactId> <name>First CI Friendly</name> <version>${revision}</version> <properties> <revision>1.0</revision> </properties> ... </project>
- 或者像这样:
<project> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.maven.ci</groupId> <artifactId>ci-parent</artifactId> <name>First CI Friendly</name> <version>${revision}${sha1}${changelist}</version> ... <properties> <revision>1.0</revision> <changelist>-SNAPSHOT</changelist> <sha1/> </properties> </project>
- 可以使用这样的命令:
mvn -Drevision=2.7.8 -Dchangelist=-RELEASE -Dsha1=ssbd clean package
- 缺点:
Install / Deploy 时,版本占位符将不能被替换。这将导致 Install / Deploy 后, maven 不能识别。
使用 flatten-maven-plugin 解决这个问题。
- flatten-maven-plugin:
<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>flatten-maven-plugin</artifactId> <version>${flatten-maven-plugin.version}</version> <configuration> <updatePomFile>true</updatePomFile> <flattenMode>resolveCiFriendliesOnly</flattenMode> </configuration> <executions> <execution> <id>flatten</id> <phase>process-resources</phase> <goals> <goal>flatten</goal> </goals> </execution> <execution> <id>flatten-clean</id> <phase>clean</phase> <goals> <goal>clean</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
2. 实例分析
2.1 先看一下自己构建的项目
基于 COLA 4.X 构建一个项目,本人目前正在写支付中台,所以就以此为例构建 “pointer-pay” 项目:
mvn archetype:generate \ -DgroupId=com.pointer.pay \ -DartifactId=pointer-pay \ -Dversion=1.0.0-SNAPSHOT \ -Dpackage=com.pointer.pay \ -DarchetypeArtifactId=cola-framework-archetype-web \ -DarchetypeGroupId=com.alibaba.cola \ -DarchetypeVersion=4.3.1
然后看一下其初始项目的版本管理方式:
parent:
module:
- 可以看到这里的父工程和modules都写死了版本。当然,像支付中台或者其他不会变更需求的项目,这个写也没什么毛病。
- But,在大多数互联网公司中,几乎每个项目都处在版本快速迭代中,甚至一两周更新一个小版本,一个月更新一个大版本。如果还是这样直接写死版本的话,通常做法就是全局搜索替换版本号,这样就显得很捞,也不太科学。然后就有了
revision 的占位符统一管理。
2.2 再看一下开源项目是怎么进行版本管理的
我们可以在 spring-boot 和 spring-cloud-alibaba 的开源项目中看到,其就是利用 revision 占位符来进行统一版本管理的。
https://github.com/spring-projects/spring-boot/blob/2.2.x/pom.xml
https://github.com/alibaba/spring-cloud-alibaba/blob/2021.x/pom.xml
2.3 改造 pointer-pay
- 先看一下原来的项目结构:
- 然后利用 revision 占位符来统一管理版本:
父工程pom:
子工程pom:
修改完以后编译运行都没问题。然后 install、deploy 的时候就出现问题了:打出来的jar包的pom文件里还是原来的revision变量,下面一起到maven仓库中查看一下:
可见这里识别不出版本号,也就会导致引用方不能识别你的 pom/jar 包。这时 flatten-maven-plugin
就该出场了,在你的父 pom 引入相关插件:
<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>flatten-maven-plugin</artifactId> <version>1.2.7</version> <configuration> <updatePomFile>true</updatePomFile> <flattenMode>resolveCiFriendliesOnly</flattenMode> </configuration> <executions> <execution> <id>flatten</id> <phase>process-resources</phase> <goals> <goal>flatten</goal> </goals> </execution> <execution> <id>flatten-clean</id> <phase>clean</phase> <goals> <goal>clean</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
然后重新 clean、install 一下,你会发现每个模块根目录下多了一个 .flattened-pom.xml
文件,那么这个玩意是怎么生成的呢?下面一起看一下 updatePomFile
标签,官方文档是这个描述的:
The flag to indicate if the generated flattened POM shall be set as POM file to the current project. By default this is only done for projects with packaging other than pom. You may want to also do this for pom packages projects by setting this parameter to true or you can use false in order to only generate the flattened POM but never set it as POM file. If flattenMode is set to bom the default value will be true.
大概意思是:updatePomFile 属性表示是否将生成的 .flattened-pom.xml 作为当前项目的 pom 文件。默认只有打包的时候(package、install、deploy)会将 .flattened-pom.xml 做为当前项目的 pom 文件,但是打包类型 pom 的 pom.xml 中的占位符是不会被替换的。如果想要都被替换,那就将 updatePomFile 的属性设置为 true 吧。如果 flattenMode 被设置为 bom,updatePomFile 默认属性值为 true。
再一起看一下引入 flatten-maven-plugin
之后编译过的 pom 文件: