Как вы получаете 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;
}
}
Исключение:
java.security.AccessControlException:
доступ закрыт
(java.lang.RuntimePermission
modifyThreadGroup) в
java.security.AccessControlContext.checkPermission (AccessControlContext.java:323)
в
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)
в
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)
в
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?