dependencyManagement覆盖传递依赖版本问题求助及原因解析
我遇到一个问题:dependencyManagement中的依赖似乎覆盖了另一个依赖的传递版本。我编写了一个包含requireUpperBounds规则的简单pom文件来复现该问题,执行mvn install时会多次出现如下错误:
Require upper bound dependencies error for io.github.resilience4j:resilience4j-ratelimiter:2.0.2 [runtime] paths to dependency are: +-com.blah:blah:1 +-io.github.resilience4j:resilience4j-vavr:2.1.0 +-io.github.resilience4j:resilience4j-ratelimiter:2.0.2 [runtime] (managed) <-- io.github.resilience4j:resilience4j-ratelimiter:2.1.0 [runtime]
Maven尝试拉取resilience4j-ratelimiter的v2.0.2版本,而非我在pom文件中指定的v2.1.0。移除dependencyManagement中的spring-cloud-dependencies依赖或其scope后,该问题不再出现,但spring-cloud-dependencies的pom中并未提及resilience4j或2.0.2版本,我不清楚该版本的来源。
此外,Maven的dependencyManagement文档说明:
the version and other values from this section are used for that dependency if they were not already specified.
对应的pom文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.blah</groupId> <artifactId>blah</artifactId> <version>1</version> <packaging>pom</packaging> <properties> <spring-cloud.version>2022.0.4</spring-cloud.version> <resilience4j.version>2.1.0</resilience4j.version> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <executions> <execution> <id>enforce-dependency-checks</id> <goals> <goal>enforce</goal> </goals> <configuration> <rules> <requireUpperBoundDeps/> </rules> <fail>true</fail> </configuration> </execution> </executions> </plugin> </plugins> </build> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-vavr</artifactId> <version>${resilience4j.version}</version> </dependency> </dependencies> </project>
请问有人能解释该问题的原因吗?
编辑补充:
根据Maven文档,在dependencyManagement中添加带有<scope>import</scope>和<type>pom</type>的依赖,相当于将该依赖的pom作为父pom引入。spring-cloud-dependencies的pom以此方式引用了多个其他pom,其中spring-cloud-circuitbreaker的属性中包含<resilience4j.version>2.0.2</resilience4j.version>,这解释了版本的来源。但我仍不清楚为何pom中指定的resilience4j版本未完全覆盖该版本:resilience4j-vavr依赖使用了我指定的版本,但其传递依赖却没有。当我下载spring-cloud-circuitbreaker的pom并将其作为父pom引用(而非通过dependencyManagement引入)时,所有resilience4j的传递依赖都按预期使用了我指定的版本。
内容的提问来源于stack exchange,提问作者DarthRitis

