Spring Boot集成Apache Ignite配置dataStorageConfiguration启动报错问题
问题根因
- Java 9起引入的JPMS模块系统默认限制了跨模块的反射访问权限,JDK 16更是直接移除了
--illegal-access=permit的默认配置,所有未显式声明开放的JDK内部API反射访问会直接抛出异常,而不是JDK 11里的警告。 - Apache Ignite 2.10.0的底层实现高度依赖
sun.misc.Unsafe相关API,需要直接操作Java NIO Buffer的address字段实现高性能内存存储逻辑。你注释掉dataStorageConfiguration时不会触发Ignite内存存储模块的初始化,不会加载GridUnsafe相关类,所以运行正常;一旦放开配置,初始化DataStorageConfiguration时会触发相关依赖类加载,就会触发反射访问java.nio.Buffer.address字段的逻辑。 - 你之前的启动参数存在两个问题:一是存在拼写错误(比如
--adDd-exports、jdk.managemeDnt),二是缺少java.nio包的开放权限配置,同时参数传递方式错误,把JVM参数当成了应用启动参数传递,导致配置未生效。
JDK 16适配解决方案
- 首先补充缺失的JVM权限配置,修正之前的拼写错误,完整的JVM参数如下:
--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED --add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED --add-exports=java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --illegal-access=permit
- 其次修正Maven启动命令的参数传递规则,
spring-boot:run中JVM参数需要通过spring-boot.run.jvmArguments传递,不能使用run.arguments(该参数是传递给应用主类的业务参数),修正后的启动命令如下:
mvn spring-boot:run -f ..\pom.xml -Dspring-boot.run.jvmArguments="--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED --add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED --add-exports=java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --illegal-access=permit"
- 长期适配建议:升级到Ignite 2.13及以上版本,该版本开始官方优化了高版本JDK的兼容性,减少了不必要的非法反射调用,能降低高版本JDK下的适配成本。
内容的提问来源于stack exchange,提问作者ttuna
相关产品推荐
相关产品推荐

