使用JBoss 6和CXF Continuation API的非阻塞Web服务端点

时间:2011-12-29 13:58:48

标签: java-ee jboss jax-ws cxf servlet-3.0

我目前正在尝试设置一个Web服务端点(在JBoss AS 6.1.0.FINAL环境中),以使客户端能够长时间轮询服务器端事件,而不会在服务器端阻塞侦听器线程。

由于似乎没有标准的解决方案,我发现这个blog post关于CXF延续(除了JBoss中的WS-Impl。)。

我可以将示例转换为JAX-WS

import javax.annotation.Resource;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.servlet.annotation.WebServlet;
import javax.xml.ws.BindingType;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import org.apache.cxf.continuations.Continuation;
import org.apache.cxf.continuations.ContinuationProvider;

@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
@WebServlet(asyncSupported = true, urlPatterns = "/LongpollWebservice")
@WebService(targetNamespace = "http://longpoll.edu/", name = "LongpollWebservice", serviceName = "LongpollWebservice", portName = "LongpollWebservice")
public class LongpollWebserviceImpl implements LongpollWebservice {

    @Resource
    WebServiceContext ctx;

    @Override
    @WebMethod
    public List<EventBase> getEvents(String topic, Date since) {
        final ContinuationProvider cp = (ContinuationProvider) ctx.getMessageContext().get(ContinuationProvider.class.getName());
        final Continuation c = cp.getContinuation();
        if (c.isNew()) {
            c.suspend(10000);
            return null;
        } else {
            return Collections.emptyList();
        }
    }
}

Continuation API来自

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-api</artifactId>
    <version>2.3.1</version>
    <scope>provided</scope>
</dependency>

这是一个简化的例子。 c.suspend(10000);的调用应将当前的servlet调用标记为State.SUSPENDED。十秒钟后,暂停应该超时,并且应该使用c.isNew() == false重新启动请求。 (在一个现实世界的例子中,Continuation可以传递给JMS-Listener Bean或有状态CDI-Eventlistener,并且一旦事件可用并且准备交付,事件调度程序将调用c.setObject(event); c.resume();

CXF拦截器链应该用SuspendedInvocationException中断正在执行的线程并重新安排webservice调用。 到目前为止,它在JBoss 6.1.0 FINAL上进行编译和部署。 wsdl完美交付。

BUT:当我从Webservice-Client调用getEvents()时,SuspendedInvocationException似乎没有被正确捕获。整个调用与以下堆栈跟踪崩溃:

14:39:59,578 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/longpoll-warfacade].[edu.hsos.dwe.wss.longpoll.warfacade.LongpollWebserviceImpl]] Servlet.service() for servlet edu.hsos.dwe.wss.longpoll.warfacade.LongpollWebserviceImpl threw exception: org.apache.cxf.continuations.SuspendedInvocationException
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:258) [:2.3.1-patch-01]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:113) [:2.3.1-patch-01]
at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:97) [:2.3.1-patch-01]
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:461) [:2.3.1-patch-01]
at org.jboss.wsf.stack.cxf.ServletControllerExt.invoke(ServletControllerExt.java:172) [:3.4.1.GA]
at org.jboss.wsf.stack.cxf.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:57) [:3.4.1.GA]
at org.jboss.wsf.stack.cxf.transport.ServletHelper.callRequestHandler(ServletHelper.java:156) [:3.4.1.GA]
at org.jboss.wsf.stack.cxf.CXFNonSpringServletExt.invoke(CXFNonSpringServletExt.java:90) [:3.4.1.GA]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179) [:2.3.1-patch-01]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:103) [:2.3.1-patch-01]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [:1.0.0.Final]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159) [:2.3.1-patch-01]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:324) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at org.jboss.resteasy.plugins.server.servlet.FilterDispatcher.doFilter(FilterDispatcher.java:63) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [:6.1.0.Final]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [:6.1.0.Final]
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:181) [:6.1.0.Final]
at org.jboss.modcluster.catalina.CatalinaContext$RequestListenerValve.event(CatalinaContext.java:285) [:1.1.0.Final]
at org.jboss.modcluster.catalina.CatalinaContext$RequestListenerValve.invoke(CatalinaContext.java:261) [:1.1.0.Final]
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:88) [:6.1.0.Final]
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:100) [:6.1.0.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159) [:6.1.0.Final]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [:6.1.0.Final]
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158) [:6.1.0.Final]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [:6.1.0.Final]
at org.jboss.web.tomcat.service.request.ActiveRequestResponseCacheValve.invoke(ActiveRequestResponseCacheValve.java:53) [:6.1.0.Final]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362) [:6.1.0.Final]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [:6.1.0.Final]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:654) [:6.1.0.Final]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:951) [:6.1.0.Final]
at java.lang.Thread.run(Thread.java:619) [:1.6.0_18]

所以最后我的问题是:有没有人有CXF Continuation和WS的经验,并且可以给我一个暗示这次尝试可能出错的原因?

我真的不明白为什么在PhaseInterceptorChain.doIntercept中重新抛出异常。

亲切的问候, avithan

1 个答案:

答案 0 :(得分:0)

解决:

  1. 将CXF 2.3.4安装到jboss / common / lib(我们需要修复此问题:https://issues.apache.org/jira/browse/CXF-3362)。

  2. JBossWS-CXF无法捕获SuspendedInvocationException。这似乎只是在jbossws-cxf-server中遗漏了。我在https://issues.jboss.org/browse/JBWS-3409提交了一个问题。附加的补丁可以很容易地应用于jbossws-cxf-3.4.1.GA(模块jbossws-cxf-server)的结账,并使用mvn package重新编译。

  3. 亲切的问候