Good Morning!
I'm trying to upgrade from Websphere 6.5 to 8.5. When the application commits xml data to DB I get the following error:
Caused by:
java.sql.SQLException: java.lang.IllegalAccessException: Class com.ibm.ws.rsadapter.jdbc.WSJdbcUtil can not access a member of class oracle.jdbc.driver.OraclePreparedStatementWrapper with modifiers "public"
at com.ibm.ws.rsadapter.AdapterUtil.toSQLException(AdapterUtil.java:1727)
at com.ibm.ws.rsadapter.jdbc.WSJdbcUtil.call(WSJdbcUtil.java:684)
at com.ibm.ws.rsadapter.jdbc.WSJdbcUtil.call(WSJdbcUtil.java:377)
at com.ibm.websphere.rsadapter.WSCallHelper.jdbcCall(WSCallHelper.java:302)
at J.D.A.A.WASOracleXMLType.nullSafeSet(Unknown Source)
at J.D.A.A.A.nullSafeSet(Unknown Source)
at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:146)
After some time to investigate I think that I've found what give me the problem: a WebSphere method name jdbcCall that has 5 parameters in WebSphere 6.5 but now can have 6 parameters.
The method is described here: https://www-01.ibm.com/support/knowledgecenter/SS7K4U_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/com/ibm/websphere/rsadapter/WSCallHelper.html
And the parameter is this:
**vendorClassName** - The name of the vendor-specific interface class
on which methName is defined. This value can be used in cases where the
implementation class of the vendor's JDBC object is a protected class, i.e.
calling methName on the underlying JDBC object produces an **IllegalAccessException**. This value should specify the name of the vendor's recommended Class/Interface which is extended/implemented by the underlying JDBC object. For example "oracle.jdbc.driver.OracleResultSet" may need to be specified when the underlying object is an OracleResultSetImpl object. If not needed, this value may be null.
This is mine implementation:
com.ibm.websphere.rsadapter.WSCallHelper.jdbcCall(
null,
a-Prepared-Statement, //OraclePreparedStatementWrapper
"setObject",
new Object[]{new Integer(index), xmlType},
new Class[]{int.class, Object.class})
So, I've read the documentation but I can't understand what I should insert as vendorClassName, maybe is enought "oracle.jdbc.OracleDriver"? And can anyone explain better throught I can understand what I should insert in this param?
Otherwise What do you think can be the problem?
I'm using Oracle12c, ojdbc6 and WebSphere 8.5
Thank you !
Why do you need to be using WSCallHelper.jdbcCall()
at all?
Since PreparedStatement.setObject(int, Object)
is fully JDBC standard, you can just invoke it on your statement object without needing to do any sort of unwrapping. You should only attempt to unwrap the WebSphere JDBC connection if you need to call vendor-specific APIs.
Simply do:
aStatement.setObject(index, xmlType);
If you need to access vendor specific APIs:
Usage of WSCallHelper.jdbcCall()
is fairly outdated. I would recommend using Connection.unwrap(Class<?>)
instead.
Example:
OraclePreparedStatement oracleStmt = aStatement.unwrap(OraclePreparedStatement.class);
If you really, really need to use WSCallHelper.jdbcCall()
:
Passing in the vendor class name will allow WebSphere to load the vendor class and perform the invoke operation in a privileged manner with the proper classloader applied.
The vendor class name you want to pass in is the class name of the vendor object you are attempting to invoke. So if you are using a Statement with the oracle drive, you would pass in the string "oracle.jdbc.OracleStatement" as your vendorClassName.
Example:
com.ibm.websphere.rsadapter.WSCallHelper.jdbcCall(
null,
aStatement, // WSJdbcPreparedStatement wrapping an OraclePreparedStatement
"someOracleSpecificMethod",
new Object[]{new Integer(index), xmlType},
new Class[]{int.class, Object.class},
"oracle.jdbc.OracleStatement");