异常:
EXCEPTION STACK TRACE:
** BEGIN NESTED EXCEPTION **
javax.net.ssl.SSLException
MESSAGE: closing inbound before receiving peer’s close_notify
STACKTRACE:
javax.net.ssl.SSLException: closing inbound before receiving peer’s close_notify
at java.base/sun.security.ssl.SSLSocketImpl.shutdownInput(SSLSocketImpl.java:762)
at java.base/sun.security.ssl.SSLSocketImpl.shutdownInput(SSLSocketImpl.java:741)
at com.mysql.cj.protocol.a.NativeProtocol.quit(NativeProtocol.java:1284)
at com.mysql.cj.NativeSession.quit(NativeSession.java:182)
at com.mysql.cj.jdbc.ConnectionImpl.realClose(ConnectionImpl.java:1911)
at com.mysql.cj.jdbc.ConnectionImpl.close(ConnectionImpl.java:730)
at cn.com.he.codegen.template.DynamicJdbcTemplate.getPk(DynamicJdbcTemplate.java:288)
at cn.com.he.codegen.service.impl.GeneratorServiceImpl.generatorCode(GeneratorServiceImpl.java:79)
at cn.com.he.codegen.controller.GeneratorController.generatorCode(GeneratorController.java:51)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
Java 应用程序在连接 MySQL 数据库时遇到了 SSL 相关的警告和异常。以下是问题分析与解决方案:
🔍 问题分析
1. SSL 连接警告
Establishing SSL connection without server's identity verification is not recommended.
...
verifyServerCertificate property is set to 'false'.
You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
这是 MySQL JDBC 驱动(mysql-connector-java
)在连接数据库时发出的安全警告。
原因:
- 从 MySQL 5.7.6+、5.6.26+、5.5.45+ 开始,默认要求使用 SSL 连接。
- 如果未显式设置
useSSL=false
或配置 SSL 信任库(truststore),则会提示该警告。
注意: 警告不是错误,但出于安全考虑建议处理。
2. SSL 异常
javax.net.ssl.SSLException: closing inbound before receiving peer's close_notify
这个异常通常表示:
- 客户端关闭了连接,但服务端还没发送完数据;
- 或者 SSL 握手过程中出现问题;
- 可能由于驱动版本、JDK 版本或 SSL 配置不一致引起。
✅ 解决方案
方案一:明确禁用 SSL(适用于开发环境)
如果你不需要 SSL 加密(如测试/开发环境),可以在 JDBC URL 中添加参数:
jdbc:mysql://localhost:3306/dbname?useSSL=false
⚠️ 注意:此方式不推荐用于生产环境。
方案二:启用 SSL 并验证证书(推荐用于生产环境)
- 获取 MySQL 服务器的 CA 证书(通常是
ca.pem
); - 将证书导入 Java 的信任库(keystore)中:
keytool -import -alias mysqlServerCACert -file ca.pem -keystore truststore.jks
- 在 JDBC URL 中指定 SSL 模式,并配置信任库路径:
jdbc:mysql://localhost:3306/dbname?useSSL=true&requireSSL=true&verifyServerCertificate=true&
clientCertificateKeyStoreUrl=file:/path/to/truststore.jks&
clientCertificateKeyStorePassword=yourpassword
- 启动应用时指定信任库:
-Djavax.net.ssl.trustStore=/path/to/truststore.jks
-Djavax.net.ssl.trustStorePassword=yourpassword
方案三:升级依赖库(MySQL Connector 和 JDK)
有时此类问题是由于旧版 JDBC 驱动或 JDK 不兼容引起的:
- 确保使用最新版本的 MySQL Connector/J(如
8.0.x
); - 使用较新的 JDK(如 JDK 11 或 17)可以避免很多 SSL 协议不兼容的问题。
🧪 示例配置(Spring Boot application.yml
)
spring:
datasource:
url: jdbc:mysql://localhost:3306/dbname?useSSL=false&serverTimezone=UTC
username: root
password: yourpassword
driver-class-name: com.mysql.cj.jdbc.Driver
📌 总结
场景 | 建议做法 |
---|---|
开发/测试环境 | 添加 useSSL=false 忽略 SSL |
生产环境 | 启用 SSL + 配置信任库 |
排查 SSL 异常 | 检查证书、驱动版本、JDK 版本 |