首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Java17上使用Spark3.3.0运行单元测试IllegalAccessError失败:类StorageUtils不能访问类sun.nio.ch.DirectBuffer

在Java17上使用Spark3.3.0运行单元测试IllegalAccessError失败:类StorageUtils不能访问类sun.nio.ch.DirectBuffer
EN

Stack Overflow用户
提问于 2022-06-23 05:09:21
回答 2查看 2.4K关注 0票数 2

根据发布说明,特别是在Java17上构建和运行SparkonJava17 (https://issues.apache.org/jira/browse/SPARK-33772)的票证,Spark现在支持在Java17上运行。

但是,使用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

堆栈是:

代码语言:javascript
复制
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)
  [...]

https://stackoverflow.com/questions/72230174在两个月前才被问到这个问题,但这个问题早于Spark3.3.0版本,因此早于官方对Java17的支持。

为什么我不能用Java 17运行我的Spark3.3.0测试,我们如何修复它呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-06-23 05:09:21

尽管Spark现在支持Java 17,但它仍然引用JDK内部类sun.nio.ch.DirectBuffer

代码语言:javascript
复制
  // 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 = [...]

在Java模块系统下,对该类的访问受到限制。Java 9迁移指南说:

如果您必须使用默认不可访问的内部API,则可以使用--add命令行选项中断封装。

我们需要打开进入我们模块的通道。为了确保这一点,我们将此配置添加到插件中:

代码语言:javascript
复制
<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>

基于与星火开发商之一的讨论,Spark添加了以下内容,以便执行其所有内部单元测试。

这些选项是用来通过所有星火UTs,但也许你不需要所有。

代码语言:javascript
复制
--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

还有人评论说:

然而,这些选项在使用星火壳、星火-sql和火花-提交时不需要显式添加。

票数 4
EN

Stack Overflow用户

发布于 2022-09-21 10:37:20

基于上述讨论,我使用:

代码语言:javascript
复制
%SPARK_HOME%\bin\spark-submit.cmd --driver-java-options "--add-exports java.base/sun.nio.ch=ALL-UNNAMED" spark_ml_heart.py

使用单个--add-exports在Java17上的Spark3.2.1上运行Python。

您可能需要包含所有--add-exports的完整版本

代码语言:javascript
复制
%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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72724816

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档