#jakarta-ee #glassfish #servlet-3.0
#джакарта-ee #glassfish #сервлет-3.0
Вопрос:
Я пытаюсь реализовать длительный опрос, однако после вызова AsyncContext.complete() я получаю исключение из Weld:
Warnung: Error invoking requestDestroyed method on ServletRequestListener org.jboss.weld.servlet.WeldListener
java.lang.NullPointerException
at org.jboss.weld.context.AbstractBoundContext.deactivate(AbstractBoundContext.java:71)
at org.jboss.weld.context.http.HttpRequestContextImpl.deactivate(HttpRequestContextImpl.java:70)
at org.jboss.weld.servlet.WeldListener.requestDestroyed(WeldListener.java:154)
at org.apache.catalina.core.StandardContext.fireRequestDestroyedEvent(StandardContext.java:5261)
at org.apache.catalina.core.StandardHostValve.postInvoke(StandardHostValve.java:255)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:359)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
at java.lang.Thread.run(Thread.java:744)
Мой сервлет выглядит следующим образом:
@WebServlet(urlPatterns = {"/newmsg"}, asyncSupported = true)
public class NewMessageNotifierLongPolling extends HttpServlet {
private static final Queue<AsyncContext> peers = new ConcurrentLinkedQueue();
public void notifyClientsAboutNewMessage(@Observes Message msg) {
for (final AsyncContext ac : peers) {
try {
final ServletOutputStream os = ac.getResponse().getOutputStream();
os.println(msg.getSubject());
ac.complete();
} catch (IOException ex) {
Logger.getLogger(NewMessageNotifierLongPolling.class.getName()).log(Level.SEVERE, null, ex);
} finally {
peers.remove(ac);
}
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(MediaType.TEXT_PLAIN);
response.setStatus(202);
response.setHeader("Pragma", "no-cache");
response.setCharacterEncoding("UTF-8");
response.flushBuffer();
final AsyncContext ac = request.startAsync(request, response);
ac.setTimeout(35 * 1000);
ac.addListener(new AsyncListener() {
@Override
public void onComplete(AsyncEvent event) throws IOException {
peers.remove(ac);
}
@Override
public void onTimeout(AsyncEvent event) throws IOException {
peers.remove(ac);
}
@Override
public void onError(AsyncEvent event) throws IOException {
peers.remove(ac);
}
@Override
public void onStartAsync(AsyncEvent event) throws IOException {
}
});
peers.add(ac);
}
}
Комментарии:
1. Это может вас заинтересовать: issues.jboss.org/browse/WELD-1020
2. Спасибо, что указали на это.
3. Насколько я понимаю, вы ответили на вопрос, я с радостью приму его, если вы опубликуете его в качестве ответа.
4. Итак, вы обновили Weld или Jboss?
5. На данный момент я ничего не изменил, это ошибка в AS. Поскольку в настоящее время я разрабатываю только примеры приложений на основе JEE6 (отсюда и длинный опрос вместо WebSockets). Я просто переключился на JBoss КАК 7 на время.
Ответ №1:
Согласно этому JIRA, в Weld 1.1.10 есть ошибка (присутствующая в Tomcat 7.0.23 и связанных серверах JBoss), из-за которой асинхронный сервлет теряет контекст между запросами к одному и тому же сервлету.
Обновление версий Weld или JBoss устраняет проблему