Using RemoteAPI to access the live datastore from my dev server

0 views
Skip to first unread message

Riley Lark via StackOverflow

unread,
Nov 28, 2013, 6:17:53 AM11/28/13
to google-appengin...@googlegroups.com

I've got an app that, in some situation I can't reproduce, locks up both Firefox and Chrome. I have no insight into what's causing the problem. I can't get any information because both browsers just lock up - even firebug and Chrome's developer tools freeze. Impressive, I know!

Anyway, I thought I'd run the app with the debugger hooked up in eclipse, but using RemoteApi to use the actual data so I can see what's happening here. I wrote a ServletFilter:

public class RemoteApiFilter implements Filter {

    RemoteApiOptions options;

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        try {
            RemoteApiInstaller installer = new RemoteApiInstaller();
            installer.install(options);
            chain.doFilter(request, response);
            installer.uninstall();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        options = new RemoteApiOptions().server(
                config.getInitParameter("host"), 443).credentials(
                config.getInitParameter("email"),
                config.getInitParameter("password"));
    }

}

I run every request through this filter, and I thought this would make my whole app work like normal, but with the live, production datastore instead of with the development datastore. But it didn't work! Instead, on the very first call I make to the datastore api, I get some sort of threading access violation exception:

java.security.AccessControlException: access denied (java.lang.RuntimePermission modifyThreadGroup)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
    at java.security.AccessController.checkPermission(AccessController.java:546)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
    at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:166)
    at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkAccess(DevAppServerFactory.java:191)
    at java.lang.ThreadGroup.checkAccess(ThreadGroup.java:299)
    at java.lang.Thread.init(Thread.java:336)
    at java.lang.Thread.<init>(Thread.java:626)
    at java.util.concurrent.Executors$DefaultThreadFactory.newThread(Executors.java:542)
    at java.util.concurrent.ThreadPoolExecutor.addThread(ThreadPoolExecutor.java:672)
    at java.util.concurrent.ThreadPoolExecutor.addIfUnderCorePoolSize(ThreadPoolExecutor.java:697)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:652)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:92)
    at com.google.appengine.tools.remoteapi.RemoteApiDelegate.makeAsyncCall(RemoteApiDelegate.java:98)
    at com.google.apphosting.api.ApiProxy.makeAsyncCall(ApiProxy.java:184)
    at com.google.appengine.api.datastore.DatastoreApiHelper.makeAsyncCall(DatastoreApiHelper.java:81)
    at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.get(AsyncDatastoreServiceImpl.java:306)
    at com.googlecode.objectify.cache.CachingAsyncDatastoreService.getFromDatastore(CachingAsyncDatastoreService.java:111)
    at com.googlecode.objectify.cache.CachingAsyncDatastoreService.get(CachingAsyncDatastoreService.java:372)
    at com.googlecode.objectify.impl.AsyncObjectifyImpl.get(AsyncObjectifyImpl.java:68)
    at com.googlecode.objectify.impl.AsyncObjectifyImpl.find(AsyncObjectifyImpl.java:192)
    at com.googlecode.objectify.impl.AsyncObjectifyImpl.get(AsyncObjectifyImpl.java:101)
    at com.googlecode.objectify.impl.AsyncObjectifyImpl.get(AsyncObjectifyImpl.java:124)
    at com.googlecode.objectify.impl.ObjectifyImpl.get(ObjectifyImpl.java:63)
    at com.activegrade.server.data.DataCoordinatorAppengineImpl.verifyUser(DataCoordinatorAppengineImpl.java:471)
    at com.activegrade.server.servlets.MainPageChooser.doGet(MainPageChooser.java:54)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.activegrade.server.filter.RemoteAPIFilter.doFilter(RemoteAPIFilter.java:25)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:58)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:351)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

I'm using Objectify and Resteasy but otherwise this is a pretty plain setup. I'm totally stumped about what to try next.

Is this a good way to try to debug my GWT application with live data on GAE? What's going wrong, and what should I try next to get more information?



Please DO NOT REPLY directly to this email but go to StackOverflow:
http://stackoverflow.com/questions/7265500/using-remoteapi-to-access-the-live-datastore-from-my-dev-server

lembas via StackOverflow

unread,
Nov 28, 2013, 6:17:55 AM11/28/13
to google-appengin...@googlegroups.com

Filter doesn't work well with RemoteServiceServlets so add these to your RemoteServiceServlet:

RemoteApiOptions options;
RemoteApiInstaller installer;

@Override
protected void onBeforeRequestDeserialized(String serializedRequest) {
    if (getThreadLocalRequest().getRequestURL().indexOf("127.0.0.1") != -1) {
        if (options == null) {
            options = new RemoteApiOptions().server("example.appspot.com", 443).credentials("username", "password");
            installer = new RemoteApiInstaller();
            try {
                installer.install(options);
                options.reuseCredentials("username", installer.serializeCredentials());
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        else {
            installer = new RemoteApiInstaller();
            try {
                installer.install(options);
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

@Override
protected void onAfterResponseSerialized(String serializedResponse) {
    if (getThreadLocalRequest().getRequestURL().indexOf("127.0.0.1") != -1)
        installer.uninstall();
}


Please DO NOT REPLY directly to this email but go to StackOverflow:
http://stackoverflow.com/questions/7265500/using-remoteapi-to-access-the-live-datastore-from-my-dev-server/20264636#20264636
Reply all
Reply to author
Forward
0 new messages