问题描述
今天遇到一个问题,情况是这样的:
项目是一个spring cloud架构,其中有两个module,一个是common通过maven依赖了某个jar,另一个是业务module,业务module依赖common,结构大致如下:
project
-- common
-- someJar: 3.14.0
-- business
-- common: 1.0
common中有一个使用someJar
的util类,在common中Test运行正常,但是在business中运行却报错,提示someJar
中的某个类找不到方法。
排查
首先查看了business的Dependencies发现了一个奇怪的现象:
business
-- common: 1.0
-- someJar: 3.6.0
business module的依赖树中someJar的版本被降低了。而util中使用新版本的方法,因此运行报错。
但又是什么原因造成这种情况的发生那?
一开始我认为这是一种不正常现象,可能是maven的缓存问题(之前使用过低版本的jar),但是经过多次clean并没有解决问题。
那肯定是找错了方向。
后来我又想到项目的maven设置parent来做版本管理,可以无需考虑版本适配的问题:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath/>
</parent>
之后就不需要显式声明版本号
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
会不会我使用的someJar已经在parent中定义了版本号?
我尝试把common中someJar显式声明的版本3.14.0去除,reimprot之后发现并没有提示缺少版本号,而且依赖树中看到的版本号就是3.6.0。已经明显了,问题的原因就是在依赖传递过程中someKar的版本被parent中定义的版本号覆盖了。
解决
找到了问题就好办了,我在common中指定版本号等于重写覆盖了以来的版本,但是在依赖传递的过程中,business并没有使用common中指定的版本,而是修正为parent中定义的版本。要解决这个问题有两种方法,一是:common中不指定版本号,使用parent定义的版本,但是不能使用新版本的方法。如果一定要使用新版本的方法,那另一种是:在business中也声明一个someJar的依赖,指定成新版本号,并且排除common中传递的依赖。
结论
对于parent中管理版本号的依赖jar来说,复写版本号只能在本module中生效,一旦依赖发生传递则会使用parent中定义的版本号。