基于Tomcat9的应用连接MySQL时抛出MySQLNonTransientConnectionException异常
我之前碰到过几乎一模一样的问题——同样的JDBC配置在普通Java主类里跑完全正常,放到Tomcat容器里就报密钥库密码错误。本质上这是Tomcat的运行上下文、权限策略和默认配置和普通Java程序存在差异导致的,下面是几个针对性的排查和解决步骤:
1. 修正JDBC URL的文件路径格式
你当前URL里的证书路径用的是file:/home/...,这种简写在Tomcat的上下文里容易出现解析异常,建议换成标准的file协议URL格式(三个斜杠),确保路径被正确识别:
DriverManager.getConnection( "jdbc:mysql://localhost:3306/ibisdb74?verifyServerCertificate=true&useSSL=true&requireSSL=true&clientCertificateKeyStoreUrl=file:///home/directoryA/mysql_certs_latest4/keystore&clientCertificateKeyStorePassword=mypass&trustCertificateKeyStoreUrl=file:///home/directoryA/mysql_certs_latest4/truststore&trustCertificateKeyStorePassword=mypass", "root", "root" );
注意:Java字符串里的URL参数分隔符直接用&即可,不需要转义成HTML实体&。
2. 明确指定密钥库类型
从异常栈里看到了PKCS12KeyStore,说明你的密钥库是PKCS12格式,但Tomcat环境下可能默认使用JKS类型,导致解析失败。在JDBC URL里添加密钥库类型参数,强制指定格式:
// 在URL末尾追加这两个参数 &clientCertificateKeyStoreType=PKCS12 &trustCertificateKeyStoreType=PKCS12
让驱动明确知道用什么格式解析你的密钥库,避免默认类型不匹配的问题。
3. 检查Tomcat运行用户的文件权限
普通Java程序是用你的个人用户账号运行的,自然有证书文件的读取权限,但Tomcat通常用专门的系统用户(比如tomcat)启动,可能没有权限访问/home/directoryA/mysql_certs_latest4/目录下的文件。执行以下命令赋予权限:
# 将证书目录的所有者切换为tomcat用户 sudo chown -R tomcat:tomcat /home/directoryA/mysql_certs_latest4/ # 设置文件为可读权限 sudo chmod -R 644 /home/directoryA/mysql_certs_latest4/
4. 排查Tomcat安全管理器的权限限制
如果你的Tomcat启用了安全管理器(配置文件为conf/catalina.policy),需要给MySQL驱动jar包添加读取证书文件的权限。打开catalina.policy,添加以下配置:
grant codeBase "file:${catalina.home}/lib/mysql-connector-java-*.jar" { permission java.io.FilePermission "/home/directoryA/mysql_certs_latest4/-", "read"; };
修改后重启Tomcat,确保驱动能正常读取证书文件。
5. 检查全局系统属性干扰
Tomcat的启动脚本(catalina.sh或catalina.bat)可能设置了全局的SSL密钥库系统属性,比如javax.net.ssl.trustStore、javax.net.ssl.keyStore,这些会直接覆盖JDBC URL里的配置。打开启动脚本,查找类似以下的配置:
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=/path/to/other/truststore"
如果存在这类配置,要么移除(让JDBC URL的配置生效),要么确保其路径和密码与你的MySQL SSL证书完全一致。
按照以上步骤逐一排查,应该能解决Tomcat环境下的SSL连接异常。
内容的提问来源于stack exchange,提问作者Murugesh

