From cbd96999e03e4c16b0f06ef370412f6552b3cf2a Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Thu, 1 Sep 2016 20:52:03 +0200 Subject: [PATCH] JDBC uses Bean ClassLoader This commit addresses the issue with deserializing JDBC sessions in Spring Boot applications that use DevTools. Previously, such configuration would cause `ClassCastException` when deserializing JDBC sessions due to app class loader being used instead of restart class loader. Fixes gh-610 --- .../http/JdbcHttpSessionConfiguration.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/spring-session/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java b/spring-session/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java index 0c6513c..240749c 100644 --- a/spring-session/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java +++ b/spring-session/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java @@ -19,6 +19,7 @@ import java.util.Map; import javax.sql.DataSource; +import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; @@ -26,6 +27,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportAware; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.core.serializer.support.DeserializingConverter; +import org.springframework.core.serializer.support.SerializingConverter; import org.springframework.core.type.AnnotationMetadata; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; @@ -52,7 +56,7 @@ import org.springframework.util.StringUtils; @Configuration @EnableScheduling public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration - implements ImportAware { + implements BeanClassLoaderAware, ImportAware { private String tableName; @@ -66,6 +70,8 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration private ConversionService springSessionConversionService; + private ClassLoader classLoader; + @Bean public JdbcTemplate springSessionJdbcOperations(DataSource dataSource) { return new JdbcTemplate(dataSource); @@ -92,6 +98,14 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration else if (this.conversionService != null) { sessionRepository.setConversionService(this.conversionService); } + else if (this.classLoader != null) { + GenericConversionService conversionService = new GenericConversionService(); + conversionService.addConverter(Object.class, byte[].class, + new SerializingConverter()); + conversionService.addConverter(byte[].class, Object.class, + new DeserializingConverter(this.classLoader)); + sessionRepository.setConversionService(conversionService); + } return sessionRepository; } @@ -123,6 +137,16 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration return this.tableName; } + public void setBeanClassLoader(ClassLoader classLoader) { + try { + DeserializingConverter.class.getConstructor(ClassLoader.class); + } + catch (NoSuchMethodException e) { + return; + } + this.classLoader = classLoader; + } + public void setImportMetadata(AnnotationMetadata importMetadata) { Map enableAttrMap = importMetadata .getAnnotationAttributes(EnableJdbcHttpSession.class.getName());