TeamCity上Java17运行Spark3.3.0单元测试遇IllegalAccessError求助
问题分析与解决方案
核心问题拆解
- 初始IllegalAccessError:Java 9+模块系统限制了未模块化的Spark代码访问
java.base模块下的sun.nio.ch.DirectBuffer,必须通过--add-exports参数开放权限。 - 启用argLine后的VM启动失败:错误日志显示实际运行测试的JDK是Java 8(
/usr/lib/jvm/java-8-amazon-corretto/bin/java),但--add-exports是Java 9+专属参数,Java 8会将其识别为非法参数,直接导致JVM启动崩溃。
针对性解决方案
方案1:统一JDK版本,确保参数匹配
保持Java 17环境
- 检查TeamCity构建配置,强制构建过程使用Java 17,避免切换到Java 8。
- 正确配置
maven-surefire-plugin的argLine参数(取消注释,注意XML转义问题):<plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <includes> <include>**/*Test.java</include> </includes> <argLine>--add-exports java.base/sun.nio.ch=ALL-UNNAMED</argLine> </configuration> <groupId>org.apache.maven.plugins</groupId> <version>3.0.0-M5</version> </plugin> - 验证Docker环境中
JAVA_HOME是否指向Java 17,防止构建时自动切换JDK版本。
切换到Java 8环境
- 删除所有
--add-exports相关配置:包括Dockerfile中的MAVEN_OPTS、JAVA_OPTS,以及pom.xml中的argLine,Java 8无模块系统,不需要此类参数。 - 确认Spark版本兼容Java 8:Spark 3.2及后续版本推荐Java 11+,若坚持用Java 8,需更换为兼容的Spark版本。
方案2:SonarQube构建步骤的参数传递
SonarQube分析时若需运行测试,需将JVM参数传递给Sonar的测试执行环节:
- 在TeamCity的Sonar构建步骤中添加参数(仅Java 9+环境适用):
sonar.test.jvm.opts=--add-exports java.base/sun.nio.ch=ALL-UNNAMED
方案3:Spark测试的参数配置
若测试依赖SparkSession,需在创建SparkSession时传递JVM参数:
SparkSession spark = SparkSession.builder() .master("local") .config("spark.driver.extraJavaOptions", "--add-exports java.base/sun.nio.ch=ALL-UNNAMED") .appName("Test") .getOrCreate();
关键注意点
- 禁止混合Java版本:Java 8与Java 9+的JVM参数不兼容,必须统一构建环境。
- 检查TeamCity配置是否覆盖Docker环境变量:TeamCity中设置的
JAVA_HOME、MAVEN_OPTS等参数可能会覆盖Dockerfile中的配置。
内容的提问来源于stack exchange,提问作者Sachin365
相关产品推荐
相关产品推荐

