2015-04-18 9 views
13

Sto iniettando un bean in un servlet Asynchronous e chiamando il metodo @Asynchronous da Serrvlet. Nei log del server di jboss non sono in grado di vedere nessuna eccezione, ma quando avvii Java Mission Control, Flight Recorder posso vedere ContextNotActiveExcetion ogni volta che Servlet effettua una chiamata al metodo @Asyncrhonous.ContextNotActiveException durante la chiamata al metodo @Asynchronous del bean @Stateless

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

classe Servizio ::

@Stateless 
public class Service { 

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

l'analisi dello stack posso vedere nel registratore di volo ::

 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) 

Vado attraverso molte post, ma il problema rimane lo stesso, ti prego di darmi una mano.

+0

è che l'intero stacktrace? Inoltre, come costruisci il progetto (Maven, Ant)? Sei sicuro che manchi qualche dipendenza? :) –

+0

Quale versione di JBoss AS? Impossibile riprodurre in WildFly 8.2. Funziona bene, quindi sembra proprio un bug nella versione di Weld, come usato nel tuo JBoss AS. Potrebbe anche essere utile eseguire l'aggiornamento a WildFly o almeno la versione di Weld utilizzata in WildFly 8.2. – BalusC

+0

Sto usando jboss eap 6.1, questo non produrrà alcun bug/eccezione in nessuno dei log del server o dell'output della console, ma se avvierai il controllo della missione Java e avvierai il java flight recorder puoi vedere ContextNotActiveException nel codice >> Exception. –

risposta

0

javadoc per AsyncContext.start:

Registri l'AsyncListener dato con il più recente asincrono ciclo che è stato avviato da una chiamata a uno dei metodi di ServletRequest.startAsync(). Il AsyncListener dato sarà ricevere un AsyncEvent quando il ciclo asincrono completa , si verifica un timeout o genera un errore.

implica che quando la presente chiamata a

service.service (asyncContext);

è fatto, il "contesto" HttpServletRequest potrebbe non essere disponibile e la richiesta può anche sono stati commessi, con conseguente a CDI non essere in grado di determinare eventuali fagioli '@RequestScoped' utilizzati dal servizio.

Si noti che AsyncContext.start registra un evento onEvent da richiamare quando la chiamata asincrona è completata, o in caso di errore, non all'avvio.

probabile che si vogliano aggiungere ascoltatori ad essere invocate prima di chiamare AsyncContext.start

+0

Lo snippet di codice sopra sta funzionando correttamente sono in grado di inviare una risposta dal metodo Service.service(), aysncContext è disponibile in Service.service() –

+2

Se si allega più stacktrace, potremmo aiutare a capire a che punto di esecuzione il cdi fallisce. Se durante l'esecuzione del '' 'service.service (asyncContext)' '' allora la probabilità che il contesto requestcoped non sia più attivo è altamente probabile. – maress

+0

Sì, come per lo stacktrace, l'eccezione si verifica alla chiamata service.service (asyncontext), e si r destra @maress come il contesto della richiesta non è attivo, ma non so come aggiungere manualmente il contesto della richiesta alla classe di servizio. –

1

L'eccezione non ha alcun effetto sulla funzionalità; è gestito sotto il cofano.

Il ContextNotActiveExcetion si applica ai fagioli @RequestScoped. Si avvia la doppia elaborazione asincrona con AsyncContext.start e la chiamata EJB @Asynchronous.

L'eccezione che si vede all'interno del registratore di volo è quella di verificare se il contesto predefinito RequestScoped è attivo e procedere, in tal caso. Se il contesto RequestScoped non è attivo, viene attivato un nuovo EjbRequestContext associato al thread.

Si può causare una visibile ContextNotActiveExcetion quando si crea un fagiolo @SessionScoped e iniettare/accesso che uno all'interno del vostro 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(); 
    } 
} 
+0

Un'ultima cosa: Ecco un esempio di elaborazione CDI, EJB e asincrono: https://github.com/wildfly/quickstart/tree/master/servlet-async/src/main/java/org/jboss/as/quickstarts/ servlet/async – mp911de

Problemi correlati