Reputation: 4246
Anyone know what could be causing the following RUN TIME error in my Java program trying to access an Oracle database on a different Linux server?
java.lang.ClassCastException : com.sun.gjc.spi.jdbc40.CallableStatementWrapper40 cannot be cast to oracle.jdbc.OracleCallableStatement
I was following the discussion/example on page 4-14 to 4-15 in Oracle's JDBC Developer Guide ( http://isu.ifmo.ru/docs/doc112/java.112/e10589.pdf ). I created something similar to that example and it worked fine. Then I started modifying it to get to the below code AND introduced GlassFish into the process, and now I get that error.
Here's my Java code:
public List<Report> GetReports(String var1, String var1, String var3) throws Exception {
Connection conn;
CallableStatement cs;
ResultSet rset;
String out1;
Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("jdbc/myPool");
conn = ds.getConnection();
cs = conn.prepareCall( "{call my_proc (?,?,?,?,?)}" );
cs.setString(1, var1);
cs.setString(2, var2);
cs.setString(3, var3);
cs.registerOutParameter(4, Types.VARCHAR);
cs.registerOutParameter(5, OracleTypes.CURSOR);
cs.execute();
out1 = cs.getString(4);
List<Report> userReports = new ArrayList<Report>();
rset = ((OracleCallableStatement)cs).getCursor(5);
while ( rset.next() ) {
Report report = new Report();
report.col1 = rset.getString("myCol1");
report.col2 = rset.getString("myCol2");
userReports.add(report);
}
if ( rset != null ) {
try { rset.close(); } catch ( Exception ex ) {}
rset = null;
}
if ( conn != null ) {
try { conn.close(); } catch ( Exception ex ) {}
conn = null;
}
return userReports;
}
Upvotes: 0
Views: 1900
Reputation: 4246
There's probably more than one way to solve this, but the following change to the above code works for me. Replace this statement:
rset = ((OracleCallableStatement)cs).getCursor(5);
with this statement:
rset = (ResultSet) cs.getObject(5);
Upvotes: 0
Reputation: 80633
GlassFish enables something called statement wrapping by default. With this option enabled your statements, result sets and database meta data objects all get wrapped in a 'proxy' object. Normally there is no issue with this because you access these objects only via their standard JDBC interfaces, but if you need vendor specific capabilities then you will need to take extra steps to get past this 'proxy'.
Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("jdbc/myPool");
conn = ds.getConnection();
conn = ds.getConnection(conn); // <-- 'Unwrap' the vendor specific connection
On a side note, it doesn't look like you need the Oracle specific version of callable statement, the cast might be totally superfluous.
You can read more about statement wrapping on the Oracle Development Guide for Glassfish Server.
Upvotes: 1
Reputation: 5706
The problem is you defined the variable as
CallableStatement cs;
and then casted it with
rset = ((OracleCallableStatement)cs).getCursor(5);
the CallableStatement
is the super interface of OracleCallableStatement
and you can't cast a super interface to it's child (you can do the opposite). You should be able to just change cs
into an OracleCallableStatement
.
Upvotes: 0