Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ContextNotActiveException while calling @Asynchronous method of @Stateless bean

I am injecting a @Stateless bean in a Asynchronous Servlet and calling @Asynchronous method from the Serrvlet. In the server logs of the jboss i am not able to see any of the Exception but whhile starting the Java Mission Control ,Flight Recorder i can see ContextNotActiveExcetion whenever Servlet makes a call to the @Asyncrhonous method.

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

Service class ::

@Stateless
public class Service {

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

the stack trace i can see in the flight Recorder ::

      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)

I have been going through many posts but still the issue remain the same, please help me out .

like image 359
Charles Stevens Avatar asked Apr 18 '15 18:04

Charles Stevens


2 Answers

javadoc for AsyncContext.start:

Registers the given AsyncListener with the most recent asynchronous cycle that was started by a call to one of the ServletRequest.startAsync() methods. The given AsyncListener will receive an AsyncEvent when the asynchronous cycle completes successfully, times out, or results in an error.

Implying that by the time this call to

service.service(asyncContext);

Is made, the httpservletrequest "context" may not be available and the request may even have been committed, resulting to CDI not being able to determine any '@RequestScoped' beans used by your service.

Note that AsyncContext.start registers an onEvent to be invoked when the async call is completed, or on error, not when it starts.

You would probably want to add listeners to be invoked before calling AsyncContext.start

like image 56
maress Avatar answered Oct 16 '22 19:10

maress


The exception has no effect on functionality; it's handled under the hood.

The ContextNotActiveExcetion applies to @RequestScoped beans. You start double async processing with AsyncContext.start and the @Asynchronous EJB call.

The exception you see within flight recorder is to test, whether the default RequestScoped context is active and to proceed, if so. If the RequestScoped context is not active, a new EjbRequestContext is activated and associated with the thread.

You can cause a visible ContextNotActiveExcetion when you create a @SessionScoped bean and inject/access that one within your 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();
    }
}
like image 31
mp911de Avatar answered Oct 16 '22 20:10

mp911de