ContextNotActiveException while calling @Asynchronous method of @Stateless bean
Asked Answered
P

2

13

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 .

Puissant answered 18/4, 2015 at 18:25 Comment(5)
Is that the whole stacktrace? Also, how do you build the project (Maven, Ant)? Are you sure there isn't some dependency missing? :)Ikeikebana
Which JBoss AS version? Can't reproduce in WildFly 8.2. Works just fine, so looks much like just a bug in Weld version as used in your JBoss AS. Might as well be worth upgrading to WildFly or at least the Weld version as used in WildFly 8.2.Showcase
I am using jboss eap 6.1, this will not produce any bug/exception in any of the server logs or console output, but if you will launch Java mission control and start java flight recorder you can see ContextNotActiveException in Code>>Exception .Puissant
Do you see the above stacktrace in the exceptions view in Flight Recorder? It might be that the Flight Recorder Exception events are created when an Exception is created, not when it's thrown, which could explain the difference between JFR and the log. Do you have an actual problem, or just the exception in JFR?Avert
I have the exception shown only in the JFR , and while executing the the flow i dont see any exception.Puissant
D
1

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

Determinism answered 21/4, 2015 at 10:19 Comment(3)
The above code snippet is working fine i am able to send response from Service.service() method, the aysncContext is available in Service.service()Puissant
If you attach more stacktrace, we could help to figure out at what point of execution the cdi fails. If its during the execution of the service.service(asyncContext) then the probability that the requestscoped context is no longer active is highly likely.Determinism
Yes as per the stacktrace the exception occurs at service.service(asyncontext) call,and you r right @Determinism as the request context is not active ,but dont know how to add the request context to service class manually.Puissant
E
1

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();
    }
}
Electroluminescence answered 27/5, 2015 at 8:43 Comment(1)
One more thing: Here's an example on CDI, EJB and async processing: github.com/wildfly/quickstart/tree/master/servlet-async/src/…Electroluminescence

© 2022 - 2024 — McMap. All rights reserved.