执行含SparkSession Builder的Maven Jar文件时遇NoSuchMethodError求助
解决Spark+MongoDB项目打包运行时的Guava依赖冲突问题
这个错误java.lang.NoSuchMethodError: com.google.common.cache.CacheBuilder.refreshAfterWrite(...)是典型的Guava版本依赖冲突导致的,核心原因是你的项目中不同依赖(Spark、MongoDB连接器或Hadoop相关组件)引入了不同版本的Guava库,打包后运行时加载了不包含refreshAfterWrite方法的旧版本Guava;而IntelliJ本地运行时依赖解析顺序不同,优先加载了兼容的版本,所以没有报错。
具体解决方案
1. 锁定Guava版本为Spark兼容的版本
Spark 2.2.0依赖的Guava版本是18.0,你可以在Maven的pom.xml中通过dependencyManagement强制锁定这个版本,确保所有依赖都使用同一版本的Guava:
<dependencyManagement> <dependencies> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version> <scope>compile</scope> </dependency> </dependencies> </dependencyManagement>
2. 排查并排除冲突的Guava依赖
先通过Maven命令查看项目的依赖树,找出引入低版本Guava的依赖:
mvn dependency:tree | grep guava
比如如果发现MongoDB Spark连接器引入了其他版本的Guava,你可以在该依赖中排除Guava:
<dependency> <groupId>org.mongodb.spark</groupId> <artifactId>mongo-spark-connector_2.11</artifactId> <version>2.2.0</version> <exclusions> <exclusion> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </exclusion> </exclusions> </dependency>
3. 使用Maven Shade插件重定位Guava包(可选)
如果上述方法无法解决,你可以使用Shade插件将Guava包重新命名,避免和其他依赖的Guava冲突:
<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> <relocations> <relocation> <pattern>com.google.common</pattern> <shadedPattern>your.project.shaded.com.google.common</shadedPattern> </relocation> </relocations> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>fr.atos.gsec.Main</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
为什么IntelliJ本地运行正常?
IntelliJ在运行项目时,会根据依赖的优先级(通常是高版本优先,或者依赖声明顺序)加载正确的Guava版本;而Maven打包时,默认会按依赖树的顺序将jar包加入classpath,如果旧版本的Guava排在前面,就会导致运行时加载错误的版本。
内容的提问来源于stack exchange,提问作者Louisa F.
相关产品推荐
相关产品推荐

