ContextNotActiveException при вызове @Asynchronous метод @Stateless bean
Я вставляю a @Stateless
bean в асинхронный сервлет и вызывая метод @Asynchronous
из Serrvlet. В журналах сервера jboss я не могу видеть какое-либо из Исключений, но когда я запускаю Java Mission Control, Flight Recorder, я могу видеть ContextNotActiveExcetion
, когда Servlet делает вызов метода @Asyncrhonous
.
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();
}
}
трассировка стека, которую я могу видеть в полете 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)
Я проходил много сообщений, но проблема осталась прежней, пожалуйста, помогите мне.
Ответы
Ответ 1
Исключение не влияет на функциональность; он обрабатывался под капотом.
ContextNotActiveExcetion
применяется к @RequestScoped
beans. Вы начинаете двойную асинхронную обработку с помощью AsyncContext.start
и вызова @Asynchronous
EJB.
Исключением, которое вы видите в полете, является проверка, активен ли контекст по умолчанию RequestScoped
и, если это так, действовать. Если контекст RequestScoped
не активен, новый EjbRequestContext
активируется и ассоциируется с потоком.
Вы можете вызвать видимый ContextNotActiveExcetion
при создании @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();
}
}
Ответ 2
javadoc для AsyncContext.start:
Регистрирует данный AsyncListener с последним асинхронным цикл, который был инициирован вызовом одной из ServletRequest.startAsync(). Данный AsyncListener будет получить AsyncEvent, когда асинхронный цикл завершается успешно, время ожидания или приводит к ошибке.
Предположим, что к моменту, когда этот вызов
service.service(asyncContext);
Сделано, контекст httpservletrequest может быть недоступен, и запрос может быть даже выполнен, в результате CDI не сможет определить какой-либо "@RequestScoped" beans, используемый вашей службой.
Обратите внимание, что AsyncContext.start
регистрирует onEvent для вызова при завершении асинхронного вызова или при ошибке, а не при его запуске.
Возможно, вам захочется добавить прослушиватели, которые будут вызываться перед вызовом AsyncContext.start