Guava版本不兼容引发Maven依赖冲突的解决方案咨询
解决Guava版本冲突的Maven依赖问题
这种跨组件的依赖版本僵局确实头疼,尤其是像Guava这种API变化较大的核心库。结合你的POM配置,我给你几个递进的解决方案,你可以根据实际测试情况选择:
第一步:先明确冲突来源
首先执行Maven命令精准定位所有引入Guava的依赖链,搞清楚每个组件到底依赖哪个版本:
mvn dependency:tree -Dverbose -Dincludes=com.google.guava:guava
这个命令会列出所有涉及Guava的依赖路径,你能清楚看到grpc、spark各自依赖的版本,以及当前Maven仲裁后实际生效的版本,方便后续针对性调整。
方案一:强制统一Guava版本(最简单优先尝试)
Maven的dependencyManagement可以强制项目中所有依赖使用指定版本的Guava,优先尝试找到一个能兼容grpc和spark的中间版本:
- 先移除你POM中显式引入的Guava 23.0(这个版本和另外两个版本差异太大,会加剧冲突)
- 在POM的
<project>节点下添加dependencyManagement块,强制统一版本:
<dependencyManagement> <dependencies> <!-- 先尝试grpc依赖的19.0版本,测试spark是否兼容 --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>19.0</version> </dependency> </dependencies> </dependencyManagement>
- 执行
mvn clean compile test测试项目是否能正常编译运行。如果spark的hadoop组件在Guava 19.0下没有报错,那这个方案就完美解决问题了。
如果19.0版本不兼容spark,你可以尝试中间版本(比如18.0、20.0),看哪个版本能同时满足两边的API需求。
方案二:使用Shade插件重命名冲突依赖(终极解决办法)
如果找不到能兼容两边的Guava版本,那就用Maven Shade插件把其中一方的Guava包重命名,实现完全隔离。比如把grpc依赖的Guava重命名为独立的包名,避免和spark的Guava冲突:
在POM的<build>节点下添加Shade插件配置:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <!-- 重命名Guava的包路径 --> <relocations> <relocation> <pattern>com.google.common</pattern> <shadedPattern>shaded.com.google.common</shadedPattern> </relocation> <relocation> <pattern>com.google.thirdparty</pattern> <shadedPattern>shaded.com.google.thirdparty</shadedPattern> </relocation> </relocations> <!-- 只对grpc相关的Guava依赖进行重命名 --> <filters> <filter> <artifact>io.grpc:*</artifact> <includes> <include>com/google/**</include> </includes> </filter> <filter> <artifact>com.google.guava:guava</artifact> <includes> <include>com/google/**</include> </includes> </filter> </filters> </configuration> </execution> </executions> </plugin> </plugins> </build>
执行mvn clean package打包后,你的jar包中会同时存在两个版本的Guava:一个是spark使用的原始路径com.google.common,另一个是grpc使用的重命名路径shaded.com.google.common,两者完全隔离,不会再出现API冲突。
方案三:升级/降级组件缩小版本差异
如果上面的方案都有问题,你可以考虑调整组件版本:
- 升级Spark版本:Spark 2.2.1比较老,升级到2.4.x版本(比如2.4.8),它依赖的Guava版本会更高(20.0左右),和grpc的19.0版本差异很小,冲突概率会大大降低。
- 调整grpc版本:找一个依赖Guava版本和Spark依赖版本更接近的grpc版本,比如grpc 1.5.x系列依赖Guava 18.0,和Spark的Guava 11.0.2差异比19.0小一些(不过这个可能不太现实,因为grpc旧版本可能存在其他稳定性问题)。
内容的提问来源于stack exchange,提问作者Nagireddy Hanisha




