如何在执行'org.apache.spark.sql.DataSet.collectAsList()'时修复“Unsupported class file major version 55”?

11

我正在创建一个使用Spark从服务器获取数据的Java RESTAPI Spring Boot应用程序。但是,当我尝试将Dataset转换为List时,它失败了。

我尝试使用jdk8和jdk11编译和执行代码,但出现了相同的“java.lang.IllegalArgumentException:Unsupported class file major version 55”错误。过去,我通过更新Java版本解决了此问题,但对于这个问题不起作用。

我使用:

  • JDK 11.0.2

  • Spring Boot 2.1.4

  • Spark 2.4.2

这是我正在执行的代码:

Dataset<Row> dataFrame = sparkSession.read().json("/home/data/*.json");
        dataFrame.createOrReplaceTempView("events");
        Dataset<Row> resultDataFrame = sparkSession.sql("SELECT * FROM events WHERE " + predicate); 
        Dataset<Event> eventDataSet = resultDataFrame.as(Encoders.bean(Event.class));
        return eventDataSet.collectAsList();

查询起作用,实际上在调试过程中您可以看到resultDataFrame和eventDataSet中都有信息。

我期望输出是一个适当的事件列表,但我得到了异常:

[http-nio-8080-exec-2] ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Unsupported class file major version 55] with root cause
java.lang.IllegalArgumentException: Unsupported class file major version 55
    at org.apache.xbean.asm6.ClassReader.<init>(ClassReader.java:166)
    at org.apache.xbean.asm6.ClassReader.<init>(ClassReader.java:148)
    at org.apache.xbean.asm6.ClassReader.<init>(ClassReader.java:136)
    at org.apache.xbean.asm6.ClassReader.<init>(ClassReader.java:237)
    at org.apache.spark.util.ClosureCleaner$.getClassReader(ClosureCleaner.scala:49)
    at org.apache.spark.util.FieldAccessFinder$$anon$3$$anonfun$visitMethodInsn$2.apply(ClosureCleaner.scala:517)
    at org.apache.spark.util.FieldAccessFinder$$anon$3$$anonfun$visitMethodInsn$2.apply(ClosureCleaner.scala:500)
    at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:733)
    at scala.collection.mutable.HashMap$$anon$1$$anonfun$foreach$2.apply(HashMap.scala:134)
    at scala.collection.mutable.HashMap$$anon$1$$anonfun$foreach$2.apply(HashMap.scala:134)
    at scala.collection.mutable.HashTable$class.foreachEntry(HashTable.scala:236)
    at scala.collection.mutable.HashMap.foreachEntry(HashMap.scala:40)
    at scala.collection.mutable.HashMap$$anon$1.foreach(HashMap.scala:134)
    at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:732)
    at org.apache.spark.util.FieldAccessFinder$$anon$3.visitMethodInsn(ClosureCleaner.scala:500)
.....

评论更新:

对于Java 8,我将pom更改为目标Java 8:

<java.version>1.8</java.version>

然后更新项目,执行 maven clean、maven install,最后运行。 仍然出现相同的版本 55 错误。


3
这表明Apache XBean所使用的ASM版本(请参考堆栈跟踪)不支持Java 11。 - Mark Rotteveel
它在Java 8上也无法工作,而且我在堆栈跟踪中没有看到任何东西...另一个奇怪的事情是它只发生在某些方法中,而不是所有方法。 - frm
1
要在Java 8上运行,您需要使用Java 8进行编译或至少针对Java 8进行编译。 - Mark Rotteveel
1
如果您使用的是Java 8,那么它就不会再说“版本55”了,所以您能描述一下您如何“尝试”使用它吗? - OneCricketeer
在Spring Boot应用程序中,您可以使用<java.version>属性在pom文件中更改Java版本,这应该足够了(至少一直以来都是这样)。 - frm
显示剩余8条评论
3个回答

19

除去spark-core依赖中的默认XBean构件,并添加最新版本的XBean构件,这对我有效。

<dependencies>
    <dependency>
        <groupId>org.apache.xbean</groupId>
        <artifactId>xbean-asm6-shaded</artifactId>
        <version>4.10</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-core_2.11</artifactId>
        <version>2.4.1</version>
        <exclusions>
            <exclusion>
                <groupId>org.apache.xbean</groupId>
                <artifactId>xbean-asm6-shaded</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

这是救星。 - Sachin Kumar
这解决了我的问题。@ManoshP,您是如何得出删除此构件并添加最新版本的结论的? - m b
这个解决方案解决了我的问题。谢谢 :) - Vasanth Subramanian
使用 org.apache.spark:spark-sql_2.11:2.4.8 和 Java 11,遇到了这个问题。建议的解决方案非常有效!谢谢。 - Shiv

5
问题的根本原因是我设置了一个错误的符号链接,它指向了错误的JDK版本,因此无法正常工作。JAVA_HOME 指向了 jdk11,而 Eclipse 正在使用这个版本。

这对我来说是Gradle JVM版本设置。 - gokhansari

3

由于大多数python开发人员为项目生成virutalenv,您可以使用以下代码片段检查不同组件的版本,以使pyspark正常工作。错误的原因是不兼容的java版本。pyspark需要java version 1.8+而不是jdk-11Major version 55对应于jdk-11,您可以在此处看到。

仅检查官方spark文档以获取版本兼容性。

import subprocess

# subprocess to find the java , scala and python version
cmd1 = "java -version"
cmd2 = "scala -version"
cmd3 = "python --version"
cmd4 = "whoami"

arr = [cmd1, cmd2, cmd3, cmd4]

for cmd in arr:
    process = subprocess.Popen(cmd.split(" "), stdout=subprocess.PIPE,stderr=subprocess.PIPE )
    stdout,stderr=process.communicate()
    logging.info(stdout.decode("utf-8") + " | "  + stderr.decode("utf-8"))

logging.info(os.getenv("JAVA_HOME"))
logging.info(os.getenv("HOME"))

您将获得以下输出:

INFO:root: | openjdk version "1.8.0_252"
OpenJDK Runtime Environment (build 1.8.0_252-8u252-b09-1~18.04-b09)
OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)

INFO:root: | Scala code runner version 2.12.2 -- Copyright 2002-2017, LAMP/EPFL and Lightbend, Inc.

INFO:root:Python 3.6.9

INFO:root:training

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接