项目背景
spring boot项目(2.3.0)里面使用pg数据库和redis。pg的连接池使用的是apache的commons-dbcp2(2.9.0),redis的操作我们统一封装在自己的infra-redis项目中(底层使用了commons-pool2连接池 2.8.0版本)。由于部分原因,我们需要升级infra-redis组件,最后发现这个2.10.0版本打死都引用不个底层的commons-pool2的版本到2.10.0上。
于是我们将infra-redis底层的commons-pool2的maven版本直接修改为2.10.0,然后打包发布。然后再spring-boot的业务项目重新引用infra-redis组件,最后发现这个2.10.0版本打死都传递不过来(spring-boot业务项目没有引用相关的commons-pool2组件)。通过maven-hepler插件查看该infra-redis引用的是2.8.0版本,但是通过链接跳转过去看到实际的pom引用实际是2.10.0。
复现
我们使用spring-boot 引用netty来进行原因复现。创建项目A和B,然后A项目依赖B项目,B项目使用自定义netty-all版本。
1.新建项目B,pom文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>project-b</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.61.Final</version>
</dependency>
</dependencies>
</project>
2.新建项目A,pom文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>project-a</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>project-b</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
3.下载maven-helper插件,并在项目A的pom文件中查看
是不是很奇怪,明明在项目B中引用的是【 4.1.61.Final】版本,咋引用进来就成4.1.50了呢?
我们通过【jump to source 】到原文件看看,结果发现的确是【 4.1.61.Final】。
在项目B通过maven helper查看
懵逼,我也懵逼了很久。找不到答案,明明是4.1.61,明明.....
分析
折腾了半天我也不知道啥原因,然后去网上查了一下资料也没找到答案,我就冷静下来仔细分析是不是spring-boot自己依赖的一些jar版本原因引起的?果然,我通过 spring-boot-dependencies 的依赖发现有一个默认版本
结果就出来了,因为spring-boot默认有一个依赖的版本,maven的传递规则是 父依赖 > 子依赖,所以spring boot 默认的生效,传递过来的不会生效。如果要改变spring-boot的默认依赖版本,那么就单独引用对应的版本就可以了。
但是,奇怪的是,maven helper在查看pom的时候,应该把两个版本的netty都显示出来啊并且提示有冲突,B项目的引用界面那里应该是4.1.61才对啊,我在想这可能是maven helper的bug。