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

JdkMongoSessionConverter httpSession & spring-boot-devtools #733

Closed
heyarny opened this issue Feb 15, 2017 · 5 comments
Closed

JdkMongoSessionConverter httpSession & spring-boot-devtools #733

heyarny opened this issue Feb 15, 2017 · 5 comments
Assignees
Labels
for: stack-overflow A question that's better suited to stackoverflow.com

Comments

@heyarny
Copy link

heyarny commented Feb 15, 2017

I saw several issues here with the combination of JdkMongoSessionConverter de/serialization while devtools are in as dependencies, but all seem to be closed.
I'm facing the same problem with spring boot 1.5.1.RELEASE. As soon I remove devtools, everything is working fine.

I'm using this tiny lines to store sessions to mongo:

@EnableMongoHttpSession(collectionName = "httpSessions")
public class HttpSessionConfig {
	
	@Bean
    public JdkMongoSessionConverter jdkMongoSessionConverter() {
		return new JdkMongoSessionConverter();
    }
	
}

My session scoped data:

@Component("userSession")
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Foobar implements Serializable {

	private static final long serialVersionUID = 1L;
	
	private String name;
	
	public Foobar() {
		name = "foo";
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}

Now as long devtools is there, I get this exception apon second request (probably on deserialization).

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: com.xxx.model.Foobar cannot be cast to com.xxx.model.Foobar
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) ~[javax.servlet-api-3.1.0.jar:3.1.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) ~[javax.servlet-api-3.1.0.jar:3.1.0]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841) ~[jetty-servlet-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1634) ~[jetty-servlet-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:206) ~[websocket-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1621) ~[jetty-servlet-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:150) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) ~[spring-security-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1621) ~[jetty-servlet-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:167) ~[spring-session-1.3.0.RELEASE.jar:na]
	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) ~[spring-session-1.3.0.RELEASE.jar:na]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1621) ~[jetty-servlet-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1621) ~[jetty-servlet-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:541) ~[jetty-servlet-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) ~[jetty-security-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1584) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1228) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:481) ~[jetty-servlet-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1130) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:561) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.Server.handle(Server.java:564) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320) ~[jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) [jetty-server-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) [jetty-io-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112) [jetty-io-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) [jetty-io-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672) [jetty-util-9.4.1.v20170120.jar:9.4.1.v20170120]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590) [jetty-util-9.4.1.v20170120.jar:9.4.1.v20170120]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_112]
Caused by: java.lang.ClassCastException: com.xxx.model.Foobar cannot be cast to com.xxx.model.Foobar
	at com.xxx.model.Foobar$$FastClassBySpringCGLIB$$754e2bdb.invoke(<generated>) ~[classes/:na]
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656) ~[spring-aop-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at com.xxx.model.Foobar$$EnhancerBySpringCGLIB$$b6c69896.getName(<generated>) ~[classes/:na]
	at com.xxx.HelloController.hello(HelloController.java:33) ~[classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_112]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
	... 67 common frames omitted

Would appreciate any help.

@vpavic vpavic self-assigned this Feb 15, 2017
@vpavic
Copy link
Contributor

vpavic commented Feb 15, 2017

Thanks for the report @heyarny.

This is due to (de)serializing mechanism not being aware of Boot's restart class loader. We've had the similar situation with JDBC session repository - see #610 (and referenced issues for more background).

You config class that declares JdkMongoSessionConverter @Bean should implement BeanClassLoaderAware and then use injected class loader to create DeserializingConverter and subsequently JdkMongoSessionConverter using explicit serializer/deserializer. See JdbcHttpSessionConfiguration as an example.

@heyarny
Copy link
Author

heyarny commented Feb 15, 2017

Okay.. I'm new to spring boot, but I'll have a look.
Thank you @vpavic

@vpavic vpavic added the for: stack-overflow A question that's better suited to stackoverflow.com label Apr 13, 2017
@vpavic
Copy link
Contributor

vpavic commented Apr 13, 2017

Closing as answered. If you have additional questions or feel that your original question isn't properly answered, please re-open the issue.

@vpavic vpavic closed this as completed Apr 13, 2017
@heyarny
Copy link
Author

heyarny commented Apr 13, 2017

Was this issue fixed? I don't see any referenced pull?
As this is not just a question as you've marked, this is actually an issue, if you ask me.

Just like the JDBC issue was fixed, this should be fixed as well.
Getting exceptions when activating dev mode while mongodb session is enabled is not actually an desired behaviour.

@vpavic
Copy link
Contributor

vpavic commented Apr 13, 2017

@heyarny Situation with Mongo is different from one with JDBC where deserializing converters are used by default.

With Mongo, Jackson based serialization will be used by default if Jackson is present on the classpath, which will be the case with Spring Boot app. Since you're registering JdkMongoSessionConverter @Bean yourself you also need to take care to configure it with deserializing converter that is aware of classloader.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: stack-overflow A question that's better suited to stackoverflow.com
Projects
None yet
Development

No branches or pull requests

2 participants