WSJDBCConnection does not wrap objects of type Ora

2020-02-06 12:44发布

问题:

I am using Websphere liberty server to run my application and I need to use ArrayDescriptor for passing arrays to the oracle stored procedure. I get an exception while unwrapping the connection. I have checked the connection meta data driver information as well and it is showing me oracle.jdbc driver. The code fails at connection unwrapping line.

Connection conn = this.getDataSource().getConnection();
OracleConnection oracleConn = conn.unwrap(oracle.jdbc.OracleConnection.class); 

Exception message: java.sql.SQLException: DSRA9122E: com.ibm.ws.rsadapter.jdbc.v41.WSJdbc41Connection@120edaf does not wrap any objects of type oracle.jdbc.OracleConnection.

I have added class loader reference for my application in the server.xml as well but that didn't help.

My server.xml looks like :

<dataSource  id="datasource" jndiName="jdbc/XXXXXX" 
type="javax.sql.XADataSource">
<jdbcDriver libraryRef="ordLib"/>
<properties.oracle databaseName="XXXX" driverType="thin" password="XXXXXX" 
portNumber="XXXXXX" serverName="XXXXXX" serviceName="XXXXXX" url="XXXXXX" 
user="XXXXXX"/>
</dataSource>

<webApplication id="NAExtractWeb" location="NAExtractWeb.war" 
name="NAExtractWeb">
<classloader commonLibraryRef="ordLib"></classloader>
</webApplication>

<library id="ordLib">
    <fileset dir="C:\lib" id="fileset" includes="ojdbc6-11.2.0.4.jar"/>
</library> 

Also I use this unwrap function in one of my dependent project jar and I have ojdbc dependency(maven) added in my dependent project. Will that affect the unwrapping step?

Here is the method which will get the data source:

 public DataSource getDataSource(String dsName) throws BatchException {

    try {
        return (DataSource) new InitialContext().lookup(dsName);
    } catch (Exception e) {
            //Code to handle
    }
}

Here is the full stack trace:

[6/19/18 17:20:29:340 IST] [process partition0] com.ibm.ws.batch.JobLogger CWWKY0030I: An exception occurred while running the step process. com.ibm.jbatch.container.exception.BatchContainerRuntimeException: Failure in Read-Process-Write Loop at com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl.invokeChunk(ChunkStepControllerImpl.java:704) at com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl.invokeCoreStep(ChunkStepControllerImpl.java:795) at com.ibm.jbatch.container.controller.impl.BaseStepControllerImpl.execute(BaseStepControllerImpl.java:293) at com.ibm.jbatch.container.controller.impl.ExecutionTransitioner.doExecutionLoop(ExecutionTransitioner.java:118) at com.ibm.jbatch.container.controller.impl.WorkUnitThreadControllerImpl.executeCoreTransitionLoop(WorkUnitThreadControllerImpl.java:93) at com.ibm.jbatch.container.controller.impl.WorkUnitThreadControllerImpl.executeWorkUnit(WorkUnitThreadControllerImpl.java:155) at com.ibm.jbatch.container.controller.impl.WorkUnitThreadControllerImpl$AbstractControllerHelper.runExecutionOnThread(WorkUnitThreadControllerImpl.java:480) at com.ibm.jbatch.container.controller.impl.WorkUnitThreadControllerImpl.runExecutionOnThread(WorkUnitThreadControllerImpl.java:89) at com.ibm.jbatch.container.util.BatchWorkUnit.run(BatchWorkUnit.java:117) at com.ibm.ws.context.service.serializable.ContextualRunnable.run(ContextualRunnable.java:79) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: com.ibm.jbatch.container.exception.BatchContainerRuntimeException: java.sql.SQLException: DSRA9122E: com.ibm.ws.rsadapter.jdbc.v41.WSJdbc41Connection@73c25e77 does not wrap any objects of type oracle.jdbc.OracleConnection. at com.ibm.jbatch.container.artifact.proxy.ItemWriterProxy.open(ItemWriterProxy.java:67) at com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl.openReaderAndWriter(ChunkStepControllerImpl.java:954) at com.ibm.jbatch.container.controller.impl.ChunkStepControllerImpl.invokeChunk(ChunkStepControllerImpl.java:599) ... 14 more Caused by: java.sql.SQLException: DSRA9122E: com.ibm.ws.rsadapter.jdbc.v41.WSJdbc41Connection@73c25e77 does not wrap any objects of type oracle.jdbc.OracleConnection. at com.ibm.ws.rsadapter.jdbc.WSJdbcWrapper.unwrap(WSJdbcWrapper.java:459) at com.fmr.nfiws.batch.writer.DBWriter.open(DBWriter.java:149) at com.ibm.jbatch.container.artifact.proxy.ItemWriterProxy.open(ItemWriterProxy.java:64) ... 16 more

回答1:

I just tested this on WebSphere Liberty and the following code worked for me:

@Resource(lookup = "jdbc/oracle")
private DataSource ds;

// ...

Connection conn = ds.getConnection();
OracleConnection oracleConn = conn.unwrap(oracle.jdbc.OracleConnection.class);

My server.xml looks like this:

<dataSource jndiName="jdbc/oracle">
    <jdbcDriver libraryRef="oracleLib"/>
    <properties.oracle URL="${jdbc.URL}" user="${jdbc.user}" password="${jdbc.password}"/>
</dataSource>

<library id="oracleLib">
    <fileset dir="${server.config.dir}/oracle"/>
</library>

<application location="myApp.war" >
    <classloader commonLibraryRef="oracleLib"/>
</application>

The important thing to note here is the use of commonLibraryRef on the <classloader> element. If you use privateLibraryRef it will not work because the app and server-defined datasource will use isolated classloaders to load the Oracle JDBC classes.

If this answer isn't helpful to you, please update your question with your server.xml configuration, and also how you are obtaining an instance of your DataSource.



回答2:

If someone has this problem here is my solution.

My mistake was that I was deploying my application to the dropins folder and if you define an application/webApplication in your server.xml it is ignored. I deployed it somewhere else, set this new location to the application tag and also added the <classloader> in server.xml, left the ojdbc jar as provided in pom.xml and it works now.

But still I had a problem when I was running the application locally, because the ojdbc jar was provided in pom.xml.
My solution was to use reflection to get the system class loader and load the jar at runtime for the local profile.

Hope this helps someone.