Java 渐变传递依赖项排除未按预期工作。(我如何摆脱com.google.guava:guava-jdk5:13.0?)

Java 渐变传递依赖项排除未按预期工作。(我如何摆脱com.google.guava:guava-jdk5:13.0?),java,google-app-engine,mapreduce,gradle,guava,Java,Google App Engine,Mapreduce,Gradle,Guava,以下是my build.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' compile 'com.google.appengine.t

以下是my build.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'
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

详情: 我在Windows8.1上试过Gradle1.2和2.1

我尝试此操作的原因是为了消除此异常:

java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch;

事实证明,番石榴-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”包中的类来描述所有依赖项

如果某个地方有另一个依赖项指向同一个依赖项,而没有任何排除项,那么该依赖项似乎不会被排除

您可以通过
配置
排除依赖项,但是:

configurations {
  all*.exclude group: 'com.google.guava', module:'guava-jdk5'
}

基于@thoutbeckers的回答,由于一个特殊情况,我认为他的回答不适用,但事实上确实适用。希望这个答案能帮助其他人分享我的特例问题。起初,我认为坏的可传递依赖项只被
build.gradle
文件中的一个依赖项引用,但实际上它被两个依赖项引用。这是因为引用坏传递依赖项的两个依赖项都有父/子关系,但我只注意到了与子依赖项的关系,而没有注意到与父依赖项的关系

考虑以下依赖关系树(由命令生成):

从依赖项树中,它看起来像是构建文件中的一个依赖项引用了
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在其回答中所示),您可以始终明确地从引用的两个依赖项中排除可传递依赖项。

我遇到了导致这种奇怪的
渐变依赖项行为的几个原因:

  • 结果表明,Gradle4.10.x在其守护进程中缓存了一些临时结果,因此仅运行该命令可能不是最新的。因此,禁用Gradle守护进程
  • 还有其他工具和IDE(Eclipse等)可以运行Gradle守护进程来进行自己的集成和项目构建。因此,检查其他守护进程并杀死它们
  • 即使禁用了守护进程,也似乎有一些额外的缓存,因此请运行
    gradleclean dependencies
  • 考虑设置环境变量
    GRADLE\u OPTS=-Dorg.GRADLE.daemon=false-Dorg.GRADLE.caching=false
    ,以避免缓存或在命令行中提供这些选项
  • 依赖关系
    报告本身具有欺骗性,因为它可能不会显示(也不会指示)通过其他路径到达的相同或不需要的依赖关系的下一次出现。然后从第一条路径中排除可传递的不需要的依赖项不起作用,并且仍然在该路径上显示它,无论它通过另一条(不可见)路径
识别所有路径到达不需要的依赖项的路径,并将其从所有路径中排除


注释掉第一个路径/依赖项运行
gradle clean dependencies
,以找到该依赖项通过的下一个路径。重复此操作,直到找到所有此类路径。然后取消注释并将不需要的依赖项从所有识别的路径中排除。

似乎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
可以帮助您找到将
排除在哪里。它显示了在其可传递依赖项中具有特定依赖项的依赖项列表(不幸的是,它没有显示其中哪些已在配置中排除了它)


更简单的方法是从整个配置(或所有配置)中排除依赖项:


参考:

如果在命令行上清理和构建(即不涉及IDE),是否会显示此库?我正在通过命令行运行它。错误只发生在运行时否,在我看来JDK5变体没有被维护。番石榴的最高版本是18.0,但jdk5变种没有18。看,这对我有用。谢谢但就我个人而言,我不喜欢gradle处理依赖关系的方式。Maven更加清晰和简单。
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'
}
configurations.all {
    exclude group: 'com.google.guava', module: 'guava-jdk5'
}