2010-04-19 5 views
4

Comment faire fonctionner java.util.concurrent.Executor ou CompletionService sur Google AppEngine? Les classes sont toutes officially white-listed, mais j'obtiens une erreur de sécurité d'exécution lorsque j'essaie de soumettre des tâches asynchrones.L'utilisation de Java Executor sur AppEngine provoque AccessControlException

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

Exception:

java.security.AccessControlException: vu refuser l'accès (java.lang.RuntimePermission modifyThreadGroup) à java.security.AccessControlContext.checkPermission (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) au java.lang.Thread. (Thread.java:565) au 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)

Ce code fonctionne correctement lorsqu'il est exécuté sur Tomcat ou via une ligne de commande JVM. Cependant, il s'étouffe dans le conteneur AppEngine SDK Jetty (essayé avec le plugin Eclipse et le plugin maven-gae). AppEngine est probablement conçu pour ne pas autoriser l'exécution de programmes potentiellement dangereux, ce qui fait que je pourrais les voir complètement désactiver la création de threads. Cependant, pourquoi Google vous autoriserait-il à créer une classe, mais ne vous autoriserait pas à appeler des méthodes? La liste blanche java.util.concurrent est trompeuse.

Existe-t-il un autre moyen de réaliser des tâches parallèles/simultanées/simultanées sur GAE?

Répondre

11

Les App Engine Java Overview états

une application ne peut pas frayer fils

Ceci est encore plus clairement indiqué dans leurs documents sur The Java Servlet Environment

Threads

A Java une pplication ne peut pas créer un nouveau java.lang.ThreadGroup ni un nouveau java.lang.Thread. Ces restrictions s'appliquent également aux classes JRE qui utilisent des threads. Par exemple, une application ne peut pas créer un nouveau java.util.concurrent.ThreadPoolExecutor ou un java.util.Timer. Une application peut effectuer des opérations sur le thread en cours, par exemple Thread.currentThread().dumpStack().

Peut-être la liste blanche est pour que vous puissiez travailler avec les bibliothèques qui acceptent Executors, et vous pouvez fournir votre propre Executor qui effectue le travail dans le thread en cours.

Vous pouvez essayer le expérimental Task Queues

+0

Merci Stephen, qui répond à ma question. – Drew

+2

Ce n'est plus vrai. Vous pouvez maintenant créer des threads de manière contrainte. Voir https://developers.google.com/appengine/docs/java/?csw=1#threads –

Questions connexes