升级JDK 8u462后WildFly使用JTDS驱动SSL连接重置问题求助
问题背景
我们长期使用WildFly 20搭配JTDS驱动实现SQL Server的JDBC连接池,大量客户环境采用该配置。近期仅将JDK从8u265升级至8u462,未做其他变更,WildFly启动创建初始连接池时出现连接重置问题,具体特征如下:
- 启用
ssl=request配置,对接SQL Server 2022; - 关闭SSL时,JTDS驱动可正常工作;
- 切换为Microsoft官方SQL Server驱动无异常;JTDS的
java.net.ssl追踪显示TLS 1.2握手完成后,SSL连接被主动关闭(无错误日志),但Microsoft驱动同流程下不会出现此情况; - 直接在Java Web应用中使用该JTDS驱动(非WildFly数据源配置),相同数据库和SSL配置可正常连接;
- 仅在WildFly的
standalone.xml中配置JTDS作为JDBC数据源时触发错误; - 使用的是带有自定义SSL补丁的最新版JTDS。
可能原因分析
JDK 8u462的SSL/TLS默认配置变更
JDK 8u462可能调整了SSL上下文的默认参数(如会话超时、套件优先级、扩展支持等),而JTDS的自定义SSL补丁未适配这些变更。WildFly数据源初始化连接时使用容器管理的SSL上下文,和应用直接调用驱动时的上下文存在差异,导致握手后连接被主动关闭。WildFly连接池验证机制冲突
WildFly连接池创建初始连接时会执行额外的连接验证逻辑(如test-on-borrow),JTDS驱动在JDK新环境下,与这些验证逻辑结合时,SSL连接的生命周期管理出现异常,导致连接被提前关闭。JTDS驱动的SSL会话复用问题
JDK升级后SSL会话复用规则发生变化,JTDS的自定义补丁未正确处理会话复用逻辑,导致握手完成后会话无法维持,连接被关闭。
解决方法尝试
1. 调整JDK SSL系统属性,兼容旧行为
在WildFly启动脚本(standalone.conf或domain.conf)中添加以下JVM参数,强制沿用JDK 8u265的SSL默认配置:
-Djdk.tls.client.protocols=TLSv1.2 -Djdk.tls.server.protocols=TLSv1.2 -Djavax.net.ssl.trustStore=$JAVA_HOME/jre/lib/security/cacerts -Djavax.net.ssl.trustStorePassword=changeit -Djdk.tls.ephemeralDHKeySize=2048 -Djdk.tls.rejectClientInitiatedRenegotiation=true
如果使用自定义信任库,替换trustStore路径和密码即可。
2. 修改WildFly数据源配置,调整连接验证策略
在standalone.xml的数据源配置中,调整连接池验证参数,避免SSL握手后立即触发额外操作:
<datasource jndi-name="java:jboss/datasources/YourDS" pool-name="YourDS" enabled="true" use-java-context="true"> <connection-url>jdbc:jtds:sqlserver://your-db-host:1433/your-db;ssl=request</connection-url> <driver>jtds</driver> <pool> <min-pool-size>5</min-pool-size> <max-pool-size>20</max-pool-size> <prefill>false</prefill> <!-- 关闭预填充,避免启动时批量创建连接触发问题 --> <use-strict-min>false</use-strict-min> </pool> <validation> <validate-on-match>false</validate-on-match> <background-validation>true</background-validation> <background-validation-millis>60000</background-validation-millis> <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker"/> </validation> </datasource>
核心是关闭prefill避免启动时批量建连,改用后台验证替代连接时的即时验证。
3. 适配JTDS驱动的SSL补丁
针对JDK 8u462的SSL变更调整自定义补丁:
- 检查补丁中是否硬编码SSL上下文参数,改为使用JDK默认动态参数;
- 确保补丁正确处理SSL会话生命周期,避免握手完成后主动关闭连接;
- 验证补丁是否兼容JDK 8u462新增的TLS扩展支持。
4. 强制WildFly使用应用级SSL上下文
在standalone.xml的数据源配置中指定自定义SSL上下文,与应用直接使用驱动时的上下文保持一致:
<datasource jndi-name="java:jboss/datasources/YourDS" pool-name="YourDS" enabled="true" use-java-context="true"> <connection-url>jdbc:jtds:sqlserver://your-db-host:1433/your-db;ssl=request</connection-url> <driver>jtds</driver> <security> <security-domain>your-ssl-security-domain</security-domain> </security> </datasource>
同时配置对应安全域:
<security-domain name="your-ssl-security-domain" cache-type="default"> <authentication> <login-module code="Certificate" flag="required"> <module-option name="securityDomain" value="your-ssl-security-domain"/> </login-module> </authentication> <jsse> <truststore path="/path/to/your/truststore.jks" password="yourpassword"/> <keystore path="/path/to/your/keystore.jks" password="yourpassword"/> </jsse> </security-domain>
内容的提问来源于stack exchange,提问作者user26533539

