Using Java Executor in AppEngine Raises AccessControlException

How do you get java.util.concurrent.Executor or CompletionService to work with Google AppEngine? Classes are officially a whitelist , but when you try to send asynchronous tasks, a security error occurs at runtime.

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

An exception:

java.security.AccessControlException: access denied (java.lang.RuntimePermission modifyThreadGroup) when java.security.AccessControlContext.checkPermission (AccessControlContext.java:323) in java.security.AccessController.checkPermission (AccessController.java.lang46) .SecurityManager.checkPermission (SecurityManager.java//32) in com.google.appengine.tools.development.DevAppServerFactory $ CustomSecurityManager.checkPermission (DevAppServerFactory.java:166) in com.google.appengine.tools.apperer.Deverver.Device (DevAppServerFactory.java:191) in java.lang.ThreadGroup.checkAccess (ThreadGroup.java:288) in java.lang.Thread.init (Thread.javahaps32) in java.lang.Thread. (Thread.javaPoint65) in java.util.concurrent.Executors $ DefaultThreadFactory.newThread (Executors.java//42) in java.util.concurrent.ThreadPoolExecutor.addThread (ThreadPoolExecutor.java:672) in java.util.concurrent. ThreadPoolExecutor.addIfUnderCorePoolSize (ThreadPoolExecutor.java:697) in java.util.concurrent.ThreadPoolExecutor.execute (ThreadPoolExecutor.java:652) in java.util.concurrent.Executors $ DelegatedExecutorService.exavaute .concurrent.ExecutorCompletionService.submit (ExecutorCompletionService.java:152)

This code works great when running on Tomcat or using the JVM command line. However, it is clamped in the Jetty AppEngine SDK container (used with the Eclipse plugin and the maven-gae plugin).

AppEngine was probably designed to not run potentially dangerous programs, so I could see that they completely disabled thread creation. However, why does Google allow you to create a class but not allow you to call methods on it? The whitelist java.util.concurrent is misleading.

Is there any other way to perform parallel / simultaneous / parallel tasks in GAE?

+4
source share
2 answers

Java App Engine Review Indicates

application cannot create threads

This is even more clearly indicated in their Java Servlet Environment docs.

Topics

A Java application cannot create a new java.lang.ThreadGroup or a new java.lang.Thread . These restrictions also apply to JRE classes that use streams. For example, an application cannot create a new java.util.concurrent.ThreadPoolExecutor or java.util.Timer . An application can perform operations against the current thread, for example Thread.currentThread().dumpStack() .

Perhaps the whitelist is that you can work with libraries that accept Executors , and you can provide your own Executor that does the work in the current thread.

You can try experimental Task Queues.

+11
source

You can start a thread in the context of the request

https://developers.google.com/appengine/docs/java/?csw=1#Java_The_sandbox

+1
source

Source: https://habr.com/ru/post/1307306/


All Articles