Spring Boot升级Java 11后出现Illegal access error问题排查
我有一个基于Spring Boot 2.7.16的应用,原本使用Java 8,升级到Java 11后,执行mvn spring-boot:run启动时出现以下错误:
Caused by: org.springframework.cglib.core.ReflectUtils$6: ClassLoader mismatch for [java.util.concurrent.ScheduledThreadPoolExecutor]: JVM should be started with --add-opens=java.base/java.lang=ALL-UNNAMED for ClassLoader.defineClass to be accessible on org.springframework.boot.loader.LaunchedURLClassLoader; consider co-locating the affected class in that target ClassLoader instead. Caused by: java.lang.IllegalAccessException: module java.base does not open java.util.concurrent to unnamed module
我已按如下方式更新pom.xml,但错误仍存在,请问原因是什么?
<build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.10.1</version> <configuration> <compilerArgs> <arg>--add-opens</arg> <arg>add-opens=java.base/java.lang=ALL-UNNAMED</arg> </compilerArgs> </configuration> </plugin> </plugins> </pluginManagement> <!-- other plugins --> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> </plugin> </plugins> </build>
当前使用Java 11,终端执行命令:
mvn spring-boot:run
原因及解决方法
核心问题
- 参数配置位置错误:你把
--add-opens配置在了maven-compiler-plugin中,这个插件仅负责编译阶段的参数传递,而mvn spring-boot:run是由spring-boot-maven-plugin启动JVM进程,编译插件的参数不会影响启动时的JVM环境。 - 参数格式错误:第二个
<arg>里多写了add-opens=前缀,正确的参数应该是java.base/java.lang=ALL-UNNAMED,和第一个<arg>的--add-opens配合使用。 - 缺失必要的开放模块:错误信息里同时提到了
java.base/java.lang和java.base/java.util.concurrent两个模块需要开放,你只配置了前者。
正确配置
修改spring-boot-maven-plugin的配置,添加启动时的JVM参数:
<plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <jvmArguments>--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED</jvmArguments> </configuration> </plugin> <!-- 其他插件保持原有配置不变 --> </plugins>
配置完成后重新执行mvn spring-boot:run即可正常启动应用。
内容的提问来源于stack exchange,提问作者karvai

