Spark与Kafka集成时抛出NoSuchMethodError异常求助
这个java.lang.NoSuchMethodError是典型的依赖版本不兼容问题,核心原因是你的Spark应用依赖的Hadoop版本和运行集群的Hadoop版本不匹配,导致运行时找不到org.apache.hadoop.fs.FileStatus.isDirectory()这个方法。
具体解决步骤:
确认版本兼容性
先搞清楚你本地构建用的Spark版本,以及集群上Spark依赖的Hadoop版本。可以通过spark-submit --version查看集群的Spark+Hadoop版本,然后对比你SBT项目里指定的依赖版本——Spark官方有明确的版本兼容矩阵,比如Spark 3.3.x对应Hadoop 3.2+,Spark 2.4.x对应Hadoop 2.7+,一定要保证两者版本匹配。调整SBT依赖配置
在你的SBT构建文件中,把Hadoop相关依赖的范围设为Provided,避免把冲突的jar包打包进你的应用jar里,同时指定和集群一致的版本:libraryDependencies += "org.apache.hadoop" % "hadoop-client" % "3.2.4" % Provided // 同时确保Spark Streaming和Kafka的依赖版本匹配,比如Spark 3.3对应kafka-clients 2.8.1 libraryDependencies += "org.apache.spark" %% "spark-streaming-kafka-0-10" % "3.3.2" % Provided提交时指定正确依赖
如果集群环境的Hadoop版本和你本地依赖确实有差异,可以在spark-submit命令中通过--packages强制指定匹配的Hadoop依赖:spark-submit --class com.yourcompany.WordCountStreaming \ --master yarn \ --deploy-mode cluster \ --packages org.apache.hadoop:hadoop-client:3.2.4 \ your-spark-kafka-app.jar排查打包后的jar包
可以用jar tf your-spark-kafka-app.jar命令查看jar包内容,如果里面包含了org.apache.hadoop.fs.FileStatus这类Hadoop类,说明你没把Hadoop依赖设为Provided,导致和集群的Hadoop jar冲突,必须调整依赖范围。
额外注意事项:
Spark Streaming的WriteAheadLog组件严重依赖Hadoop的文件系统API,版本不匹配很容易触发这类反射/方法找不到的错误。如果你用的是CDH、HDP这类大数据发行版,建议直接使用发行版自带的Spark和Hadoop版本进行开发,能最大程度避免兼容性问题。
内容的提问来源于stack exchange,提问作者Rudresh Angadi

