Spring Maven集成测试创建SparkSession时遇非法访问错误求助
解决Spring Maven集成测试中SparkSession创建的IllegalAccessError问题
问题根源
Java 9+的模块系统默认限制了内部API(如sun.nio.ch.DirectBuffer)的访问,Spark的StorageUtils类需要调用这个内部API,但未被java.base模块导出给未命名模块,导致权限错误。
具体解决步骤
- 用对Maven插件:集成测试必须用
maven-failsafe-plugin而非maven-surefire-plugin(surefire专门用于单元测试),很多人因插件用错导致配置不生效。 - 正确配置Failsafe插件的JVM参数:确保
--add-exports参数传递到集成测试的JVM进程,同时避免被其他插件覆盖参数:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.1.2</version> <configuration> <!-- 保留原有参数的同时添加模块导出配置 --> <argLine>--add-exports java.base/sun.nio.ch=ALL-UNNAMED ${argLine}</argLine> <additionalClasspathElement>${project.build.outputDirectory}</additionalClasspathElement> <!-- 可选:避免Spring与Spark类加载器冲突 --> <useSystemClassLoader>false</useSystemClassLoader> </configuration> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> - 匹配Spark与Java版本:如果用Java 11+,Spark 3.x可兼容;若用Java 17,可能需要额外添加
--add-opens java.base/java.nio=ALL-UNNAMED参数;允许的话,降级到Java 8可直接规避模块系统权限问题。 - 确认Profile激活:如果配置在特定Maven Profile中,运行集成测试时要显式激活,比如执行
mvn verify -P你的集成测试Profile名称。 - 验证参数是否生效:可以在测试代码中添加打印JVM参数的代码,确认
--add-exports是否被正确加载:System.out.println("JVM Args: " + Arrays.toString(ManagementFactory.getRuntimeMXBean().getInputArguments()));
额外注意点
如果项目中使用了spring-boot-maven-plugin,它可能会修改argLine参数,所以必须在Failsafe的argLine中加上${argLine}来继承原有配置,避免被覆盖。
内容的提问来源于stack exchange,提问作者Guy Assaf
相关产品推荐
相关产品推荐

