【问题标题】:Dependency management between modules模块之间的依赖管理
【发布时间】:2017-07-15 13:52:17
【问题描述】:

如果我的模块 A 和模块 B 都需要 JSON 库(比如 GSON), 然后我有包含模块 A 和 B 的应用程序 C。如果模块 A 和 B 使用不同的版本,我有可能获得两个不同版本的 JSON 库吗?还是 gradle 删除其中一个并只使用其中一个版本?

如果我有更多模块,更新它们以使用相同版本的依赖项似乎需要做很多工作。在这种情况下,让应用程序 C 决定在所有模块上使用哪个版本会很好(但由于向后兼容性,我猜它并不总是有效)。无论如何要做到这一点?

所以我的问题是如何最好地处理在许多模块中非常常见的依赖关系。我是否应该在我的所有模块中注入一个 Json 包装器,让应用程序定义要使用的内容?

我猜日志记录可能是一个类似的依赖项

【问题讨论】:

    标签: java gradle dependency-management


    【解决方案1】:

    是的。如果您在项目 A 和 B 中特别要求同一库的不同版本,您最终可能会得到相同直接依赖项的不同版本。

    对于临时依赖,默认行为是选择请求依赖的最新版本。请注意最新这个词,而不是要求的最高版本。只要版本向后兼容您的项目实际期望的最低版本,这很好。

    幸运的是,gradle 有几个内置的方法来解决依赖冲突。

    我在这里写了很多关于这个主题的文章:http://www.devsbedevin.net/android-understanding-gradle-dependencies-and-resolving-conflicts/

    TL;DR

    您可以选择在冲突中失败:

    configurations.all {  
      resolutionStrategy {
        failOnVersionConflict()
      }
    }
    

    强制一个特定的依赖:

    configurations.all {  
      resolutionStrategy {
        force 'asm:asm-all:3.3.1', 'commons-io:commons-io:1.4', 'com.parse.bolts:bolts-android:1.+'
      }
    }
    

    更喜欢你自己的模块:

    configurations.all {  
      resolutionStrategy {
        preferProjectModules()
      }
    }
    

    将库 X 的所有实例替换为 Y(库、模块或项目):

    configurations.all {  
      resolutionStrategy {
        dependencySubstitution {
          substitute module('commons-io:commons-io:2.4') with project(':my-commons-io')
        }
      }
    }
    

    排除特定库的所有临时依赖项并手动添加必要的库:

    dependencies {  
        compile('com.android.support:appcompat-v7:23.1.0') {
            transitive = false
        }
    }
    

    排除特定的传递依赖:

    dependencies {  
        compile('com.android.support:appcompat-v7:23.1.0') {
            exclude group: 'com.parse.bolts'
        }
    }
    

    无论实际的依赖要求如何,强制您的项目使用特定版本:

    dependencies {  
        compile('com.parse.bolts:bolts-android:1.+') {
            force = true
        }
    }
    

    【讨论】:

    • 非常好的答案,谢谢! :) 我认为在我的情况下,我将使用库的包装器,为所有需要它的模块提供我自己的依赖项。但这是一篇非常出色的文章!
    【解决方案2】:

    考虑一个包含两个模块/项目的 Gradle 构建。 settings.gradle 文件:

    include 'modA', 'modB'
    

    假设两者都使用commons-lang3-3.6modA 使用gson-2.8.1,而modB 使用gson-2.2.4。可以在根目录的build.gradle 文件中进行配置:

    subprojects { p ->
        apply plugin: 'java'
    
        repositories {
            jcenter()
        }
        dependencies {
            compile 'org.apache.commons:commons-lang3:3.6'
        }
    
        if (p.name == 'modA') {
            dependencies {
                compile 'com.google.code.gson:gson:2.8.1'
            }
        } else if (p.name == 'modB') {
            dependencies {
                compile 'com.google.code.gson:gson:2.2.4'
            }
        }
    }
    

    可以通过以下方式确认所需的配置:

    $ gradle :modA:dependencies
    $ gradle :modB:dependencies
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-14
      • 1970-01-01
      • 2016-08-14
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      相关资源
      最近更新 更多