Connection cannot be cast to oracle.jdbc.OracleConnection

大城市里の小女人 提交于 2019-11-27 20:39:27

The connection you are retrieving is probably a wrapped connection.

If you really need to get the underlying Oracle connection you should use:

if (connection.isWrapperFor(OracleConnection.class)){
   OracleConnection oracleConnection= connection.unwrap(OracleConnection.class);  
}else{
   // recover, not an oracle connection
}

The isWrapperFor and unwrap methods are available since Java 1.6, and should be meaningfully implemented by the A/S connection wrappers.

The connection pool usually has a wrapper around the real connection instance, that's why your cast fails.

What you are doing wouldn't work anyway, because the parameters in the properties instance are only checked when the connection is established. As you have a connection that is already active, it won't change anything.

You need tou use DBMS_APPLICATION_INFO.SET_CLIENT_INFO() in order to change this for an existing connection.

This is just for people who come here via search on how to set metrics in OracleConnection, I spend great deal of time on this, so might help someone.

After you get your "connection" this should work:

DatabaseMetaData dmd = connection.getMetaData();
Connection metaDataConnection = null;

if(dmd != null)
{
    metaDataConnection = dmd.getConnection();
}

if(!(metaDataConnection instanceof OracleConnection))
{
    log.error("Connection is not instance of OracleConnection, returning");
    return; /* Not connection u want */
}

OracleConnection oraConnection = (OracleConnection)metaDataConnection;

String[] metrics = new String[END_TO_END_STATE_INDEX_MAX]; // Do the rest below...

It works for me for OracleConnection, but I face diff issue when setting metrics:

short zero = 0;
oraConnection.setEndToEndMetrics(metrics, zero);

After proxying connection via my method where I set metrics few times, I get:

java.sql.SQLRecoverableException: No more data to read from socket

But I think it has to do with some Spring wiring inits or connection pool.

i had faced this issue when using spring to get connections. Typically , each layer adds a wrapper over the basic classes. i had just done connection.getClass().getName() to see the runtime type of the connection being retuned. It will be a Wrapper/proxy over which you can easily find the method to get the base OracleConnection type.

You can access the inner OracleObject inside a Wrapper, in this case the wrapper type is NewProxyConnection:

( I've used it in my project, it Worked ...no mistery, just use reflection)

Field[] fieldsConn= connection.getClass().getDeclaredFields();

Object innerConnObject = getFieldByName(fieldsConn,"inner").get(connection);


if(innerConnObject instanceof OracleConnection ){
  OracleConnection oracleConn = (OracleConnection)innerConnObject;
 //OracleConnection unwrap = ((OracleConnection)innerConnObject).unwrap();
  // now you have the OracleObject that the Wrapper 
}


//Method: Set properties of the ooject accessible.
 public static  Field getFieldByName(Field[] campos, String name) {
    Field f = null;
    for (Field campo : campos) {
        campo.setAccessible(true);
        if (campo.getName().equals(name)) {
            f = campo;
            break;
        }
    }
    return f;
 }

Try the following

I had encountered the same issue. We were using spring and it has a class called NativeJdbcExtractor. It has many implementations and the following one works for TomCat. There is a specific implementation for Jboss called the JBossNativeJdbcExtractor

<bean id="jdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"></bean>

In your DAO you can inject the bean and use the following method

protected NativeJdbcExtractor jdbcExtractor;
Connection conn=jdbcExtractor.getNativeConnection(oracleConnection);

Not sure if my situation is related, but with my project, simply changing a database configuration setting actually causes unwrap to fail!

I'm using the Play framework with Scala; this works for me only when logSql=false:

db.withConnection { implicit c  =>
  val oracleConnection = c.unwrap(classOf[OracleConnection])
}

(this is just the Scala version of unwrapping an OracleConnection)

When I set logSql=true, I get:

com.sun.proxy.$Proxy17 cannot be cast to oracle.jdbc.OracleConnection java.lang.ClassCastException: com.sun.proxy.$Proxy17 cannot be cast to oracle.jdbc.OracleConnection

So something about the logSql configuration can actually cause unwrap to fail. No idea why.

With either configuration, my connection object is:

HikariProxyConnection@1880261898 wrapping oracle.jdbc.driver.T4CConnection@6b28f065

isWrapperFor(OracleConnection) is true in both cases

This happens with Hikari Connection Pool and Bone CP. Maybe it's a bug in Oracle JDBC?

Oracle JDBC Driver version according to MANIFEST.MF

Implementation-Version: 11.2.0.3.0
Repository-Id: JAVAVM_11.2.0.4.0_LINUX.X64_130711

After trial and error. This way works:

        DelegatingConnection delConnection = new DelegatingConnection(dbcpConnection);
    oraConnection = (oracle.jdbc.OracleConnection)delConnection.getInnermostDelegate();

But this way returned a null pointer for oraConnection:

DelegatingConnection delConnection = (DelegatingConnection) dbcpConnection;
    oraConnection = (oracle.jdbc.OracleConnection)delConnection.getInnermostDelegate();
Dezman

The following worked to get around AQ's TopicConnection.getTopicSession => JMS-112

//DEBUG: Native DataSource : weblogic.jdbc.common.internal.RmiDataSource
con = DataSource.getConnection();
debug("Generic SQL Connection: " + con.toString());               
//DEBUG: Generic Connection: weblogic.jdbc.wrapper.PoolConnection_oracle_jdbc_driver_T4CConnection
if (con != null && con.isWrapperFor(OracleConnection.class)) {
  WebLogicNativeJdbcExtractor wlne = new WebLogicNativeJdbcExtractor();//org.springframework to the rescue!!
  java.sql.Connection nativeCon = wlne.getNativeConnection(con);
  this.oraConnection = (OracleConnection) nativeCon;
  debug("Unwrapp SQL Connection: " + this.oraConnection.toString());
}

//DEBUG: Native Connection: oracle.jdbc.driver.T4CConnection è 

Now I could use this in the AQ-Factory w/o JMS-112

user4322893

try casting like below

WrappedConnectionJDK6 wc = (WrappedConnectionJDK6) connection;
connection = wc.getUnderlyingConnection();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!