ORA-01017在Java应用中出现,根本原因是JDBC驱动与Oracle服务端密码哈希校验不匹配:ojdbc8.jar仅支持到12.2,无法处理19c/21c的s:段哈希;需升级至ojdbc11.jar或更高,并确认spare4含有效s:哈希、连接串用双引号包裹凭据、服务名格式正确指向PDB。

ORA-01017 在 Java 应用里出现,基本可以确定不是网络不通、监听没起,而是 JDBC 驱动把凭据传给 Oracle 后,服务端校验失败——SQL*Plus 能连但 Java 死活报错,就是典型信号。
检查 ojdbc 驱动版本是否匹配服务端
Oracle 19c/21c 默认禁用旧密码哈希算法,ojdbc8.jar 只支持到 12.2 的认证协议,无法生成或验证 s: 段哈希,直接被拒。
- 确认服务端版本:SELECT * FROM v$version WHERE banner LIKE 'Oracle%';
- 对应驱动最低要求:
ojdbc11.jar(JDK 11+)或ojdbc12.jar(JDK 17+),不兼容ojdbc6.jar或ojdbc8.jar - 检查 classpath 是否混入多个版本:
find . -name "ojdbc*.jar",删掉所有旧版 - 连接时加
?oracle.jdbc.fanEnabled=false参数可绕过部分高可用协商干扰(临时排查用)
连接串中 Password 和 User Id 必须用英文双引号包裹
JDBC 驱动解析 URL 时会按分号、@、/ 等字符切分字段,不加引号会导致凭据被截断——比如 Password=Pass@123 实际只取到 Pass。
- 正确写法:
jdbc:oracle:thin:@//host:1521/orclpdb1?user="my_user"&password="Pass@123" - Spring Boot
application.yml中必须用单引号包裹整个值:url: 'jdbc:oracle:thin:@//host:1521/orclpdb1?user="my_user"&password="Pass@123"' - 若从环境变量读取,务必调用
.trim(),Windows 下配置文件常带 BOM 或末尾空格
确认用户在 PDB 中且连接串用了服务名格式
12c+ 多租户环境下,普通用户只存在于 PDB,但连接串若误用 SID 格式(如 @host:1521:ORCL),请求会被路由到 CDB$ROOT,查不到该用户,统一返回 ORA-01017。
- 查用户归属:
SELECT con_id, username FROM cdb_users WHERE username = 'MYUSER',CON_ID > 1 表示在 PDB - 必须用服务名格式:
@//host:1521/orclpdb1(注意双斜杠),或 TNS 别名且其SERVICE_NAME明确指向 PDB - tnsping 别名后看返回的
Service "orclpdb1"是否匹配,不是Service "ORCL"
验证 spare4 字段是否含有效 s: 哈希段
用户密码是 11g/12.1 时代创建且未重置过,spare4 字段为空或只有 t: 段,JDBC 就无法完成现代认证流程。
- 以 SYSDBA 登录后执行:
SELECT username, password_versions, spare4 FROM dba_users WHERE username = 'MYUSER' - 若
spare4为空或无s:开头内容,强制刷新:ALTER USER myuser IDENTIFIED BY "NewPass@2026" REPLACE "oldpass" - 执行后立刻生效,无需重启数据库
真正棘手的是 spare4 刷新和驱动版本这两项叠加——旧驱动传不了新哈希,新驱动又读不到旧哈希,表面都是 ORA-01017,但根因完全相反。先锁死驱动版本,再查 spare4,顺序不能反。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











