最近遇到了一个Gradle的依赖问题,但发现使用常见的解决依赖冲突的方式无效,最后发现是因为引入Spring Boot Plugin的问题,在这记录下过程。
问题描述
我有一个core
项目,它显式的引入了guava:23.0
版本。
有另外一个api
项目,它引入了core
作为依赖。 表现的问题是api
项目最终使用的guava
版本是18.0
, 而不是期望的23.0
。
尝试使用常用的方式解决依赖问题
一开始很容易想到是依赖冲突的问题,即api
项目引入了其他的依赖中包含了guava:18.0
版本,最终覆盖了core
项目的guava:23.0
。但其实这个想法不对,因为Gradle默认的依赖管理方式是使用新版本。先不管了,先试试这种办法。
先运行命令看看还有谁在用guava。1
./gradlew dependencyInsight --configuration compile --dependency guava
发现是springfox-swagger2
在使用guava:18.0
版本。 于是将swagger的guava依赖exclude掉。1
2
3compile('io.springfox:springfox-swagger2:2.7.0') {
exclude group: 'com.google.guava', module: 'guava'
}
但是这种方法无效,api
项目依然使用guava:18.0
版本。
Spring Boot Plugin引发的问题
经过调查,最终是由于引入了Spring Boot的插件所引起的。1
2
3
4
5
6
7apply plugin: 'org.springframework.boot'
dependencyManagement {
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Edgware.RELEASE'
}
}
Spring Boot的插件有它自己的一套依赖管理规则,如果没有显示地指定依赖版本,它会使用它自定义的依赖规则。
再回去看下上面的依赖图,其中有一行是1
com.google.guava:guava:18.0 (selected by rule)
selected by rule
便是一个提示,表示有程序明确地表示使用这个版本。在这个问题里,是Spring Boot的插件自己的Rule明确表示使用guava:18.0
。
而之前提到过当发生依赖冲突时,Gradle会默认选择新版本来使用。它的表现为conflict resolution
,类似于下面这样。1
com.google.guava:guava:23.0 (conflict resolution)
所以这个问题并不是依赖冲突的问题,而是Spring Boot的插件带来的问题。
解决方案
有多种方式可以解决这个问题,细节可以参考spring boot plugin官方文档
我这里是在Spring Boot插件的依赖管理中,显示地声明我希望使用的guava版本。1
2
3
4
5
6
7
8
9dependencyManagement {
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Edgware.RELEASE'
}
dependencies {
dependency('com.google.guava:guava:23.0')
}
}