You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark 3.5.1搭配Java 17测试报IllegalAccessError的解决求助

解决方案:Java 17下Spark 3.5.1 IllegalAccessError及反序列化问题

问题根源

Java 17严格限制了对sun.nio.ch等内部API的访问,Spark 3.5.1的StorageUtils类需要调用这些内部API;直接添加单一--add-exports参数会破坏序列化兼容性,触发InvalidObjectException。

通用解决方案(适配SBT、Git Actions等非IDE场景)

1. 完善SBT多阶段JVM参数配置

确保JVM参数覆盖编译、测试、运行全阶段,且参数组合精准。修改build.sbt如下:

name := "spark-java17-project"
version := "0.1"
scalaVersion := "2.12.12"

val sparkVersion = "3.5.1"

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % sparkVersion % Provided,
  "org.apache.spark" %% "spark-sql" % sparkVersion % Provided
)

// SBT自身及基础编译阶段的JVM参数
javaOptions ++= Seq(
  "--illegal-access=permit",
  "--add-exports=java.base/sun.nio.ch=ALL-UNNAMED",
  "--add-opens=java.base/java.nio=ALL-UNNAMED",
  "--add-opens=java.base/java.lang=ALL-UNNAMED"
)

// Spark任务运行阶段的独立JVM参数(必须开启fork)
fork := true
javaOptions in run ++= Seq(
  "--add-exports=java.base/sun.nio.ch=ALL-UNNAMED",
  "--add-opens=java.base/java.nio=ALL-UNNAMED",
  "--add-opens=java.base/java.lang=ALL-UNNAMED",
  "--add-opens=java.base/java.util=ALL-UNNAMED"
)

// 测试阶段的专属参数
javaOptions in Test ++= Seq(
  "--add-exports=java.base/sun.nio.ch=ALL-UNNAMED",
  "--add-opens=java.base/java.nio=ALL-UNNAMED"
)

2. Spark任务提交时显式传递JVM参数

如果通过spark-submit运行任务,需在命令行或代码中指定Driver和Executor的参数:

import org.apache.spark.SparkConf

val conf = new SparkConf()
  .setAppName("TaskDemo")
  .setMaster("local[*]")
  .set("spark.driver.extraJavaOptions", "--add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED")
  .set("spark.executor.extraJavaOptions", "--add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED")

3. 修复反序列化错误

出现InvalidObjectException时,通过以下方式解决:

  • 确保所有序列化类实现java.io.Serializable接口
  • 启用Spark的Kryo序列化(推荐,兼容性更强):
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
conf.set("spark.kryo.registrationRequired", "false")

4. Git Actions中的配置示例

在.github/workflows/build.yml中注入JVM参数,确保构建测试正常执行:

name: Spark Build & Test
on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
      - name: Build with SBT
        run: sbt clean test
        env:
          JAVA_OPTS: "--add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --illegal-access=permit"

关键注意点

  • fork := true必须开启:保证Spark任务运行在独立JVM进程,应用配置的参数
  • 区分SBT自身参数与Spark任务参数:两者作用的JVM进程不同,需分别配置
  • 避免依赖--illegal-access=permit:Java 17中该参数已废弃,需配合精准的--add-exports/--add-opens授权

内容的提问来源于stack exchange,提问作者Mujtaba Faizi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 04:22:23