结合Resteasy async无法向CDI注入SessionScoped和RequestScoped bean

时间:2012-03-13 18:35:29

标签: java cdi resteasy interceptor

我正在处理与Reasteasy中的异步工作相关的问题(http://docs.jboss.org/resteasy/docs/2.3.1.GA/userguide/html_single/index.html#async_job_service).

我向url发布了一个请求添加?asynch = true,然后异步运行该作业,但是当它运行时,它可以与@ApplicationScoped或@Singleton注释bean一起正常工作,但它无法访问声明的类的bean @RequestScoped注释,我总是遇到这个错误:

org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.RequestScoped
    at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:664)
    at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:77)
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:87)
    at com.examplecompany.exampleproject.multitenancy.org$jboss$weld$bean-flat-ManagedBean-class_com$examplecompany$exampleproject$multitenancy$PersistenceContext_$$WeldClientProxy.setDb(org$jboss$weld$bean-flat-ManagedBean-class_com$examplecompany$exampleproject$multitenancy$PersistenceContext$$_WeldClientProxy.java)
    at com.examplecompany.exampleproject.auth.oauth.secure.OAuthDelegate.filterHttp(OAuthDelegate.java:115)
    at com.examplecompany.exampleproject.auth.oauth.secure.AuthorizationInterceptor.preProcess(AuthorizationInterceptor.java:59)
    at com.examplecompany.exampleproject.auth.oauth.secure.org$jboss$weld$bean-flat-ManagedBean-com$examplecompany$exampleproject$auth$oauth$secure$AuthorizationInterceptor$@javax$enterprise$context$ApplicationScoped()@javax$ws$rs$ext$Provider()@org$jboss$resteasy$annotations$interception$SecurityPrecedence()@org$jboss$resteasy$annotations$interception$ServerInterceptor()${com$examplecompany$exampleproject$auth$oauth$secure$AuthorizationInterceptor$oauthDelegate$@javax$inject$Inject()$$}_$$_WeldClientProxy.preProcess(org$jboss$weld$bean-flat-ManagedBean-com$examplecompany$exampleproject$auth$oauth$secure$AuthorizationInterceptor$@javax$enterprise$context$ApplicationScoped()@javax$ws$rs$ext$Provider()@org$jboss$resteasy$annotations$interception$SecurityPrecedence()@org$jboss$resteasy$annotations$interception$ServerInterceptor()${com$examplecompany$exampleproject$auth$oauth$secure$AuthorizationInterceptor$oauthDelegate$@javax$inject$Inject()$$}_$$_WeldClientProxy.java)
    at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:247)
    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:222)
    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:211)
    at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:525)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:502)
    at org.jboss.resteasy.core.AsynchronousDispatcher.invokeSuper(AsynchronousDispatcher.java:227)
    at org.jboss.resteasy.core.AsynchronousDispatcher$1.call(AsynchronousDispatcher.java:267)
    at org.jboss.resteasy.core.AsynchronousDispatcher$1.call(AsynchronousDispatcher.java:259)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)

如果我发布相同的请求而不添加?asynch = true。

,则不会发生此错误

我进一步调查了这个问题,并在我的代码中写了以下几行

try {
    Context context = beanManager.getContext(RequestScoped.class);
} catch (ContextNotActiveException e) {
    logger.info("Oops the context does not exists, we are in bad sh*t",e);
}

如果我处于异步模式,则始终抛出ContextNotActiveException,并且日志具有相同的异常消息WELD-001303 No active contexts for scope type javax.enterprise.context.RequestScoped

所以我想当任务启动异步模式时,不会创建两个上下文Session和Request,因此我在这些范围内定义的bean是不可访问的。

我为Resteasy Jira提出了一张票:https://issues.jboss.org/browse/RESTEASY-682

1 个答案:

答案 0 :(得分:0)

根据规范第6.7.2节,SessionScope不适用于Web服务请求。您将不得不创建一个新的持久范围并使用它。 Web服务调用(JAXRS或JAXWS)和会话的问题在于无法保证从一个请求跟踪会话到下一个请求。客户不需要发回cookie或使用请求参数。如果您的服务需要并强制执行此操作,则您必须创建新的作用域和上下文支持,或使用CDI实现的API手动启动并绑定到会话作用域。