尝试在 Oracle 11.2.0.2.0(64 位)中获取连接时出现 java.lang.ArithmeticException
Posted
技术标签:
【中文标题】尝试在 Oracle 11.2.0.2.0(64 位)中获取连接时出现 java.lang.ArithmeticException【英文标题】:java.lang.ArithmeticException when attempting to get connection in Oracle 11.2.0.2.0 (64 bit) 【发布时间】:2012-06-08 08:23:55 【问题描述】:我目前正在使用 Oracle 中的 Java 存储过程,并且在尝试在我的 Java 代码中建立连接时看到一些奇怪的行为。
我的 Java 被打包成一个 jar 文件,然后使用 loadjava
命令行实用程序部署到 Oracle 中。然后在数据库中创建一个package
,它将指定 Java 类中的每个方法通过调用规范映射到一个 PL/SQL 函数。
我正在使用的一些列是CLOB
s。在 Java 中,我尝试将 CLOB
(在调用规范中映射为 oracle.sql.CLOB
)的值提取到 String
:
private static String getStringFromCLOB(CLOB clob) throws SQLException
long length = clob.length();
return clob.getSubString(1, (int) length);
当我运行此代码时,我会在 SQL*Plus 中看到以下堆栈跟踪:
java.lang.ArithmeticException: / by zero
at oracle.jdbc.driver.T2SConnection.<init>(T2SConnection.java:107)
at oracle.jdbc.driver.T2SDriverExtension.getConnection(T2SDriverExtension.java:31)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:481)
at oracle.jdbc.driver.OracleDriver.defaultConnection(OracleDriver.java:505)
at oracle.sql.DatumWithConnection.getPhysicalConnection(DatumWithConnection.java:53)
at oracle.sql.DatumWithConnection.getInternalConnection(DatumWithConnection.java:177)
at oracle.sql.CLOB.getDBAccess(CLOB.java:1383)
at oracle.sql.CLOB.length(CLOB.java:197)
在我刚刚看到Exception
的消息之前,我用try / catch
包装了有问题的方法的内容,这样我就可以将完整的堆栈跟踪转储到System.out
。
值得注意的是,我已经在 Oracle 11.2.0.1.0(32 位)上运行过此功能,但它不适用于 Oracle 11.2.0.2.0(64 位)。
我也有其他支持 Java 的 PL/SQL function
s 正常工作。只有那些试图建立连接的人才会失败。
我查看了<ORACLE_HOME>\jdbc\lib
和罐子,虽然名称相同,但在这两个发行版中似乎有所不同。目录中的罐子是(11.2.0.1.0 大小和 11.2.0.2.0 大小显示):
ojdbc5.jar
(1,950KB | 1,983KB)
ojdbc5_g.jar
(3,010KB | 3,271KB)
ojdbc5dms.jar
(2,374KB | 2,489KB)
ojdbc5dms_g.jar
(3,030KB | 3,291KB)
ojdbc6.jar
(2,062KB | 2,102KB)
ojdbc6_g.jar
(3,323KB | 3,782KB)
ojdbc6dms.jar
(2,594KB | 2,698KB)
ojdbc6dms_g.jar
(3,344KB | 3,805KB)
simplefan.jar
(20KB | 20KB)
这些 jar 的清单文件确认它们是为特定版本构建的,即 11.2.0.1.0 或 11.2.0.2.0。 11.2.0.2.0 中是否可能引入了错误?还是更有可能是用户,即我的错误:-)
另外,oracle.jdbc.driver.T2SConnection
类住在哪里?
非常感谢任何帮助/指导。如果您需要更多信息,请告诉我。
【问题讨论】:
看起来像驱动程序中的错误,向 oracle 报告或尝试/捕获,忽略...(或两者) 【参考方案1】:当我的密码即将到期时,我遇到了这个问题。我解决了这个只是更改密码。
【讨论】:
【参考方案2】:最近的 Oracle JDBC 驱动程序也有类似的问题。我们的案例似乎是混合来自不同版本的 jar 的问题,例如 11.2.0.1 和 11.2.0.3,例如 11.2.0.1 的 ojdbc6.jar 和 11.2.0.3 的 oi18n.jar。一种不错的技术是反编译 Oracle JDBC 驱动程序的整个 jar,并查看源代码中引发错误的行。可以提供有关错误/错误的提示。
尝试在两台客户端机器上使用相同的 JDBC 驱动程序版本。
oracle.jdbc.driver.T2CConnection
存在于驱动程序的任何主 jar 中,例如 ojdbc5.jar。
【讨论】:
谢谢大卫。我很确定所有的罐子都是 11.2.0.2 但会仔细检查。你知道oracle.jdbc.driver.T2SConnection
(S而不是C)类在哪里吗?
你是对的,这是一个错误。 oracle.jdbc.driver.T2CConnection
存在于任何主 jar 中,您只需将 jar 的内容列为常规 ZIP 文件即可。在 Oracle JDBC Drivers 11.2.0.* 的任何 jar 中都找不到 oracle.jdbc.driver.T2SConnection
。尝试在服务器中找到的任何 jar 中查找列出 jar 内容的类,而不仅仅是在 /lib 中。
感谢大卫的回复。 oracle.jdbc.driver.T2SConnection
似乎不存在于 <ORACLE_HOME>
内的任何 jar 中。是否可以动态创建?
没有。在服务器启动之前,JAR 文件必须在文件系统上可用。当服务器启动时,类加载器加载所有可用的 jar,在 java 类路径变量中配置,通常填充在启动脚本中并包含几个文件夹。服务器可以在启动后和运行时动态加载 jar,通常是用户应用程序,检测到 jar 上的更改并重新加载它。这通常不适用于通常在启动时可用的 JDBC 驱动程序之类的 jar。在任何情况下,服务器都不会动态创建 jar,只有用户可以使用新版本更新 jar 文件。【参考方案3】:
我的 Java/JDBC 代码有一天突然停止工作。
同样的问题。密码过期。我尝试了 ojdbc6 和 ojdbc7。升级了我的虚拟机环境。该代码在不同的数据库上运行良好。
target_user="c##ora$rman_bkp"
Placeholder START_DATE=20170422
Placeholder START_DATE_TIME=2017Apr22-20h47m13s
jdbcURL='jdbc:oracle:oci8:@twelve_static'
Exception in thread "main" java.lang.ArithmeticException: / by zero
at oracle.jdbc.driver.OraclePreparedStatement.<init>(OraclePreparedStatement.java:1387)
at oracle.jdbc.driver.T2CPreparedStatement.<init>(T2CPreparedStatement.java:109)
at oracle.jdbc.driver.T2CDriverExtension.allocatePreparedStatement(T2CDriverExtension.java:81)
at oracle.jdbc.driver.PhysicalConnection.prepareStatementInternal(PhysicalConnection.java:2013)
at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:1960)
at oracle.jdbc.driver.T2CConnection.prepareStatement(T2CConnection.java:57)
at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:1866)
at oracle.jdbc.driver.T2CConnection.prepareStatement(T2CConnection.java:57)
at LV.verifyLicensedDbId(LV.java:238)
at RmanJ.<init>(RmanJ.java:1891)
at RmanJ.main(RmanJ.java:1809)
SYS@TWELVE:SQL> select account_status from dba_users where username='c##ora$rman_bkp';
ACCOUNT_STATUS
--------------------------------
EXPIRED(GRACE)
SYS@TWELVE:SQL> connect "c##ora$rman_bkp"
Enter password:
ERROR:
ORA-28002: the password will expire within 5 days
Connected.
c##ora$rman_bkp@TWELVE:SQL> password
Changing password for "c##ora$rman_bkp"
Old password:
New password:
Retype new password:
Password changed
测试了我的代码,它再次运行良好。甲骨文软件中的另一个令人难以置信的错误。 他们的质量保证永远不会正确。我绝对相信他们甚至没有适当的测试计划, 否则他们会捕捉到像过期密码被零除这样的严重错误。
【讨论】:
【参考方案4】:对于那些可能遇到此问题的人,我们发现它是由 Oracle 中的 JVM 安装损坏引起的。这可能是由于安装错误造成的。
重新安装 Oracle 的 JVM 方面允许 oracle.jdbc.driver.OracleConnection.defaultConnection()
运行而不会出现任何问题,无论是显式调用还是作为另一个调用的堆栈的一部分调用,例如oracle.sql.CLOB.length()
.
【讨论】:
以上是关于尝试在 Oracle 11.2.0.2.0(64 位)中获取连接时出现 java.lang.ArithmeticException的主要内容,如果未能解决你的问题,请参考以下文章
plsql developer 64位 怎么连接oracle 64位
Oracle11gR2官网下载,windows64位与linux64位