使用Spark SFTP库执行代码时触发NoSuchMethodError错误求助
看起来你遇到了一个典型的依赖版本不兼容问题——虽然SFTP客户端已经成功完成了文件复制,但Spark代码执行时抛出了java.lang.NoSuchMethodError,这个错误几乎都是因为类路径里的依赖版本不匹配导致的,尤其是Spark SQL相关的API。
先把你的错误日志整理得更清晰:
18/03/01 12:16:07 INFO sftp.DefaultSource: 正在复制/output/skytree_output_201801.csv到/hadoop/user/fl/data/skytree_output_201801.csv
18/03/01 12:16:07 INFO client.SFTPClient: 正在从/output/skytree_output_201801.csv复制文件到/hadoop/user/fl/data/skytree_output_201801.csv
18/03/01 12:16:07 INFO client.SFTPClient: 文件复制成功...
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.spark.sql.DataFr...
给你几个针对性的排查和解决方向:
核对Spark版本与SFTP库的兼容性
你使用的SFTP相关库(比如spark-sftp这类第三方库)通常是针对特定Spark版本开发的。比如如果你的集群用的是Spark 2.3,但SFTP库是基于Spark 1.6编写的,就会出现这种方法找不到的问题。去查一下SFTP库的官方文档,确认它支持你当前的Spark版本。排查依赖冲突
用构建工具的依赖树命令检查项目依赖:- Maven项目执行:
mvn dependency:tree - Gradle项目执行:
gradle dependencies
重点看输出里的spark-sql、spark-core这类核心依赖,有没有同时存在多个版本的情况。如果项目里引入了和集群Spark版本不一致的依赖,类加载时就会找到错误版本的类,从而触发方法找不到的错误。
- Maven项目执行:
调整打包方式(集群运行场景)
如果你是把代码打包成JAR提交到Spark集群运行,一定要给Spark核心依赖加上<scope>provided</scope>(Maven)或者compileOnly(Gradle)。这样打包时不会把本地的Spark JAR包打进去,避免和集群上的Spark环境版本冲突。检查代码中DataFrame的调用
看看你代码里调用DataFrame的方法是不是已经被废弃或移除?比如Spark 2.x之后,很多DataFrame的API被整合到Dataset中,或者方法签名发生了变化。比如旧版本的saveAsTextFile重载方法、select的参数形式,可能在新版本中已经调整了。
内容的提问来源于stack exchange,提问作者SteveTR

