项目中常用的一些公共组件是独立开发的,但版本却没有有效管理,导致在构建使用中问题频发,一番折腾后发现 Maven 官方已经提供了版本控制的最佳实践,下面就来一起看看。
前提
原文名为 Maven CI Friendly Versions 意为 CI 版本友好,从 3.5.0-beta-1 开始,Maven 支持使用 ${revision}
作为 pom 文件中版本的占位符,IDEA 会报错但不影响使用。
单模块项目
如下是一个常规的工程
1 2 3 4 5 6 7 8 9 10 11 12 13
| <project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache</groupId> <artifactId>apache</artifactId> <version>18</version> </parent> <groupId>org.apache.maven.ci</groupId> <artifactId>ci-parent</artifactId> <name>First CI Friendly</name> <version>${revision}</version> ... </project>
|
版本使用的是 ${revision}
占位符,有如下两种方式可以指定版本
命令行
mvn 参数指定的方式
1
| mvn -Drevision=1.0.0-SNAPSHOT clean package
|
示例便是指定 revision 为 1.0.0-SNAPSHOT 为构建版本
属性配置
也可以可以在 pom.xml 文件中指定版本属性配置达到相同的效果
1 2 3 4 5 6
| <project> ... <properties> <revision>1.0.0-SNAPSHOT</revision> </properties> </project>
|
多模块项目
父项目
例如我们可能有一个多模块项目,项目的 parent pom 应当像这样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache</groupId> <artifactId>apache</artifactId> <version>18</version> </parent> <groupId>org.apache.maven.ci</groupId> <artifactId>ci-parent</artifactId> <name>First CI Friendly</name> <version>${revision}</version> ... <properties> <revision>1.0.0-SNAPSHOT</revision> </properties> <modules> <module>child1</module> <module>child2</module> .. </modules> </project>
|
延续之前 version 设置为 ${revision}
占位符
子模块
子模块应该是如下这种模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache.maven.ci</groupId> <artifactId>ci-parent</artifactId> <version>${revision}</version> </parent> <groupId>org.apache.maven.ci</groupId> <artifactId>child1</artifactId> ... <dependencies> <dependency> <groupId>org.apache.maven.ci</groupId> <artifactId>child2</artifactId> <version>${project.version}</version> </dependency> </dependencies> </project>
|
子模块配置中值得注意的有两点:
- parent version 引用
${revision}
- 对其他子模块的 version 引用
${project.version}
Install / Deploy
以上内容发布在 Maven 私服上是无法被其他项目引用的,还需要配合 flatten-maven-plugin 插件进行处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <project> <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> </project>
|
flatten 工作时会替换 pom 中的占位符,让 pom 变的完整可用,前面提到的 IDEA 报错也会在 Install 之后消除。
SNAPSHOT 版本
SNAPSHOT
意为快照,用来表示不稳定的开发版本,建议开发过程中版本号加上-SNAPSHOT
,在预发布时去掉或替换为 -RELEASE
。
使用-SNAPSHOT
的好处就是开发过程中版本号不用频繁修改,减少模块依赖方的使用负担,那么模块依赖方如何使用呢?
Idea
中勾选 File | Settings | Build, Execution, Deployment | Build Tools | Maven
中的 Always update snapshot
Maven
命令行使用时需加 -U
例如:mvn package -U
上述操作可以保证在使用过程中始终使用仓库上的最新包。
优化引用
如果模块较多会也会对依赖方造成困扰,这时可以新增 bom
模块,用于对子模块进行统一管理, parent pom :
1 2 3 4 5 6 7 8 9
| <project> ... <modules> <module>child1</module> <module>child2</module> <module>child-bom</module> .. </modules> </project>
|
child-bom
则通过 dependencyManagement
引入其他全部子模块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache.maven.ci</groupId> <artifactId>ci-parent</artifactId> <version>${revision}</version> </parent> <groupId>org.apache.maven.ci</groupId> <artifactId>child-bom</artifactId> <packaging>pom</packaging> ... <dependencyManagement> <dependency> <groupId>org.apache.maven.ci</groupId> <artifactId>child1</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.apache.maven.ci</groupId> <artifactId>child2</artifactId> <version>${project.version}</version> </dependency> </dependencyManagement> </project>
|
在模块依赖方仅引用 bom
即可,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <project> ... <dependencyManagement> <dependency> <groupId>org.apache.maven.ci</groupId> <artifactId>child-bom</artifactId> <version>${ci-project.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencyManagement> <dependencies> <dependency> <groupId>org.apache.maven.ci</groupId> <artifactId>child2</artifactId> </dependency> </dependencies> </project>
|
可以看到模块依赖方在通过 dependencyManagement
引入 bom
模块,再引入 child2
可以免版本号。
写在最后
经过这样修改之后可以有效解决 Maven 版本混乱的问题,避免使用上的冲突和错误,希望可以帮到各位。