运行Spark Scala程序时遭遇NoSuchMethodError报错求助
java.lang.NoSuchMethodError(Jackson版本冲突) 嘿,这个问题我之前碰到过好多次,几乎可以100%确定是Jackson版本冲突导致的——Spark本身自带了特定版本的Jackson库,而你的项目里引入的其他依赖(比如AWS SDK相关的包)大概率带了另一个版本的Jackson,导致运行时找不到正确的方法签名。
为啥会出这个错?
java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.JsonMappingException.(Ljava/io/Closeable;Ljava/lang/String;)V 这个错误的意思是:运行时加载的JsonMappingException类没有这个构造方法,但你的代码或者依赖库却想调用它。根源就是:
- Spark依赖的Jackson版本,和你项目中其他依赖(比如AWS SDK)的Jackson版本对不上
- 打包的时候没处理好依赖冲突,错误版本的Jackson被塞进了最终的Jar包
一步步解决问题
1. 先搞清楚依赖树里的Jackson版本
首先得找出项目里所有Jackson相关的依赖,看看哪个版本在搞事情:
- 如果用SBT,在终端跑:
sbt dependencyTree - 如果用Maven,跑:
mvn dependency:tree
重点看com.fasterxml.jackson.core下面的三个核心包:jackson-databind、jackson-core、jackson-annotations,然后对比Spark自带的版本(比如Spark 3.x一般用Jackson 2.12.x,Spark 2.x用2.6.x左右,具体可以查Spark官方文档)。
2. 要么统一版本,要么排除冲突依赖
找到冲突的依赖后,有两种处理方式:
方式一:强制用Spark兼容的Jackson版本
在你的构建文件里指定和Spark匹配的Jackson版本,比如Spark 3.3.x用2.12.7:// SBT示例 libraryDependencies += "com.fasterxml.jackson.core" % "jackson-databind" % "2.12.7" force() libraryDependencies += "com.fasterxml.jackson.core" % "jackson-core" % "2.12.7" force() libraryDependencies += "com.fasterxml.jackson.core" % "jackson-annotations" % "2.12.7" force()方式二:把冲突依赖里的Jackson排除掉
如果是AWS SDK带进来的Jackson冲突,就在引入AWS依赖的时候排除Jackson相关包,让项目用Spark自带的版本:// SBT示例,排除AWS SDK中的Jackson依赖 libraryDependencies += "com.amazonaws" % "aws-java-sdk-s3" % "1.12.400" excludeAll( ExclusionRule(organization = "com.fasterxml.jackson.core") )
3. 打包的时候也要注意
如果用assembly插件打包Jar,得确保assemblyMergeStrategy正确处理Jackson的配置文件,避免合并冲突:
// SBT assembly插件配置示例 assemblyMergeStrategy in assembly := { case PathList("META-INF", "services", "com.fasterxml.jackson.databind.Module") => MergeStrategy.concat case x => val oldStrategy = (assemblyMergeStrategy in assembly).value oldStrategy(x) }
4. 顺便检查下UtilsKPI的代码
虽然错误触发在downloadFromS3这行,但也可以确认下这个方法内部是不是用到了Jackson的序列化/反序列化——比如AWS SDK在处理S3对象的时候可能会隐含用到Jackson,版本不匹配的话就会触发这个错误。
快速验证的小技巧
可以先用spark-submit指定兼容的Jackson包,看看能不能临时解决问题,验证是不是版本冲突:
spark-submit --packages com.fasterxml.jackson.core:jackson-databind:2.12.7 your-program.jar
内容的提问来源于stack exchange,提问作者Markus

