将传递依赖转换为 compileOnly 依赖
Converting a transitive dependency into a compileOnly dependency
我正在尝试使用 OSGI 来允许我使用两个不同版本的传递依赖项。计划是一个版本(较新的版本)将隐藏在 OSGI 包中,另一个将像往常一样位于运行时类路径中。
我已经使用 Gradle(使用 Groovy DSL)构建了 bundle jar,但问题是它相关的运行时依赖是错误的——它带来了更新的版本,这应该是隐藏在包内。当我在 build.gradle
文件中这样做时,这仍然是正确的:
compileOnly deps.diffx
runtimeOnly(deps.diffx) {
exclude group: 'com.propensive', module: 'magnolia_' + versions.scala_v
}
如果我检查与 Gradle dependencies
任务的依赖关系,它表明 magnolia 被排除在 runtimeOnly
配置之外,正如预期的那样 - 但 不是 从 runtimeClasspath
配置中排除。
如果我随后使用 ./gradlew dependencyInsight --dependency magnolia_2.12 --configuration runtime
尝试找出此依赖项的来源,它会告诉我较新的版本来自 runtimeClasspath
,具体取决于 diffx
,并且这是通过冲突解决选择的。好吧,谢谢 - 我已经知道了。问题是,为什么 我的排除未应用于派生配置?
基本上我想做与this question相反的事情。
我也试过约束版本,但他们表现出同样的问题:
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'
}
}
}
On the upside, Gradle’s exclude handling is, in contrast to Maven, taking the whole dependency graph into account. So if there are multiple dependencies on a library, excludes are only exercised if all dependencies agree on them. For example, if we add opencsv as another dependency to our project above, which also depends on commons-beanutils, commons-collection is no longer excluded as opencsv itself does not exclude it.
因此,我们可以使用 dependency resolve rule:
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 模块中再次应用它。
我正在尝试使用 OSGI 来允许我使用两个不同版本的传递依赖项。计划是一个版本(较新的版本)将隐藏在 OSGI 包中,另一个将像往常一样位于运行时类路径中。
我已经使用 Gradle(使用 Groovy DSL)构建了 bundle jar,但问题是它相关的运行时依赖是错误的——它带来了更新的版本,这应该是隐藏在包内。当我在 build.gradle
文件中这样做时,这仍然是正确的:
compileOnly deps.diffx
runtimeOnly(deps.diffx) {
exclude group: 'com.propensive', module: 'magnolia_' + versions.scala_v
}
如果我检查与 Gradle dependencies
任务的依赖关系,它表明 magnolia 被排除在 runtimeOnly
配置之外,正如预期的那样 - 但 不是 从 runtimeClasspath
配置中排除。
如果我随后使用 ./gradlew dependencyInsight --dependency magnolia_2.12 --configuration runtime
尝试找出此依赖项的来源,它会告诉我较新的版本来自 runtimeClasspath
,具体取决于 diffx
,并且这是通过冲突解决选择的。好吧,谢谢 - 我已经知道了。问题是,为什么 我的排除未应用于派生配置?
基本上我想做与this question相反的事情。
我也试过约束版本,但他们表现出同样的问题:
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'
}
}
}
On the upside, Gradle’s exclude handling is, in contrast to Maven, taking the whole dependency graph into account. So if there are multiple dependencies on a library, excludes are only exercised if all dependencies agree on them. For example, if we add opencsv as another dependency to our project above, which also depends on commons-beanutils, commons-collection is no longer excluded as opencsv itself does not exclude it.
因此,我们可以使用 dependency resolve rule:
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 模块中再次应用它。