Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.ClassCastException in Jetty when using Spring Session #3044

Closed
johanhaleby opened this issue Oct 31, 2018 · 9 comments
Closed

java.lang.ClassCastException in Jetty when using Spring Session #3044

johanhaleby opened this issue Oct 31, 2018 · 9 comments
Assignees

Comments

@johanhaleby
Copy link

johanhaleby commented Oct 31, 2018

I'm using Jetty 9.4.12 to which I deploy a Spring application using Spring Session with Redis. The application exposes a server-sent event (SSE) endpoint configured by Spring. But I seem to run into an issue when the javascript SSE client connection times out. I see the following log produced by Jetty:

[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

I.e. the cast made in SessionAsyncListener fails.

Is this a bug in Jetty? Is it correct to always assume that session is an instance of SessionIf? It doesn't seem to be the case for me at least.

For context I've also posted this as a question on Stackoverflow.

@joakime
Copy link
Contributor

joakime commented Oct 31, 2018

Do you have the complete stacktrace?

@johanhaleby
Copy link
Author

johanhaleby commented Nov 1, 2018

Jetty just logs the last line and I've struggled to change this but I've not yet succeeded. However I've managed to connect a debugger and calling exception.getStackTrace() gives me the following:

{java.lang.StackTraceElement[11]@17832} 
 0 = {java.lang.StackTraceElement@17833} "org.eclipse.jetty.server.session.SessionHandler.complete(SessionHandler.java:366)"
 1 = {java.lang.StackTraceElement@17834} "org.eclipse.jetty.server.session.SessionHandler$SessionAsyncListener.onComplete(SessionHandler.java:173)"
 2 = {java.lang.StackTraceElement@17835} "org.eclipse.jetty.server.HttpChannelState$4.run(HttpChannelState.java:889)"
 3 = {java.lang.StackTraceElement@17836} "org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1431)"
 4 = {java.lang.StackTraceElement@17837} "org.eclipse.jetty.server.HttpChannelState.runInContext(HttpChannelState.java:1116)"
 5 = {java.lang.StackTraceElement@17838} "org.eclipse.jetty.server.HttpChannelState.onComplete(HttpChannelState.java:905)"
 6 = {java.lang.StackTraceElement@17839} "org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:508)"
 7 = {java.lang.StackTraceElement@17840} "org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:305)"
 8 = {java.lang.StackTraceElement@17841} "org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)"
 9 = {java.lang.StackTraceElement@17842} "org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)"
 10 = {java.lang.StackTraceElement@17843} "java.lang.Thread.run(Thread.java:748)"

@gregw
Copy link
Contributor

gregw commented Nov 1, 2018

I think it is kind of strange and fragile to wrap the session object.... But obviously it is done. We can use our Request.getBaseRequest method to navigate to the unwrapped request and get the unwrapped session from it.

@johanhaleby
Copy link
Author

johanhaleby commented Nov 1, 2018

@gregw

Do you mean that instead of doing this?

complete(((HttpServletRequest)event.getAsyncContext().getRequest()).getSession(false));

we could do:

HttpSession session = ((HttpServletRequest)event.getAsyncContext().getRequest()).getSession(false)
complete(Request.getBaseRequest(session));

Or do you mean instead of the cast inside SessionHandler?

Btw, is this warning something that we could ignore for now? Or will this produce resource leaks or something that will accumulate over time?

@gregw
Copy link
Contributor

gregw commented Nov 1, 2018

I was thinking:

complete(Request.getBaseRequest(event.getAsyncContext().getRequest()).getSession(false));

Depending on what session store you are using, the warnings are probably not good and could mean that sessions are not being passivated correctly.

We have a release due this week... so @janbartel can you fix (assuming the fix is OK?) this before that?

janbartel added a commit that referenced this issue Nov 1, 2018
Signed-off-by: Jan Bartel <janb@webtide.com>
janbartel added a commit that referenced this issue Nov 1, 2018
Signed-off-by: Jan Bartel <janb@webtide.com>
janbartel added a commit that referenced this issue Nov 1, 2018
* Issue #3044 Use unwrapped session for SessionAsyncListener
@janbartel
Copy link
Contributor

Fixed for 9.4.13.

@joakime
Copy link
Contributor

joakime commented Nov 12, 2018

Jetty version 9.4.13.v20181111 is now available on Maven Central.

@johanhaleby
Copy link
Author

@joakime Awesome!

Thanks for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants