Using Java Executor on AppEngine causes AccessControlException

Posted by Drew on Stack Overflow See other posts from Stack Overflow or by Drew
Published on 2010-04-19T01:23:29Z Indexed on 2010/04/19 1:33 UTC
Read the original article Hit count: 501

How do you get java.util.concurrent.Executor or CompletionService to work on Google AppEngine? The classes are all officially white-listed, but I get a runtime security error when trying to submit asynchronous tasks.

Code:

    // uses the async API but this factory makes it so that tasks really
    // happen sequentially
    Executor executor = java.util.concurrent.Executors.newSingleThreadExecutor();
    // wrap Executor in CompletionService
    CompletionService<String> completionService = 
        new ExecutorCompletionService<String>(executor);
    final SomeTask someTask = new SomeTask();
    // this line throws exception
    completionService.submit(new Callable<String>(){
        public String call() {
            return someTask.doNothing("blah");
        }
    });
    // alternately, send Runnable task directly to Executor,
    // which also throws an exception
    executor.execute(new Runnable(){
        public void run() {
            someTask.doNothing("blah");
        }
    });
}

private class SomeTask{
    public String doNothing(String message){
        return message;
    }
}

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:288) at java.lang.Thread.init(Thread.java:332) at java.lang.Thread.(Thread.java:565) 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.Executors$DelegatedExecutorService.execute(Executors.java:590) at java.util.concurrent.ExecutorCompletionService.submit(ExecutorCompletionService.java:152)

This code works fine when run on Tomcat or via command-line JVM. However, it chokes in the AppEngine SDK Jetty container (tried with Eclipse plugin and the maven-gae-plugin).

AppEngine is likely designed to not allow potentially dangerous programs to run, so I could see them completely disabling thread creation. However, why would Google allow you to create a class, but not allow you to call methods on it? White-listing java.util.concurrent is misleading.

Is there some other way to do parallel/simultaneous/concurrent tasks on GAE?

© Stack Overflow or respective owner

Related posts about google-app-engine

Related posts about multithreading