9 Gradle 版本冲突问题

在之前的文章上,我们已经知道了如何添加依赖,如何来管理依赖。其实管理依赖的最重要的环节就是传递性依赖过程中存在的版本冲突的问题处理。接下来咱们先来看个传递性依赖过程中存在 jar 包版本冲突问题,再来看下 Gradle 有哪些处理方法。

传递性依赖中的版本冲突

版本冲突

上图我们可以知道,项目需要依赖 hibernate3.6.3 的版本,而此版本需要依赖几个 jar 包,而依赖的 hibernate-commons-annotations.jar 依赖了一个slf4j 的jar包,当前hibernate框架也依赖了slf4j 的 jar 包。由于传递性依赖的特点,两个不同版本的 jar 包会被依赖进来,这样就存在版本冲突的问题。

存在版本冲突问题是需要解决的,如果没有解决程序就会出问题,那我们使用 Gradle 做依赖管理,要如何来解决此问题?Gradle 有没有帮咱们解决此问题?请继续往下看版本冲突的解决方案。

版本冲突解决方法

对于 Maven 的自动处理传递性依赖版本冲突问题,是按最短路径和优先声明原则来处理。

Maven版本冲突解决方法

而对于 Gradle 来说同样有着自动处理传递性依赖版本冲突问题的功能,只是 Gradle 是默认使用版本最高的。而针对一些特殊的需求还是需要使用手动解决。以下便是 Gradle 的手动处理版本冲突。

1. 修改默认配置策略

如果想检查有哪些 jar 包有版本冲突,或者想去除 Gradle 的默认处理方式,可修改默认的配置策略。

    1. 在 build.gradle 中加入如下配置
configurations.all{
  resolutionStrategy{
      // 修改 gradle不自动处理版本冲突
      failOnVersionConflict()
  }
}
    1. 执行 help -> dependencies 可查看冲突的 jar 包
A conflict was found between the following modules:
- org.slf4j:slf4j-api:1.6.1
- org.slf4j:slf4j-api:1.5.8

以上配置完,如果存在依赖 jar 包版本冲突问题,Gradle 将不再自动处理,build 会抛异常。

2. 排除传递性依赖

  • 排除单个jar 包的传递性依赖
dependencies {
   compile (group: 'org.hibernate', name: 'hibernate-core', version: '3.6.3.Final'){
       // module 是 jar 的 name
       exclude group:"org.slf4j", module:"slf4j-api"
   }
}

此处的 module 指的是 jar 的 name,只无需写版本,此配置的意义就是排除 hibernate-core 引入时 slf4f-api 的传递性依赖。也就是说我们的项目目前没有依赖任何版本的 slf4f-api。

  • 排除所有 jar 的传递性依赖
dependencies {
    compile (group: 'org.hibernate', name: 'hibernate-core', version: '3.6.3.Final'){
        transitive=false
    }
}

transitive 默认为true,表示 Gradle 自动添加子依赖项,设置为false 则需要手动添加每个依赖项。在真实开发中,需要自动添加子依赖的比较多,而手动添加的比较少,毕竟使用工具的主要目的是减少工作量,所以开发中此配置建议不使用。

3. 强制指定一个版本

给有冲突的 jar 包强制指定一个版本,在 build.gradle 中配置如下:

configurations.all{
    resolutionStrategy{
        force 'org.slf4j:slf4j-api:1.7.24'
    }
}

执行 help -> dependencies 可看到所有的 slf4j 都改为了1.7.24 的版本了。

以上便是 Gradle 在传递性依赖中的版本冲突问题的默认解决方式介绍和如何手动解决版本冲突的两种方案。

至此我们已经掌握了如何使用 Gradle 配置依赖和管理依赖,下一篇我们就来做个小实践:《Gradle 实现多项目构建》。

转载链接:https://www.jianshu.com/p/385daa68c73c

推荐阅读更多精彩内容