将传递依赖转换为 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'
        }
    }
}

来自the Gradle documentation

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 模块中再次应用它。