SpringBoot SerializationUtils克隆(反序列化) 类加载器不一致问题(ClassCastException)

问题分析

在SpringBoot中使用 org.apache.commons.lang.SerializationUtils.clone 方法时,发现克隆出来的类强转对应类时发生类型不一致的错误,经过检测发现两个看似相同的类的类加载器不一致

场景

在这里插入图片描述

报错信息

java.lang.ClassCastException: com.tianqiauto.tis.pc.dingdanyupai.po.PrePoint cannot be cast to com.tianqiauto.tis.pc.dingdanyupai.po.PrePoint

检测信息

在这里插入图片描述

在这里插入图片描述

解决方法分析

既然发现类加载器不一致,那么需要找到类反序列化时的类加载器是如何指定得
在这里插入图片描述

深入SerializationUtils.clone方法时发现内部是通过jdk的反序列化类ObjectInputStream将字节码转为对象得
在这里插入图片描述

在这里插入图片描述

发现返回对象是由cons创建的,cons 是一个Constructor,那么需要判断cons是在哪里生成的,从而推断出类加载器的生成依据,而cons存在于ObjectStreamClass,进入ObjectStreamClass desc = readClassDesc(false);判断cons何时赋值
在这里插入图片描述

发现执行完desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));这段代码时,cons有值,进入initNonProxy方法中
在这里插入图片描述

发现最终指向Caches.localDescs一个map中
在这里插入图片描述

localDescs是一个全局静态变量,所以需要知道在什么地方添加值的
在这里插入图片描述

打断点debug发现在序列化的时候会new ObjectStreamClass(cl)并放在localDescs里,所以进入new ObjectStreamClass(cl)的方法里,找cons的来源
在这里插入图片描述

发现cons是由Class<?> cl生成,也就是说cons的类加载器信息是由Class<?> cl的类加载器决定的,反向查找cl的加载
在这里插入图片描述

发现cl的类加载信息由latestUserDefinedLoader(),查阅资料发现,latestUserDefinedLoader()会根据栈帧信息查找第一个非根类加载器或扩展类加载器,而SerializationUtils属于ApplicationClassLoader加载的范围,所以SerializationUtils.clone(point)返回的对象是由ApplicationClassLoader加载
在这里插入图片描述

解决方案

方案一(推荐)

SerializationUtils.clone中的方法复制到项目中

public class TestClassLoaderController {private static PrePoint point = new PrePoint();@GetMapping("/testClassLoader")public AjaxResult testClassLoader() {PrePoint deserialize = (PrePoint) cloneObject(point);return null;}private static Object cloneObject(PrePoint point) {ByteArrayOutputStream baos = new ByteArrayOutputStream(512);serialize(point, baos);byte[] bytes = baos.toByteArray();return deserialize(bytes);}public static Object deserialize(byte[] objectData) {if (objectData == null) {throw new IllegalArgumentException("The byte[] must not be null");}ByteArrayInputStream bais = new ByteArrayInputStream(objectData);return deserialize(bais);}public static Object deserialize(InputStream inputStream) {if (inputStream == null) {throw new IllegalArgumentException("The InputStream must not be null");}ObjectInputStream in = null;try {// stream closed in the finallyin = new ObjectInputStream(inputStream);return in.readObject();} catch (ClassNotFoundException ex) {throw new SerializationException(ex);} catch (IOException ex) {throw new SerializationException(ex);} finally {try {if (in != null) {in.close();}} catch (IOException ex) {// ignore close exception}}}public static void serialize(Serializable obj, OutputStream outputStream) {if (outputStream == null) {throw new IllegalArgumentException("The OutputStream must not be null");}ObjectOutputStream out = null;try {// stream closed in the finallyout = new ObjectOutputStream(outputStream);out.writeObject(obj);} catch (IOException ex) {throw new SerializationException(ex);} finally {try {if (out != null) {out.close();}} catch (IOException ex) {// ignore close exception}}}
}

方案二

关闭热加载

spring:devtools:restart:enabled: false

或者

@SpringBootApplication
public class SSMPApplication {public static void main(String[] args) {System.setProperty("spring.devtools.restart.enabled","false");SpringApplication.run(SSMPApplication.class);}
}

方案三

移除热加载的jar包

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
</dependency>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/124841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OSEK OS介绍(一)

目录 1.OSEK OS架构 2.OSEK Task Management 2.1 Basic task&#xff1a; 2.2 Extended task 2.3 任务状态机 2.4 任务优先级 3.调度策略 3.1 完全抢占策略 3.2 非抢占式调度 3.3 混合式调度 4. Application Mode OSEK&#xff0c;汽车电子开放式系统及其接口&#…

KT6368A蓝牙芯片的4脚也就是蓝牙天线脚对地短路了呢?是不是坏了

一、问题简介 KT6368A芯片的4脚&#xff0c;也就是蓝牙天线脚&#xff0c;万用表测量对地短路了呢&#xff1f;是不是芯片坏掉了&#xff0c;能不能重新寄样品给我。 详细说明 首先&#xff0c;芯片没有坏&#xff0c;遇到自己不懂的地方&#xff0c;不要轻易的去怀疑。 而是…

基于计算机视觉的 Transformer 研究进展

论文地址&#xff1a; https://kns.cnki.net/kcms/detail/11.2127.tp.20211129.1135.004.html 18页&#xff0c;74篇参考文献 目录 摘 要 1 Transformer 基本原理 1.1 编码器-解码器 1.2 自注意力 1.3 多头注意力 2 在计算机视觉领域的应用 2.1 图像分类 2.1.1 iGPT …

【kubernetes】Debian使用Kubeadm部署Kubernetes失败:Connection Refused

这篇文章也可以在我的博客中查看 今天废话不多说直接解决一个阴间问题 问题 在部署kubernetes后&#xff08;执行完kubeadm init后&#xff09;&#xff0c;执行任何kubectl命令&#xff0c;都会报以下错误&#xff1a; The connection to the server xxx.xxx.xxx.xxx:6443…

井下设备智能远程控制方案

井下设备智能远程控制方案 井下设备的智能远程控制是指通过网络技术和传感器设备&#xff0c;实现对井下设备进行数据监测、故障诊断和远程控制操作的方法。目前&#xff0c;随着物联网技术的发展&#xff0c;井下设备的智能化水平不断提高&#xff0c;但仍存在一些问题需要解…

无需更换vue-cli 脚手架 uniapp-搭建项目-H5-低版本安卓IOS兼容问题(白屏)(接口请求异常)

✨求关注~ &#x1f4bb;博客&#xff1a;www.protaos.com I. 简介 A. UniApp项目概述 B. 白屏和接口请求异常问题的背景 II. 白屏问题 A. 问题描述 1、uniapp 打包H5内嵌入APP内、低版本手机系统访问白屏问题 B. 问题根本原因 1、低版本手机系统 自带的webview内核不支持ES6语…

C++进阶语法——智能指针【学习笔记(五)】

文章目录 1、智能指针简介1.1 原始指针&#xff08;raw pointer&#xff09;的⼀些问题1.2 智能指针&#xff08;smart pointers&#xff09; 2、智能指针&#xff08;smart pointers&#xff09;——unique_ptr2.1 unique_ptr 的声明2.2 unique_ptr 的函数2.3 ⾃定义类型使⽤ …

0004net程序设计-抗疫物资

文章目录 **摘** **要**目 录系统设计开发环境 摘 要 近些年来&#xff0c;随着科技的飞速发展&#xff0c;互联网的普及逐渐延伸到各行各业中&#xff0c;给人们生活带来了十分的便利&#xff0c;抗疫物资管理系统利用计算机网络实现信息化管理&#xff0c;使整个抗疫物资管理…

Python小技巧分享

import模块 在Python经常使用import声明&#xff0c;以使用其他模块(也就是其它.py文件)中定义的对象。 1) 使用__name__ 当我们编写Python库模块的时候&#xff0c;我们往往运行一些测试语句。当这个程序作为库被import的时候&#xff0c;我们并不需要运行这些测试语句。一种…

leetcode_1339. 分裂二叉树的最大乘积

题目链接&#xff1a;1339. 分裂二叉树的最大乘积 DFS两次即可 #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MOD ((int)pow(10, 9) 7)static void post_order_traversal(struct TreeNode* node) {if (!node) {return;}post_order_traversal(node->left);post…

Linux下GPIO和看门狗应用编程

文章目录 GPIO应用编程看门狗应用编程 GPIO应用编程 应用层操控硬件可以通过操作这些硬件的设备文件来进行&#xff0c;设备文件是各种硬件设备向应用层提供的一个接口&#xff0c;应用层通过对设备文件的I/O操作来操控硬件设备。设备文件通常在/dev/目录下&#xff0c;该目录…

Yolo-Z:改进的YOLOv5用于小目标检测

目录 一、前言 二、背景 三、新思路 四、实验分析 论文地址&#xff1a;2112.11798.pdf (arxiv.org) 一、前言 随着自动驾驶汽车和自动驾驶赛车越来越受欢迎&#xff0c;对更快、更准确的检测器的需求也在增加。 虽然我们的肉眼几乎可以立即提取上下文信息&#xff0c;即…

延迟队列实现方案总结

日常开发中&#xff0c;可能会遇到一些延迟处理的消息任务&#xff0c;例如以下场景 ①订单支付超时未支付 ②考试时间结束试卷自动提交 ③身份证或其他验证信息超时未提交等场景。 ④用户申请退款&#xff0c;一天内没有响应默认自动退款等等。 如何处理这类任务&#xff0c;最…

Spring Security系例—漏洞防御

目录 一、在Maven中使用 1、Spring Boot 和 Maven 2、没有使用 Spring Boot 的 Maven 3、Maven 仓库&#xff08;Repository&#xff09; 二、文章系列 ​​​​​​​1、Spring Security漏洞防护—HTTP 安全响应头-CSDN博客 2、Spring Security —漏洞防护—跨站请求伪造…

【CSDN 每日一练 ★☆☆】【数组/数学】加一

【CSDN 每日一练 ★☆☆】【数组/数学】加一 数组 数学 题目 给定一个由 整数 组成的 非空 数组所表示的非负整数&#xff0c;在该数的基础上加一。 最高位数字存放在数组的首位&#xff0c; 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外&#xff0c;这个整…

elasticsearch存储数据压缩

一.前言 elk是流行的日志监控分析平台&#xff0c;但es占用存储空间过大&#xff0c;下面介绍几种压缩方案。 二.方案 1.禁用不需要的特性 不需要分词的字段&#xff0c;禁用text类型&#xff0c;使用keyword.&#xff08;我们所有字段都是keyword&#xff09; 2.使用更高…

MAC缓解WebUI提示词反推

当前环境信息&#xff1a; 在mac上安装好stable diffusion后&#xff0c;能做图片生成了之后&#xff0c;遇到一些图片需要做提示词反推&#xff0c;这个时候需要下载一个插件&#xff0c;参考&#xff1a; https://gitcode.net/ranting8323/stable-diffusion-webui-wd14-tagg…

虚拟机构建单体项目及前后端分离项目

引言 在现代化办公环境中&#xff0c;会议是组织沟通、决策和合作的重要方式之一。为了提高会议的效率和质量&#xff0c;许多企业选择部署会议OA系统来实现会议管理的自动化和数字化。本博客将介绍如何部署和优化会议OA系统&#xff0c;并探讨前后端分离的SPA项目在此过程中的…

66 内网安全-域横向批量atschtasksimpacket

目录 演示案例:横向渗透明文传递at&schtasks 案例2-横向渗透明文HASH传递atexec-impacket案例3-横向渗透明文HASH传递批量利用-综合案例5-探针主机域控架构服务操作演示 传递攻击是建立在明文和hash值的一个获取基础上的攻击&#xff0c;也是在内网里面常见协议的攻击&…

python pandas提取正无穷inf与负无穷-inf所在数据行/列

dataframe.replace([np.inf, -np.inf], np.nan,inplaceTrue) # 替换值然后再删除所在行&#xff1a; dataframe.dropna(inplaceTrue)或是删除所在列&#xff1a; dataframe.dropna(axis1,inplaceTrue)示例程序 import numpy as np import pandas as pddataframe.replace([np…