与RxJava和AppEngine的线程问题

时间:2016-07-06 09:20:39

标签: google-app-engine rx-java

App Engine使用他们的方式来创建/处理踏板,为了使用RxScheduler,您需要实现自己的钩子,如this

我的问题仍然存在于使用rx-java 1.1.6的RxRingBuffer

java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
  at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
  at java.security.AccessController.checkPermission(AccessController.java:884)
  at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
  at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:445)
  at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkAccess(DevAppServerFactory.java:470)
  at java.lang.ThreadGroup.checkAccess(ThreadGroup.java:315)
  at java.lang.Thread.init(Thread.java:391)
  at java.lang.Thread.init(Thread.java:349)
  at java.lang.Thread.<init>(Thread.java:548)
  at rx.internal.util.RxThreadFactory.newThread(RxThreadFactory.java:39)
  at java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor.java:612)
  at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:925)
  at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1587)
  at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:334)
  at java.util.concurrent.ScheduledThreadPoolExecutor.scheduleAtFixedRate(ScheduledThreadPoolExecutor.java:573)
  at rx.internal.util.ObjectPool.start(ObjectPool.java:112)
  at rx.internal.util.ObjectPool.<init>(ObjectPool.java:59)
  at rx.internal.util.ObjectPool.<init>(ObjectPool.java:36)
  at rx.internal.util.RxRingBuffer$1.<init>(RxRingBuffer.java:280)
  at rx.internal.util.RxRingBuffer.<clinit>(RxRingBuffer.java:280)
  at rx.internal.operators.OperatorPublish$PublishSubscriber.<init>(OperatorPublish.java:248)
  at rx.internal.operators.OperatorPublish$1.call(OperatorPublish.java:60)
  at rx.internal.operators.OperatorPublish$1.call(OperatorPublish.java:49)
  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50)
  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50)
  at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
  at rx.Observable.subscribe(Observable.java:8759)
  at rx.Observable.subscribe(Observable.java:8726)
  at rx.Observable.subscribe(Observable.java:8549)

1 个答案:

答案 0 :(得分:2)

经过一番调查后发现问题是rx-java版本1.1.X,我们可以在GAE中使用rx-java 1.0.X,并在问题中详细说明钩子解决方案

所以我open an issue in rx-java

<强>更新

在rx-java 1.1.7之后,可以使用GAE的最后一个版本的rx,只需要在ContextListener中使用新的RxJavaHook而不是RxJavaPlugin.getInstance()。registerSchedulerHook()

public class RxServletContextListener implements ServletContextListener {

private static final ScheduledExecutorService THREAD_POOL_EXECUTOR = new ScheduledThreadPoolExecutor(10, ThreadManager.currentRequestThreadFactory());

@Override
public void contextInitialized(final ServletContextEvent servletContextEvent) {
    Scheduler gaeScheduler = Schedulers.from(THREAD_POOL_EXECUTOR);
    RxJavaHooks.onIOScheduler(gaeScheduler);
    RxJavaHooks.onComputationScheduler(gaeScheduler);
    RxJavaHooks.onNewThreadScheduler(gaeScheduler);
    RxJavaHooks.setOnGenericScheduledExecutorService(new Func0<ScheduledExecutorService>() {
        @Override
        public ScheduledExecutorService call() {
            return THREAD_POOL_EXECUTOR;
        }
    });
}

@Override
public void contextDestroyed(final ServletContextEvent servletContextEvent) {
    // App Engine does not currently invoke this method.
}

}