Gradle:通过版本分类器覆盖传递依赖

69

我的项目中声明的一个依赖项具有对'com.google.guava:guava:15.0'的传递依赖。但由于CDI问题,我在WAS / Weblogic上部署的应用程序无法正常工作,这个问题已经在'com.google.guava:guava:15.0:cdi1.0'中得到了解决。(相同版本,但带有分类器) 我需要告诉gradle在构建和打包过程中使用这个jar文件。我正在尝试弄清楚如何使用特定版本分类器覆盖这个传递依赖。

尝试了以下方法:

  1. 显式添加依赖项:compile 'com.google.guava:guava:15.0:cdi1.0'。但是,两个jar都被包含在生成的WAR中。

  2. 显式添加依赖项并定义解析策略:

    configurations.all {
        resolutionStrategy {
            force 'com.google.guava:guava:15.0:cdi1.0'
        }
    }
    

即使这样也没有起作用。

  1. 定义了一种解析策略来检查和更改版本。

configurations.all {
     resolutionStrategy.eachDependency { DependencyResolveDetails details ->
         if (details.requested.group + ":" + details.requested.name == 'com.google.guava:guava') {
            details.useVersion "15.0:cdi1.0"
            //details.useTarget "com.google.guava:guava:15.0:cdi1.0"
        }
    }
}

甚至这个也没用。

需要你的建议,如何解决这个问题。

9个回答

75

目前在解决方案(resolutionStrategies)方面还没有考虑分类器。您可以采用一种变通方法,即在声明依赖项时排除传递性 Guava 库,并显式添加 Guava cdi1.0 版本:

dependencies {
    compile ("org.acme:someDependency:1.0"){
        exclude group: 'com.google.guava', module: 'guava'
    }       
    compile "com.google.guava:guava:15.0:cdi1.0"
}

10
请注意,这不再是正确的答案。请参阅有关升级(可传递)依赖项的信息:https://docs.gradle.org/current/userguide/dependency_constraints.html 以及有关降级或排除(可传递)依赖项的信息:https://docs.gradle.org/current/userguide/dependency_downgrade_and_exclude.html - Pieter
1
@Pieter 我鼓励你提交一个新答案,因为当前的答案都没有包括约束条件的答案。 - yshavit

41

我发现了一种更优雅的方法,就是:

compile ("com.google.guava:guava:15.0:cdi1.0") {
  force = true
}

解释

在依赖项中设置 force = true,告诉 Gradle 在版本冲突时使用指定的版本。


5
我得到了 'force' is deprecated 的提示,意思是“'force'已经过时”。 - lionello
7
使用implementation("...") { version { strictly("...") } } - Dr.jacky

17

6

Gradle 4.5.1有一个名为DependencySubstitutions的功能。下面是一个替换依赖项的例子:

configurations.each {
    c -> c.resolutionStrategy.dependencySubstitution {
        all { DependencySubstitution dependency ->
            if (dependency.requested.group == 'org.json') {
                dependency.useTarget 'com.vaadin.external.google:android-json:0.0.20131108.vaadin1'
            }
        }
    }
}

4

由于 force = true 已被弃用,相关解决方案是使用 strictly(...) 版本,例如:

dependencies {
    // no need to exclude transitive spring-data-relational from this dependency
    implementation("org.springframework.data", "spring-data-r2dbc", "1.1.0.RC1")

    implementation("org.springframework.data", "spring-data-relational").version {
        strictly("2.0.0.RC1")
    }
}

P.S. 已在 Gradle 6.3 上进行测试。


1
有文档吗?“strictly”在Gradle 6.4.1中不起作用。 - happy
1
@happy 我在 https://docs.gradle.org/current/userguide/rich_versions.html#rich-version-constraints 上找到的文档链接如下:implementation( group: 'commons-codec', name: 'commons-codec'){ version{ strictly "[1.15]" } } - Pravanjan

3

如果同一依赖项被其他 jar 文件指向,此方法将无法起作用。排除依赖项的绝佳方法。

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

2

我通过从导致此重复错误的模块中排除org.bouncycastle来解决它。

build.gradle(:app)

implementation(project(Modules.yourModuleName)) {
    exclude group: 'org.bouncycastle'
}

1

试试这个:

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->

        // https://docs.gradle.org/current/userguide/resolution_rules.html
        if (details.requested.group == 'com.google.guava' && details.requested.name == 'guava') {
            details.useVersion '15.0:cdi1.0'
        }
    }
}

放在哪里?放在Android标签内还是外部? - undefined

0

尝试这个,在我的情况下在 App 级别的 build.gradle 文件中完美运行

android {
configurations {
    all*.exclude module: 'conceal'

    all*.exclude module: 'bcprov-jdk15on'
    }
}   

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接