Maven 在选择依赖版本时不会比较版本号。它只是选择在执行广度优先搜索时遇到的第一个版本。出于这个原因,gRPC 团队强烈 recommends 使用 Maven 强制执行器 requireUpperBoundDeps 让您检测您面临的问题:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireUpperBoundDeps/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
那么,解决问题有两种方法:
- 重新排序依赖列表或重新定义传递依赖
- 使用 BOM
(1) 以 Maven 的广度优先搜索为目标,以获得您希望 Maven 搜索首先“看到”的版本。例如,您可以在<dependencies> 中重新排序netty-handler before grpc-netty,然后Maven 将首先遇到它并在grpc-netty 的直接依赖项之前选择它的直接依赖项。当您无法重新排序以解决问题时,您可以在传递依赖项上添加显式依赖项以显式选择其版本。例如,您可以在 <dependencies> 中添加带有版本 4.1.51.Final 的 netty-resolver。
(2) 适用于像 gRPC 和 Netty 这样的多工件项目,您确实希望各种工件的版本一致。您通常不想将netty-buffer 4.1.51.Final 与netty-codec-http2 4.1.27.Final 一起使用;你想要他们相同的版本。在这些情况下,您可以检查项目是否具有 BOM。 gRPC 和 Netty 都有 BOM。使用 BOM,您可以为该项目中的所有各种工件选择一次使用的版本。 BOM 在<dependencyManagement> 部分中定义,该部分与<dependencies> 不同。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-bom</artifactId>
<version>4.1.51.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
...
无论做什么,都不要排斥。排除在以后会导致依赖问题,因为它们隐藏了传递依赖。如果较新版本的 gRPC 依赖于 较新 版本的 Netty,那么您最终会降级 Netty。到那时,构建工具将无法检测或管理问题;您只会在运行时发现此类问题。
从您所展示的内容中可以清楚地看出,您的 pom.xml 中还有更多内容;你真的需要分享更多你的 pom 来诊断。但是,由于其他答案告诉您要排除,我想展示更合适的解决方法。