Gradle:如何让多依赖使用同一传递依赖的不同版本
在Gradle中为不同依赖指定特定版本的传递依赖
首先要明确:Java的类加载机制决定了同一个类加载器下无法同时存在同一类的两个版本,所以我们没法让两个版本的google-api-client同时出现在主类路径中。但可以通过Gradle的依赖解析策略,强制让google-tink使用1.33.2版本,同时保证beam-dataflow-java使用2.2.0版本——不过要注意:如果两个库对google-api-client的API使用存在不兼容,可能会引发运行时异常(比如NoSuchMethodError),建议先验证兼容性,或者优先尝试升级google-tink到兼容2.2.0的版本(如果可用),这是更稳妥的方案。
下面是两种可行的Gradle配置方案:
方案1:通过resolutionStrategy按依赖路径指定版本
在build.gradle(Groovy)或build.gradle.kts(Kotlin)中,配置依赖解析策略,根据依赖树的路径区分版本:
Groovy DSL 示例:
configurations.all { resolutionStrategy.eachDependency { details -> def req = details.requested if (req.group == 'com.google.api-client' && req.name == 'google-api-client') { // 判断依赖是否来自google-tink if (details.target.path.contains('com.google.crypto.tink:tink')) { details.useVersion '1.33.2' } else { // 其他依赖(比如beam)使用2.2.0 details.useVersion '2.2.0' } } } }
Kotlin DSL 示例:
configurations.all { resolutionStrategy.eachDependency { val req = requested if (req.group == "com.google.api-client" && req.name == "google-api-client") { if (target.path.contains("com.google.crypto.tink:tink")) { useVersion("1.33.2") } else { useVersion("2.2.0") } } } }
方案2:排除传递依赖后手动指定版本
先排除beam-dataflow-java传递的google-api-client,再分别为两个库指定所需版本:
Groovy DSL 示例:
dependencies { // 引入beam-dataflow-java并排除其传递的google-api-client implementation('org.apache.beam:beam-dataflow-java') { exclude group: 'com.google.api-client', module: 'google-api-client' } // 手动引入beam需要的2.2.0版本 implementation 'com.google.api-client:google-api-client:2.2.0' // 引入google-tink,并通过约束强制其使用1.33.2版本 implementation 'com.google.crypto.tink:tink:1.7.0' constraints { implementation('com.google.api-client:google-api-client') { because 'google-tink requires version 1.33.2' version { strictly '1.33.2' prefer '1.33.2' } } } }
配置完成后,可以通过./gradlew dependencies命令查看依赖树,确认google-tink对应的google-api-client版本为1.33.2,beam-dataflow-java对应的版本为2.2.0。
内容的提问来源于stack exchange,提问作者Mahesh Ramchandra Bhatkande
相关产品推荐
相关产品推荐

