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.
CahecRowSet is an interface so obviously this is whitelisted.
Interface CachedRowSet
I am guessing you are connecting a Google CloudSQL instance.
from the javadoc :
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.