ojdbc6中OraclePreparedStatement的ArrayIndexOutOfBoundsException异常BUG-6396242
现场信息
Caused by: java.lang.ArrayIndexOutOfBoundsException: -32203
at oracle.jdbc.driver.OraclePreparedStatement.setupBindBuffers(OraclePreparedStatement.java:2677)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:9270)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:210)
at weblogic.jdbc.wrapper.PreparedStatement.executeBatch(PreparedStatement.java:191)
... 6 more
运行时OraclePreparedStatement相关jar加载信息

排查解决
首先,看到有人遇到类似的问题,主要提到两点问题:
第一点,Ojdbc.jar和Oracle的版本有一个匹配关系的,对应关系如下图:
| Oracle 版本 | JDK版本 | 推荐jar包 | 
|---|---|---|
| Oracle 10g | JDK 1.4 and 1.5 | ojdbc14.jar | 
| Oracle 11g | JDK1.5 | ojdbc5.jar | 
| Oracle 11g | JDK1.6 | ojdbc6.jar | 
第二点:Ojdbc14版本在进行executeBatch操作的时候,如果参数多于32766会出现越界问题。
但是我的Ojdbc6.jar版本是:
Manifest-Version: 1.0
Implementation-Vendor: Oracle Corporation
Implementation-Title: ojdbc6.jar
Implementation-Version: Oracle JDBC Driver version - "11.1.0.6.0-Production+"
Implementation-Time: Tue Oct ::
Specification-Vendor: Oracle Corporation
Created-By: 1.6. (Sun Microsystems Inc.)
Specification-Title: Oracle JDBC driver classes for use with JDK6
Specification-Version: Oracle JDBC Driver version - "11.1.0.6.0-Production+"
Oracle版本
select * from v$version;
Oracle Database 11g Enterprise Edition Release 11.2.0.1. - Production
所以排除第一点版本匹配方面问题。
然后,从第二点数据量来看,我实际的批量提交量在56*1000=56000左右,而且已经有1000条记录正常写入,推测不完全是batch数量方面的问题。
理所当然尝试在开发环境复现问题,但是死活复现不了,怀疑开发和正式环境差异,添加VM参数-XX:+TraceClassLoading观察,发现tomcat加载的Ojdbc版本是ojdbc14,尽管ojdbc14没有问题,但目前看来这个还和中间件类加载顺序或者机制有关,并且肯定不能轻易的拿tomcat的ojdbc14去替换weblogic默认的ojdbc6。
测试环境将ojdbc14强行删掉只留ojdbc6后,终于复现了问题,与此同时如果把批量从1000降到500问题便消失,然后升到550问题重新出现(但是这时提交量在56*550=30800明显低于32768);再次说明不完全是batch数量的问题,从现象来看是在参数个数和行数达到某些条件同时批量到达一定长度后,多次提交才会触发此问题。
解决方法
1降低批量提交数量;2升级ojdbc6的版本。两种不同的解决方案,1并不是长久之计,还是要从根本上解决问题。
现在唯一能确定的就是ojdbc6出了问题,掉回头来搜索具体版本号:11.1.0.6.0,果然在11.1.0.7.0官方文档中找到了个修复相关bug的列表,

下载11.1.0.7.0新版的ojdbc6之后问题解决
原因分析
反编译后对比新旧两个版本的ojdbc6,定位到错误抛出方法setupBindBuffers,发现其中只有一行代码发生变动

但是由于反编译的代码隐去了很多具体意义变量,这里只能初步判断就是此处附近取值时发生了数组越界异常;
思考总结
这里对模拟线上环境使用了arthas进行了类加载定位,但是对于没有安装arthas的环境,如何才能获取到jar具体的加载信息这个需要进一步了解jvm相关tools。
排查过程中开发测试环境前期始终不能复现bug这个问题应该在发布、测试中引起注意,中间件的差异点要有预期。中间件的类加载器、加载机制相关内容需要进一步了解。
ojdbc6中OraclePreparedStatement的ArrayIndexOutOfBoundsException异常BUG-6396242的更多相关文章
- (转)C#中的那些全局异常捕获
		
C#中的那些全局异常捕获(原文链接:http://www.cnblogs.com/taomylife/p/4528179.html) 1.WPF全局捕获异常 public partia ...
 - Directx11教程(21) 修正程序最小化异常bug
		
原文:Directx11教程(21) 修正程序最小化异常bug 很长时间竟然没有注意到,窗口最小化时候,程序会异常,今天调试水面程序时,随意间最小化了窗口,发现程序异常了.经过调试,原来程 ...
 - Java中编写代码出现异常,如何抛出异常,如何捕获异常
		
异常的产生过程解析 先运行下面的程序,程序会产生一个数组索引越界异常ArrayIndexOfBoundsException.我们通过图解来解析下异常产生的过程. 工具类 class ArrayTool ...
 - C/C++相对论——C++中为什么要使用异常?
		
C++中为什么要使用异常? 很多人也许知道C++中的异常机制,很多人也许不知道.很多人知道C中常用的assert,也知道在编译时候指定NODEBUG来忽略它. 对于C语言,使用正常的if-else即是 ...
 - C/C++相对论——C++中为什么要使用异常(跳转语句会造成对象没有被析构)
		
C++中为什么要使用异常? 很多人也许知道C++中的异常机制,很多人也许不知道.很多人知道C中常用的assert,也知道在编译时候指定NODEBUG来忽略它. 对于C语言,使用正常的if-else即是 ...
 - 页面打开 抛出w3wp.exe 中发生未处理异常
		
页面打开 抛出w3wp.exe 中发生未处理异常
 - IE6/IE7中li底部4px的Bug
		
当li的子元素中有浮动(float)时,IE6/IE7中<li>元素的下面会产生4px空隙的bug. XHTML <ul class="list"> < ...
 - Delphi中取整函数Round的Bug解决
		
Delphi中 Round函数有个Bug一旦参数是形如 XXX.5这样的数时如果 XXX 是奇数 那么就会 Round up如果 XXX 是偶数 那么就会 Round down例如 Round(17. ...
 - 【IE6的疯狂之六】li在IE中底部3像素的BUG(增加浮动解决问题)
		
今天开发项目中碰到一个li在IE中的BUG,先来看设计原型(如图:) 两个红色中间是<li>1px的底边框: 我写的代码如下: ============================== ...
 
随机推荐
- blazor wasm访问非本地的restful service
			
准备工作 blazor wasm正式版发布了!在尝试使用的过程中,发现几个小坑,跟大家分享一下,希望有所帮助. 我是通过keycloak来保护blazor和service的,如何保护service请参 ...
 - 【Java8新特性】关于Java8的Stream API,看这一篇就够了!!
			
写在前面 Java8中有两大最为重要的改变.第一个是 Lambda 表达式:另外一个则是 Stream API(java.util.stream.*) ,那什么是Stream API呢?Java8中的 ...
 - 王艳 201771010127《面向对象程序设计(java)》第十三周学习总结
			
一:理论部分. 1.事件处理基础. 1)事件源:能够产生事件的对象都可以成为事件源,如文本框.按钮等.一个事件源是一个能够注册监听器并向监听器发送事件对象的对象. 2)事件监听器:事件监听器对象接收事 ...
 - 使用vue2.0创建的项目的步骤
			
1.由于vue项目依赖 node.js npm 需要先安装. 若没有请先安装,请百度 //检查是否有node.js npm vue win+r 输入cmd 输入node -v 回车 会出 ...
 - python字典详细介绍
			
字典的用途 字典是Python提供的一种常用的数据结构,它用于存放具有映射关系的数据. 字典相当于保存了两组数据,其中一组数据是关键数据,被称为 key:另一组数据可通过 key 来访问,被称为 ...
 - 仿开源框架从零到一完整实现高性能、可扩展的RPC框架 | 6个月做成教程免费送
			
去年年就在写一本付费小册,今年年初基本上就写完了,本来预计计划是春节上线结果由于平台的原因一直拖着没上.五一前跟平台联系给的反馈是五月份能上,结果平台又在重构,停止小册的申请和上线,最后我考虑了一下决 ...
 - PHP时间操作
			
PHP中对日期进行处理常用的几个函数如下: date(format,timestamp): 把时间戳格式化为更易读的日期和时间 format : 必需,规定输出日期字符串的格式 timestamp : ...
 - Verilog语言中的系统任务和系统函数
			
Verilog语言中预先定义了一些任务和函数,用于完成一些特殊的功能,它们被称为系统任务和系统函数,这些函数大多数都是只能在Testbench仿真中使用的,使我们更方便的进行验证. `timescal ...
 - vue 基于elment UI tree 组件实现带引导、提示线
			
实现样式 准备工作,先实现 树状组件的基本样式 <span style="height:500px; display:block; overflow-y:auto;" cla ...
 - Spring基础之AOP
			
一.AOP能解决什么问题 业务层每个service都要管理事务,在每个service中单独写事务,就会产生很多重复性的代码,而且修改事务时,需要修改源码,不利于维护.为此,把横向重复的代码,纵向抽取形 ...