Spark集群提交Scala项目fat jar时出现java.lang.ClassNotFoundException错误
错误排查:Spark集群提交Fat Jar触发ClassNotFoundException
错误原因
- 主类未声明包名:你定义的
object input没有设置包名,Spark集群的类加载器在cluster模式下对无包名类的兼容性较差,大概率无法识别根路径下的无包名类。 - sbt配置存在语法错误:你提供的build.sbt里有一行单独的
connector无效内容,会导致sbt打包流程异常,主类信息未正确写入Jar包。 - Spark依赖打入Jar包引发冲突:spark-core、spark-sql属于Spark集群自带的依赖,你没有将其设置为
provided范围,打入Fat Jar后会和集群自带的类产生冲突,干扰主类加载逻辑。 - Jar包访问权限不足:Standalone集群的cluster模式下Driver会运行在Worker节点上,如果你提交的
/home/jars/sql-mongo-validation.jar仅存放在提交命令执行的节点,其余Worker节点无法访问该路径,也会导致类加载失败。 - 版本不兼容:如果你的Spark集群运行的Scala版本不是2.12.x,和你打包用的Scala 2.12.10版本不匹配,也会出现类找不到的异常。
解决方案
- 给主类添加包名:在主类代码顶部添加包声明,比如
package com.yourcompany,同步修改提交命令中--class参数为com.yourcompany.input,同时把build.sbt里的mainClass配置改为Some("com.yourcompany.input")。 - 修正build.sbt配置:
- 删除多余的
connector无效行 - 给Spark相关依赖添加
Providedscope,避免打入Fat Jar,修改后的依赖配置如下:
libraryDependencies += "org.apache.spark" %% "spark-core" % "3.1.2" % Provided libraryDependencies += "org.apache.spark" %% "spark-sql" % "3.1.2" % Provided - 删除多余的
- 校验Jar包完整性:打包完成后在本地执行
jar tf sql-mongo-validation.jar | grep input,确认输出中存在对应的主类class文件。 - 解决集群Jar包访问问题:要么把Jar包上传到所有Worker节点都能访问的同路径下,要么先切换为
client模式提交测试,确认业务逻辑本身没有问题。 - 校验版本一致性:确认Spark集群运行的Scala版本为2.12.x,同时Spark集群版本和你依赖的3.1.2版本匹配。
内容的提问来源于stack exchange,提问作者Shantanu Gupta
相关产品推荐
相关产品推荐

