如何调试 Gradle 为啥使用我在依赖子项目中指定的不同版本的库?

Posted

技术标签:

【中文标题】如何调试 Gradle 为啥使用我在依赖子项目中指定的不同版本的库?【英文标题】:How do I debug why Gradle is using a different version of the library I specified in a dependent sub-project?如何调试 Gradle 为什么使用我在依赖子项目中指定的不同版本的库? 【发布时间】:2018-04-09 17:30:53 【问题描述】:

我有一个 Gradle 构建,它将我的 JOOQ 生成的代码拆分为一个单独的 jooq 子项目,然后我的 api-svc 项目依赖于该子项目。

当我将jooq 子项目升级到3.10.1 时,出于某种原因,Gradle 决定使用3.9.5 来构建api-svc。我不知道为什么,我必须通过在我的 api-svc 项目中添加显式依赖项来解决它。

我如何调试正在发生的事情以了解 Gradle 覆盖版本的原因?

我的 JOOQ 子项目的定义:

buildscript 
  repositories 
    mavenCentral()
    jcenter()
  
  dependencies 
    ...
    classpath 'org.jooq:jooq-codegen:3.10.1'
    ... 
  

...
dependencies 
  compile 'org.jooq:jooq:3.10.1'

...

这是jooq 子项目的完整版本:https://bitbucket.org/snippets/shorn/64RnL5

并包含在api-svc 项目中:

dependencies 
  compile project(":idl")
  compile project(":api-svc:jooq")
  ...
  various other compile dependencies, spring-boot, etc.

当我执行./gradlew :api-svc:jooq:dependencies 时,它会说:

  ------------------------------------------------------------
  Project :api-svc:jooq
  ------------------------------------------------------------
  ...
  compile - Dependencies for source set 'main' (deprecated, use 'implementation ' instead).
  \--- org.jooq:jooq:3.10.1
  ...

但是,当我执行./gradlew :api-svc:dependencies 时,它会显示:

  ------------------------------------------------------------
  Project :api-svc
  ------------------------------------------------------------
  ...
  compile - Dependencies for source set 'main' (deprecated, use 'implementation ' instead).
  +--- project :idl
  |    +--- org.apache.commons:commons-lang3:3.4
  |    \--- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.8.8
  |         +--- com.fasterxml.jackson.core:jackson-core:2.8.8 -> 2.8.10
  |         \--- com.fasterxml.jackson.core:jackson-databind:2.8.8 -> 2.8.10
  |              +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0
  |              \--- com.fasterxml.jackson.core:jackson-core:2.8.10
  +--- project :api-svc:jooq
  |    \--- org.jooq:jooq:3.10.1 -> 3.9.5
  ...

这里有完整的输出,如果有帮助的话:https://bitbucket.org/snippets/shorn/4x8eaG

因此,您可以看到 Gradle 选择使用 JOOQ 的 3.9.5 版本,而不是我指定的版本。

我该如何调试为什么 Gradle 会这样做?

我可以通过添加 jooq:3.10.1 作为 api-svc 项目的直接编译依赖项来解决此问题 - 但这是多余的,据我所知,我不应该这样做。

编辑:Lukas Eder 在 cmets 中指出问题的根本原因是 Spring 依赖于 JOOQ 3.9.5 而 Gradle 正在使用它。但问题是 - 我如何在不遍历项目中的每个依赖项的情况下为自己弄清楚这一点,以防万一他们碰巧有引用扰乱了我的构建?

【问题讨论】:

你在使用 Gradle jOOQ 插件吗? @LukasEder 显然没有。这是 jooq 项目的副本:bitbucket.org/snippets/shorn/64RnL5 我明白了,所以你的依赖路径上有一些版本的 Spring Boot。它们又依赖于特定的 jOOQ 版本。他们的依赖最近才升级到 3.10.1:github.com/spring-projects/spring-boot/issues/10677。但是你可能不应该依赖他们的依赖,而是使用你自己的。不幸的是,我不太了解 Gradle,无法了解为什么默认设置会覆盖您的特定版本... @LukasEder 您是如何发现 Spring 具有 JOOQ 依赖关系的? (或者这只是因为你是 JOOQ 的人而你碰巧知道的事情?) 1) 我以前见过这个问题,不知道在哪里。 2) jOOQ 是 Spring Boot 启动器的一部分:docs.spring.io/spring-boot/docs/current/reference/html/… 【参考方案1】:

我在 Gradle 表单上发了一个帖子来尝试回答这个问题:https://discuss.gradle.org/t/how-do-i-debug-why-a-dependency-was-overridden/24572

私信里还有一些其他的讨论,但我的结论是Gradle没有办法调试这种依赖覆盖。

如果您在尝试找出自己构建的问题时发现了这个问题 - 唯一的建议似乎是您需要挖掘所有依赖项以寻找冲突的根源。

或者,尝试 *** 问题或在 Gradle 论坛上发帖。

【讨论】:

以上是关于如何调试 Gradle 为啥使用我在依赖子项目中指定的不同版本的库?的主要内容,如果未能解决你的问题,请参考以下文章

gradle 不会从我在 build.gradle 中指定的库中的依赖版本中的父属性中解析占位符

为啥我在构建项目时出现 Flutter gradle 错误?

Spring-boot 和 Gradle:构建时间太长 - 如何调试?

Eclipse在运行或调试期间没有使用gradle依赖jar

启用Gradle远程调试

即使在 build.gradle 中指定,也无法解析符号“EnableJpaRespositories”