zoukankan      html  css  js  c++  java
  • 对象反序列化出现类型不匹配的情况(spring-boot-devtools)

    目前在做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 ,

    那么我们知道JVM判断两个类对象是否相同的依据:一是类全称;一个是类加载器

    既然他俩的类全称一样,那么问题肯定就出在了类加载器上了

    我们可以Debug看一下他俩的类加载器

    果然不出所料,他俩的类加载器是不同的!

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

      大家都知道虚拟机的默认类加载机制是通过双亲委派实现的。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() 来使用。
    
    
  • 相关阅读:
    变长参数表
    以二进制方式输出数字在内存中的存储形式
    asp.net mvc controller 获取数据
    asp.net mvc 3.0 新特性之 Model
    一个实体对象不能由多个 IEntityChangeTracker 实例引用
    iis6.0运行asp请求资源正在使用中
    view的使用
    asp.net mvc RenderAction 和RenderPartial用法
    今天
    当下的力量
  • 原文地址:https://www.cnblogs.com/UncleWang001/p/10063172.html
Copyright © 2011-2022 走看看