JEE6 Long Polling WebServlet - Exception after calling AsyncContext#complete

青春壹個敷衍的年華 提交于 2019-12-13 04:07:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!