java 11连接oracle报sslhandshakeexception或ora-28040的根本原因是jvm默认禁用tlsv1.0/tlsv1.1,而oracle 11g/12c早期版本依赖这些协议;最轻量解法是启动时加-djdk.tls.client.protocols="tlsv1,tlsv1.1,tlsv1.2"(引号、逗号、大小写必须严格正确),并确保使用ojdbc8.jar。

Java 11 连接 Oracle 报 SSLHandshakeException 或 ORA-28040
根本原因不是驱动写错了,而是 Java 11 默认禁用 TLSv1.0/TLSv1.1,而 Oracle 11g/12c 早期版本(尤其未打 PSU 补丁的)仍依赖这些协议握手。即使 ojdbc8.jar 已就位,DriverManager.getConnection() 仍会在 SSLContext 初始化阶段直接拒绝协商,抛出 javax.net.ssl.SSLHandshakeException: No appropriate protocol 或静默超时后报 ORA-28040: No matching authentication protocol。
- 检查 Oracle 服务端是否强制要求旧协议:若为 Oracle 11g R2(11.2.0.4 之前),基本无法支持 TLSv1.2 原生协商
- 确认客户端实际启用的协议:用
System.getProperty("jdk.tls.client.protocols")打印当前值,Java 11 默认为空(即仅启用 TLSv1.2+),不包含 TLSv1.0/TLSv1.1 - 不要指望改连接字符串参数(如
?oracle.net.ssl_version=1.0)生效——这是 Oracle Net 层配置,JVM SSL 层已提前拦截
-Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2" 必须加且引号不能少
这是最轻量、无需改代码、不碰 java.security 文件的解法。Java 11 允许运行时覆盖协议白名单,但语法极其敏感:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 必须用双引号包裹整个值,否则 JVM 解析失败,参数被忽略
- 逗号后不能有空格(正确:
"TLSv1,TLSv1.1,TLSv1.2";错误:"TLSv1, TLSv1.1") - 协议名大小写敏感,必须全大写 + 数字(
TLSv1,不是tlsv1或TLS1) - 如果还连不上,再补一个
-Dhttps.protocols="TLSv1,TLSv1.1,TLSv1.2"(部分老驱动内部会走 HTTPS 协议栈)
ORA-28547 或 “connection closed” 很可能是证书链或加密套件不匹配
当 Oracle 服务端启用了 SSL/TLS(比如 SQLNET.ENCRYPTION_SERVER=REQUIRED),但客户端没提供可信证书或双方不支持共同的加密算法时,监听器会在握手中途主动断开,表现为 ORA-28547: connection closed,而非明确的 SSL 错误。
- 先用
tnsping确认 TCP 层通:如果tnsping成功但 JDBC 失败,基本可锁定是 SSL/TLS 协商问题 - 检查服务端
sqlnet.ora中SSL_VERSION和ENCRYPTION_TYPES_SERVER设置,例如设为(AES256)时,Java 11 默认可能不带对应 provider(需确认 JCE 策略或加 Bouncy Castle) - 临时跳过证书验证仅用于排查:加 JVM 参数
-Djavax.net.ssl.trustStore=(空值)和-Djavax.net.ssl.trustStorePassword=changeit,若此时连通,说明是证书链不完整或自签名问题
ojdbc8.jar 是底线,别用 ojdbc6 或 ojdbc11
用错驱动版本会叠加 TLS 问题:ojdbc6 编译于 JDK 6,Java 11 能加载但内部 SSL 实现陈旧,无法适配新 JVM 的 TLS 策略;ojdbc11 则默认启用 TLSv1.2+ 和新认证流程,与 Oracle 11g 不兼容,大概率触发 ORA-28040。
- Oracle 官方明确标注:
ojdbc8.jar支持 JDK 8~17(含 Java 11),且对旧版 Oracle 服务端做了向后兼容处理 - Maven 引入务必排除传递依赖:
spring-boot-starter-data-jpa可能偷偷带入ojdbc6,用mvn dependency:tree | grep ojdbc检查并<exclusion></exclusion> - 运行时 classpath 中只能存在一个
ojdbc8-*.jar,IDE 的 External Libraries 面板要手动确认
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










