Search code examples
jbossjettyatmosphere

no Atmosphere Handler found - Jetty Websocket Jboss


I'm trying to set up a project such as I have : - Jboss as main container web - a project call PWS which ran with jetty to support web socket in Jboss - Connecting with Web Socket to make the use of the Atmosphere framework.

My programmtic Jetty Server configuration :

JettyIntegration.java

public final class JettyIntegration implements ServletContextListener {

    private Server server;

    public void contextInitialized(ServletContextEvent sce) {
        String jbossWebHost;


        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        try {
            jbossWebHost = "localhost";
            // ObjectName http =
            // new ObjectName("jboss.as:socket-binding-group=standard" +
            // "-sockets,socket-binding=http");
            // jbossWebHost =
            // (String) mBeanServer.getAttribute(http, "boundAddress");
            // jbossWebPort = (Integer) mBeanServer.getAttribute(http,
            // "boundPort");

        } catch (Exception e) {
            throw new Error(e);
        }

        server = new Server();

        SelectChannelConnector connector = new SelectChannelConnector();
        connector.setHost(jbossWebHost);
        connector.setPort(8181);
        server.addConnector(connector);

        ContextHandlerCollection contexts = new ContextHandlerCollection();
        contexts.setHandlers(new Handler[] { createJerseyRestServletHandler() });

        server.setHandler(contexts);

        try {
            server.start();
        } catch (Exception e) {
            sce.getServletContext().log("An error occurred while starting Jetty", e);
        }
    }

    public void contextDestroyed(ServletContextEvent sce) {
        if (server != null) {
            try {
                server.stop();
            } catch (Exception e) {
                sce.getServletContext().log("An error occurred while shutting down Jetty", e);
            }
        }
    }

    private ServletContextHandler createJerseyRestServletHandler() {
        MeteorServlet servlet = new MeteorServlet();
        ServletHolder atmosphereServletHolder = new ServletHolder(servlet);

        // atmosphere
        atmosphereServletHolder.setInitParameter("org.atmosphere.useWebSocket", "true");
        atmosphereServletHolder.setInitParameter("WebSocketProtocol", "PWSHandler");
        atmosphereServletHolder.setInitParameter("org.atmosphere.cpr.atmosphereHandlerPath", "/WEB-INF/classes/com/sis/sante/centaure/pws/web");

        atmosphereServletHolder.setAsyncSupported(true);

        FilterHolder filterHolder = new FilterHolder(CrossOriginFilter.class);
        filterHolder.setInitParameter("allowedOrigins", "*");
        filterHolder.setInitParameter("allowedMethods", "GET, POST");

        ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        servletHandler.addServlet(atmosphereServletHolder, "/pws/*");
        servletHandler.addFilter(filterHolder, "/*", null);
        servletHandler.setInitParameter("org.atmosphere.cpr.atmosphereHandlerPath", "/WEB-INF/classes/com/sis/sante/centaure/pws/web");

        return servletHandler;
    }


}

PWSHandler.java

@WebSocketHandlerService(path = "/pws", broadcaster = SimpleBroadcaster.class)
public class PWSHandler extends WebSocketHandlerAdapter {

    private final ObjectMapper mapper = new ObjectMapper();

    @Override
    public void onOpen(WebSocket webSocket) {
        System.out.println("on Open");
        webSocket.resource().setBroadcaster(BroadcasterFactory.getDefault().lookup("/pws", true));
    }

    @Override
    public void onTextMessage(WebSocket webSocket, String data) {
        System.out.println("on Message");
        AtmosphereResource r = webSocket.resource();
        Broadcaster b = r.getBroadcaster();
        b.broadcast("test message" + data);
        //b.broadcast(mapper.writeValueAsString(mapper.readValue(message, Data.class)));
    }

}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>   
    <listener>
        <listener-class>com.sis.sante.centaure.pws.web.JettyIntegration</listener-class>
    </listener> 
</web-app>

When deployed under Jboss, I can connect in Web Socket as the atmosphere client respond: Using URL: ws://localhost:8181/pws?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=1.0&X-Atmosphere-Transport=websocket&X-Cache-Date=0&Content-Type=application/json jquery.atmosphere.js:2301 Websocket successfully opened

But the server throw me that log :

16:55:29,618 INFO  [org.eclipse.jetty.server.Server] (MSC service thread 1-5) jetty-8.1.2.v20120308
16:55:29,652 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Atmosphere is using org.atmosphere.cpr.DefaultAnnotationProcessor for processing annotation
16:55:29,655 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Auto detecting atmosphere handlers /WEB-INF/classes/com/sis/sante/centaure/pws/web
    16:55:29,656 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Auto detecting WebSocketHandler in /WEB-INF/classes/com/sis/sante/centaure/pws/web
    16:55:29,656 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Installed WebSocketProtocol org.atmosphere.websocket.protocol.SimpleHttpProtocol 
    16:55:29,667 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Atmosphere is using async support: org.atmosphere.container.JettyAsyncSupportWithWebSocket running under container: jetty/8.1.2.v20120308 with WebSocket enabled.
    16:55:29,668 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Installing Default AtmosphereInterceptor
    16:55:29,669 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5)    org.atmosphere.interceptor.JavaScriptProtocol : Atmosphere JavaScript Protocol
    16:55:29,670 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5)    org.atmosphere.interceptor.JSONPAtmosphereInterceptor : JSONP Interceptor Support
    16:55:29,671 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5)    org.atmosphere.interceptor.SSEAtmosphereInterceptor : SSE Interceptor Support
    16:55:29,672 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5)    org.atmosphere.interceptor.AndroidAtmosphereInterceptor : Android Interceptor Support
    16:55:29,673 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5)    org.atmosphere.interceptor.StreamingAtmosphereInterceptor : Streaming Interceptor Support
    16:55:29,675 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5)    org.atmosphere.interceptor.DefaultHeadersInterceptor : Default Response's Headers Interceptor
    16:55:29,675 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Installed Default AtmosphereInterceptor [Default Response's Headers Interceptor, Streaming Interceptor Support, Android Interceptor Support, SSE Interceptor Support, JSONP Interceptor Support, Atmosphere JavaScript Protocol]. Set org.atmosphere.cpr.AtmosphereInterceptor.disableDefaults in your xml to disable them.
    16:55:29,678 WARN  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) No BroadcasterCache configured. Broadcasted message between client reconnection will be LOST. It is recommended to configure the org.atmosphere.cache.EventCacheBroadcasterCache
    16:55:29,679 WARN  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Neither TrackMessageSizeInterceptor or TrackMessageSizeFilter are installed. atmosphere.js may receive glued and incomplete message.
    16:55:29,679 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) HttpSession supported: false
    16:55:29,680 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Using BroadcasterFactory: org.atmosphere.cpr.DefaultBroadcasterFactory
    16:55:29,680 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Using WebSocketProcessor: org.atmosphere.websocket.DefaultWebSocketProcessor
    16:55:29,681 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Using Broadcaster: org.atmosphere.cpr.DefaultBroadcaster
    16:55:29,682 INFO  [org.atmosphere.cpr.AtmosphereFramework] (MSC service thread 1-5) Atmosphere Framework 1.1.0.beta3 started.
    16:55:29,705 INFO  [org.eclipse.jetty.server.AbstractConnector] (MSC service thread 1-5) Started SelectChannelConnector@localhost:8181
    16:55:29,715 INFO  [org.jboss.web] (MSC service thread 1-5) JBAS018210: Registering web context: /pws
    16:55:29,798 INFO  [org.jboss.as.server] (HttpManagementService-threads - 17) JBAS018559: Deployed "pws.war"
    16:55:30,114 ERROR [org.atmosphere.cpr.AsynchronousProcessor] (qtp292954387-257) No AtmosphereHandler found. Make sure you define it inside WEB-INF/atmosphere.xml or annotate using @AtmosphereHandlerService
    16:55:30,115 WARN  [org.atmosphere.websocket.DefaultWebSocketProcessor] (qtp292954387-257) Failed invoking AtmosphereFramework.doCometSupport(): org.atmosphere.cpr.AtmosphereMappingException: No AtmosphereHandler found. Make sure you define it inside WEB-INF/atmosphere.xml or annotate using @AtmosphereHandlerService
        at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:188) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:165) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.container.JettyWebSocketUtil.doService(JettyWebSocketUtil.java:78) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.container.JettyAsyncSupportWithWebSocket.service(JettyAsyncSupportWithWebSocket.java:69) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1403) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:360) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.websocket.DefaultWebSocketProcessor.open(DefaultWebSocketProcessor.java:145) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.container.JettyWebSocketHandler.onOpen(JettyWebSocketHandler.java:106) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.eclipse.jetty.websocket.WebSocketConnectionRFC6455.onWebSocketOpen(WebSocketConnectionRFC6455.java:435) [jetty-websocket-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.websocket.WebSocketServletConnectionRFC6455.handshake(WebSocketServletConnectionRFC6455.java:57) [jetty-websocket-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:288) [jetty-websocket-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.websocket.WebSocketFactory.acceptWebSocket(WebSocketFactory.java:361) [jetty-websocket-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.atmosphere.container.JettyWebSocketUtil.doService(JettyWebSocketUtil.java:65) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.container.JettyAsyncSupportWithWebSocket.service(JettyAsyncSupportWithWebSocket.java:69) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1403) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.cpr.AtmosphereServlet.doPost(AtmosphereServlet.java:294) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at org.atmosphere.cpr.AtmosphereServlet.doGet(AtmosphereServlet.java:280) [atmosphere-runtime-1.1.0.beta3.jar:1.1.0.beta3]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:734) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:594) [jetty-servlet-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1366) [jetty-servlet-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.servlets.CrossOriginFilter.handle(CrossOriginFilter.java:212) [jetty-servlets-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.servlets.CrossOriginFilter.doFilter(CrossOriginFilter.java:179) [jetty-servlets-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1337) [jetty-servlet-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:484) [jetty-servlet-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1065) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:413) [jetty-servlet-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:999) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.Server.handle(Server.java:351) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:890) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:944) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:634) [jetty-http-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230) [jetty-http-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77) [jetty-server-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:609) [jetty-io-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:45) [jetty-io-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599) [jetty-util-8.1.2.v20120308.jar:8.1.2.v20120308]
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534) [jetty-util-8.1.2.v20120308.jar:8.1.2.v20120308]
        at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_07]

    16:55:30,130 WARN  [org.atmosphere.websocket.protocol.SimpleHttpProtocol] (qtp292954387-257) org.atmosphere.cpr.AtmosphereMappingException: No AtmosphereHandler found. Make sure you define it inside WEB-INF/atmosphere.xml or annotate using @AtmosphereHandlerService Status 500 Message Server Error

What could go wrong ?


Solution

  • Instead of trying with Jetty, install websockets to JBoss AS 7.2 / JBoss EAP 6.1.Alpha and you should be ok.

    Here are instructions, but according to my experiences, they're bit off (outdated). What you really need is 1. APR enabled, so switch

    <subsystem xmlns="urn:jboss:domain:web:1.1"
            default-virtual-server="default-host" native="true"> 
    

    to:

    <subsystem xmlns="urn:jboss:domain:web:1.1"
            default-virtual-server="default-host" native="true">
    

    in your web server configuration (domain.xml or standalone.xml), and 2. use maven dependency

    <dependency>
         <groupId>org.atmosphere.jboss.as</groupId>
         <artifactId>jboss-as-websockets</artifactId>
         <version>0.4</version>
    </dependency>
    

    That's it, then you should be good to go. Just extend org.atmosphere.jboss.as.websockets.servlet.WebSocketServlet in your app.

    Edit: for the interested, I have a simple example app source code in github.