尝试在 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 函数。

我正在使用的一些列是CLOBs。在 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 functions 正常工作。只有那些试图建立连接的人才会失败。

我查看了&lt;ORACLE_HOME&gt;\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.T2SConnectionS而不是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 似乎不存在于 &lt;ORACLE_HOME&gt; 内的任何 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的主要内容,如果未能解决你的问题,请参考以下文章

centos下安装cx_oracle 源码安装 64位

在 Oracle XDB 中转义控制字符

plsql developer 64位 怎么连接oracle 64位

Oracle11gR2官网下载,windows64位与linux64位

Oracle11gR2官网下载,windows64位与linux64位

Oracle11gR2官网下载,windows64位与linux64位