该用ojdbc8还是ojdbc11?看数据库版本,不是jdk版本;ojdbc8支持oracle 11g至21c全系列且兼容jdk 8~21,ojdbc11仅适用于启用tls 1.2+和新认证协议的oracle 21c+实例,误用将导致ora-28040错误。

该用 ojdbc8 还是 ojdbc11?看数据库版本,不是 JDK 版本
Java 17 下连接 Oracle,驱动选错是最高频的失败原因。ojdbc8.jar(如 21.12.0.0)支持 Oracle 11g 到 21c 全系列,且兼容 JDK 8~21;ojdbc11.jar(如 23.7.0.24.07)只适用于明确启用 TLS 1.2+ 和新认证协议的 Oracle 21c+ 实例。
常见错误现象:ORA-28040: No matching authentication protocol——基本就是用了 ojdbc11 去连 11g/12c/19c。
- 查清真实数据库版本:执行
SELECT * FROM v$version,再对照 Oracle 官方 JDBC FAQ 中 “Supported Database Versions” 表格 - 绝大多数生产环境(尤其老系统)应选
com.oracle.database.jdbc:ojdbc8:21.12.0.0,Maven 坐标必须从 Oracle 官方仓库拉取,别用 Maven Central 上无签名的镜像包(缺模块声明,JDK 17 模块化项目会直接编译失败) - 若确认 DBA 已关闭旧协议回退、且数据库为 21c+ 并强制启用新认证,则可试 ojdbc11,但需同步调整连接 URL 和 TLS 参数
classpath 里混了多个 ojdbc.jar?LinkageError 就是它干的
典型报错:java.lang.LinkageError: loader constraint violation 或运行时报 oracle.jdbc.driver.T4CConnection cannot be cast to java.sql.Connection。
根本原因是 classpath 中同时存在多个版本的 Oracle 驱动(比如 ojdbc6、ojdbc7、ojdbc8),尤其 Spring Boot 2.x starter 默认带 ojdbc6,容易被间接引入。
- 执行
mvn dependency:tree | grep ojdbc检查依赖树,定位冲突来源 - 在 pom.xml 中显式排除老版本,例如:
<exclusion><groupid>com.oracle</groupid><artifactid>ojdbc6</artifactid></exclusion>
- 删掉本地仓库中非目标版本:
rm -rf ~/.m2/repository/com/oracle/database/jdbc/*ojdbc[67]* - IDE 刷新 Maven 后,检查 External Libraries —— 只应剩一个
ojdbc8-21.12.0.0.jar(或你选定的精确版本)
模块化项目(module-info.java)必须写 requires oracle.jdbc
哪怕你代码里只调用 DriverManager.getConnection()、没 import 任何 Oracle 特有类,也必须声明模块依赖。否则编译期报 module not found: oracle.jdbc,或运行时因类加载器隔离导致 No suitable driver。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
ojdbc8 虽然兼容 JDK 17,但它没有 module-info.java,在 JPMS 下作为 unnamed module 加载,与显式声明的模块混用极易出问题;ojdbc11 才真正支持模块系统,但仅限于匹配的数据库版本场景。
- 如果你用的是 ojdbc8 + 模块化项目,唯一稳妥方案是升级到 ojdbc11(且数据库版本达标),否则放弃模块化或改用非模块化启动
- 若确定用 ojdbc11,
module-info.java中必须包含:requires oracle.jdbc;
,不要加transitive - 不写
requires,靠--add-modules oracle.jdbc启动参数只是临时补救,绕不过编译检查,也不解决运行时类加载隔离
URL 格式和连接参数不能照抄老项目
Oracle 21c 起默认禁用旧加密套件,仍用 jdbc:oracle:thin:@localhost:1521:xe(SID 格式)大概率握手失败,报 IO Error: Connection reset 或 ORA-28040。
必须改用服务名(SERVICE_NAME)格式,并显式指定 TLS 版本:
- 正确 URL 示例:
jdbc:oracle:thin:@//localhost:1521/XE(注意双斜杠 +/XE,不是冒号) - 若 DB 启用 SSL,追加参数:
?oracle.net.ssl_version=1.2&oracle.net.encryption_client=REQUIRED - 纯本地开发可加
&oracle.jdbc.javaNetNio=false避免 NIO 相关偶发超时 -
Driver类名保持oracle.jdbc.driver.OracleDriver即可,ojdbc8/11 均已自动注册,无需Class.forName()
最易被忽略的一点:密码含 !、@、# 等特殊字符时,必须 URL 编码(如 lyt%21QAZ123456),配置文件里写 \! 是 XML 转义,不是 JDBC URL 转义,两者不能混用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










