管理依赖最重要的问题就是传递性依赖过程中存在的版本冲突问题的处理。在之前手动管理依赖过程中经常遇到版本冲突问题,版本一冲突程序就无法运行,而作为版本管理工具就应该拥有解决此问题的能力。
传递性依赖中的版本冲突问题示例:
compile group:'org.hibernate',name:'hibernate-core',version:'3.6.3.Final'
hibernate 依赖的hibernate-commons-annotations.jar依赖slf4j,当前的hibernate框架也依赖了slf4j,由于依赖传递性的特点,两个不同版本的jar包会被依赖进来,这样就会存在版本冲突的问题
版本冲突解决
Maven版本冲突自动解决方案
对比maven,自动处理传递性依赖版本冲突,Maven是按照最短路径原则和优先声明原则来处理
最短路径原则:
D1路径为:项目->A->D1
D2路径为:项目->B->E1->D2
D1路径比D2短,所以使用D1
优先声明原则:
E1和E2的路径距离相同,而E1比E2先声明,所以使用E1,而不适用E2
gradle版本冲突解决方案
Gradle默认的自动解决版本冲突的方案是 选用版本最高的 ,一般情况下高版本都是向下兼容低版本的,所以此处这种选择可以使用新版本的特性,也不容易出问题
手动解决版本冲突
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group:'org.hibernate',name:'hibernate-core',version:'3.6.3.Final'
}
我们先引用heibernate,查看依赖关系:
可以看到引用的slf4j 是1.6.1的版本
修改配置策略,对所有jar不做冲突自动解决
configurations.all{
resolutionStrategy{
//修改gradle不自动处理版本冲突
failOnVersionConflict()
}
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group:'org.hibernate',name:'hibernate-core',version:'3.6.3.Final'
}
刷新 gradle,
Could not resolve all dependencies for configuration ':compileClasspath'.
A conflict was found between the following modules:
- org.slf4j:slf4j-api:1.6.1
- org.slf4j:slf4j-api:1.5.8
Run with:
--scan or
:dependencyInsight --configuration compileClasspath --dependency org.slf4j:slf4j-api
to get more insight on how to solve the conflict.
会看到版本冲突报错,上面配置会使 gradle不在自动处理版本冲突问题,构建会抛出异常。此操作可以查看哪些jar存在版本冲突问题。
排除某个jar包的传递性依赖:
还是以slf4j为例:
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile (group:'org.hibernate',name:'hibernate-core',version:'3.6.3.Final') {
exclude group:'org.slf4j', module:'slf4j-api'
}
}
再次查看依赖关系:
可以看到项目中不在依赖任何版本的slf4j-api的jar包。需要自己来配置所需要的版本的jar包
排除所有的jar的传递性依赖(不推荐使用)
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile (group:'org.hibernate',name:'hibernate-core',version:'3.6.3.Final') {
transitive = false
}
}
手动指定某个jar版本
configurations.all{
resolutionStrategy{
force 'org.slf4j:slf4j-api:1.7.24'
}
}