Versions Maven Plugin 支持两种配置方式:
外置配置文件 maven-version-rules.xml;
内置在 POM 文件中,直接写在插件的 标签中。
第一种方案不方便迁移。还要额外管理一个配置文件。推荐使用第二种方式。另外,直接将这些配置放在 Maven BOM 中,使用继承的方式使用 Maven BOM,那么子项目就自动继承了这些配置。后续也只需要一个地方的配置即可。示例配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<!-- @author: D瓜哥 · https://www.diguage.com -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.15.0</version>
<configuration>
<ruleSet>
<ignoreVersions>
<!-- 可以使用 ignoreVersion 配置忽略 SNAPSHOT、alpha、beta 版等 -->
<ignoreVersion>
<!-- 'exact' (默认) 或 'regex' -->
<type>regex</type>
<version>(.+-SNAPSHOT|.+-M\d)</version>
</ignoreVersion>
<ignoreVersion>
<type>regex</type>
<version>.+-(alpha|beta)</version>
</ignoreVersion>
</ignoreVersions>
</ruleSet>
</configuration>
</plugin>
|
设置好这些配置后,后续如果想检查版本升级情况,只需要执行如下命令即可:
1
|
$ mvn versions:display-dependency-updates
|
第一次执行,时间较长,后续再执行就很快。(根据 D 瓜哥的执行情况来看,这个缓存的有效期是一天,第二天第一次执行也会比较慢。也可能是由于修改了 配置,导致执行变慢的。)执行结果如下:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
# 检查依赖升级情况
$ mvn versions:display-dependency-updates
# 此处省略一万个字
[INFO] ch.qos.logback:logback-access ........................ 1.2.11 -> 1.4.7
[INFO] ch.qos.logback:logback-classic ....................... 1.2.11 -> 1.4.7
[INFO] ch.qos.logback:logback-core .......................... 1.2.11 -> 1.4.7
[INFO] com.mysql:mysql-connector-j ......................... 8.0.32 -> 8.0.33
[INFO] com.zaxxer:HikariCP ................................... 4.0.3 -> 5.0.1
[INFO] jakarta.validation:jakarta.validation-api ............. 2.0.2 -> 3.0.2
[INFO] mysql:mysql-connector-java .......................... 8.0.32 -> 8.0.33
[INFO] org.aspectj:aspectjrt ................................ 1.9.7 -> 1.9.19
[INFO] org.aspectj:aspectjtools ............................. 1.9.7 -> 1.9.19
[INFO] org.aspectj:aspectjweaver ............................ 1.9.7 -> 1.9.19
[INFO] org.bouncycastle:bcjmail-jdk18on ........................ 1.72 -> 1.73
[INFO] org.bouncycastle:bcmail-jdk18on ......................... 1.72 -> 1.73
[INFO] org.bouncycastle:bcpg-jdk18on ........................... 1.72 -> 1.73
[INFO] org.bouncycastle:bcpkix-jdk18on ......................... 1.72 -> 1.73
[INFO] org.bouncycastle:bcprov-ext-jdk18on ..................... 1.72 -> 1.73
[INFO] org.bouncycastle:bcprov-jdk18on ......................... 1.72 -> 1.73
[INFO] org.bouncycastle:bctls-jdk18on .......................... 1.72 -> 1.73
[INFO] org.bouncycastle:bcutil-jdk18on ......................... 1.72 -> 1.73
[INFO] org.hibernate.validator:hibernate-validator ...
[INFO] 6.1.7.Final -> 8.0.0.Final
[INFO] org.hibernate.validator:hibernate-validator-annotation-processor ...
[INFO] 6.1.7.Final -> 8.0.0.Final
[INFO] org.mockito:mockito-core ............................. 4.11.0 -> 5.3.0
[INFO] org.mockito:mockito-inline ........................... 4.11.0 -> 5.2.0
[INFO] org.mockito:mockito-junit-jupiter .................... 4.11.0 -> 5.3.0
[INFO] org.mybatis:mybatis-spring ............................ 2.1.0 -> 3.0.1
[INFO] org.slf4j:jcl-over-slf4j ............................. 1.7.36 -> 2.0.7
[INFO] org.slf4j:jul-to-slf4j ............................... 1.7.36 -> 2.0.7
[INFO] org.slf4j:log4j-over-slf4j ........................... 1.7.36 -> 2.0.7
[INFO] org.slf4j:slf4j-api .................................. 1.7.36 -> 2.0.7
[INFO] org.slf4j:slf4j-ext .................................. 1.7.36 -> 2.0.7
# 疑问:
# 因为 Spring 6+ 要求 Java 17,所以,对于 Java 8 的项目,则需要忽略 6+ 的版本。该怎么办?
[INFO] org.springframework:spring-aop ....................... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-aspects ................... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-beans ..................... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-context ................... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-context-indexer ........... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-context-support ........... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-core ...................... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-expression ................ 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-instrument ................ 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-jcl ....................... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-jdbc ...................... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-test ...................... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-tx ........................ 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-web ....................... 5.3.27 -> 6.0.8
[INFO] org.springframework:spring-webmvc .................... 5.3.27 -> 6.0.8
|
因为 Spring 6+ 要求 Java 17,所以,对于 Java 8 的项目,则需要忽略 6+ 的版本,减少不必要的干扰。那么只需要增加如下配置即可:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<!-- @author: D瓜哥 · https://www.diguage.com -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.15.0</version>
<configuration>
<ruleSet>
<!-- <ignoreVersions> 的相关配置,请看上文。 -->
<rules>
<!-- 可以使用 rule 指定忽略的具体依赖及相关版本 -->
<!-- 例如:如果面向 Java 8 的应用,就不能升级到 Spring 6+。 -->
<rule>
<groupId>org.springframework</groupId>
<ignoreVersion>
<type>regex</type>
<version>[6-9].*</version>
</ignoreVersion>
</rule>
</rules>
</ruleSet>
</configuration>
</plugin>
|
不仅仅 Spring 有此问题,Spring Boot 3+ 也要求 Java 17+; HikariCP 5+ 要求 Java 11+;mybatis-spring 3+ 要求 Spring 6+,间接要求 Java 17+ 等等。关于这些依赖,应该如何配置?这个问题就当给小伙伴留个作业啦。
除了展示依赖可以升级的版本,还可以使用命令行进行升级。具体命令行如下:
1
2
3
4
5
6
7
8
|
# 将 SNAPSHOT 升级为正式版
$ mvn versions:use-releases
# 升级到下一个正式版
$ mvn versions:use-next-releases
# 使用最新的正式版
$ mvn versions:use-latest-releases
|
升级项目版本
现在的 Maven 项目,一般都会用多模块开发。升级项目版本时,就需要一个一个 POM 文件去改,费时费劲。这个操作,也可以让 Versions Maven Plugin 来完成。在项目的根目录执行如下命令
这里假设要发布 1.0.0 正式版
$ mvn versions:set -DnewVersion=1.0.0
执行完后,该项目及子模块的版本都会给修改为 1.0.0;同时,每个 POM 文件都会生成一个对应的 pom.xml.versionsBackup,该文件是用于回滚的。
如果发现什么问题,想要回滚到上一个版本,则可以使用以下命令回滚到备份的 pom.xml:
$ mvn versions:revert
如果一些 OK,则可以执行以下命令会删除备份文件,完成版本升级:
$ mvn versions:commit
如果想省事,也可以增加参数 -DgenerateBackupPoms=false 不产生备份文件:
这里假设要发布 1.0.0 正式版
$ mvn versions:set -DgenerateBackupPoms=false -DnewVersion=1.0.0
D 瓜哥觉得这个回滚机制有点设计过度。专业的事情应该交给专业的人干。如果需要回滚,可以使用版本管理直接回滚,也可以重新执行版本设置,设置回原来的版本即可。
可以增加如下配置,来避免手动在命令行设置该参数:
Versions Maven Plugin 还有升级插件等其他功能,感兴趣可以自行去探索。这里就不再赘述。
参考资料
jdk17 升级
为什么要升级?
- java 9 之后的 Java 改变了更新策略,java 11 是 8 之后的第一个 LTS 版本,之后每隔半年更新一个小版本,三年更新一个 LTS 版本,所以 java 17 是下一个 LTS 版本。
- 最显著的改善是几乎免费获得的性能提升。java 8 默认 GC 是 Parallel GC,java 9 之后默认是 G1 GC,且就算是同一个 GC,新版本中的表现也会比旧版本性能好,我们的程序触发 full GC 的次数和 GC 造成的程序暂停会更短。关于这一点,有一篇文章分析了性能How much faster is Java 17?。除此之外,每一个新的 Java 版本,尤其是 LTS 版本,都包含改进,例如解决安全漏洞、改进性能和添加新功能。让 java 保持最新有助于项目的健壮性和安全性。开发人员通常也更想在日常工作中使用新技术。
- oracleJdk 在 11 版本之后商用是需要付费的,17 这个版本又改回了商用免费,openJdk 和 oracleJdk 之间又可以自由选择了
- spring 刚刚官宣 2022 年即将发布的 spring framework 6.0 和 springboot 3.0 版本最低要求 java 17,且 kafka 3.0 版本之后也会弃用 java 8,升级已经是一个趋势,未来更多框架和中间件会弃用 java 8,作为开发人员也不能停止脚步
第一步建议先升级依赖项
如果你的项目基于 java 8,在升级前最好先升级依赖项,从 java 8 升级到 java 17 是一个很大的跨越,依赖项不升级则出问题的概率会比较高,maven 可以用mvn versions:display-dependency-updates
命令检查依赖项更新,输出会类似这样
升级完成后可以做的事情
对开发人员来说最想做的自然是使用新的特性,包括 var records instanceof switch 这些新关键字和旧语法的改进,以及 Stream 和 Optional 等 API 的改进等,此处不在赘述。
结语
这里总结的是一些我自己升级过程中遇到的问题,只要将依赖项同步升级,基本可以解决升级会遇到的所有问题。当然不是所有项目都适合升级的,这里需要根据项目的情况仔细斟酌,如果是新项目,想跟上技术迭代的脚步,还是非常推荐升级到 java 17 的。
参考文章及链接:
- https://www.optaplanner.org/blog/2021/09/15/HowMuchFasterIsJava17.html
- https://www.infoq.com/articles/why-how-upgrade-java17/
- https://github.com/johanjanssen/JavaUpgrades