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

时间:2015-04-18 18:25:33

标签: java java-ee asynchronous ejb stateless-session-bean

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

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

服务类::

@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)

我一直在浏览很多帖子,但问题仍然存在,请帮助我。

2 个答案:

答案 0 :(得分:1)

AsyncContext.start的javadoc:

  

使用最新的异步注册给定的AsyncListener   通过调用其中一个开始的循环   ServletRequest.startAsync()方法。给定的AsyncListener将   异步循环完成时接收AsyncEvent   成功,超时或导致错误。

暗示在此次调用时

  

service.service(asyncContext);

生成后,httpservletrequest“context”可能无法使用,甚至可能已提交请求,导致CDI无法确定您的服务使用的任何“@RequestScoped”bean。

请注意AsyncContext.start在异步调用完成时或错误时注册要调用的onEvent,而不是在启动时注册。

您可能希望在调用AsyncContext.start

之前添加要调用的侦听器

答案 1 :(得分:1)

该例外对功能没有影响;它是在引擎盖下处理的。

ContextNotActiveExcetion适用于@RequestScoped个bean。您可以使用AsyncContext.start@Asynchronous EJB调用启动双异步处理。

您在飞行记录仪中看到的例外情况是测试默认RequestScoped上下文是否处于活动状态并继续,如果是,则继续。如果RequestScoped上下文未处于活动状态,则会激活新的EjbRequestContext并与该线程关联。

当您创建ContextNotActiveExcetion bean并在@SessionScoped

中注入/访问该bean时,您可以生成可见的Service

MySessionScoped.java

@SessionScoped
public class MySessionScoped implements Serializable {

    private int value;

    public int getValue() {
        return value;
    }

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

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