将Wildfly 10从Java 8升级至Java 11时遇类找不到错误求解决方案
问题重现
升级Java版本到11后,Wildfly 10启动时出现如下错误:
at org.jboss.threads.JBossThread.run(JBossThread.java:320) Caused by: java.lang.ClassNotFoundException: jdk.internal.reflect.ConstructorAccessorImpl from [Module "org.infinispan:main" from local module loader @502a16d9 (finder: local module finder @122003cc (roots: /opt/wildfly10/modules,/opt/wildfly10/modules/system/layers/base))] at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:198) at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363) at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93)
该问题源于Java 9引入的模块系统(JPMS)将jdk.internal.reflect标记为内部模块,默认禁止外部代码访问,而Wildfly 10自带的Infinispan版本未适配该机制。
可行解决办法
添加JVM启动参数开放内部模块访问:
编辑Wildfly的启动配置文件(如standalone.conf或domain.conf),在JAVA_OPTS中添加以下参数,允许未命名模块访问jdk.internal.reflect包:JAVA_OPTS="$JAVA_OPTS --add-opens java.base/jdk.internal.reflect=ALL-UNNAMED"若仅需给Infinispan模块授权,可改为:
JAVA_OPTS="$JAVA_OPTS --add-opens java.base/jdk.internal.reflect=org.infinispan"重启Wildfly后验证是否解决问题。
替换兼容Java 11的Infinispan模块:
Wildfly 10自带的Infinispan版本过旧,不支持Java 11。下载与Wildfly 10 API兼容且支持Java 11的Infinispan版本(推荐9.x系列),替换/opt/wildfly10/modules/system/layers/base/org/infinispan目录下的模块文件,并更新module.xml中的依赖声明与版本信息。修改应用代码避免依赖内部API:
若应用代码中直接调用了jdk.internal.reflect下的类,替换为标准的java.lang.reflectAPI。内部API在Java 9+属于非公开API,存在被移除的风险,使用标准API可提升代码兼容性与稳定性。
关于直接升级Wildfly的可行性
直接升级到Wildfly 15及以上版本是更简单且长期稳定的方案:
- Wildfly 15及后续版本原生支持Java 11,官方已完成JPMS模块适配,不会出现此类内部类访问问题;
- 配置迁移可通过Wildfly自带的CLI工具完成,执行
jboss-cli.sh的migrate命令可自动迁移standalone.xml/domain.xml等核心配置文件; - 标准Java EE应用在Wildfly 15上兼容性良好,无需大规模修改代码;
- 临时 workaround(如添加JVM参数)仅能解决单个问题,后续可能遇到更多Java 11兼容问题(如废弃API、其他内部模块访问限制),升级Wildfly可从根源避免这类问题,降低长期维护成本。
内容的提问来源于stack exchange,提问作者Gary Kephart

