maven 如何解决 spring data gemfire 的 slf4j 依赖关系?
How's maven resolving the slf4j dependency of spring data gemfire?
Spring data gemfire 1.7.0.RELEASE 对 slf4j-api
和 jcl-over-slf4j
的版本 1.7.12 具有编译时依赖性。我在我的 maven pom 文件中定义了以下依赖项,因为我们需要 slf4j 1.7.10 依赖项(很少有其他 jar 依赖于此):
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-gemfire</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.10</version>
<scope>runtime</scope>
</dependency>
我有一个内部 Maven 仓库作为 Maven 中央仓库。以下是我在不同场景中看到的行为,基于 Maven 中心可用的 jar:
我的问题:
- 在场景 1 中,我不明白为什么构建没有抱怨缺少 1.7.12 jar。依赖是如何解决的?
- 在场景 2 中,如果我没有在 spring 数据依赖项中指定对 slf4j 1.7.12 的排除,1.7.10 jar 如何覆盖 1.7.12?
- 在场景3中,当Maven Central 中缺少slf4j-parent 1.7.12 的pom 时,为什么会报错?由于存在 1.7.10 罐子,构建 运行 是否应该可以很好地拾取 1.7.10 罐子(类似于场景 1)?
答案基于Maven Dependencies Mediation机制,具体是这样的说法:
You can always guarantee a version by declaring it explicitly in your project's POM
因此,从本质上讲,通过将其显式声明为依赖项的一部分,您将覆盖传递依赖项的任何版本,因此您不需要添加任何排除项。你声明它,你有项目的知识,Maven信任你。
因此,在场景 1 和 2 中,Maven 应用了上述规则,并仅遵循 POM 中指定的内容。
在场景 1 中,由于它根本没有找到任何 1.7.12 版本,它甚至没有尝试解析它并信任你的 POM。
在场景 2 中,它解析了 1.7.12 的依赖项树,但随后根据您的 POM,版本 1.7.10 获胜。
在场景 3 中,它无法解析版本 1.7.12 的整个依赖树,因此它给出了一个错误:是的,你的 POM 中的版本无论如何都会赢,但是因为 Maven在获取完整的依赖关系树时出错,然后执行失败。
这是一个特例,最终确认只能看你使用的Maven版本的相关代码。
更新
我建议在三种情况下尝试获得更多细节,是从控制台 运行:
mvn dependency:resolve -Dsort=true -X
由于调试标志,它将在依赖调解过程中提供包含和排除的依赖项列表。
作为补充,运行宁:
mvn dependency:tree
将为您提供完整的依赖关系图,显示实际从 POM 中获取的内容以及通过传递依赖项获得的内容。这可能会给你更多的信息。有关详细信息,我建议查看 Maven Dependency Plugin 目标。
Spring data gemfire 1.7.0.RELEASE 对 slf4j-api
和 jcl-over-slf4j
的版本 1.7.12 具有编译时依赖性。我在我的 maven pom 文件中定义了以下依赖项,因为我们需要 slf4j 1.7.10 依赖项(很少有其他 jar 依赖于此):
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-gemfire</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.10</version>
<scope>runtime</scope>
</dependency>
我有一个内部 Maven 仓库作为 Maven 中央仓库。以下是我在不同场景中看到的行为,基于 Maven 中心可用的 jar:
我的问题:
- 在场景 1 中,我不明白为什么构建没有抱怨缺少 1.7.12 jar。依赖是如何解决的?
- 在场景 2 中,如果我没有在 spring 数据依赖项中指定对 slf4j 1.7.12 的排除,1.7.10 jar 如何覆盖 1.7.12?
- 在场景3中,当Maven Central 中缺少slf4j-parent 1.7.12 的pom 时,为什么会报错?由于存在 1.7.10 罐子,构建 运行 是否应该可以很好地拾取 1.7.10 罐子(类似于场景 1)?
答案基于Maven Dependencies Mediation机制,具体是这样的说法:
You can always guarantee a version by declaring it explicitly in your project's POM
因此,从本质上讲,通过将其显式声明为依赖项的一部分,您将覆盖传递依赖项的任何版本,因此您不需要添加任何排除项。你声明它,你有项目的知识,Maven信任你。
因此,在场景 1 和 2 中,Maven 应用了上述规则,并仅遵循 POM 中指定的内容。
在场景 1 中,由于它根本没有找到任何 1.7.12 版本,它甚至没有尝试解析它并信任你的 POM。
在场景 2 中,它解析了 1.7.12 的依赖项树,但随后根据您的 POM,版本 1.7.10 获胜。
在场景 3 中,它无法解析版本 1.7.12 的整个依赖树,因此它给出了一个错误:是的,你的 POM 中的版本无论如何都会赢,但是因为 Maven在获取完整的依赖关系树时出错,然后执行失败。
这是一个特例,最终确认只能看你使用的Maven版本的相关代码。
更新
我建议在三种情况下尝试获得更多细节,是从控制台 运行:
mvn dependency:resolve -Dsort=true -X
由于调试标志,它将在依赖调解过程中提供包含和排除的依赖项列表。
作为补充,运行宁:
mvn dependency:tree
将为您提供完整的依赖关系图,显示实际从 POM 中获取的内容以及通过传递依赖项获得的内容。这可能会给你更多的信息。有关详细信息,我建议查看 Maven Dependency Plugin 目标。