Question

I'm testing Atmosphere 2.1.3 using Grizzly 2.3.11. I've created a ManagedService(path="/chat"), but I get this error: 'No AtmosphereHandler maps request for /chat Status 500 Message Server Error'. If I change the path to ManagedService(path="/") it works. I've debugged a bit and it seems that org.atmosphere.cpr.AtmosphereRequest.getServletPath() returns null, so a default path "/" is used and that's the cause that makes my test work using ManagedService(path="/").

I'll appreciate your help because I need to use a path kinda ManagedService(path="/chat").

NOTE: this post is related to Atmosphere + Grizzly: No AtmosphereHandler maps request for /chat Status 500 Message Server Error

PD: This is my Main test class:

package com.dweb.atmosphere.grizzly;

import java.io.IOException;
import org.atmosphere.container.Grizzly2CometSupport;
import org.atmosphere.cpr.AtmosphereServlet;
import org.glassfish.grizzly.comet.CometAddOn;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.http.server.NetworkListener;
import org.glassfish.grizzly.http.server.StaticHttpHandler;
import org.glassfish.grizzly.servlet.ServletRegistration;
import org.glassfish.grizzly.servlet.WebappContext;
import org.glassfish.grizzly.websockets.WebSocketAddOn;

public class Main {

    public static void main(String[] args) throws IOException {

        final HttpServer server = HttpServer.createSimpleServer(".", 8181);

        final WebappContext ctx = new WebappContext("ctx", "/");

        // enable web socket support
        final WebSocketAddOn addon = new WebSocketAddOn();

        for (NetworkListener listener : server.getListeners()) {
            listener.registerAddOn(addon);
        }

        // add atmosphere servlet support
        final AtmosphereServlet atmosphereServlet = new AtmosphereServlet();.

        final ServletRegistration atmosphereServletRegistration = ctx.addServlet("AtmosphereServlet", atmosphereServlet);

        atmosphereServletRegistration.setInitParameter(
                "org.atmosphere.websocket.messageContentType",
                "application/json");
        atmosphereServletRegistration.addMapping("/chat/*");
        atmosphereServletRegistration.setLoadOnStartup(1);

        // deploy
        ctx.deploy(server);

        try {
            server.start();
            System.out.println("Press enter to stop the server...");
            System.in.read();
        } finally {
            server.shutdownNow();
        }  
    }
}

PD2: This is my ChatRoom test class:

package com.dweb.atmosphere.grizzly;

import static org.atmosphere.cpr.ApplicationConfig.MAX_INACTIVE;
import java.io.IOException;
import org.atmosphere.config.service.Disconnect;
import org.atmosphere.config.service.Get;
import org.atmosphere.config.service.ManagedService;
import org.atmosphere.config.service.Ready;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Simple annotated class that demonstrate the power of Atmosphere. This class supports all transports, support
 * message length garantee, heart beat, message cache thanks to the {@link ManagedService}.
 */
@Config
@ManagedService(path = "/chat", atmosphereConfig = MAX_INACTIVE + "=120000")
public class ChatRoom {
    private final Logger logger = LoggerFactory.getLogger(ChatRoom.class);

    /**
     * Invoked when the connection as been fully established and suspended, e.g ready for receiving messages.
     *
     * @param r
     */
    @Ready
    public void onReady(final AtmosphereResource r) {
        logger.debug("Browser {} connected.", r.uuid());
    }

    /**
     * Invoked when the client disconnect or when an unexpected closing of the underlying connection happens.
     *
     * @param event
     */
    @Disconnect
    public void onDisconnect(AtmosphereResourceEvent event) {
        if (event.isCancelled()) {
            logger.info("Browser {} unexpectedly disconnected", event.getResource().uuid());
        } else if (event.isClosedByClient()) {
            logger.info("Browser {} closed the connection", event.getResource().uuid());
        }
    }

    /**
     * Simple annotated class that demonstrate how {@link org.atmosphere.config.managed.Encoder} and {@link org.atmosphere.config.managed.Decoder
     * can be used.
     *
     * @param message an instance of {@link Message}
     * @return
     * @throws IOException
     */
    @org.atmosphere.config.service.Message
    public String onMessage(String message) throws IOException {
        logger.info("just send() {}", message);
        return message;
    }

}

PD3: this is my server log

Apr 23, 2014 2:16:46 PM org.glassfish.grizzly.servlet.WebappContext deploy
INFO: Starting application [ctx] ...
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Atmosphere is using org.atmosphere.cpr.DefaultAnnotationProcessor for processing annotation
[main] INFO org.atmosphere.cpr.DefaultAnnotationProcessor - AnnotationProcessor class org.atmosphere.cpr.DefaultAnnotationProcessor$BytecodeBasedAnnotationProcessor being used
[main] INFO org.atmosphere.cpr.DefaultAnnotationProcessor - Found Annotation in com.dweb.atmosphere.grizzly.ChatAtmosphereHandler being scanned: interface org.atmosphere.config.service.AtmosphereHandlerService
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereHandler com.dweb.atmosphere.grizzly.ChatAtmosphereHandler mapped to context-path /chat2 and Broadcaster Class org.atmosphere.cpr.DefaultBroadcaster
[main] INFO org.atmosphere.cpr.DefaultAnnotationProcessor - Found Annotation in com.dweb.atmosphere.grizzly.ChatRoom being scanned: interface org.atmosphere.config.service.ManagedService
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereHandler org.atmosphere.config.managed.ManagedAtmosphereHandler mapped to context-path /chat and Broadcaster Class org.atmosphere.cpr.DefaultBroadcaster
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor [@ManagedService Interceptor, Atmosphere LifeCycle,  Track Message Size Interceptor using |, UUID Tracking Interceptor] mapped to AtmosphereHandler org.atmosphere.config.managed.ManagedAtmosphereHandler
[main] INFO org.atmosphere.cpr.DefaultAnnotationProcessor - Found Annotation in com.dweb.atmosphere.grizzly.Chat being scanned: interface org.atmosphere.config.service.ManagedService
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereHandler org.atmosphere.config.managed.ManagedAtmosphereHandler mapped to context-path /chatzz and Broadcaster Class org.atmosphere.cpr.DefaultBroadcaster
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor [@ManagedService Interceptor, Atmosphere LifeCycle,  Track Message Size Interceptor using |, UUID Tracking Interceptor] mapped to AtmosphereHandler org.atmosphere.config.managed.ManagedAtmosphereHandler
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Auto detecting WebSocketHandler in /WEB-INF/classes/
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed WebSocketProtocol org.atmosphere.websocket.protocol.SimpleHttpProtocol 
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Installing Default AtmosphereInterceptor
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.CorsInterceptor : CORS Interceptor Support
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.CacheHeadersInterceptor : Default Response's Headers Interceptor
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.PaddingAtmosphereInterceptor : Browser Padding Interceptor Support
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.AndroidAtmosphereInterceptor : Android Interceptor Support
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.HeartbeatInterceptor : Heartbeat Interceptor Support
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.SSEAtmosphereInterceptor : SSE Interceptor Support
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.JSONPAtmosphereInterceptor : JSONP Interceptor Support
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.JavaScriptProtocol : Atmosphere JavaScript Protocol
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.WebSocketMessageSuspendInterceptor : org.atmosphere.interceptor.WebSocketMessageSuspendInterceptor
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.OnDisconnectInterceptor : Browser disconnection detection
[main] INFO org.atmosphere.cpr.AtmosphereFramework -    org.atmosphere.interceptor.IdleResourceInterceptor : org.atmosphere.interceptor.IdleResourceInterceptor
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Set org.atmosphere.cpr.AtmosphereInterceptor.disableDefaults to disable them.
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Using EndpointMapper class org.atmosphere.util.DefaultEndpointMapper
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Using BroadcasterCache: org.atmosphere.cache.UUIDBroadcasterCache
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Default Broadcaster Class: org.atmosphere.cpr.DefaultBroadcaster
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Broadcaster Polling Wait Time 100
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Shared ExecutorService supported: true
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Messaging Thread Pool Size: Unlimited
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Async I/O Thread Pool Size: 200
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Using BroadcasterFactory: org.atmosphere.cpr.DefaultBroadcasterFactory
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Using WebSocketProcessor: org.atmosphere.websocket.DefaultWebSocketProcessor
[main] INFO org.atmosphere.cpr.AtmosphereFramework - HttpSession supported: false
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Atmosphere is using DefaultAtmosphereObjectFactory for dependency injection and object creation
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Atmosphere is using async support: org.atmosphere.container.GlassFishServ30WebSocketSupport running under container: Grizzly 2.3.11 with WebSocket enabled.
[main] INFO org.atmosphere.cpr.AtmosphereFramework - Atmosphere Framework 2.1.3 started.
[main] INFO org.atmosphere.cpr.AtmosphereFramework - 

    For Atmosphere Framework Commercial Support, visit 
    http://www.async-io.org/ or send an email to support@async-io.org

Apr 23, 2014 2:16:46 PM org.glassfish.grizzly.servlet.WebappContext initServlets
INFO: [ctx] Servlet [org.atmosphere.cpr.AtmosphereServlet] registered for url pattern(s) [[/chat/*]].
Apr 23, 2014 2:16:46 PM org.glassfish.grizzly.servlet.WebappContext deploy
INFO: Application [ctx] is ready to service requests.  Root: [/].
Apr 23, 2014 2:16:46 PM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [0.0.0.0:8181]
Apr 23, 2014 2:16:46 PM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Press enter to stop the server...
[Thread-1] INFO org.atmosphere.cpr.AtmosphereFramework - Latest version of Atmosphere's JavaScript Client 2.1.5
[Grizzly(7) SelectorRunner] WARN org.atmosphere.websocket.DefaultWebSocketProcessor - Failed invoking AtmosphereFramework.doCometSupport()
org.atmosphere.cpr.AtmosphereMappingException: No AtmosphereHandler maps request for /chat
    at org.atmosphere.cpr.AsynchronousProcessor.map(AsynchronousProcessor.java:329)
    at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:133)
    at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:95)
    at org.atmosphere.container.GlassFishServ30WebSocketSupport.service(GlassFishServ30WebSocketSupport.java:60)
    at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1805)
    at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:432)
    at org.atmosphere.websocket.DefaultWebSocketProcessor.open(DefaultWebSocketProcessor.java:186)
    at org.atmosphere.container.GlassFishServ30WebSocketSupport$Grizzly2WebSocketApplication.onConnect(GlassFishServ30WebSocketSupport.java:144)
    at org.glassfish.grizzly.websockets.SimpleWebSocket.onConnect(SimpleWebSocket.java:135)
    at org.glassfish.grizzly.websockets.WebSocketEngine.upgrade(WebSocketEngine.java:185)
    at org.glassfish.grizzly.websockets.WebSocketEngine.upgrade(WebSocketEngine.java:143)
    at org.glassfish.grizzly.websockets.WebSocketFilter.doServerUpgrade(WebSocketFilter.java:104)
    at org.glassfish.grizzly.websockets.WebSocketFilter.handleServerHandshake(WebSocketFilter.java:87)
    at org.glassfish.grizzly.websockets.WebSocketFilter.handleHandshake(WebSocketFilter.java:68)
    at org.glassfish.grizzly.websockets.BaseWebSocketFilter.handleRead(BaseWebSocketFilter.java:197)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:291)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:209)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:137)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:115)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:550)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.SameThreadIOStrategy.executeIoEvent(SameThreadIOStrategy.java:103)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.executeIoEvent(AbstractIOStrategy.java:89)
    at org.glassfish.grizzly.nio.SelectorRunner.iterateKeyEvents(SelectorRunner.java:412)
    at org.glassfish.grizzly.nio.SelectorRunner.iterateKeys(SelectorRunner.java:381)
    at org.glassfish.grizzly.nio.SelectorRunner.doSelect(SelectorRunner.java:345)
    at org.glassfish.grizzly.nio.SelectorRunner.run(SelectorRunner.java:276)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
    at java.lang.Thread.run(Thread.java:744)
[Grizzly(7) SelectorRunner] WARN org.atmosphere.websocket.protocol.SimpleHttpProtocol - org.atmosphere.cpr.AtmosphereMappingException: No AtmosphereHandler maps request for /chat Status 500 Message Server Error

Hi Alexey,

I'm debugging this issue, these are my tests & results:

-. When I call 'http://localhost:8181/chat/a/b/c' internally this request is built: 'AtmosphereRequest{ contextPath= servletPath=/chat pathInfo=/a/b/c requestURI=/chat/a/b/c destroyable=true}' Well, Http Get requests seem to work fine.

-. When I call 'new WebSocket('ws://localhost:8181/chat/a/b/c')' internally this request is built 'AtmosphereRequest{ contextPath= servletPath=null pathInfo=null requestURI=/chat/a/b/c destroyable=true}' I think the problem (servletPath & pathInfo are null) only happens when I use websockets

I'm debbuging the method org.glassfish.grizzly.websockets.WebSocketEngine.upgrade(FilterChainContext ctx, HttpContent requestContent, Mapper mapper) and the param requestContent receives this value:

HttpRequestPacket (
   method=GET
   url=/chat/a/b/c
   query=null
   protocol=HTTP/1.1
   content-length=-1
   headers=[
      upgrade=websocket
      connection=Upgrade
      host=localhost:8181
      origin=http://localhost:8080
      pragma=no-cache
      cache-control=no-cache
      sec-websocket-key=3pRm4vKnwqvRO8G0/WUNBw==
      sec-websocket-version=13
      sec-websocket-extensions=permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
      user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36]
)

but at the end of my debugging session the method org.atmosphere.util.DefaultEndpointMapper.computePath(AtmosphereRequest req) receives the param req with this value: AtmosphereRequest{ contextPath= servletPath=null pathInfo=null requestURI=/chat/a/b/c destroyable=true}

Well I hope these tests have some value for you, anyway if you need more tests feel free to ask.

Was it helpful?

Solution

The issue was found and fixed in Grizzly 2.3.12.

https://java.net/jira/browse/GRIZZLY-1680 The code should work as it is.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top