调用@Stateless bean的@Asynchronous方法时的ContextNotActiveException

Cha*_*ens 13 java asynchronous ejb stateless-session-bean java-ee

@Stateless在异步Servlet中注入一个bean并@Asynchronous从Serrvlet 调用方法.在jboss的服务器日志中,我无法看到任何异常但是在启动Java Mission Control时,我会看到ContextNotActiveExcetionServlet调用该@Asyncrhonous方法的时候.

Servlet ::

@WebServlet(urlPatterns = { "/asyncservice" }, asyncSupported = true)
public class AsyncServiceServlet extends HttpServlet {

@Inject
private Service service;

protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
        throws ServletException, IOException {
    final AsyncContext asyncContext = request.startAsync(request, response);
    asyncContext.start(new Runnable() {
        @Override
        public void run() {
            try {
                service.service(asyncContext);
            } catch (ContextNotActiveException | IOException e) {
                e.printStackTrace();
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

服务类::

@Stateless
public class Service {

@Asynchronous
public void service(final AsyncContext asyncContext) throws IOException {
    HttpServletResponse res = (HttpServletResponse) asyncContext.getResponse();
    res.setStatus(200);
    asyncContext.complete();
     }
}
Run Code Online (Sandbox Code Playgroud)

我可以在飞行记录器中看到的堆栈跟踪::

      java.lang.Throwable.<init>()  4
      java.lang.Exception.<init>()  4
      java.lang.RuntimeException.<init>()   4
      javax.enterprise.context.ContextException.<init>()    4
      javax.enterprise.context.ContextNotActiveException.<init>()   4
      org.jboss.weld.context.ContextNotActiveException.<init>(Enum,Object[])    4
      org.jboss.weld.manager.BeanManagerImpl.getContext(Class)  4
      org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(InterceptorContext)  4
     org.jboss.invocation.InterceptorContext.proceed()  4
        org.jboss.invocation.InitialInterceptor.processInvocation(InterceptorContext)   4
   org.jboss.invocation.InterceptorContext.proceed()    4
     org.jboss.invocation.ChainedInterceptor.processInvocation(InterceptorContext)  4
 org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(InterceptorContext)    4
    org.jboss.invocation.InterceptorContext.proceed()   4
      org.jboss.as.ejb3.component.pool.PooledInstanceInterceptor.processInvocation(InterceptorContext)  4
  org.jboss.invocation.InterceptorContext.proceed() 4
    org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(InterceptorContext,TransactionManager,EJBComponent) 4
    org.jboss.as.ejb3.tx.CMTTxInterceptor.required(InterceptorContext,EJBComponent,int) 4
  org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(InterceptorContext)
Run Code Online (Sandbox Code Playgroud)

我一直在经历很多帖子,但问题仍然存在,请帮助我.

mar*_*ess 1

AsyncContext.start 的 javadoc:

将给定的 AsyncListener 注册到通过调用 ServletRequest.startAsync() 方法之一启动的最近异步周期。当异步周期成功完成、超时或导致错误时,给定的 AsyncListener 将接收 AsyncEvent。

这意味着当这个电话

service.service(asyncContext);

完成后,httpservletrequest“上下文”可能不可用,并且请求甚至可能已提交,导致 CDI 无法确定您的服务使用的任何“@RequestScoped”bean。

请注意,AsyncContext.start注册一个 onEvent 以便在异步调用完成或出错时调用,而不是在异步调用开始时调用。

您可能希望在调用 AsyncContext.start 之前添加要调用的侦听器

  • 如果您附加更多堆栈跟踪,我们可以帮助找出 cdi 在哪个执行点失败。如果是在“service.service(asyncContext)”执行期间,那么 requestscoped 上下文很可能不再处于活动状态。 (2认同)