Java17迁移Spark3.3.2遇权限错误,如何通过Jar/Manifest预设模块参数?
解决Spark 3.3.2 + Java 17的非法访问错误:无需全局修改启动命令的构建期方案
Spark 3.3.2未适配Java 17的模块系统,访问java.base内部API时会触发IllegalAccessError,不用全局修改所有启动脚本,以下是几个在构建/配置阶段就能解决问题的方案:
1. 单元测试自动注入参数(Maven)
修改项目pom.xml,给maven-surefire-plugin配置默认的argLine,所有单元测试运行时自动带上所需JVM参数,不用手动调整测试启动命令:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <configuration> <argLine> --add-exports java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED </argLine> </configuration> </plugin>
2. Spark应用预设JVM参数
在项目的src/main/resources下添加spark-defaults.conf,把所需参数配置到Spark的驱动和执行器选项中,提交作业时会自动加载:
spark.driver.extraJavaOptions --add-exports java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED spark.executor.extraJavaOptions --add-exports java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED
无论是本地运行还是用spark-submit提交,都不用在命令行手动加参数。
3. 容器化部署简化
在Dockerfile中设置_JAVA_OPTIONS环境变量,Java进程会自动读取该变量中的参数,无需修改java -jar命令:
ENV _JAVA_OPTIONS="--add-exports java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED" CMD ["java", "-jar", "/app/myProgram.jar"]
4. 长期根治:升级Spark版本
Spark 3.4.0及以上版本已官方适配Java 17,完全不需要手动添加这些--add-exports/--add-opens参数。如果项目允许,直接升级到3.4.x或更高版本,从根源上消除迁移障碍。
内容的提问来源于stack exchange,提问作者Marc Le Bihan
相关产品推荐
相关产品推荐

