如何强制Gradle为两个依赖项设置相同的版本?


73

我使用以下两个依赖项:

compile 'com.google.guava:guava:14.0.1'
compile 'com.google.guava:guava-gwt:14.0.1'

两者必须为同一版本才能正常工作。由于我的其他依赖项使用更高的版本,因此Gradle为每个依赖项使用不同的版本。

我通过运行发现了这一点gradle dependencies

compile - Compile classpath for source set 'main'.
+--- com.google.guava:guava:14.0.1 -> 17.0
+--- com.google.guava:guava-gwt:14.0.1
|    +--- com.google.code.findbugs:jsr305:1.3.9
|    \--- com.google.guava:guava:14.0.1 -> 17.0 

如何强制Gradle为这两个依赖项设置相同的版本?

Answers:


17

您的依赖项之一是强制更新番石榴版本。使用gradle dependencies以定位库驱逐你的版本。

您遇到的问题是,如果您强制它使用14.0.1,则另一个库可能无法正常工作。您是否可以仅使用17.0版本作为依赖项?

我不是在build.gradle中维护单个版本号,而是使用dependencies.gradle文件,该文件将具有版本号的映射并将其拉入build.gradle。这样,我只需要维护单个番石榴版本。因此,您的示例将是:

Dependencies.gradle

ext {
    ver = [
        guava: '14.0.1'
    ]
}

然后在build.gradle文件中,您可以拥有:

apply from: "dependencies.gradle"

dependencies {
    compile group: 'com.google.guava', module: 'guava', version: ver.guava
    compile group: 'com.google.guava', module: 'guava-gwt', version: ver.guava
}

那么当我想移至17.0时,我只需要更改dependencies.gradle。

我也是将传递依赖项设置为false的绝对支持者

configurations.compile { transitive = false }

这样,尽管在退出时库没有完全向后兼容,但在运行时可能会遇到问题,尽管编译时没有退出某些依赖项。面对现实吧,如果您正在编写代码,则应该知道使用了哪些库,并且应该明确了解依赖项。它可以保护您免受依赖升级或使您陷入混乱的依赖之一。


102

将此部分添加到dependencies.gradle文件中

configurations.all {
        resolutionStrategy { 
            force 'com.google.guava:guava:14.0.1'
            force 'com.google.guava:guava-gwt:14.0.1'
        }
    }

28
将其放在gradle文件中的哪里?在方块的底部?
IgorGanapolsky

1
我仍然收到以下错误:Execution failed for task ':transformClassesWithJarMergingForDebug'. > com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: com/google/android/gms/gcm/GoogleCloudMessaging$1.class
IgorGanapolsky '16

1
@IgorGanapolsky位置通常并不重要,但我会将其放在顶部附近。
cmcginty

2
这正好在dependencies.gradle文件
华Iurchuk

1
@cmcginty“扩展类型”是什么意思?
Aravinth '19

62
configurations.all {
  resolutionStrategy.eachDependency { details ->
    if (details.requested.group == 'com.google.guava') {
      details.useVersion "14.0.1"
    }
  }
}

dependencies {
  compile 'com.google.guava:guava'
  compile 'com.google.guava:guava-gwt'
}

由于某种原因,force方法不会阻止将其他版本的库添加到jar文件中,但是使用您的方法,我将在jar文件中获得同一库的多个确切版本。更近了一步。谢谢!
瑞斯(Reith)

1
在androidsudio 3.3.0中找不到DependencyResolveDetails
X先生

@MrX我已经从代码中删除了不必要的DependencyResolveDetails提及。请重试
Vyacheslav Shvets's

40

我遇到过类似的情况,其中一个依赖项使用了spring-web 4.2.4,它已损坏。您必须强制使用所需的特定库版本。如另一条评论中所述,这可能会导致兼容性问题,但有时是必需的。

强制我发现的库版本的最低介入方式不是使用

compile "org.springframework:spring-web:4.2.3.RELEASE"

将依赖项配置指定为强制:

compile("org.springframework:spring-web:4.2.3.RELEASE"){
    force = true
}

我需要临时降级Spring版本时使用它(直到下一个版本)。


4

另一个选择是使用依赖关系约束:https : //docs.gradle.org/current/userguide/dependency_constraints.html

dependencies {
    implementation 'org.apache.httpcomponents:httpclient'
    constraints {
        implementation('org.apache.httpcomponents:httpclient:4.5.3') {
            because 'previous versions have a bug impacting this application'
        }
        implementation('commons-codec:commons-codec:1.11') {
            because 'version 1.9 pulled from httpclient has bugs affecting this application'
        }
    }
}

2

或者,您可以在spring-dependency-management Gradle插件中使用dependencySets(或在可用BOM BOM时使用mavenBom)支持。请注意,此插件也会与spring-boot Gradle插件一起自动应用。有关更多详细信息,请参见此处

plugins {
  id 'io.spring.dependency-management' version '1.0.1.RELEASE'
}

dependencyManagement {
  dependencies {
    dependencySet(group: 'com.google.guava', version: '14.0.1') {
      entry 'guava'
      entry 'guava-gwt'
    }
  }
}

dependencies {
  compile 'com.google.guava:guava'
  compile 'com.google.guava:guava-gwt'
}


1

如果可以对两个依赖项都使用较新版本,则解决问题的最简单方法是更新依赖项:

compile 'com.google.guava:guava:17.0'
compile 'com.google.guava:guava-gwt:17.0'

这将确保它们都在17.0上。这比尝试将它们都强制在旧版本上简单,而且作为一个额外的好处,您可以获得一个新版本,这个新版本(可能)包含错误修复和新功能。

坦白地说,@ Klunk在回答中提到了这一点,问“您是否可以仅将17.0版本用作依赖项?”,但这只是顺便说一句,很容易遗漏,因此我认为将其作为单独的答案发布是有道理的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.