5

I'm encountering an aggravating issue, here's the facts -

I'm registering a return parameter specific and to do so I'm casting a java.sql.PreparedStatement to oracle.jdbc.OraclePreparedStatement.

((OraclePreparedStatement) getStatement())
    .registerReturnParameter(index, sqlType);   

This works great when I run this from Eclipse and it even runs as expected on our development server. However, it's when I move it to our testing server where I hit an unexpected error...

oracle.jdbc.driver.OraclePreparedStatementWrapper cannot be cast
 to oracle.jdbc.OraclePreparedStatement

It's incredibly strange error to me because I'm sure that OraclePreparedStatement is assignable from getStatement(). I've debugged and found that this is TRUE for all environments:

//class oracle.jdbc.driver.OraclePreparedStatementWrapper
getStatement().getClass();

LOCAL and DEV environments both use a DataSource I've set up in META-INF/context.xml:

<Resource name="dataSource/dbsubm" auth="Container"
    type="oracle.jdbc.xa.client.OracleXADataSource"
    factory="org.apache.naming.factory.BeanFactory"
    user="*****" password="******"
    URL="jdbc:oracle:thin:@host:port:db" />

TEST environment differs because it has a DataSource coming from server.xml even though the configuration is exactly the same. This to me is the only difference between these environments.

What could be the issue? Why do I get a ClassCastException using the same code but different environments? Using getClass() I can tell that they are all the same type... please help!

3
  • 3
    Are your ojdbc.jar files the same version on all machines? Commented Aug 4, 2011 at 14:02
  • What versions are the ojdbc drivers and see if there has been any changes from one with the other. Commented Aug 4, 2011 at 14:05
  • Why are you casting to OraclePreparedStatement. The OraclePreparedStatementWrapper implements OraclePreparedStatement so if you cast to OraclePreparedStatementWrapper you should be able to call registerReturnParameter. Which will in turn call registerReturnParameter on the wrapped statement. Commented Aug 4, 2011 at 14:18

1 Answer 1

9

A ClassCastException can occur if the cast crosses classloader boundaries. For example, if the returned statement object's class was loaded by a classloader different from the one that loaded OraclePreparedStatemen in your code. This can be caused by having two separate copies of the JDBC jar in two places, one of which is being used by your Java EE container (Tomcat? WAS?) and the other by your code.

Sign up to request clarification or add additional context in comments.

4 Comments

+1. @John Strickler: As you have defined the datasource for LOCAL and DEV in the app's context.xml you may also have deployed the driver twice, in WEB-INF/lib and tomcat/lib?
This is exactly what is happening. Now I'm trying to figure out how to avoid this conflict... it's not going to be as easy as removing it from one of the locations.
@John Strickler: I'd recommend having the driver in one place only, tomcat/lib. I understand that it's not easy to solve - have fun with IT operations + your team :-)
For others who stumble upon this - I use maven to load the oracle driver into my codebase - I can prevent it from being deployed to the server by setting the scope to "provided" inside the ojdbc dependency. This basically says the JAR is provided on the server already so don't include it in the WAR file for deployment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.