Hessian#UnsafeDeserializer对象反序化后初始化的问题

Hessian#UnsafeDeserializer对象反序化后初始化的问题

场景

交易系统各子服务分批上线时出现交易失败的报警,log日志发现服务通信实例的Map类型的成员变量未被正确初始化NullpointerException异常,因为多个服务系统间使用hessian通信,各系统使用的业务数据对象版本不一致(如A服务版本是1.0.1调用B服务1.0.5版本)新添加的变量没有初始化,进而影响了业务服务。

原因分析

1.UnsafeDeSerializer使用Unsafe#allocateInstance创建一个类的实例,Unsafe的这个方法不会调用类实例的构造函数、初始化代码段。

计算机生成了可选文字:protected Object instantiate() throws Exception

2.UnsafeDeserializer使用远程传递的实例变量值对创建的实例对象进行赋值

计算机生成了可选文字:public Object readMap(AbstractHessianInput in, thro"S IOException try { int ref — in.addRef(obj); "hi le in. isEnd()) { Object key — in. readObject(); Object obi) FieldDeseriauzer deser — (FieldDeseriauzer) if (deser null) deser . deserialize(in, obi); else in . readObject() ; in . readMapEnd() ; Object resolve — resolve(in, obi); if (obj ! — resolve) in. setRef(ref, resolve); return resolve; } catch (IOException e) { throw e; } catch (Exception e) { thro" nevi IOExceptionWrapper(e); _fieIdMap . get(key) ;

3.FieldDeserializer使用sun.misc.Unsafe#pubObject负责对对象实例成员变量进行赋值。

计算机生成了可选文字:void deseriaIize(AbstractHessianInput in, Object obi) throws IOException Object value — null ; try { value — in. .getType()); _offset, value); } catch (Exception e) { ZogDeseriaZ obi, value, e);

 

对象版本不一致的情况一些成员变量在低版本没有定义,调用服务时传递过来的值对象不包含这个成员变量,所以赋值的时候也会跳过。最终这个新版本成员变量未初始化、未被赋值,业务应用场景如果没处理这种情况就会出现NullpointerException异常。

 

解决办法

1.覆盖readResolve让通信对象自己来进行初始化、对特定数据变量进行较验。

2.业务服务层解决,繁琐影响面太多,不规范。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值