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

Java17迁移WAR配置Add-Opens仍报InaccessibleObjectException问题

问题原因

在WAR包的MANIFEST.MF中添加Add-Opens配置无法解决该问题,核心原因是这个配置的生效场景和你的部署模式不匹配:

  • Add-Opens是JVM提供的Jar包manifest属性,仅对通过java -jar命令直接启动的可执行独立Jar生效。你的应用是部署在Tomcat中的WAR包,WAR内的类由Tomcat自定义的WebApp类加载器加载,JVM启动时不会主动读取WAR包manifest中的Add-Opens配置,自然不会为kryo相关类开放对应的模块反射权限。
  • 报错信息里提到的unnamed module @726825d9,就是Tomcat类加载器加载kryo组件时生成的未命名模块,由于没有拿到java.util包的开放权限,反射访问Arrays$ArrayList内部私有字段时就会抛出InaccessibleObjectException。
解决方法

按照优先级从高到低选择方案:

  1. 升级兼容版本(推荐长期使用)
    你使用的kryo 2.23、kryo-serializers 0.42本身就存在Java 17兼容性硬伤,仅靠开放模块权限无法覆盖所有潜在问题。可以在Maven依赖中排除内部库传递引入的旧版本kryo相关组件,手动引入适配Java 17的高版本(kryo 5.x+、对应适配高版本JDK的kryo-serializers),提前做好序列化/反序列化逻辑的兼容性验证,从根源上规避非法反射问题。
  2. 添加JVM启动参数(临时兼容方案)
    如果暂时无法升级依赖,直接修改Tomcat启动配置,在CATALINA_OPTS变量中添加JVM模块开放参数,不要在WAR包manifest中配置:
    CATALINA_OPTS="--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED"
    
    配置完成后重启Tomcat即可,该参数会直接传递给JVM,为所有未命名模块开放对应JDK内部包的反射访问权限,解决当前报错。
  3. 容器版本适配
    你使用的Tomcat 9.0.24是较早的小版本,对Java 17的适配存在已知缺陷,如果配置完参数后仍出现其他模块访问报错,可以先将Tomcat升级到9.0.x系列的最新稳定版,减少容器本身和高版本JDK的兼容问题。

注:不要依赖WAR包manifest配置JVM启动参数,所有Servlet容器部署场景下,JVM层面的参数都需要在容器启动脚本中配置,不会读取应用包内的manifest相关JVM参数配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:24:34