今天遇到的一个aone编译不通过的问题,再一次证明了在生产环境依赖mvn snapshot版本的风险和危害。
起因
针对一个变更修改代码,本地运行单元测试的时候编译不通过。昨天运行单元测试的时候还是正常的,而且编译不同过的类和引起编译失败的二方库都没有被修改到。
排查
- 尝试在aone预发环境进行部署,编译失败;
- 下掉aone预发环境所有变更,直接部署master分支,成功;
- 在个人pc上编译打包应用的master分支,编译失败;
2,3两步使用的maven版本是一样的,而且都是对master分支打包,但个人pc上却出现了编译失败。
之后,登陆aone预发环境打包master成功的打包机,在代码目录下执行aone构建日志中的打包命令,打包成功:
执行下面的mvn命令,却出现了编译错误:
mvn -U clean package -Dmaven.test.skip=true -DskipTests=true -Dappname=matrixexchange -DAPP_NAME=matrixexchange -Pmatrixexchange
由此怀疑是aone实际执行的打包命令中有些特殊的命令行参数会影响打包结果。自己查看aone打包命令后,发现其中有一些关于依赖缓存的命令行参数,也就是截图中红框内的-D参数。
尝试执行去掉dependency.graph.cache.enable,dependency.graph.cache.dir这两个环境变量后的mvn命令(其他命令行参数保持不变),果然发现编译失败了。这就说明是这个依赖缓存引起本地pc打包master分支失败,aone却成功的现象。
进一步分析需要找出具体缓存的具体位置,dependency.graph.cache.dir参数已经告诉我们了缓存所在的目录。但我们还需要知道过多的信息。由于知道编译失败的是exchange的server模块,所以检查相关的maven日志,找到了如下的输出:
从红色框中的日志可以猜测,server模块的依赖缓存似乎是从e46bec54e7fbf366d0e02d16437ebb59_2.2.1这个文件读出来的。所以尝试在cache目录查找这个文件:
果然找到了文件。
结论
在依赖缓存文件中,看到引起本地编译失败的tp-client-base版本是3.4.3。而在master分支执行mvn dependency:tree命令输出的结果中,显示tp-client-base版本是1.8.91。
由于pom依赖没有发生修改,所以基本上可以肯定是由于某个snapshot的依赖发生了变化导致tp-client-base这个间接依赖的二方包的版本发生了变化。
找到原因之后,修改工程的pom,强制依赖tp-client-base:3.4.3版本,编译和打包都正常了。
由于是在编译期发现的问题,所以影响还不是很大。如果是在上线运行时出现由于snapshot包发生变化(可能是代码,也可能是依赖)而出现的失败,问题就会严重很多。如果上一个稳定版依赖的是相同的snapshot版本,回滚代码都没有用。只能通过修改代码中的依赖版本,重新发布解决。
依赖snapshot版本的风险和危害,由此可见一斑。