2010-04-19 32 views
4

如何讓java.util.concurrent.Executor或CompletionService在Google AppEngine上運行?這些類都是officially white-listed,但在嘗試提交異步任務時遇到運行時安全錯誤。在AppEngine上使用Java執行程序會導致AccessControlException

代碼:

// 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; 
    } 
} 

例外:

java.security.AccessControlException: 訪問在 java.security.AccessControlContext.checkPermission否認 (java.lang.RuntimePermission modifyThreadGroup)( AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) 在 java.lang.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 ) at java.lang.Thread。(Thread.java:565) at 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) 在 java.util.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可能設計爲不允許潛在危險的程序運行,所以我可以看到它們完全禁用線程創建。但是,爲什麼Google允許你創建一個類,但不允許你調用它的方法?白名單java.util.concurrent是誤導性的。

是否有其他方式可以在GAE上執行並行/同時/併發任務?

回答

11

App Engine Java Overview狀態

一個應用程序無法生成線程

這更清楚地在他們的文檔上The Java Servlet Environment

線程

一個Java聲明一個應用程序不能創建新的java.lang.ThreadGroup也不能創建新的java.lang.Thread。這些限制也適用於使用線程的JRE類。例如,應用程序無法創建新的java.util.concurrent.ThreadPoolExecutorjava.util.Timer。應用程序可以針對當前線程執行操作,例如Thread.currentThread().dumpStack()

也許白名單是爲了讓你可以接受Executors庫工作,你可以提供自己的Executor執行當前線程的工作。

你可以嘗試實驗Task Queues

+0

感謝斯蒂芬,這回答我的問題開始線程。 – Drew 2010-04-19 02:41:53

+2

這不再是事實。您現在可以以受限制的方式創建線程。請參閱https://developers.google.com/appengine/docs/java/?csw=1#threads – 2014-03-05 01:48:44

相關問題