Oracle:错误码ORA-28040 的坑

一、背景

因项目要求,第一次部署了Oracle 12 C的Server,Linux CentOS版,数据库装好之后部署一个Java Web项目(A项目)去连接数据库,该Java项目之前用的Oracle是11 g版本,这次换成了12 C的版本,日志显示的错误信息如下:

ORA-28040: No matching authentication protocol

二、原因分析与修改测试

1、按照错误码在网上找了一下解决的案例,不外乎都是修改 $ORACLE_HOME\NETWORK\ADMIN\sqlnet.ora 文件,网上提供了两种版本的修改:

a、增加一行配置如下

 SQLNET.ALLOWED_LOGON_VERSION=8

b、增加两行配置如下“

 SQLNET.ALLOWED_LOGON_SERVER=8

 SQLNET.ALLOWED_LOGON_CLIENT=8

按照这两种改法,分别进行了修改和测试,修改之后,重启了数据库监听、数据库服务和Tomcat,结果依然报 ORA-28040 错误。

2、使用PL/SQL去连接数据库,也能正常连接使用。

3、检查连接数据库的配置文件,检查结果OK。

4、考虑到Oracle不同的版本驱动jar包可能不一样,在网上看了一下Oracle 12C依赖的jar包,发现用的是 ojdbc6,A项目中依赖的也是 ojdbc6,因此版本驱动也认为OK了。

5、经项目组导师提示,使用原始的Java代码连接Oracle 12 C,使用的jar包从Oracle安装目录中获取,版本依然是 ojdbc6,测试结果发现能连上数据库。

Connection con = null;// 创建一个数据库连接
	    PreparedStatement pre = null;// 创建预编译语句对象,一般都是用这个而不用Statement
	    ResultSet result = null;// 创建一个结果集对象
	    try
	    {
	        Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
	        System.out.println("开始尝试连接数据库!");
	        String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";// 127.0.0.1是本机地址,orcl是Oracle的示例
	        String user = "c##abc";// Oracle用户名
	        String password = "1111111";// Oracle用户名的密码
	        con = DriverManager.getConnection(url, user, password);// 获取连接
	        System.out.println("连接成功!");
	        String sql = "select user from dual";// 预编译语句
	        pre = con.prepareStatement(sql);// 实例化预编译语句
	        result = pre.executeQuery();// 执行查询,注意括号中不需要再加参数
	        while (result.next())
	            // 当结果集不为空时
	            System.out.println("用户名:" + result.getString("user"));
	    }
	    catch (Exception e)
	    {
	        e.printStackTrace();
	    }
	    finally
	    {
	        try
	        {
	            // 逐一将上面的几个对象关闭,因为不关闭的话会影响性能、并且占用资源
	            // 注意关闭的顺序,最后使用的最先关闭
	            if (result != null)
	                result.close();
	            if (pre != null)
	                pre.close();
	            if (con != null)
	                con.close();
	            System.out.println("数据库连接已关闭!");
	        }
	        catch (Exception e)
	        {
	            e.printStackTrace();
	        }
	    }	

代码参考:https://www.cnblogs.com/zhwl/p/3736114.html

6、使用Oracle 12C 自带的ojdbc6.jar替换A项目中依赖的ojdbc6的jar包,替换之后发现终于正常连上数据库了!

三、经验教训总结

1、Oracle的 ojdbc 6竟然还有不同的版本,而且支持的协议还不一样!

我在oracle官网上看到ojdbc6只有一个jar包,不分版本!这个ojdbc6-11.1.0.7.0.jar可以支持Oracle 11g,但是支持不了Oracle 12C,从文件大小也可以看出,ojdbc6-11.1.0.7.0.jar应该是老版本,根据版本向下兼容的原则,ojdbc6应该是兼容ojdbc6-11.1.0.7.0.jar的。

2、由于A项目之前使用的Oracle版本是 11g,替换到Oracle 12C的时候,考虑不周,虽然考虑到了驱动jar包的版本问题,却没仔细查看jar包的不同。当然,更规范的做法应该是在Oracle的版本发生更换的时候,对应的驱动jar包也一并更换,且更换的jar包从Oracle的安装目录中获取

3、从想到驱动的问题到略过该问题,暴露了自己解决问题的思路不够细致。

4、排查该问题的思路整理:

服务器本机使用用户登录、操作数据库排查用户的账号密码、权限等问题
PL/SQL连接Oracle排查网络问题
sqlnet.ora文件修改排查ora-28040问题
Java连接Oracle的配置文件排查连接参数
ojdbc驱动jar包检查与替换排查驱动jar包问题和协议不匹配的问题

 

 

 

 

 

  • 18
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值