Apache Spark 3.3.0 在 Java 17 上中断并显示“无法访问类 sun.nio.ch.DirectBuffer”

Gar*_*son 52 java apache-spark java-17

在Running unit test with Spark 3.3.0 on Java 17 failed with IllegalAccessError: class StorageUtils cannot access class sun.nio.ch.DirectBuffer 中提出了类似的问题,但该问题(和解决方案)仅与单元测试有关。对我来说 Spark 正在破坏程序的实际运行。

根据Spark 概述,Spark 可与 Java 17 配合使用。我在 Windows 10 上使用 Temurin-17.0.4+8 (build 17.0.4+8),包括 Maven 中的 Spark 3.3.0,如下所示:

<scala.version>2.13</scala.version>
<spark.version>3.3.0</spark.version>
...
<dependency>
  <groupId>org.apache.spark</groupId>
  <artifactId>spark-core_${scala.version}</artifactId>
  <version>${spark.version}</version>
</dependency>

<dependency>
  <groupId>org.apache.spark</groupId>
  <artifactId>spark-sql_${scala.version}</artifactId>
  <version>${spark.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

我尝试运行一个简单的程序:

final SparkSession spark = SparkSession.builder().appName("Foo Bar").master("local").getOrCreate();
final Dataset<Row> df = spark.read().format("csv").option("header", "false").load("/path/to/file.csv");
df.show(5);
Run Code Online (Sandbox Code Playgroud)

这到处都是:

Caused by: java.lang.IllegalAccessError: class org.apache.spark.storage.StorageUtils$ (in unnamed module @0x59d016c9) cannot access class sun.nio.ch.DirectBuffer (in module java.base) because module java.base does not export sun.nio.ch to unnamed module @0x59d016c9
    at org.apache.spark.storage.StorageUtils$.<clinit>(StorageUtils.scala:213)
    at org.apache.spark.storage.BlockManagerMasterEndpoint.<init>(BlockManagerMasterEndpoint.scala:114)
    at org.apache.spark.SparkEnv$.$anonfun$create$9(SparkEnv.scala:353)
    at org.apache.spark.SparkEnv$.registerOrLookupEndpoint$1(SparkEnv.scala:290)
    at org.apache.spark.SparkEnv$.create(SparkEnv.scala:339)
    at org.apache.spark.SparkEnv$.createDriverEnv(SparkEnv.scala:194)
    at org.apache.spark.SparkContext.createSparkEnv(SparkContext.scala:279)
    at org.apache.spark.SparkContext.<init>(SparkContext.scala:464)
    at org.apache.spark.SparkContext$.getOrCreate(SparkContext.scala:2704)
    at org.apache.spark.sql.SparkSession$Builder.$anonfun$getOrCreate$2(SparkSession.scala:953)
    at scala.Option.getOrElse(Option.scala:201)
    at org.apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:947)
Run Code Online (Sandbox Code Playgroud)

Spark 显然做了一些在 Java 17 中不应该做的事情。

令人失望。我该如何解决这个问题?

Ser*_*nov 35

解决方案

\n
\n

在Running unit test with Spark 3.3.0 on Java 17 failed with IllegalAccessError: class StorageUtils cannot access class sun.nio.ch.DirectBuffer 中提出了类似的问题,但该问题(和解决方案)仅与单元测试有关。对我来说 Spark 正在破坏程序的实际运行。

\n
\n

请考虑添加适当的 Java 虚拟机命令行选项。
\n添加它们的确切方法取决于您运行程序的方式:使用命令行、IDE 等。

\n

例子

\n

命令行选项取自类JavaModuleOptionsspark/JavaModuleOptions.java,位于 v3.3.0 \xc2\xb7 apache/spark

\n

命令行

\n

例如,.jar使用命令行运行程序(文件):

\n
java \\\n    --add-opens=java.base/java.lang=ALL-UNNAMED \\\n    --add-opens=java.base/java.lang.invoke=ALL-UNNAMED \\\n    --add-opens=java.base/java.lang.reflect=ALL-UNNAMED \\\n    --add-opens=java.base/java.io=ALL-UNNAMED \\\n    --add-opens=java.base/java.net=ALL-UNNAMED \\\n    --add-opens=java.base/java.nio=ALL-UNNAMED \\\n    --add-opens=java.base/java.util=ALL-UNNAMED \\\n    --add-opens=java.base/java.util.concurrent=ALL-UNNAMED \\\n    --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED \\\n    --add-opens=java.base/sun.nio.ch=ALL-UNNAMED \\\n    --add-opens=java.base/sun.nio.cs=ALL-UNNAMED \\\n    --add-opens=java.base/sun.security.action=ALL-UNNAMED \\\n    --add-opens=java.base/sun.util.calendar=ALL-UNNAMED \\\n    --add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED \\\n    -jar <JAR_FILE_PATH>\n
Run Code Online (Sandbox Code Playgroud)\n

IDE:IntelliJ IDEA

\n

参考:

\n\n

参考

\n\n

  • 感谢您的回复,但遗憾的是没有人进一步调查这一点,当然这些选项(从电子邮件线程复制)是矫枉过正的。我想大多数选项都可以使用 `--add-exports` 而不是 `--add-opens` (请参阅[文档](https://docs.oracle.com/en/java/javase/17/migrate/ migating-jdk-8-later-jdk-releases.html)),因为 Spark 肯定不会在所有这些包上使用反射。对于读取 CSV 文件并在本地保存到 JSON 的简单用例,只需 --add-exports java.base/sun.nio.ch=ALL-UNNAMED 就适合我。 (2认同)

小智 33

以下步骤帮助我解决了这个问题。

如果您从IDE (intelliJ IDEA)运行应用程序,请按照以下说明操作。

添加 JVM 选项“--add-exports java.base/sun.nio.ch=ALL-UNNAMED”

在此输入图像描述

来源: https: //arrow.apache.org/docs/java/install.html#java-compatibility


Hon*_*iao 16

这三种方法对我的项目有用

  • 火花3.3.2
  • 斯卡拉 2.13.10
  • Java 17.0.6(我的项目很小,它甚至可以在Java 19.0.1上运行。但是,如果你的项目很大,最好等待Spark正式支持它)

方法一

export JAVA_OPTS='--add-exports java.base/sun.nio.ch=ALL-UNNAMED'
sbt run
Run Code Online (Sandbox Code Playgroud)

方法二

在项目文件夹中创建一个.jvmopts文件,内容为:

--add-exports java.base/sun.nio.ch=ALL-UNNAMED
Run Code Online (Sandbox Code Playgroud)

然后你就可以运行

--add-exports java.base/sun.nio.ch=ALL-UNNAMED
Run Code Online (Sandbox Code Playgroud)

方法三

如果您使用的是 IntelliJ IDEA,这是基于 @Anil Reddaboina 的回答,谢谢!

这添加了更多信息,因为默认情况下我没有“VM 选项”字段。

请按照以下步骤操作:

在此输入图像描述

然后您应该能够添加--add-exports java.base/sun.nio.ch=ALL-UNNAMED到“VM 选项”字段。

或添加完全必要的 VM 选项参数:

--add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/sun.nio.cs=ALL-UNNAMED --add-opens=java.base/sun.security.action=ALL-UNNAMED --add-opens=java.base/sun.util.calendar=ALL-UNNAMED --add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述