【问题标题】:How can I force Gradle to set the same version for two dependencies?如何强制 Gradle 为两个依赖项设置相同的版本?
【发布时间】:2015-04-11 05:08:09
【问题描述】:

我使用以下两个依赖:

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 为这两个依赖项设置相同的版本?

【问题讨论】:

    标签: java gradle dependencies


    【解决方案1】:

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

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

    【讨论】:

    • 把这个放在 gradle 文件的什么地方?在区块的底部?
    • 我仍然收到如下错误: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 位置通常并不重要,但我会把它放在顶部附近。
    • 这在dependencies.gradle文件中
    • @cmcginty “扩展类型”是什么意思?
    【解决方案2】:
    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'
    }
    

    【讨论】:

    • 由于某种原因,强制方法并没有阻止将其他版本的库添加到 jar 文件中,但是使用您的方法,我将在 jar 文件中获得同一个库的多个确切版本。更近了一步。谢谢!
    • 在 androidsudio 3.3.0 中找不到 DependencyResolveDetails
    • @MrX 我已经从代码中删除了不必要的 DependencyResolveDetails 提及。请重试
    【解决方案3】:

    我遇到过类似的情况,其中一个依赖项使用了损坏的 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 版本时使用它(直到下一个版本)。

    【讨论】:

    • force = true 现已弃用
    【解决方案4】:

    您的依赖项之一是强制更新 guava 版本。使用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 }
    

    这样你就不会在编译时驱逐一些依赖项,尽管如果驱逐库不完全向后兼容,你可能会在运行时遇到问题。让我们面对它,如果您正在编写代码,您应该知道您使用哪些库并且您应该明确说明您的依赖关系。它可以保护您免受其中一个依赖项升级和搞砸。

    【讨论】:

      【解决方案5】:

      另一种选择是使用依赖约束: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'
              }
          }
      }
      

      【讨论】:

        【解决方案6】:

        我建议不要设置transitive = false,因为这种方法会迫使你自己手动解决依赖关系树。

        您可以通过configurations.all 强制使用所需的番石榴版本,或者显式添加依赖项并将其设置为forced = true

        此处的示例:http://www.devsbedevin.net/android-understanding-gradle-dependencies-and-resolving-conflicts/

        【讨论】:

          【解决方案7】:

          您也可以在 spring-dependency-management Gradle 插件中使用 dependencySets(或当 BOM POM 可用时使用 mavenBom)支持。请注意,此插件也会自动与 spring-boot Gradle 插件一起应用。更多详情请见here

          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'
          }
          

          【讨论】:

            【解决方案8】:

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

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

            这将确保它们都在 17.0.0 上。这比试图在旧版本上强制使用它们更简单,并且作为额外的奖励,你会得到一个新版本,它(可能)带有错误修复和新功能。

            公平地说,@Klunk 在他的回答中提到了这一点,他问“你能不能只使用 17.0 版本作为你的依赖项?”,但这只是顺带一提,很容易错过,所以我认为发布为一个单独的答案。

            【讨论】:

              【解决方案9】:

              您可以像这样“强制”gradle 中的库/依赖项的版本:

                  configurations.all {
                      resolutionStrategy {
                          force("org.jetbrains.kotlin:kotlin-stdlib:1.4.32",
                              "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.32", 
              "org.jetbrains.kotlin:kotlin-reflect:1.4.32"
                          )
                      }
                  }
              

              您可以在此处获得更多信息:https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-12-29
                • 2014-11-17
                • 1970-01-01
                • 1970-01-01
                • 2019-03-30
                • 2019-12-23
                相关资源
                最近更新 更多