2个不同依赖问题中的相同接口

Same interface in 2 different dependency issue

我有依赖冲突问题。

我的项目有两个这样的依赖项:

dependencies {

  provided group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'

  compile files('path/to/ABC.jar')

}

ABC.jarjavax.servlet:servlet-api:

有自己的依赖
dependencies {

  provided group: 'javax.servlet', name: 'servlet-api', version: '2.5'

}

这是我正在处理的问题;我需要使用 servlet-api 库提供的 ServletContext 接口,而编译器使用了错误的接口。

Gradle 按照 here 所述自动解决版本冲突。

但在我的情况下它没有帮助,因为它仅在依赖项具有两个不同版本时才有效。在这种情况下;虽然这是一个较新的版本问题,但名称已从 javax.servlet:servlet-api 更改为 javax.servlet:javax.servlet-api。所以 gradle 不会自动解决这个冲突,因为它似乎不是版本问题。

我尝试的是使用排除传递依赖,如here所述。

compile files('path/to/ABC.jar') {
    exclude group: 'javax.servlet'
}

但是没用,似乎 exclude 对本地 'jar' 文件不起作用。

现在,我不知道还能做什么。

如何排除作为本地文件添加的依赖项的依赖项?

(如果第一个问题还没有答案)我怎么告诉编译器使用正确的ServletContext接口?

我现在无法测试这个,但我相信你的语法是错误的。我这里有一些看起来不同的例子,在你的情况下是:

compile(files('path/to/ABC.jar')) {
    exclude group: 'javax.servlet'
}

正如我所说,我现在无法测试它,看看它是否有帮助并发表评论。

compile files('path/to/ABC.jar')是文件依赖,文件依赖没有任何依赖信息,所以不会引入传递依赖。如果此 ABC.jar 是一个 "fat" jar,它具有包含在 JAR 中的依赖项-类,则它不适合在 Gradle、Maven 或 [=36 之类的东西中使用=] 应该处理依赖关系。您将必须使用正确的 "thin" 版本的依赖项并正确声明依赖项,或者您需要 "repackage" 构建脚本中的 JAR 以排除您不需要的依赖项 类想拉进来。没有依赖管理可以为你做这件事。

你可以执行gradlew dependencyInsight --configuration runtime --dependency javax.servlet:servlet-apigradlew dependencies --configuration runtime来找出依赖的真正来源。


实际上,如果我没看错的话,你的例子应该不会编译,因为它很可能是

compile files('path/to/ABC.jar'), {
    exclude group: 'javax.servlet'
}

compile(files('path/to/ABC.jar')) {
    exclude group: 'javax.servlet'
}

但正如我所说,对于本地文件依赖性,没有传递依赖性,因此无论如何排除都没有任何意义。


要使 Gradle 版本冲突魔术发挥作用,您可以简单地告诉 Gradle 这些库实际上是同一个库,只是通过使用像

这样的模块替换,只是坐标不同
dependencies {
    modules {
        module('javax.servlet:servlet-api') {
            replacedBy 'javax.servlet:javax.servlet-api'
        }
    }
}

然后 Gradle 将它们视为同一个库,并且可以发挥其版本冲突解决的魔力。需要旧版本的库是否仍然适用于新版本是一个不同的主题,您必须检查和/或自己尝试。这个like总是要看新版本是否向后兼容旧版本。