You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDK18运行Spring应用报java.lang.IllegalStateException如何解决

异常含义

这个异常是Java 9引入模块化系统(JPMS)后,高版本JDK和旧版第三方库不兼容的典型报错,完整报错链路逻辑如下:

  • Spring启动时要对@Configuration标注的配置类做CGLIB动态代理增强,CGLIB初始化过程中需要通过反射修改ClassLoader.defineClass方法的访问权限,来实现动态类的定义
  • JDK 18默认对核心模块的内部API做了严格的访问限制,不允许未命名模块(也就是非模块化的业务代码、旧版第三方Jar)通过反射访问java.base模块下java.lang包的受保护方法,直接抛出InaccessibleObjectException
  • 反射初始化失败导致CGLIB的增强器类无法正常加载,最终Spring无法处理配置类,容器启动中断。
核心诱发原因

你提到的JDK版本差异确实是本次问题的核心诱因,具体逻辑:

  • Ant脚本里配置的source=1.8、target=1.8仅能保证javac编译出来的业务代码字节码版本符合JDK 8规范,既不会改变项目依赖的第三方包(Spring、CGLIB)的已有逻辑,也不会自动适配高版本JDK的模块化规则。
  • 你的项目是适配JDK 8的遗留应用,依赖的Spring版本大概率是3.x/4.x系列,内置的CGLIB没有做高版本JDK的模块化兼容。不管是构建时用JDK 18连带打包了不兼容的依赖,还是新机器上运行Jar时使用JDK 18作为运行时,只要代码跑在JDK 9及以上的环境,且没有做模块开放配置,就会触发这个报错。
  • 旧机器上能正常运行,本质是旧机器的运行时JDK版本为1.8,没有模块化访问限制。
可行解决方案

按改造成本从低到高排序:

  • 方案1(零改动最稳妥):全链路使用JDK 8。把执行Ant构建的JDK换成JDK 8,新机器上运行Jar也使用JDK 8作为运行时环境,和原有遗留应用的适配环境保持完全一致,不需要修改任何代码、配置,直接规避所有高版本JDK兼容性问题。
  • 方案2(必须用高版本JDK运行时选):添加JVM启动参数开放模块权限。启动Jar时在命令里追加如下参数,放开CGLIB需要的反射访问权限:
java --add-opens java.base/java.lang=ALL-UNNAMED -jar 你的应用包名.jar

如果启动后还出现其他模块的InaccessibleObjectException报错,按照报错提示的模块名、包名,按相同格式追加--add-opens参数即可。这个方案不需要改项目代码,仅调整启动命令。

  • 方案3(长期适配选):升级Spring版本。将项目依赖的Spring升级到5.3.x及以上的正式版本,这些版本内置的CGLIB已经完成高版本JDK的模块化适配,不需要额外加启动参数即可在JDK 18上正常运行。注意Spring大版本升级可能存在API变更,需要全量回归业务功能。

内容的提问来源于stack exchange,提问作者user2526586

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:06:21