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

我正在异步Servlet中注入一个bean,并从Serrvlet调用方法。在jboss的服务器日志中,我无法看到任何异常,但whhile启动Java任务控制,飞行记录器,我可以看到每当Servlet调用该方法时。@Stateless@AsynchronousContextNotActiveExcetion@Asyncrhonous

服务 ::

@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();
            }
        });
    }

服务等级 ::

@Stateless
public class Service {

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

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

      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)

我一直在浏览许多帖子,但问题仍然保持不变,请帮助我。


答案 1

javadoc for AsyncContext.start:

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

暗示到此调用时

service.service(asyncContext);

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

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

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


答案 2

该异常对功能没有影响;它在引擎盖下处理。

适用于豆类。启动双异步处理 和 EJB 调用。ContextNotActiveExcetion@RequestScopedAsyncContext.start@Asynchronous

您在飞行记录器中看到的例外情况是测试默认上下文是否处于活动状态并继续(如果是)。如果上下文未处于活动状态,则会激活一个新的上下文并将其与线程关联。RequestScopedRequestScopedEjbRequestContext

当您创建一个 Bean 并在您的ContextNotActiveExcetion@SessionScopedService

MySessionScoped.java

@SessionScoped
public class MySessionScoped implements Serializable {

    private int value;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

售后服务.java

@Stateless
public class Service {

    @Inject
    private MySessionScoped mySessionScoped;

    @Asynchronous
    public void service(final AsyncContext asyncContext) throws IOException {

        System.out.println(mySessionScoped.getValue());

        HttpServletResponse res = (HttpServletResponse) asyncContext.getResponse();
        res.setStatus(200);
        asyncContext.complete();
    }
}

推荐