Gradle 传递依赖排除未按预期工作。 (我如何摆脱 com.google.guava:guava-jdk5:13.0 ?)
Posted
技术标签:
【中文标题】Gradle 传递依赖排除未按预期工作。 (我如何摆脱 com.google.guava:guava-jdk5:13.0 ?)【英文标题】:Gradle Transitive dependency exclusion is not working as expected. (How do I get rid of com.google.guava:guava-jdk5:13.0 ?) 【发布时间】:2014-11-05 16:40:38 【问题描述】:这是我的 build.gradle 的 sn-p:
compile 'com.google.api-client:google-api-client:1.19.0'
compile 'com.google.apis:google-api-services-oauth2:v2-rev77-1.19.0'
compile 'com.google.apis:google-api-services-plus:v1-rev155-1.19.0'
compile 'com.google.appengine.tools:appengine-gcs-client:0.4.1'
compile 'com.google.appengine.tools:appengine-mapreduce:0.8'
它可以导入多个版本的番石榴,正如您在dependencyInsight中看到的那样:
com.google.guava:guava:15.0 (conflict resolution)
com.google.guava:guava:14.0.1 -> 15.0
+--- com.googlecode.objectify:objectify:4.1.3
| \--- default
\--- net.eusashead.spring:spring-cache-gae:1.0.0.RELEASE
\--- default
com.google.guava:guava:[15.0,15.99] -> 15.0
+--- com.google.appengine.tools:appengine-gcs-client:0.4.1
| +--- default
| +--- com.google.appengine.tools:appengine-mapreduce:0.8
| | \--- default
| \--- com.google.appengine.tools:appengine-pipeline:0.2.10
| \--- com.google.appengine.tools:appengine-mapreduce:0.8 (*)
+--- com.google.appengine.tools:appengine-mapreduce:0.8 (*)
\--- com.google.appengine.tools:appengine-pipeline:0.2.10 (*)
com.google.guava:guava-jdk5:13.0
\--- com.google.api-client:google-api-client:1.19.0
+--- default
+--- com.google.apis:google-api-services-oauth2:v2-rev77-1.19.0
| \--- default
+--- com.google.apis:google-api-services-plus:v1-rev155-1.19.0
| \--- default
+--- com.google.appengine.tools:appengine-gcs-client:0.4.1
| +--- default
| +--- com.google.appengine.tools:appengine-mapreduce:0.8
| | \--- default
| \--- com.google.appengine.tools:appengine-pipeline:0.2.10
| \--- com.google.appengine.tools:appengine-mapreduce:0.8 (*)
+--- com.google.api-client:google-api-client-appengine:1.17.0-rc
| \--- com.google.appengine.tools:appengine-gcs-client:0.4.1 (*)
+--- com.google.apis:google-api-services-storage:v1-rev1-1.18.0-rc
| \--- com.google.appengine.tools:appengine-gcs-client:0.4.1 (*)
+--- com.google.apis:google-api-services-bigquery:v2-rev154-1.19.0
| \--- com.google.appengine.tools:appengine-mapreduce:0.8 (*)
\--- com.google.api-client:google-api-client-servlet:1.17.0-rc
\--- com.google.api-client:google-api-client-appengine:1.17.0-rc (*)
(*) - dependencies omitted (listed previously)
我已尝试通过以下方式删除对 : 的依赖:
compile ('com.google.api-client:google-api-client:1.19.0')
exclude group: 'com.google.guava', module: 'guava-jdk5'
compile ('com.google.api-client:google-api-client:1.19.0')
exclude group: 'com.google.guava',
但dependencyInsight 保持不变。 我也试过了
compile ('com.google.guava:guava:15.0')force = true
但是依赖洞察力仍然保持不变。 如何摆脱 com.google.guava:guava-jdk5:13.0 ?
详情: 我在 Windows 8.1 机器上尝试过 gradle 1.2 和 2.1
我尝试这个的原因是为了摆脱这个异常:
java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch;
【问题讨论】:
如果您在命令行上清理和构建(即不涉及 IDE),是否会出现此库? 我正在通过命令行运行它。该错误仅在运行时发生 【参考方案1】:如果某处有另一个依赖项指向相同的依赖项而没有任何排除项,则似乎不会排除依赖项。
您可以通过configuration
排除依赖项:
configurations
all*.exclude group: 'com.google.guava', module:'guava-jdk5'
【讨论】:
这对我有用。谢谢!但就个人而言,我不喜欢 gradle 处理依赖项的方式。 Maven 更加清晰和简单。【参考方案2】:基于@thoutbeckers 的回答,由于一个特殊情况,我认为他的回答并不适用,但它确实适用。希望这个答案可以帮助其他分享我的特殊情况问题的人。最初我认为错误的传递依赖项仅被build.gradle
文件中的一个依赖项引用,但实际上它被两个依赖项引用。这是因为引用错误传递依赖的两个依赖都具有父/子关系,但我只注意到与子依赖的关系,而不是父依赖。
考虑以下依赖树(由命令gradle <my-project-name>:dependencies
生成):
compileClasspath - Compile classpath for source set 'main'.
+--- my.org:com.my.pkg.parent:6.+ -> 6.0.4
| +--- # misc. dependencies
| +--- my.org:com.my.pkg.child:6.0.4
| | +--- # misc. dependencies
| | +--- other.org:bad.transitive.dependency:0.9.1 FAILED
| | +--- # misc. dependencies
| |--- # misc. dependencies
+--- # misc. dependencies
从依赖关系树看来,other.org:bad.transitive:dependency:0.9.1
似乎只被构建文件中的一个依赖项引用,而不是两个。但是,假设您的 Gradle 文件如下所示:
// ... misc. ...
dependencies
// ... misc. dependencies ...
compile 'my.org:com.my.pkg.parent:6.+'
// ... misc. dependencies ...
compile ('my.org:com.my.pkg.child:6.0.4')
exclude group: 'other.org', module: 'bad.transitive.dependency'
对于像上面这样的 Gradle 文件,即使您要排除的传递依赖项仅发生在子依赖项中,而不是父依赖项中,错误也会持续存在。但是,因为父项目和子项目都被 build.gradle
文件引用,所以必须从这两个依赖项中排除错误的传递依赖项,正如上面的 @thoutbeckers 所述。
请注意,如果您不想在配置级别添加排除项(正如@thoutbeckers 在他们的回答中显示的那样),您始终可以明确地从引用它的两个依赖项中排除传递依赖项。
【讨论】:
【参考方案3】:原来 guava-jdk5 还在维护中。
所以我改变了这个:
compile ('com.google.guava:guava:15.0')force = true
为此:
compile('com.google.guava:guava-jdk5:17.0') force = true
这解决了我的问题,我现在可以使用 Google App Engine 项目中“com.google.common”包中的类以及所有描述的依赖项
【讨论】:
不,在我看来,JDK5 变体没有得到维护。 Guava 最高为 18.0,但 jdk5 变体没有 18。见 search.maven.org/…【参考方案4】:我遇到了gradle dependencies
这种奇怪行为的几个原因:
gradle clean dependencies
考虑设置环境变量GRADLE_OPTS=-Dorg.gradle.daemon=false -Dorg.gradle.caching=false
以避免缓存或在命令行中提供这些选项
dependencies
报告本身具有欺骗性,因为它可能不会显示(也未指明)通过其他路径到达的相同不需要的依赖项的下一次出现。然后从第一条路径中排除传递的不需要的依赖项不起作用并且仍然在该路径上显示它,无论它来自另一个(不可见)路径。
识别所有路径通过并从所有路径中排除不需要的依赖项。
注释掉第一个路径/依赖运行gradle clean dependencies
以找到到达依赖的下一个路径。重复直到找到所有此类路径。然后取消注释并从所有标识的路径中排除不需要的依赖项。
【讨论】:
【参考方案5】:似乎 Gradle 的工作方式是每个依赖项都会带来其所有传递依赖项。如果您将其中一些从一个依赖项中排除,它们可能是由其他依赖项带来的。
如果你有
compile 'com.google.api-client:google-api-client:1.19.0'
compile 'com.google.apis:google-api-services-oauth2:v2-rev77-1.19.0'
compile 'com.google.apis:google-api-services-plus:v1-rev155-1.19.0'
为了从构建过程中排除com.google.guava:guava-jdk5
,您必须从它们中排除它:
compile ('com.google.api-client:google-api-client:1.19.0')
exclude group: 'com.google.guava', module: 'guava-jdk5'
compile ('com.google.apis:google-api-services-oauth2:v2-rev77-1.19.0')
exclude group: 'com.google.guava', module: 'guava-jdk5'
compile ('com.google.apis:google-api-services-plus:v1-rev155-1.19.0')
exclude group: 'com.google.guava', module: 'guava-jdk5'
dependencyInsight
可以帮助找出在哪里放置exclude
。它显示了在其传递依赖项中具有特定依赖项的依赖项列表(不幸的是,它没有显示其中哪些已经在配置中排除了它)
更简单的方法是从整个配置(或从所有配置)中排除依赖:
configurations.all
exclude group: 'com.google.guava', module: 'guava-jdk5'
参考:https://docs.gradle.org/current/userguide/resolution_rules.html#excluding_a_dependency_from_a_configuration_completely
【讨论】:
以上是关于Gradle 传递依赖排除未按预期工作。 (我如何摆脱 com.google.guava:guava-jdk5:13.0 ?)的主要内容,如果未能解决你的问题,请参考以下文章
Android Gradle 插件Gradle 依赖管理 ⑦ ( dependencies 传递依赖设置 | transitive 关闭依赖传递配置 | exclude 排除子依赖配置 )
Gradle-5.3:依赖-管理依赖的版本(传递(transitive)排除(exclude)强制(force)动态版本(+))