如何调试 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:构建时间太长 - 如何调试?