利用Maven插件高效去除SNAPSHOT

1. 前言

公司质量保障团队近期在Push各技术团队在线上应用中禁止使用SNAPSHOT,因此各个技术团队均开始修改完善。不同人员对Maven学习了解程度不同,有些同事修改起来效率较低,因此我将自己所使用的方法和工具在公司内网BBS进行分享,供大家参考借鉴。

2. SNAPSHOT出现场景

  1. 对外提供了SNAPSHOT
  2. 依赖三方SNAPSHOT

2.1. 对外提供服务由SNAPSHOT改为RELEASE

一般在开发测试阶段,需要经常变动代码,所以使用SNAPSHOT是合理的,但是线上对外提供的服务必须是稳定的版本,一般以RELEASE包提供。此处涉及修改版本号。我们的项目一般是以一个Project和多个Module的形式组织,Project与Module存在父子关系。如果手动一个个修改版本号,比较容易出错。Maven提供了插件:Versions,用于管理版本。

设置新版本号

1
mvn versions:set -DnewVersion=1.0.1-RELEASE

确认提交新版本号

1
mvn versions:commit

撤消版本号变更

1
mvn versions:revert

2.2. 发现并去除SNAPSHOT依赖

2.2.1. 发现SNAPSHOT依赖

一般我们的项目会有很多三方依赖,而他们自身亦可能有很多依赖,如果通过人工逐个去判断是否存在SNAPSHOT依赖,几乎是不可能的事。Maven提供了插件:dependency,用于管理依赖。为了发现SNAPSHOT依赖,可以通过以下两种方式:

方式一:通过dependency:list

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mvn dependency:list | grep -i snapshot

[INFO] com.google.flatbuffers:flatbuffers-java:jar:1.2.0-SNAPSHOT:compile
[INFO] com.google.flatbuffers:flatbuffers-java:jar:1.2.0-SNAPSHOT:compile
[INFO] com.google.flatbuffers:flatbuffers-java:jar:1.2.0-SNAPSHOT:compile
[INFO] com.sample.service:gateway_fundout_api:jar:1.0.0-SNAPSHOT:compile
[INFO] com.sample.service:pay-ledger-api:jar:1.0.1-SNAPSHOT:compile
[INFO] com.sample.service:gateway_fundout_api:jar:1.0.0-SNAPSHOT:compile
[INFO] com.sample.service:pay-ledger-api:jar:1.0.1-SNAPSHOT:compile
[INFO] com.google.flatbuffers:flatbuffers-java:jar:1.2.0-SNAPSHOT:compile
[INFO] com.sample.service:gateway_fundout_api:jar:1.0.0-SNAPSHOT:compile
[INFO] com.sample.service:pay-ledger-api:jar:1.0.1-SNAPSHOT:compile
[INFO] com.google.flatbuffers:flatbuffers-java:jar:1.2.0-SNAPSHOT:compile
[INFO] com.sample.service:gateway_fundout_api:jar:1.0.0-SNAPSHOT:compile
[INFO] com.sample.service:pay-ledger-api:jar:1.0.1-SNAPSHOT:compile
[INFO] com.google.flatbuffers:flatbuffers-java:jar:1.2.0-SNAPSHOT:compile

这种方式会筛选出当前项目所有的SNAPSHOT依赖,但是问题很明显,我们很难判断是哪里依赖了这些SNAPSHOT。因此,我倾向采用第二方式。

方式二:通过dependency:tree

1
2
3
4
5
6
7
8
9
10
11
12
mvn dependency:tree -Dincludes=:::*-SNAPSHOT

[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ pay_pcs_impl ---
[INFO] com.xxx.service:pay_pcs_impl:jar:1.0.1-RELEASE
[INFO] +- com.sample.service:pay_pcs_service:jar:1.0.1-RELEASE:compile
[INFO] | +- com.sample.service:gateway_fundout_api:jar:1.0.0-SNAPSHOT:compile
[INFO] | \- com.sample.service:pay-ledger-api:jar:1.0.1-SNAPSHOT:compile
[INFO] \- com.sample:pay-common:jar:1.0.1.1:compile
[INFO] \- com.sample.sentry:sentry-client:jar:2.1.15:compile
[INFO] \- com.google.flatbuffers:flatbuffers-java:jar:1.2.0-SNAPSHOT:compile

通过dependency:tree的方式,可以清晰明了的看到依赖的层次关系,从而快速的定位到SNAPSHOT依赖点。如上述:pay_pcs_service –> pay_common –> sentry-client –> flatbuffers-java。

2.2.2. 去除SNAPSHOT依赖

通过2.2.1的方式发现SNAPSHOT依赖后,便可根据结果去除相应的SNAPSHOT依赖。去除的方式归根结底是变更依赖的版本,同样有多种方式。我主要采用两种方式。

方式一:利用Maven Versions插件

1
2
3
mvn versions:use-releases
mvn versions:use-next-releases
mvn versions:use-latest-releases

该方式可批量的将SNAPSHOT替换成相应的RELEASE版本。

注:某些服务提供方发布版本不合规范,所以请注意结合git的变更等,判断所变更的RELEASE是否正确。比如我在使用过程中遇到某一个依赖,同一版本号,SNAPSHOT和RELEASE代码出入较大,导致编译失败。经排查改用其他版本号才正常。

方式二:人工逐个变更依赖的版本号
通过发现SNAPSHOT方式二发现的依赖,层次关系已经十分明确。在数量不多的情况下,保险起见,人工逐个核实确认新的RELEASE版本号。可以借助以下方法获取依赖是否有更新

1
mvn versions:display-dependency-updates

3. FAQ

  1. zsh:no matches found: -Dincludes=:::-SNAPSHOT,该问题是由于zsh对通配符的解析,简单的解决方法是给参数加上引号:mvn dependency:tree -Dincludes=”:::-SNAPSHOT”

4. 参考文献

  1. http://www.mojohaus.org/versions-maven-plugin/usage.html
  2. https://maven.apache.org/plugins/maven-dependency-plugin/usage.html