ojdbc8在java 17下必然失败,因其无module-info.java,加载为unnamed module,导致noclassdeffounderror: javax/sql/datasource和module not found: java.xml.bind,且不支持jdbc 4.3;oracle 21c仅官方支持ojdbc11。

必须用 ojdbc11,不是 ojdbc8;模块化项目要写 requires oracle.jdbc;连接 URL 必须用服务名格式(@//host:port/SERVICE_NAME),不能用旧式 SID 格式。
为什么 ojdbc8 在 Java 17 下必然失败
Java 17 默认启用模块系统(JPMS),而 ojdbc8 没有 module-info.java,加载时变成 unnamed module,导致两类典型错误:
-
java.lang.NoClassDefFoundError: javax/sql/DataSource(缺java.sql模块可见性) -
Module not found: java.xml.bind(ojdbc8依赖已移除的 JAXB,且未适配 Jakarta EE 9+)
Oracle 官方明确:21c 只支持 JDBC 4.3(对应 Java 11+),ojdbc11(如 com.oracle.database.jdbc:ojdbc11:23.7.0.24.07)是唯一兼容选项。Maven Central 上非 Oracle 签名的包常缺失模块声明,务必从 Oracle 官网或其 Maven 仓库下载。
module-info.java 里漏写 requires oracle.jdbc 就连不上
模块化项目中,仅靠启动参数 --add-modules oracle.jdbc 是临时补救,编译期会报错 module not found: oracle.jdbc,运行时 DriverManager.getConnection() 仍抛 SQLException: No suitable driver——因为类加载器隔离,驱动类根本不可见。
正确写法(注意不加 transitive):
module my.app {
requires java.sql;
requires oracle.jdbc; // 必须显式声明
exports com.myapp.db;
}
不需要 requires transitive oracle.jdbc:你的代码只调用 java.sql 接口,不直接引用 Oracle 特有类;ojdbc11 自身也不导出第三方模块。
URL 格式和参数错一个字符就握手失败
Oracle 21c 默认禁用旧加密套件,沿用 jdbc:oracle:thin:@localhost:1521:XE 这种 SID 格式,即使连得上也会在 TLS 握手阶段失败,报 IO Error: Connection reset 或 ORA-28040。
必须改用服务名格式,并注意细节:
- 开头双斜杠:
@//localhost:1521/FREEPDB1(不是@localhost:1521/FREEPDB1) - 末尾是服务名(如
FREEPDB1、XEPDB1),不是 SID(如XE) - 本地开发可加
&oracle.jdbc.javaNetNio=false避免 NIO 偶发超时 - 除非 DB 启用了 Wallet 或自定义 SSL,否则不要硬加
oracle.net.ssl_version=1.2——默认已安全
driver-class-name 必须设为 oracle.jdbc.OracleDriver:ojdbc11 已废弃 oracle.jdbc.driver.OracleDriver,设错会静默跳过自动注册。
Spring Boot 3.x 的配置陷阱
Spring Boot 3.x 默认基于 Java 17,若还在 application.yml 里配 ojdbc8 和旧 driver 类名,应用能启动但首次数据库操作必炸:
- 日志里可能只显示
Failed to configure a DataSource,没提驱动问题 - HikariCP 初始化时找不到可用 driver,
getConnection()直接抛No suitable driver
最小可用配置(注意缩进和冒号空格):
spring:
datasource:
url: jdbc:oracle:thin:@//localhost:1521/FREEPDB1
username: system
password: Oracle_123
driver-class-name: oracle.jdbc.OracleDriver
sql:
init:
mode: always
schema-locations: classpath:schema-oracle.sql
连接池参数建议:设 spring.datasource.hikari.connection-timeout=30000(30 秒),低于 DBA 设置的 SQLNET.EXPIRE_TIME(通常 10 分钟),避免池内连接被防火墙或 RAC VIP 切换 silently 断开后还卡着不释放。
真正容易被忽略的是:Oracle 21c 的服务名(SERVICE_NAME)和实例名(SID)是两回事,查不到 FREEPDB1 就去查 v$pdbs,别硬套旧习惯;驱动版本、模块声明、URL 格式这三处只要错一个,就不会连——不是“连不上”,而是根本没走到认证那步。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











