Search code examples
javaspringserver-sent-eventsspring-sessionspring-data-redis

java.lang.ClassCastException in Jetty when using Spring Session with Redis in combination with SseEmitter


I'm using Jetty 9.4 (but I've tried 9.2 as well), spring-data-redis 1.8.6 and Spring 4.2. I'm essentially using the default configuration provided by org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration and everything seems to be working just fine until I add a Controller that has a endpoint that returns org.springframework.web.servlet.mvc.method.annotation.SseEmitter:

@RequestMapping(value = "sse", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<SseEmitter> sse() {
    SseEmitter emitter = new SseEmitter();
    emitter.onCompletion(..);
    emitter.onTimeout(..);

    storeEmitterInHashMap(emitter);

    return ResponseEntity.ok().header("Cache-Control", "no-store").body(emitter);
}

What seems to happen is that when there's a connection timeout to the SSE connection after 30s, Spring/Jetty tries to close a listener. But this fails due to a ClassCastException which is printed in the console:

[WARNING] java.lang.ClassCastException: 
    org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper 
    cannot be cast to org.eclipse.jetty.server.session.SessionHandler$SessionIf 
    while invoking onComplete listener
    org.eclipse.jetty.server.session.SessionHandler$SessionAsyncListener@67e50aa3

This happens roughly every 30s. If I navigate to another page which doesn't connect to the SSE endpoint the warning goes away.

Is this something to worry about? What is causing this? How can I fix it?


Solution

  • This was a bug in Jetty and fixed in version 9.4.13.v20181111.