Gre*_*pff 14 java apache-spark java-17
根据发行说明,特别是在 Java 17 上构建和运行 Spark ( SPARK-33772 ),Spark 现在支持在 Java 17 上运行。
但是,将 Java 17 (Temurin-17.0.3+7) 与 Maven (3.8.6) 和 maven-surefire-plugin (3.0.0-M7) 一起使用,在运行使用 Spark (3.3.0) 的单元测试时会失败和:
java.lang.IllegalAccessError: class org.apache.spark.storage.StorageUtils$ (in unnamed module @0x1e7ba8d9) cannot access class sun.nio.ch.DirectBuffer (in module java.base) because module java.base does not export sun.nio.ch to unnamed module @0x1e7ba8d9
堆栈是:
java.lang.IllegalAccessError: class org.apache.spark.storage.StorageUtils$ (in unnamed module @0x1e7ba8d9) cannot access class sun.nio.ch.DirectBuffer (in module java.base) because module java.base does not export sun.nio.ch to unnamed module @0x1e7ba8d9
at org.apache.spark.storage.StorageUtils$.<init>(StorageUtils.scala:213)
at org.apache.spark.storage.StorageUtils$.<clinit>(StorageUtils.scala)
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:189)
at org.apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:947)
[...]
Run Code Online (Sandbox Code Playgroud)
Spark 的 Java 17 解决方案- java.lang.NoClassDefFoundError: Could not initialize class org.apache.spark.storage.StorageUtils 问题仅在 2 个月前提出,但这早于 Spark 3.3.0 版本,因此早于官方版本支持 Java 17。
为什么我无法使用 Java 17 运行 Spark 3.3.0 测试,我们该如何修复它?
Gre*_*pff 15
尽管 Spark 现在支持 Java 17,但它仍然引用 JDK 内部类sun.nio.ch.DirectBuffer:
// In Java 8, the type of DirectBuffer.cleaner() was sun.misc.Cleaner, and it was possible
// to access the method sun.misc.Cleaner.clean() to invoke it. The type changed to
// jdk.internal.ref.Cleaner in later JDKs, and the .clean() method is not accessible even with
// reflection. However sun.misc.Unsafe added a invokeCleaner() method in JDK 9+ and this is
// still accessible with reflection.
private val bufferCleaner: DirectBuffer => Unit = [...]
Run Code Online (Sandbox Code Playgroud)
在Java模块系统下,对该类的访问是受到限制的。Java 9 迁移指南说:
如果您必须使用默认情况下无法访问的内部 API,则可以使用 --add-exports 命令行选项来打破封装。
我们需要开放对我们的模块的访问。为了对 Surefire 执行此操作,我们将此配置添加到插件中:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<argLine>--add-exports java.base/sun.nio.ch=ALL-UNNAMED</argLine>
</configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)
根据与 Spark 开发人员之一的讨论,Spark 添加了以下内容以执行其所有内部单元测试。
这些选项用于传递所有 Spark UT,但也许您不需要全部。
--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
Run Code Online (Sandbox Code Playgroud)
也有人评论说:
但是,在使用spark-shell、spark-sql和spark-submit时,这些选项不需要显式添加
根据上面的讨论,我正在使用:
%SPARK_HOME%\bin\spark-submit.cmd --driver-java-options "--add-exports java.base/sun.nio.ch=ALL-UNNAMED" spark_ml_heart.py
Run Code Online (Sandbox Code Playgroud)
只需--add-exports在 Java 17 上的 Spark 3.2.1 上运行 Python 脚本即可。
您可能需要包含以下所有内容的完整版本--add-exports:
%SPARK_HOME%\bin\spark-submit.cmd --driver-java-options "--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" spark_ml_heart.py
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13838 次 |
| 最近记录: |