gradle - 将传递依赖转换为 compileOnly 依赖
问题描述
我正在尝试使用 OSGI 来允许我使用两个不同版本的传递依赖项。计划是一个版本(较新的版本)将隐藏在 OSGI 包中,另一个将像往常一样位于运行时类路径中。
我已经使用 Gradle(使用 Groovy DSL)构建了 bundle jar,但问题是其相关的运行时依赖项是错误的 - 它带来了较新的版本,该版本应该隐藏在 bundle 中。当我这样做时,这仍然是正确的,在build.gradle
文件中:
compileOnly deps.diffx
runtimeOnly(deps.diffx) {
exclude group: 'com.propensive', module: 'magnolia_' + versions.scala_v
}
如果我使用 Gradledependencies
任务检查依赖关系,它显示 magnolia 已从runtimeOnly
配置中排除,正如预期的那样 - 但未从配置中排除runtimeClasspath
。
如果我随后./gradlew dependencyInsight --dependency magnolia_2.12 --configuration runtime
尝试找出此依赖项的来源,它会告诉我较新的版本来自runtimeClasspath
取决于diffx
,并且这是通过冲突解决选择的。好吧,谢谢-我已经知道了。问题是,为什么我的排除不适用于派生配置?
基本上我想做与这个问题相反的事情。
我也尝试了约束版本,但它们表现出同样的问题:
compileOnly deps.diffx
runtimeOnly(deps.diffx) {
constraints {
implementation('com.propensive:magnolia_' + versions.scala_v + ':0.10.0') {
because 'this version is required by our other dependencies'
}
}
}
解决方案
从好的方面来说,与 Maven 相比,Gradle 的排除处理将整个依赖关系图考虑在内。因此,如果一个库上有多个依赖项,则只有在所有依赖项都同意它们时才会执行排除。例如,如果我们在上面的项目中添加 opencsv 作为另一个依赖项,它也依赖于 commons-beanutils,commons-collection 不再被排除,因为 opencsv 本身并不排除它。
因此,我们可以使用依赖解析规则:
def magnoliaVersion = '0.10.0'
configurations.runtimeClasspath {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
if (details.requested.group == 'com.propensive' && details.requested.name.startsWith("magnolia_") && details.requested.version != magnoliaVersion) {
details.useVersion magnoliaVersion
details.because 'this version is required by our other dependencies'
}
}
}
然后将依赖项改回一个简单的单一的依赖项implementation
:
implementation deps.diffx
不幸的是,正如文档所述,此解析规则未发布,因此必须在任何依赖的 Gradle 模块中再次应用它。
推荐阅读
- php - 使用 nav_menu_item_id 编辑 Wordpress 菜单中的特定元素
- node.js - Mongodb.connect 不执行回调函数
- collections - Winrt 和 PhotoEditor 示例中的集合范围
- best-buy-api - 等待从 BestBuy 的 developer@support 获取 api 密钥或响应需要多长时间?
- java - 读取 DOM 并使用 selenium 为每一行创建一个数组数据结构
- java - hashmap 已更新,但从未查询过 android studio
- php - LoginController 中的 redirectTo 变量被忽略并始终重定向回“/”
- php - 如何找到字符串的加密格式
- java - java unirest如何设置内容长度
- c++ - Solaris mdb 调试器不显示正确的堆栈信息