This discussion is archived
6 Replies Latest reply: Jul 24, 2013 10:55 AM by RohitJadhav RSS

Class com.ibm.ws.rsadapter.jdbc.WSJdbcUtil can not access a member of class oracle.jdbc.driver.OraclePreparedStatementWrapper with modifiers "public"

RohitJadhav Newbie
Currently Being Moderated

We have WAS JDBC Connection pool API's implemented in our code and was working till the point we upgrade WAS6 to WAS7.

 

Post upgrade Issue we are facing :

 

PreparedStatement l_stmt : object is fetched from WAS 7 datasource connection object.

 

Observed Value when inspected the l_stmt object from eclipse :

----------------------------------------------------------------------

l_stmt.pstmtimpl = oracle.jdbc.driver.OraclePreparedStatementWrapper (Returned when connection is fetched from IBM Datasource)

 

I have a piece of code which tries to create instance of OraclePreparedStatementWrapper class from ojdb6.jar,below is the source snippet.

 

com.ibm.websphere.rsadapter.WSCallHelper.jdbcCall(null, l_stmt,  "setFixedCHAR", new Object[]{new Integer(1), p_txn_key}, new Class[]{Integer.TYPE, String.class} );

                                                                                                                                                                                 

Above execution internally (IBM WAS Jars) calls OraclePreparedStatementWrapper based on the object it received from datasource.

 

I am getting below error :

------------------------

 

Caused by: 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 sun.reflect.Reflection.ensureMemberAccess(Reflection.java:77)

                at java.lang.reflect.Method.invoke(Method.java:590)

                at com.ibm.ws.rsadapter.jdbc.WSJdbcUtil.call(WSJdbcUtil.java:528)

 

It is observed in ojdbc6.jar OraclePreparedStatementWrapper has "default" access modifier. Due to which i am getting above exception.

Please let me know if there is any work around which will help me overcome above error.

  • 1. Re: Class com.ibm.ws.rsadapter.jdbc.WSJdbcUtil can not access a member of class oracle.jdbc.driver.OraclePreparedStatementWrapper with modifiers "public"
    Joe Weinstein Expert
    Currently Being Moderated

    It sounds like a difference in the internals of the oracle JDBC driver being used in the two environments.

    What on earth are you doing trying to instantiate driver-internal classes? You really should stick to the

    standard JDBC API...

  • 2. Re: Class com.ibm.ws.rsadapter.jdbc.WSJdbcUtil can not access a member of class oracle.jdbc.driver.OraclePreparedStatementWrapper with modifiers "public"
    RohitJadhav Newbie
    Currently Being Moderated

    Hi,

     

    I have just used ibm exposed api which to which I am pasing connection object I recieve from datasource

    Defined on WAS 7. It seems stmt obj creatd by returning oracleprepstmtwrapper clas which is default in ojdbc6

  • 3. Re: Class com.ibm.ws.rsadapter.jdbc.WSJdbcUtil can not access a member of class oracle.jdbc.driver.OraclePreparedStatementWrapper with modifiers "public"
    Joe Weinstein Expert
    Currently Being Moderated

    You'll have to show the code. No IBM API is going to require you to instantiate some other vendor's drivers internal classes.

  • 4. Re: Class com.ibm.ws.rsadapter.jdbc.WSJdbcUtil can not access a member of class oracle.jdbc.driver.OraclePreparedStatementWrapper with modifiers "public"
    RohitJadhav Newbie
    Currently Being Moderated

    Hope below stuff helps :

    ---------------------------------------------

    What WAS JDBC Connection pool API's I you implemented in my code ?

     

    1. com.ibm.websphere.rsadapter.WSCallHelper.jdbcCall(null,l_stmt,"setFixedCHAR",new Object[]{new Integer(1),p_txn_key},new Class[]{Integer.TYPE,String.class} );

     

    Am I using the same Oracle version with both WAS 6 and WAS 7?

     

    WAS7 :

     

    Oracle DB Version : 11G

    Oracle Driver Version : ojdbc6.jar

     

    WAS6:

    Oracle DB Version : 10G

    Oracle Driver Version : ojdbc14.jar

     

     

    Note : When it is WAS6 and ojdbc14.jar code snippet mentioned above works fine, But Since we are in process of WAS upgrade we are facing this major callenge.

     

    What is the OS?

     

    Windows 2003 Server in Testing Environment, AIX in production.

     

    Am I able to provide us a testcase to recreate this issue?

     

    1) Create Connection Pool in WAS7, Fetch the connection object from WAS7.

    2) Example :

                                   Connection l_con        = /*GET JDBC Connection from WAS7 Connection Pool (DataSource) - code here "datasource class defined in WAS7 is OracleConnectionPoolDataSource"*/;

                                        PreparedStatement l_stmt      = l_con.createStatement ();

                                        PreparedStatement l_stmt1 = null;

                                        l_rs      = l_stmt.executeQuery ("SELECT "TESTJDBC1" COL1 FROM DUAL");

                                        while (l_rs.next ()) {

                                                    String col1                  = l_rs.getString ("COL1");

                                                                  l_stmt1          = l_con.prepareStatement ("SELECT col2 FROM tbl_test WHERE column =? ");

                                                                if ("oracle".equalsIgnoreCase(/*GET DB METADATA i.e DatabaseName - code here*/)) {

              /*Below if will be TRUE since instance recieved from Connection pool will be of WSJdbcPreparedStatement */

                                                                            if(l_stmt1 instanceof com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement) {

                                                                                        com.ibm.websphere.rsadapter.WSCallHelper.jdbcCall(null,l_stmt1,"setFixedCHAR",new Object[]{new Integer(1),col1},new Class[]{Integer.TYPE,String.class} );

    /*

    ABOVE statement will fail during excution since l_stmt1 fetched from l_con (WSJDBCConnection) has OraclePreparedStatementWrapper in its pstmtimpl object. and OraclePreparedStatementWrapper is "default" in ojdbc6.jar, When WSJDC API's internally

    tries to bind setFixedCHAR public method inside OraclePreparedStatementWrapper of ojdbc6.jar, it throws error


    Caused by: 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 sun.reflect.Reflection.ensureMemberAccess(Reflection.java:77)

    at java.lang.reflect.Method.invoke(Method.java:590)

    at com.ibm.ws.rsadapter.jdbc.WSJdbcUtil.call(WSJdbcUtil.java:528)

                                                                                                                                                 

    Observations :

              I could see there are two WSCallHelper.jdbcCall methods declared in WSCallHelper WSCallHelper.jdbcCall with 5 parameters and WSCallHelper.jdbcCall with 6 parameter. Since we have been using 5 parameter method in WAS6 and ojdbc14.jar, we have more than 1000's of java classes using WSCallHelper.jdbcCall with 5 parameter. However when i tried example of having used 6 parameter of WSCallHelper.jdbcCall, in which i hardcoded vendorClassName "oracle..OraclePreparedStatement"    Code seemed to be working fine.

    Question here is, when i used WSCallHelper.jdbcCall method with 5 parameter why does WAS Connection/statement objects return OraclePreparedStatementWrapper, which is has access modifier "default", due to this WSCallHelper.jdbcCall method with 5 parameter becomes meaning less.          I am afriad i have to change all java classes. Since we cannot keep changing existing implementations unless depricated or not logical.

     

    */

                                                                            }

                                                                            else if(l_stmt1 instanceof oracle.jdbc.OraclePreparedStatement) {

                                                                                        ((oracle.jdbc.OraclePreparedStatement)l_stmt1).setFixedCHAR (1, l_col1);

                                                                            } else {

                                                                                                    l_stmt1.getClass().getMethod("setFixedCHAR", new Class[]{Integer.TYPE,String.class}).invoke(l_stmt1,new Object[]{new Integer(1),l_col1});

                                                                            }

                                                                }

                                                                else

                                                                {

                                                                            l_stmt1.setString (1, l_col1);

                                                                }

                                                    }

  • 5. Re: Class com.ibm.ws.rsadapter.jdbc.WSJdbcUtil can not access a member of class oracle.jdbc.driver.OraclePreparedStatementWrapper with modifiers "public"
    Joe Weinstein Expert
    Currently Being Moderated

    OK, so the deal is that you want to call the Oracle-specific setFixedCHAR() method, and

    you are working with IBM pool-wrapped objects. Oracle provides the specific instructions

    about how to call that method, and the specific cast you need to make. If IBM's code tries

    to get the method by introspection and fails, because the method is only implemented in

    a non-public parent class of the driver object, IBM has to fix their code. Ideally, you should

    change your code, once and for all, to use only the standard JDBC API, which should allow

    you to do everything, and not have to worry about IBM trying to find methods by introspection,

    and Oracle changing the internal class architecture in their driver (which as long as they meet

    all their public APIs is totally their perogative).

    IBM should offer you an API to get a direct handle one the actual Oracle statement. If you

    use/get that, you can simply cast to oracle.jdbc.OraclePreparedStatement to make that call.

  • 6. Re: Class com.ibm.ws.rsadapter.jdbc.WSJdbcUtil can not access a member of class oracle.jdbc.driver.OraclePreparedStatementWrapper with modifiers "public"
    RohitJadhav Newbie
    Currently Being Moderated

    As said.....

    IBM has exposed one more method which accepts 6 parameters in which if i pass "oracle.jdbc.OraclePreparedStatement" as 6tht param, my code works fine.

    But existing 5 parameters method throws error mentioned above. My Concerns is number of classes impacted in my code!!!!.....and again this is become limitation and incorrect behavior, we cannot keep changing implementations unless it is deprecated or no more supported......, i had raised issue with IBM and at the same time i posted it on this Forum as well, with a hope of getting response from both or either.....IBM is already in touch with me for this issue.....my earlier post is what i have dropped in to IBM. lets see if they come up with fix.

     

    Thanks for the Time and Efforts.......

     

    Cheerz,

    RJ

    I bet for the best....!!!!!

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points