JEE6长轮询WebServlet - 调用AsyncContext#complete后的异常 [英] JEE6 Long Polling WebServlet - Exception after calling AsyncContext#complete

查看:144
本文介绍了JEE6长轮询WebServlet - 调用AsyncContext#complete后的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 我试图实现长轮询,但是在调用AsyncContext.complete()之后,我得到了一个来自Weld的异常: Warnung:在ServletRequestListener上调用requestDestroyed方法的错误org.jboss.weld.servlet.WeldListener 
java.lang.NullPointerException $ b $在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)
在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.serv ices.impl.ContainerMapper.service(ContainerMapper.java:188)
位于org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
位于org.glassfish.grizzly。 http.server.HttpHandler.doHandle(HttpHandler.java:168)
在org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
在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.T CPNIOTransport.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)

我的Servlet的外观如下:

  @WebServlet(urlPatterns = {/ newmsg},asyncSupported = true)
public class NewMessageNotifierLongPolling扩展HttpServlet {

p rivate 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);
}终于{
peers.remove(ac);



@Override
保护无效doGet(HttpServletRequest请求,HttpServletResponse响应)抛出ServletException,IOException {
响应。的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 $ b $ 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)抛出IOException {
}
});
peers.add(ac);



$ div $解析方案

这个JIRA ,Weld 1.1.10中存在一个错误(存在于Tomcat 7.0.23和相关的JBoss服务器),这会导致Async servlet在对同一个servlet的请求之间丢失上下文。



升级您的Weld或JBoss版本可解决问题。


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

解决方案

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

这篇关于JEE6长轮询WebServlet - 调用AsyncContext#complete后的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆