Spark读取GCS CSV写入Delta Lake报NoClassDefFoundError排查
问题根因
报错由Delta Lake与Spark版本不兼容直接导致:
- 你引入的
delta-core_2.12:1.2.1是官方针对Spark 3.2.x系列编译发布的版本,内部代码依赖Spark 3.2新增的抽象类org.apache.spark.sql.execution.command.LeafRunnableCommand - 你当前项目运行时实际加载的Spark版本低于3.2(常见为3.1.x、3.0.x版本),类路径下不存在上述类,触发
NoClassDefFoundError - 特殊场景:如果你pom中Spark相关依赖设置了
providedscope,且IntelliJ本地运行时未将provided依赖加入类路径,也可能触发类缺失,但这类场景一般会先报Spark核心类找不到的错误,你当前报错栈是Delta初始化数据源时才触发类缺失,优先排查版本匹配问题。
修复步骤
按以下顺序调整即可正常写入:
- 对齐版本绑定关系
Delta Lake和Spark有严格的版本对应要求,禁止跨大版本混用,你可以二选一调整:- 保留当前Delta 1.2.1版本:将pom中所有Spark相关依赖(
spark-core、spark-sql等)版本统一升级到3.2.x - 保留当前低版本Spark:将Delta依赖替换为对应版本,比如Spark 3.1.x匹配
delta-core_2.12:1.1.0,Spark 3.0.x匹配delta-core_2.12:0.9.0
- 保留当前Delta 1.2.1版本:将pom中所有Spark相关依赖(
- 修正本地调试配置(仅IntelliJ本地运行main方法时需要)
如果你为了适配集群提交,把Spark依赖scope设为provided避免和集群内置依赖冲突,本地调试时需要打开对应运行配置,在Modify options中勾选Add dependencies with "provided" scope to classpath,保证运行时类加载完整。 - 补全GCS访问配置(版本问题修复后若仍有读写报错再处理)
读写GCS路径需要提前在Spark Session中配置GCS连接器参数,参考配置如下:
同时需要在pom中引入对应Hadoop版本的GCS连接器依赖,以Hadoop 3.x为例:val spark = SparkSession.builder() .appName("DeltaGCSDemo") .config("spark.hadoop.fs.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem") .config("spark.hadoop.fs.AbstractFileSystem.gs.impl", "com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS") .config("spark.hadoop.google.cloud.auth.service.account.enable", "true") // 替换为你本地存储的GCS服务账号JSON密钥路径 .config("spark.hadoop.google.cloud.auth.service.account.json.keyfile", "/your/local/path/service-account.json") .master("local[*]") // 本地调试保留,提交到集群时删除 .getOrCreate()<dependency> <groupId>com.google.cloud.bigdataoss</groupId> <artifactId>gcs-connector</artifactId> <version>hadoop3-2.2.10</version> <scope>provided</scope> </dependency>
内容的提问来源于stack exchange,提问作者maxmadroad
相关产品推荐
相关产品推荐

