Spark 2.3中基于Case Class创建DataFrame报错求助
java.lang.VerifyError的解决方案 先梳理下你的场景:你尝试在Spark 2.3(搭配Scala 2.11.8)环境下通过Case Class创建DataFrame,不管是IDE项目还是spark-shell操作,都触发了java.lang.VerifyError,错误指向HiveExternalCatalog覆盖了final方法。
错误原因分析
这个报错本质是Spark与Hive依赖版本不兼容导致的。Spark 2.3.x系列默认依赖Hive 1.2.1版本,如果你的项目引入了其他版本的Hive依赖,或者环境中混入了不兼容的Hive Jar包,就会触发Java的验证错误——因为不同版本Hive的类结构发生了变化,Spark的HiveCatalog类尝试覆盖一个被标记为final的方法,违反了Java的类验证规则。
另外,你的代码还有一个潜在问题:Case Class定义在了main方法内部,这在Spark中会引发序列化异常(虽然不是当前报错的直接原因,但后续一定会出问题),因为Spark需要将Case Class的类型信息序列化到Executor端,而方法内部定义的类无法被正确识别和序列化。
具体解决方案
1. 修正Case Class的位置
先把Case Class移到main方法外部,比如作为顶层类或者放在object Test内部但在main方法之前:
package org.XXX import org.apache.spark.sql.SparkSession // 将Case Class移到这里,作为顶层类 case class Employee(Name: String, Age: Int, Designation: String, Salary: Int, ZipCode: Int) object Test { def main(args: Array[String]): Unit = { val spark = SparkSession .builder .appName("test") .getOrCreate() val EmployeesData = Seq( Employee("Anto", 21, "Software Engineer", 2000, 56798)) val Employee_DataFrame = EmployeesData.toDF // 添加show()验证结果 Employee_DataFrame.show() spark.stop() } }
2. 确保Spark与Hive依赖版本匹配
如果是Maven/Gradle项目,需要严格控制Hive相关依赖的版本与Spark 2.3.x兼容:
- Spark 2.3.x对应Hive版本为1.2.1,所有Hive相关依赖(如
hive-common、hive-metastore)都要使用这个版本。 - 如果项目中其他依赖引入了更高版本的Hive,需要主动排除冲突模块。比如Maven的pom.xml可以这样配置:
<dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_2.11</artifactId> <version>2.3.4</version> <exclusions> <exclusion> <groupId>org.apache.hive</groupId> <artifactId>hive-common</artifactId> </exclusion> <exclusion> <groupId>org.apache.hive</groupId> <artifactId>hive-metastore</artifactId> </exclusion> </exclusions> </dependency> <!-- 手动引入兼容版本的Hive依赖 --> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-common</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-metastore</artifactId> <version>1.2.1</version> </dependency>
3. 解决Spark Shell环境中的冲突
如果是在spark-shell中遇到这个问题:
- 确保使用Spark官方提供的预编译带Hive的版本(比如
spark-2.3.4-bin-hive-1.2.tgz),而非不带Hive的基础版本。 - 检查系统环境变量,比如
HIVE_HOME是否指向了与Spark兼容的Hive版本,如果指向了Hive 2.x等更高版本,会导致Jar包冲突,建议临时取消该环境变量后再启动spark-shell。 - 启动spark-shell时,可通过
--exclude-packages参数排除冲突的Hive包:
spark-shell --exclude-packages org.apache.hive:hive-common,org.apache.hive:hive-metastore
验证方案
按照上述步骤调整后,重新运行代码或spark-shell操作,应该就能正常创建DataFrame了。如果仍有问题,可以检查项目依赖树(Maven用mvn dependency:tree,Gradle用./gradlew dependencies),找出所有冲突的Hive相关依赖并排除。
内容的提问来源于stack exchange,提问作者Jill Clover

