在AppEngine上使用Java Executor会导致AccessControlException

Dre*_*rew 4 java google-app-engine multithreading

如何让java.util.concurrent.Executor或CompletionService在Google AppEngine上运行?这些类都正式列入白名单,但在尝试提交异步任务时遇到运行时安全性错误.

码:

    // 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

例外:

java.security.AccessControlException:在java.lang中的访问在java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)在java.security.AccessController.checkPermission(AccessController.java:546)拒绝(java.lang.RuntimePermission modifyThreadGroup) .SecurityManager.checkPermission(SecurityManager.java:532)在com.google.appengine.tools.development.DevAppServerFactory $ CustomSecurityManager.checkPermission(DevAppServerFactory.java:166)在com.google.appengine.tools.development.DevAppServerFactory $ CustomSecurityManager.checkAccess (DevAppServerFactory.java:191)在java.lang.ThreadGroup.checkAccess(ThreadGroup.java:288)在java.lang.Thread.init(Thread.java:332)在java.lang.Thread中.(Thread.java:565 )在java.util.concurrent.Executors $ DefaultThreadFactory.newThread(Executors.java:542)在java.util.concurrent.ThreadPoolExecutor.addThread(ThreadPoolExecutor.java:672)在java.util.concurrent.ThreadPoolExecutor.addIfUnderCorePoolSize(的ThreadPoolExecutor. java:697)at java.ut il.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:652)在java.util.concurrent.Executors $ DelegatedExecutorService.execute(Executors.java:590)在java.util.concurrent.ExecutorCompletionService.submit(ExecutorCompletionService.java:152)

在Tomcat上运行或通过命令行JVM运行时,此代码可以正常工作.但是,它在AppEngine SDK Jetty容器中窒息(尝试使用Eclipse插件和maven-gae-plugin).

AppEngine可能设计为不允许运行潜在危险的程序,因此我可以看到它们完全禁用线程创建.但是,谷歌为什么允许你创建一个类,但不允许你调用它的方法?白名单java.util.concurrent具有误导性.

还有其他方法可以在GAE上执行并行/同时/并发任务吗?

Ste*_*nne 11

App Engine的Java的概述状态

应用程序无法生成线程

在他们关于Java Servlet环境的文档中更清楚地说明了这一点

主题

Java应用程序无法创建新的java.lang.ThreadGroup或新的java.lang.Thread.这些限制也适用于使用线程的JRE类.例如,应用程序无法创建新的java.util.concurrent.ThreadPoolExecutor或a java.util.Timer.应用程序可以对当前线程执行操作,例如Thread.currentThread().dumpStack().

也许白名单是这样的,你可以使用接受的库,Executors你可以提供自己的Executor,在当前线程中执行工作.

您可以尝试实验性任务队列

  • 这不再是真的.您现在可以以受约束的方式创建线程.请参阅https://developers.google.com/appengine/docs/java/?csw=1#threads (2认同)