问题
I am trying to implement long polling, however after calling AsyncContext.complete() I get an exception from 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)
My Servlet looks as follows:
@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:
According to this JIRA, there's a bug in Weld 1.1.10 ( present in Tomcat 7.0.23 and related JBoss servers) that causes the Async servlet to lose context between requests to the same servlet.
Upgrading either your Weld or JBoss versions resolves the issue
来源:https://stackoverflow.com/questions/24258951/jee6-long-polling-webservlet-exception-after-calling-asynccontextcomplete