首页 > 其他 > 详细

对象反序列化出现类型不匹配的情况

时间:2018-12-04 12:52:47      阅读:274      评论:0      收藏:0      [点我收藏+]

目前在做springboot项目的shiro session redis共享功能。但是有一个对象我把它放到redis中之后再取出来就会出现类型不匹配的异常

AuthorizationUser user = (AuthorizationUser) cache.getSuper(key);

异常信息:

java.lang.ClassCastException: com.ch.evaluation.auth.shiro.entity.AuthorizationUser cannot be cast to com.ch.evaluation.auth.shiro.entity.AuthorizationUser

通过debug看到他们的类信息是一样的

技术分享图片

难道只是看起来一样么?我来判断一下

技术分享图片

结果是false ,我的天啊!!!!到底问题出在了那里呢???

明明类信息一样,但却匹配不上,问题到底出在了那里呢?

最终我发现,原来他们的类加载器不一样

技术分享图片

是什么原因导致他的类加载器不一样呢?

1.       JVM判断两个类对象是否相同的依据:一是类全称;一个是类加载器.(具体原理请自行百度,在此不再赘述)。

2.       大家都知道虚拟机的默认类加载机制是通过双亲委派实现的。springboot为了实现程序动态性(比如:代码热替换、模块热部署等,白话讲就是类文件修改后容器不重启),“破坏或牺牲” 了双亲委派模型。springboot通过强行干预-- “截获”了用户自定义类的加载(由jvm的加载器AppClassLoader变为springboot自定义的加载器RestartClassLoader,一旦发现类路径下有文件的修改,springboot中的spring-boot-devtools模块会立马丢弃原来的类文件及类加载器,重新生成新的类加载器来加载新的类文件,从而实现热部署。比较流行的OSGI也能实现热部署)。



既然源头因热部署而起,所以只要想办法关掉springboot的热部署即可。

<方案一>  通过卸掉springboot的热部署模块spring-boot-devtools来实现

在pom中注释掉springboot的spring-boot-devtools

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
 </dependency>

<方案二>如果不想卸掉spring-boot-devtools模块也可禁用部署功能

 
技术分享图片
 

读者也可以在application.properties设置禁用属性,但它的作用域只发生在当前模块,如果你的项目牵扯到多个模块,最好通过上面的方式在整个运行系统的级别禁用,以免出现多个模块之间实现类文件调用时类加载器不一致的问题。

<方案三>既然是类加载器的问题也可使用Spring的ConfigurableObjectInputStream配合Thread.currentThread().getContextClassLoader() 来使用。

 

对象反序列化出现类型不匹配的情况

原文:https://www.cnblogs.com/UncleWang001/p/10063172.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!