Как вы получаете java.util.concurrent.Executor или CompletionService для работы с Google AppEngine? Все классы - officially white-listed, но при попытке отправки асинхронных задач возникает ошибка безопасности во время выполнения.Использование Java Executor on AppEngine вызывает 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.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?
Благодаря Стивен, который отвечает на мой вопрос. – Drew
Это уже не так. Теперь вы можете создавать потоки ограниченным образом. См. Https://developers.google.com/appengine/docs/java/?csw=1#threads –