How to use CachedRowSet in Google App Engine?

257 views Asked by At

I am using Google App Engine (Endpoints) to generate a simple API service.

I'm currently trying to make my queries to the database faster and more efficient, so I decided to double check where I was calling ResultSet and Connections and closing them.

However I want to use CachedRowSet and it almost seems impossible given that when I try to access CachedRowSetImpl() the logger returns:

java.lang.NoClassDefFoundError: com.sun.rowset.CachedRowSetImpl is a restricted class. Please see the Google App Engine developer's guide for more details

So I did some investigation and Google App Engine's JRE whitelist includes:

javax.sql.rowset.CachedRowSet

but not

com.sun.rowset.CachedRowSetImpl

Does that make any sense? How can I initialize/use CachedRowSet otherwise?

My code:

public ResultSet getRecordsWhereInt(String table, String where, int condition) throws SQLException {

   c = DatabaseConnect();

   preStatement = c.prepareStatement("SELECT * FROM " + table + " WHERE " + where + " = ?");

   preStatement.setInt(1, condition);

   CachedRowSet rowset = new CachedRowSetImpl();

   rowset.populate(preStatement.executeQuery());

   c.close();

   return rowset;

}

Any help would/guidance would be appreciated.

Update 1 (09/06/2015):
Investigating further, I found that you can implement CachedRowSetImpl's functionality using RowSetProvider.newFactory().createCachedRowSet();

However, Google has also restricted use to RowSetProvider().

That left me with the only other whitelisted library RowSetFactory. So I made my own, implementing RowSetFactory according to Oracle's implementation:

public class CachedRowSetFactory implements RowSetFactory {


    public CachedRowSet createCachedRowSet() throws SQLException {
        return new CachedRowSetImpl();
    }

    public FilteredRowSet createFilteredRowSet() throws SQLException {
        return null;
    }

    public JdbcRowSet createJdbcRowSet() throws SQLException {
        return null;
    }

    public JoinRowSet createJoinRowSet() throws SQLException {
        return null;
    }

    public WebRowSet createWebRowSet() throws SQLException {
        return null;
    }
}

And then used it like this:

CachedRowSet crs = new CachedRowSetFactory().createCachedRowSet();

However, even this fails. The above example returns a Null Pointer Exception when I try to populate it with a working result set. I'm guessing the factory implementation isn't 100% correct or that I'm skipping over something obvious.

Update 2 (11/06/2015):
I tried rolling my own implementation of CachedRowSetImpl, and of the RowSetProvider by duplicating some of the libraries by hand and eliminating the libraries not covered in App Engines Whitelist. Was not successful. I know I need to give up on this but I'm determined to make this work.

1

There are 1 answers

2
koma On BEST ANSWER

CahecRowSet is an interface so obviously this is whitelisted.

Interface CachedRowSet

I am guessing you are connecting a Google CloudSQL instance.

from the javadoc :

A CachedRowSet object is a container for rows of data that caches its rows in memory, which makes it possible to operate without always being connected to its data source.

What you are trying to do does not make sense IMO. AppEngine does not keep state between different requests and certainly not when your application auto-scales and new instances spin up.

Why don't you cache your results in Memcache, this will persist over subsequent requests and different instances.