Gradle: Springboot 重写依赖(jersey 和 apache httpclient)
Gradle: Springboot overriding dependencies (jersey and apache httpclient)
我有一个非常简单的spring引导应用程序用于测试目的。
这是我的 build.gradle:
plugins {
id 'org.springframework.boot' version '2.1.0.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mandas:docker-client:2.0.2'
}
org.mandas:docker-client:2.0.2
对 org.glassfish.jersey.core:jersey-client:2.28
具有传递依赖性。但是 gradle 然后提取版本 2.27
而不是 2.28
.
如果我 运行 ./gradlew dependencyInsight --dependency org.glassfish.jersey.core:jersey-client
我得到以下输出:
org.glassfish.jersey.core:jersey-client:2.27 (selected by rule)
...
org.glassfish.jersey.core:jersey-client:2.27
\--- org.glassfish.jersey.connectors:jersey-apache-connector:2.27
\--- org.mandas:docker-client:2.0.2 (requested org.glassfish.jersey.connectors:jersey-apache-connector:2.28)
\--- compileClasspath
org.glassfish.jersey.core:jersey-client:2.28 -> 2.27
\--- org.mandas:docker-client:2.0.2
\--- compileClasspath
似乎 spring-boot-starter-web
以某种方式依赖于 org.glassfish.jersey.core:jersey-client:2.27
。但是,如果我使用 ./gradlew dependencies
打印所有依赖项,我看不到 spring-boot-starter-web
.
对 org.glassfish.jersey.core:jersey-client:2.27
的依赖项
然而,在网上搜索了一下,我发现了另一种追踪依赖关系的方法:
grep -r "2.27" ~/.gradle/caches/modules-2/files-2.1/*
像这样,我能够找到 2.27 版的引入位置。它似乎在以下 poms 中声明:
- spring-boot-dependencies-2.1.0.RELEASE.pom
- spring-boot-autoconfigure-2.1.0.RELEASE.pom
我现在的问题是多方面的:
- 首先,为什么
spring-boot-starter-web
依赖于jersey
?我一直认为,如果我们想在 spring
实现上明确使用 jersey
,我们将包括 spring-boot-starter-jersey
.
- 为什么在运行宁
./gradlew dependencies
时看不到spring-boot-starter-web
依赖于org.glassfish.jersey.core:jersey-client:2.27
。显然在降级版本时必须在某处依赖它。
- 为什么2.28版本降级到2.27版本?我如何知道 spring 引导应用了哪个策略以便为特定版本做出选择。
- 该应用程序 运行 非常好,但是现在我遇到了版本冲突,我应该如何最好地处理这个问题?仅使用 v2.28 而不是 v2.27 是否可行?我认为这也指的是我关于为什么 spring-boot 实际上使用
jersey
. 的第一个答案
我知道这些是多个问题,但我认为最好在一个问题中提出,而不是分散在多个问题上,因为它们都与相同的上下文相关。
顺便说一句:这不仅发生在 org.glassfish.jersey.core:jersey-client
身上。完全相同的事情适用于 org.apache.httpcomponents:httpclient
.
感谢您的帮助!
First of all, why does spring-boot-starter-web
depend on jersey? I was always under the impression that if we want to explicitly use jersey
over the spring
implementation we would include spring-boot-starter-jersey
.
没有。相反,它取决于 Tomcat。你是对的,你需要 jersey starter 来自动配置它。
Why can't I see that spring-boot-starter-web
depends on org.glassfish.jersey.core:jersey-client:2.27
when running ./gradlew dependencies
. Obviously there must be a dependeny on it somewhere as it downgrades the version.
因为没有。更多内容见下文。
Why is version 2.28 downgraded to version 2.27? How can I know which policy is applied by spring boot in order to make a choice for a specific version.
这是根本问题。我会在下面解释。
The application is running perfectly fine, but now as i got a version conflict, how should i best handle this? Is it a viable option to just use v2.28 instead of v2.27. I think this also refers to my first answer on why spring-boot is actually using jersey
.
视情况而定。根据我的经验,与构建和测试的传递依赖相比,你的依赖可能会通过升级和降级传递依赖来破坏,即使它只是一个次要版本(我在看着你,SnakeYAML!)所以你真的只是有试一试。通常升级比降级更安全,但有时还是会出问题。
这是关于球衣降级的协议。
Spring 依赖管理插件用于控制依赖的版本,包括直接依赖和传递依赖。
当您同时应用依赖管理插件和 Spring 启动插件时,后者将应用其默认版本,该版本来自 Spring 启动 BOM。您可以通过 运行 gradle dependencyManagement
.
检查管理哪些依赖项以及在哪些版本中
所有这一切的想法是您获得一组已知可以很好地相互配合的依赖项。如果您喜欢不同版本的托管依赖项之一,则必须使用 dependencyManagement
扩展名(如文档 here)对其进行配置。
这就是您的 Jersey 依赖项降级的原因。
我个人不使用 Spring 依赖管理插件,因为我喜欢你在普通 Gradle 中处理依赖的方式。所以我通常只做这样的事情:
plugins {
id 'org.springframework.boot' version '2.1.0.RELEASE'
id 'java'
}
dependencies {
implementation platform("org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE")
}
在这种情况下,它将默认使用 Spring 引导 BOM 中的依赖项,但如果有人需要更新版本,则不会降级它们。但它会在需要时升级它们,如果你不想,你也不必自己指定版本,在这种情况下,它会使用 BOM 中的版本。
我有一个非常简单的spring引导应用程序用于测试目的。
这是我的 build.gradle:
plugins {
id 'org.springframework.boot' version '2.1.0.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mandas:docker-client:2.0.2'
}
org.mandas:docker-client:2.0.2
对 org.glassfish.jersey.core:jersey-client:2.28
具有传递依赖性。但是 gradle 然后提取版本 2.27
而不是 2.28
.
如果我 运行 ./gradlew dependencyInsight --dependency org.glassfish.jersey.core:jersey-client
我得到以下输出:
org.glassfish.jersey.core:jersey-client:2.27 (selected by rule)
...
org.glassfish.jersey.core:jersey-client:2.27
\--- org.glassfish.jersey.connectors:jersey-apache-connector:2.27
\--- org.mandas:docker-client:2.0.2 (requested org.glassfish.jersey.connectors:jersey-apache-connector:2.28)
\--- compileClasspath
org.glassfish.jersey.core:jersey-client:2.28 -> 2.27
\--- org.mandas:docker-client:2.0.2
\--- compileClasspath
似乎 spring-boot-starter-web
以某种方式依赖于 org.glassfish.jersey.core:jersey-client:2.27
。但是,如果我使用 ./gradlew dependencies
打印所有依赖项,我看不到 spring-boot-starter-web
.
org.glassfish.jersey.core:jersey-client:2.27
的依赖项
然而,在网上搜索了一下,我发现了另一种追踪依赖关系的方法:
grep -r "2.27" ~/.gradle/caches/modules-2/files-2.1/*
像这样,我能够找到 2.27 版的引入位置。它似乎在以下 poms 中声明:
- spring-boot-dependencies-2.1.0.RELEASE.pom
- spring-boot-autoconfigure-2.1.0.RELEASE.pom
我现在的问题是多方面的:
- 首先,为什么
spring-boot-starter-web
依赖于jersey
?我一直认为,如果我们想在spring
实现上明确使用jersey
,我们将包括spring-boot-starter-jersey
. - 为什么在运行宁
./gradlew dependencies
时看不到spring-boot-starter-web
依赖于org.glassfish.jersey.core:jersey-client:2.27
。显然在降级版本时必须在某处依赖它。 - 为什么2.28版本降级到2.27版本?我如何知道 spring 引导应用了哪个策略以便为特定版本做出选择。
- 该应用程序 运行 非常好,但是现在我遇到了版本冲突,我应该如何最好地处理这个问题?仅使用 v2.28 而不是 v2.27 是否可行?我认为这也指的是我关于为什么 spring-boot 实际上使用
jersey
. 的第一个答案
我知道这些是多个问题,但我认为最好在一个问题中提出,而不是分散在多个问题上,因为它们都与相同的上下文相关。
顺便说一句:这不仅发生在 org.glassfish.jersey.core:jersey-client
身上。完全相同的事情适用于 org.apache.httpcomponents:httpclient
.
感谢您的帮助!
First of all, why does
spring-boot-starter-web
depend on jersey? I was always under the impression that if we want to explicitly usejersey
over thespring
implementation we would includespring-boot-starter-jersey
.
没有。相反,它取决于 Tomcat。你是对的,你需要 jersey starter 来自动配置它。
Why can't I see that
spring-boot-starter-web
depends onorg.glassfish.jersey.core:jersey-client:2.27
when running./gradlew dependencies
. Obviously there must be a dependeny on it somewhere as it downgrades the version.
因为没有。更多内容见下文。
Why is version 2.28 downgraded to version 2.27? How can I know which policy is applied by spring boot in order to make a choice for a specific version.
这是根本问题。我会在下面解释。
The application is running perfectly fine, but now as i got a version conflict, how should i best handle this? Is it a viable option to just use v2.28 instead of v2.27. I think this also refers to my first answer on why spring-boot is actually using
jersey
.
视情况而定。根据我的经验,与构建和测试的传递依赖相比,你的依赖可能会通过升级和降级传递依赖来破坏,即使它只是一个次要版本(我在看着你,SnakeYAML!)所以你真的只是有试一试。通常升级比降级更安全,但有时还是会出问题。
这是关于球衣降级的协议。
Spring 依赖管理插件用于控制依赖的版本,包括直接依赖和传递依赖。
当您同时应用依赖管理插件和 Spring 启动插件时,后者将应用其默认版本,该版本来自 Spring 启动 BOM。您可以通过 运行 gradle dependencyManagement
.
所有这一切的想法是您获得一组已知可以很好地相互配合的依赖项。如果您喜欢不同版本的托管依赖项之一,则必须使用 dependencyManagement
扩展名(如文档 here)对其进行配置。
这就是您的 Jersey 依赖项降级的原因。
我个人不使用 Spring 依赖管理插件,因为我喜欢你在普通 Gradle 中处理依赖的方式。所以我通常只做这样的事情:
plugins {
id 'org.springframework.boot' version '2.1.0.RELEASE'
id 'java'
}
dependencies {
implementation platform("org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE")
}
在这种情况下,它将默认使用 Spring 引导 BOM 中的依赖项,但如果有人需要更新版本,则不会降级它们。但它会在需要时升级它们,如果你不想,你也不必自己指定版本,在这种情况下,它会使用 BOM 中的版本。