
本文详解 WildFly 26+ 中启用 HTTPS 后远程 JNDI 查找失败的根本原因,重点说明 remote+http:// 与 remote+https:// 协议的本质差异、Elytron SSL 上下文的客户端适配要点,并提供可直接复用的 wildfly-config.xml 配置方案及关键注意事项。
本文详解 wildfly 26+ 中启用 https 后远程 jndi 查找失败的根本原因,重点说明 `remote+http://` 与 `remote+https://` 协议的本质差异、elytron ssl 上下文的客户端适配要点,并提供可直接复用的 `wildfly-config.xml` 配置方案及关键注意事项。
当 WildFly 从 HTTP 切换到 HTTPS 后,JNDI 远程调用失败(报错 javax.naming.CommunicationException: WFNAM00018: Failed to connect to remote host + java.io.IOException: Invalid response),根本原因并非证书信任问题,而是协议不匹配。错误日志中 HttpUpgradeParser.parseVersion 失败明确指向:客户端仍在尝试通过 HTTP 协议发起 Remoting 握手,而服务端已将 9090 端口配置为 HTTPS 监听器——此时该端口只接受 TLS 加密的 HTTP/1.1 或 HTTP/2 请求,无法处理原始的 HTTP Upgrade 流程(Remoting 的底层连接协商机制依赖此流程)。简言之:remote+http://host:9090 在 HTTPS 模式下是非法的,必须显式切换为 remote+https://。
✅ 正确配置:启用 remote+https:// 协议
WildFly 客户端(jboss-client.jar)使用 wildfly-config.xml(或 jboss-ejb-client.properties)定义连接策略。您当前的配置:
<configuration>
<jboss-ejb-client xmlns="urn:jboss:wildfly-client-ejb:3.0">
<connections>
<connection uri="remote+http://<FQDNofHost>:9090"/>
</connections>
</jboss-ejb-client>
</configuration>仅适用于 EJB 调用,且强制走 HTTP 协议;它不控制 JNDI 命名服务的底层 Remoting 连接。JNDI 远程查找由 org.wildfly.naming.client 组件驱动,其连接行为由 <endpoint></endpoint> 配置块控制,而非 <jboss-ejb-client></jboss-ejb-client>。
因此,必须添加 <endpoint></endpoint> 块并指定 remote+https:// URI:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- ✅ 关键:为 Remoting 命名服务配置 HTTPS 连接 -->
<endpoint xmlns="urn:jboss-remoting:5.0">
<connections>
<!-- 注意:URI 必须是 remote+https://,端口需与 standalone.xml 中 https-listener 绑定的 socket-binding 一致 -->
<connection
destination="remote+https://<FQDN>:9090"
read-timeout="50"
write-timeout="50"
heartbeat-interval="10000"/>
</connections>
</endpoint>
<!-- 可选:保留 EJB 客户端配置(若同时调用 EJB) -->
<jboss-ejb-client xmlns="urn:jboss:wildfly-client-ejb:3.0">
<connections>
<connection uri="remote+https://<FQDN>:9090"/>
</connections>
</jboss-ejb-client>
</configuration>⚠️ 重要校验点:
<fqdn></fqdn>必须与服务器证书中的 Subject Alternative Name (SAN) 或 Common Name (CN) 完全一致(区分大小写),否则触发SSLHandshakeException: No subject alternative DNS name matching...。- 端口
9090必须是<https-listener></https-listener>实际绑定的端口(如您的配置中<socket-binding name="https" port="8443"></socket-binding>,则此处应为8443,除非您已将httpssocket-binding 的 port 显式改为9090)。请检查standalone.xml中<https-listener name="https" socket-binding="https" ...></https-listener>对应的<socket-binding name="https"></socket-binding>的port值。
? 客户端证书信任:复用 Windows 证书存储(无需额外配置)
您已在 JVM 启动参数中指定:
-Djavax.net.ssl.trustStoreProvider=SunMSCAPI -Djavax.net.ssl.trustStoreType=Windows-ROOT
这已足够让 JVM(及基于 JVM 的 WildFly 客户端)信任 Windows 系统根证书库(如您的服务器证书由企业 CA 签发并已导入 Windows 信任库)。wildfly-config.xml 中无需重复配置 truststore——Elytron 客户端会自动继承 JVM 的 SSL 上下文设置。
✅ 验证方式:在客户端代码中添加调试语句,确认
SSLContext.getDefault()返回的上下文已加载 Windows-ROOT 证书:SSLContext ctx = SSLContext.getDefault(); System.out.println("Default SSLContext provider: " + ctx.getProvider().getName());
? 常见误区与排错建议
| 问题现象 | 根本原因 | 解决方案 |
|---|---|---|
Invalid response + HttpUpgradeParser 错误 |
客户端仍用 remote+http:// 连接 HTTPS 端口 |
强制改用 remote+https:// 并配置 <endpoint></endpoint>
|
SSLHandshakeException: unknown certificate |
服务器证书未被客户端信任(如自签名、或未导入 Windows 信任库) | 将服务器证书链导入 Windows “受信任的根证书颁发机构” 存储,或改用 -Djavax.net.ssl.trustStore=... 指向含该证书的 JKS |
No subject alternative DNS name matching |
客户端访问的主机名(如 myapp.local)与证书 SAN 不符 |
使用 openssl s_client -connect host:port -servername host -showcerts 检查证书 SAN,并确保客户端 URI 中的主机名与之完全一致 |
JNDI list("") 返回空或超时 |
未启用 http-invoker 或安全域配置错误 |
确保 <host></host> 下存在 <http-invoker security-realm="ApplicationRealm"></http-invoker>,且 ApplicationRealm 中用户具有 guest 或对应角色 |
✅ 最终验证步骤
- 更新
wildfly-config.xml,确保<endpoint></endpoint>使用remote+https://; - 确认 JVM 启动参数包含
-Djavax.net.ssl.trustStoreType=Windows-ROOT; - 重启 WildFly 服务端,确认
https-listener已激活(日志中出现WFLYUT0021: Registered web context: '...'); - 运行客户端,观察是否成功执行
jndiContext.list("")并返回命名空间内容。
通过以上配置,WildFly 26+ 的 HTTPS Remoting JNDI 调用即可稳定工作——核心在于理解协议层语义:HTTP 端口走 remote+http://,HTTPS 端口必须走 remote+https://,且二者由不同 XML 配置块控制。

















