正常打包项目正常,分离打包项目报空指针
2018-07-13 14:32:43,418[ERROR][http-nio-1314-exec-1] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/template].[dispatcherServlet][182] Servlet.service() for servlet [dispatcherServlet] in context with path [/template] threw exception [Request pro
cessing failed; nested exception is org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte ar
ray a result of corresponding serialization for DefaultDeserializer?; nested exception is org.springframework.core.NestedIOException: Failed to deserialize object type; nested exception is java.lang.ClassNotFoundException: site.yuyanjia.template.common.model.We
bUserDO] with root cause
java.lang.ClassNotFoundException: site.yuyanjia.template.common.model.WebUserDO
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[?:1.8.0_40]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_40]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[?:1.8.0_40]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_40]
at java.lang.Class.forName0(Native Method) ~[?:1.8.0_40]
at java.lang.Class.forName(Class.java:348) ~[?:1.8.0_40]
我碰到的问题是因为项目中用到了 redis的 JdkSerializationRedisSerializer
序列化
JdkSerializationRedisSerializer
使用的 ClassLoader不同导致找不到class
旧代码
/**
* redis模板
*
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate redisTemplateWithJdk(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(redisConnectionFactory);
stringRedisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
stringRedisTemplate.afterPropertiesSet();
return stringRedisTemplate;
}
新代码
/**
* redis模板
*
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate redisTemplateWithJdk(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(redisConnectionFactory);
/**
* SpringBoot扩展了ClassLoader,进行分离打包的时候,使用到JdkSerializationRedisSerializer的地方
* 会因为ClassLoader的不同导致加载不到Class
* 指定使用项目的ClassLoader
*
* JdkSerializationRedisSerializer默认使用{@link sun.misc.Launcher.AppClassLoader}
* SpringBoot默认使用{@link org.springframework.boot.loader.LaunchedURLClassLoader}
*/
ClassLoader classLoader = this.getClass().getClassLoader();
stringRedisTemplate.setValueSerializer(new JdkSerializationRedisSerializer(classLoader));
stringRedisTemplate.afterPropertiesSet();
return stringRedisTemplate;
}