Spark:不支持的类版本错误

Posted

技术标签:

【中文标题】Spark:不支持的类版本错误【英文标题】:Spark: Unsupported class version error 【发布时间】:2015-03-20 04:30:09 【问题描述】:

我正在尝试使用 spark-submit 在所有节点都安装了 java 1.7 的集群上运行 java spark 作业。

作业失败并出现 java.lang.UnsupportedClassVersionError: com/windlogics/dmf/wether/MyClass: Unsupported major.minor version 51.0。

这个错误似乎是用较低版本的java编译并用较高版本运行引起的。但是,我已经验证了代码是用 1.7 编译的。

此外,当 master 设置为本地时,作业可以正常工作。我该如何调试和修复此错误?

部分错误日志如下。

15/01/21 15:14:57 WARN scheduler.TaskSetManager:在阶段 0.0 中丢失任务 0.0(TID 0,sphddp07.zzz.local):java.lang.UnsupportedClassVersionError:com/zzz/dmf/wether/MyClass :不支持的major.minor 51.0版 java.lang.ClassLoader.defineClass1(本机方法) java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) java.lang.ClassLoader.defineClass(ClassLoader.java:615) java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) java.net.URLClassLoader.defineClass(URLClassLoader.java:283) java.net.URLClassLoader.access$000(URLClassLoader.java:58) java.net.URLClassLoader$1.run(URLClassLoader.java:197) java.security.AccessController.doPrivileged(本机方法) java.net.URLClassLoader.findClass(URLClassLoader.java:190) java.lang.ClassLoader.loadClass(ClassLoader.java:306) java.lang.ClassLoader.loadClass(ClassLoader.java:247) java.lang.Class.forName0(本机方法) java.lang.Class.forName(Class.java:247) org.apache.spark.serializer.JavaDeserializationStream$$anon$1.resolveClass(JavaSerializer.scala:59) java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574) java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495) java.io.ObjectInputStream.readClass(ObjectInputStream.java:1461) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1311) java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) scala.collection.immutable.$colon$colon.readObject(List.scala:362) sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597) java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) scala.collection.immutable.$colon$colon.readObject(List.scala:362) sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597) java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) org.apache.spark.serializer.JavaDeserializationStream.readObject(JavaSerializer.scala:62) org.apache.spark.serializer.JavaSerializerInstance.deserialize(JavaSerializer.scala:87) org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:57) org.apache.spark.scheduler.Task.run(Task.scala:54) org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:177) java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

【问题讨论】:

"所有节点都安装了 java 1.7" - 但是您是否使用 Java 1.7运行?你能记录java.version系统属性的值吗? 在失败的节点上是 java 版本 -bash-3.2$ java -version java version "1.7.0_45" Java(TM) SE Runtime Environment (build 1.7.0_45-b18) Java HotSpot(TM) 64 位服务器 VM(内部版本 24.45-b08,混合模式) 嗯,当您从 bash 的命令行运行 java 时会发生这种情况 - 但这绝对是正在运行和失败的版本吗?这就是为什么我建议你应该添加一些日志记录。 我在 main 方法中添加了 System.err.println("Java Version: " + System.getProperty("java.version")) ,生成了“Java Version: 1.7.0_45”。虽然,我实际上不知道这段代码是否正在集群节点上运行。 对,所以你需要找出来。很抱歉这么挑剔,但是当它看起来像环境问题时,您确实需要找出运行问题所在的确切版本。 (版本 51 用于 Java 1.7,因此看起来某处正在运行早期版本。) 【参考方案1】:

我遇到了同样的错误信息。我发现当我输入“java -version”时它是 1.7。我需要 Java 8。以下是更新方法:

sudo yum install java-1.8.0
sudo alternatives --config java

【讨论】:

【参考方案2】:

我有同样的问题尝试在主从机器上的 bashrc 文件中设置适当的 JAVA_HOME,但这没有帮助。

然后当我在整个集群级别设置 JAVA_HOME 时,major.minor 错误消失了。我使用cloudera,所以我必须在cloudera manager中设置JAVA_HOME来解决这个错误。

【讨论】:

【参考方案3】:

请查看 Spark 文档页面 https://spark.apache.org/docs/latest/ 中的 Spark 版本和相应的 JDK 要求。

例如,Spark 2.4.5 在 Java 8 上运行,而我的系统上安装了 Java 13。通过将我的系统移动到所需的 JDK 解决了这个问题。

【讨论】:

你可以拥有多个版本的 Java 并且仍然可以运行代码,你只需要设置正确的 Java Home 就可以了。

以上是关于Spark:不支持的类版本错误的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 2015:xamarin 中的“不支持的类版本错误”

适用于VS 2017的Cordova工具 - 不支持的类文件版本52

Spark 支持使用 Windows 功能

注册 UDF 时出现 Spark 错误:不支持 AnyRef 类型的架构

Spark Python:标准缩放器错误“不支持...... SparseVector”

IDEA中打包Spark项目提示Error:(16, 48) java: -source 1.5 中不支持 lambda 表达式