United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6322649 There is no way to plug SyncProvider for CachedRowSet implementation
6322649 : There is no way to plug SyncProvider for CachedRowSet implementation

Details
Type:
Bug
Submit Date:
2005-09-12
Status:
Resolved
Updated Date:
2012-03-23
Project Name:
JDK
Resolved Date:
2006-12-08
Component:
core-libs
OS:
generic
Sub-Component:
javax.sql
CPU:
generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:
6u1

Related Reports
Backport:
Relates:
Relates:

Sub Tasks

Description
In accordance with the javadoc and "JDBC RowSet Implementations Tutorial" I try to implement and register my own SyncProvider instance in the following manner:
----------------MyProvider.java--------------------------------------------------
package com.sun.spb.rowset.providers;

import java.sql.Types;
import javax.sql.rowset.spi.*;
import javax.sql.rowset.*;
import javax.sql.*;

/**
 *
 * @author aag
 */
public class MyProvider extends SyncProvider implements RowSetReader,
        RowSetWriter {

    protected int datasource_lock = SyncProvider.DATASOURCE_NO_LOCK;

    /** Creates a new instance of MyProvider */
    public MyProvider() {
        System.out.println("New instance of " + getProviderID() +
                " created");
    }

    public void setDataSourceLock(int datasource_lock)
    throws SyncProviderException {
        this.datasource_lock = datasource_lock;
    }

    public int supportsUpdatableView() {
        return SyncProvider.UPDATABLE_VIEW_SYNC;
    }

    public String getVersion() {
        return "1.0";
    }

    public String getVendor() {
        return "Spb JCK Team";
    }

    public RowSetWriter getRowSetWriter() {
        return this;
    }

    public RowSetReader getRowSetReader() {
        return this;
    }

    public String getProviderID() {
        return this.getClass().getName();
    }

    public int getProviderGrade() {
        return SyncProvider.GRADE_NONE;
    }

    public int getDataSourceLock() throws SyncProviderException {
        return datasource_lock;
    }

    public boolean writeData(RowSetInternal caller) throws
            java.sql.SQLException {
        System.out.println("writeData");
        return true;
    }

    public void readData(RowSetInternal caller) throws java.sql.SQLException {
        System.out.println("readData");
        CachedRowSet crs = (CachedRowSet) caller;
        RowSetMetaData rsmd = new RowSetMetaDataImpl();
        crs.setReadOnly(false);
        crs.setType(RowSet.TYPE_SCROLL_INSENSITIVE);
        rsmd.setColumnCount(1);
        rsmd.setColumnName(1, "FIELD1");
        rsmd.setColumnType(1, Types.VARCHAR);
        crs.setMetaData(rsmd);
        crs.moveToInsertRow();
        crs.updateString(1, "VALUE1");
        crs.insertRow();
        crs.moveToCurrentRow();
        crs.beforeFirst();
    }

    public static void main(String[] argv) throws Exception {
        final String providerID = "com.sun.spb.rowset.providers.MyProvider";
        SyncFactory.registerProvider(providerID);
        /*final Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(SyncFactory.ROWSET_SYNC_PROVIDER, providerID);
        final CachedRowSet crs = new com.sun.rowset.CachedRowSetImpl(env); */
        final CachedRowSet crs = new com.sun.rowset.CachedRowSetImpl();
        crs.setSyncProvider(providerID);
        crs.execute();
    }
}
-------------------------------------------------------------------------------------
But unexpected exception occurs:
run:
New instance of com.sun.spb.rowset.providers.MyProvider created
Exception in thread "main" java.lang.ClassCastException:
com.sun.spb.rowset.providers.MyProvider
        at
com.sun.rowset.CachedRowSetImpl.setSyncProvider(CachedRowSetImpl.java:1380)
        at com.sun.spb.rowset.Test.main(Test.java:36)
Java Result: 1


I've looked into CachedRowSetImpl.java file and find the public interface type casts to non-public API type. Please have a look:
------------------------------------------------------------------------------
...
public void execute(Connection conn) throws SQLException {

        // store the connection so the reader can find it.
        setConnection(conn);

        if(getPageSize() != 0){
            crsReader = (CachedRowSetReader)provider.getRowSetReader();
            crsReader.setStartPosition(1);
            callWithCon = true;
            crsReader.readData((RowSetInternal)this);
        }

        // Now call the current reader's readData method
        else {
           rowSetReader.readData((RowSetInternal)this);
        }
        RowSetMD = (RowSetMetaDataImpl)this.getMetaData();

        if(conn != null){

          try {
                 dbmslocatorsUpdateCopy = conn.getMetaData().locatorsUpdateCopy();
          } catch(SQLException sqle) {
                  /*
                   * Since the Lobs and this method is not mandated by J2EE spec,
                   * drivers are not implementing it. We need to catch this
                   * and do nothing in this block and help populate()
                   * method do it's task
                   */
          } //end catch

        } else {

                  CachedRowSetReader crsTempReader = (CachedRowSetReader)rowSetReader;
                  ^^^^^^^^^^^^^^^^^^^
                  type cast to non-public API com.sun.rowset.internal.CachedRowSetReader
                  Connection tempCon = crsTempReader.connect((RowSetInternal)this);
...
----------------------------------------------------------------------
It looks like the user is not able to plug the own RowSetReader implementation into CachedRowSet.

                                    

Comments
EVALUATION

This is being deferred for next release of jdk
                                     
2006-07-20



Hardware and Software, Engineered to Work Together