尽管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 = [...]
在Java模块系统下,对该类的访问是受到限制的。这Java 9 迁移指南 says:
如果您必须使用默认情况下无法访问的内部 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>
基于一个与一位 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
也有人评论说:
但是,在使用spark-shell、spark-sql和spark-submit时,这些选项不需要显式添加