7

I'm currently working with Java Stored Procedures in Oracle and am seeing some strange behaviour when attempting to get a connection within my Java code.

My Java is packaged up into a jar file and then deployed into Oracle using the loadjava command line utility. A package is then created in the database which maps each method in a designated Java class to a PL/SQL function via call specifications.

Some of the columns which I'm working with are CLOBs. In the Java I attempt to extract the value of this CLOB (mapped in call specification as oracle.sql.CLOB) into a String:

private static String getStringFromCLOB(CLOB clob) throws SQLException {
    long length = clob.length();
    return clob.getSubString(1, (int) length);
}

When I run this code I get the following stack trace showing up in 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)

Before I was just seeing the message of the Exception so I wrapped the offending method's contents with a try / catch so I could dump the full stack trace to the System.out.

It is worth noting that I have had this working on Oracle 11.2.0.1.0 (32bit) but it is not working on Oracle 11.2.0.2.0 (64bit).

I have also had other Java-backed PL/SQL functions working without a problem. It is only the ones that attempt to make a connection that fail.

I have had a look in <ORACLE_HOME>\jdbc\lib and the jars, although named the same, seem to be different in these two distributions. The jars in the directory are (11.2.0.1.0 size and 11.2.0.2.0 size shown):

  • 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) <-- probably the same

The manifest files of these jars confirm they are built for the specific version, i.e. 11.2.0.1.0 or 11.2.0.2.0. Is it possible a bug has been introduced in 11.2.0.2.0? Or is it more likely to be user, i.e. my, error :-)

Also, where does the oracle.jdbc.driver.T2SConnection class live?

Any help / guidance very much appreciated. Please let me know if you need more information.

jabclab
  • 14,786
  • 5
  • 54
  • 51

4 Answers4

5

I had this issue when my password was expiring. I solved this just changing the password.

Fábio Almeida
  • 276
  • 3
  • 11
2

Have similar problem with recent Oracle JDBC drivers. Our case seems to be a problem mixing jars from different versions, like 11.2.0.1 and 11.2.0.3, for example ojdbc6.jar from 11.2.0.1 and oi18n.jar from 11.2.0.3. One nice technique is decompiling the entire jars of the Oracle JDBC driver and look the line in the source code that is raising the error. Could provide a tip about the error/bug.

Try to use the same JDBC driver version in both client machines.

oracle.jdbc.driver.T2CConnection lives in any main jar of the driver, like ojdbc5.jar.

David Oliván
  • 2,717
  • 1
  • 19
  • 26
  • Thanks David. I'm pretty sure all the jars are for 11.2.0.2 but will double-check. D'you know where the `oracle.jdbc.driver.T2SConnection` (**S** rather than C) class lives? – jabclab Jun 12 '12 at 07:31
  • You are right, it's a mistake. `oracle.jdbc.driver.T2CConnection` exists in any main jar, as you can see by simply listing the content of the jars as regular ZIP files. `oracle.jdbc.driver.T2SConnection` is not found in any jar of Oracle JDBC Drivers 11.2.0.*. Try to find the class listing jar contents in any jar found in your server, no only in /lib. – David Oliván Jun 12 '12 at 10:30
  • Thanks for your reply David. `oracle.jdbc.driver.T2SConnection` doesn't appear to exist in any jar within ``. Is it possible it could be dynamically created? – jabclab Jun 13 '12 at 09:15
  • No. JAR files must be available on file system prior to server startup. When server starts, the classloader loads all the available jars, configured in java classpath variable, normally populated in start script and containing several folders. The server could load dynamically jars after startup and while running, typically the user application, detects a change on a jar and reloads it. This normally not applies to jars like JDBC drivers that are normally available at startup time. In any case, server not create jars dynamically, only the user can updating a jar file with a new version. – David Oliván Jun 13 '12 at 10:14
1

My Java/JDBC code suddenly stopped working from one day to another.

Same problem here. Expired password. I tried both ojdbc6 and ojdbc7. Upgraded my VM environment. The code worked fine against a different database.

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

Tested my code and it worked fine again. Yet another unbelievable bug in Oracle's software. Their quality assurance never ever gets it right. I'm absolutely convinced that they don't even have proper test plans, otherwise they would catch such severe errors as division by zero for an expired password.

abhi
  • 1,760
  • 1
  • 24
  • 40
Ray
  • 11
  • 1
0

To those that might come across this issue we discovered that it was caused by a corruption of the JVM install within Oracle. This probably occurred due to a bad installation.

Reinstalling the JVM aspect of Oracle allowed oracle.jdbc.driver.OracleConnection.defaultConnection() to run without any issues whether explicitly called or called as part of the stack of another call, e.g. oracle.sql.CLOB.length().

jabclab
  • 14,786
  • 5
  • 54
  • 51