Hessian#UnsafeDeserializer对象反序化后初始化的问题
场景
交易系统各子服务分批上线时出现交易失败的报警,log日志发现服务通信实例的Map类型的成员变量未被正确初始化NullpointerException异常,因为多个服务系统间使用hessian通信,各系统使用的业务数据对象版本不一致(如A服务版本是1.0.1调用B服务1.0.5版本)新添加的变量没有初始化,进而影响了业务服务。
原因分析
1.UnsafeDeSerializer使用Unsafe#allocateInstance创建一个类的实例,Unsafe的这个方法不会调用类实例的构造函数、初始化代码段。
2.UnsafeDeserializer使用远程传递的实例变量值对创建的实例对象进行赋值
3.FieldDeserializer使用sun.misc.Unsafe#pubObject负责对对象实例成员变量进行赋值。
对象版本不一致的情况一些成员变量在低版本没有定义,调用服务时传递过来的值对象不包含这个成员变量,所以赋值的时候也会跳过。最终这个新版本成员变量未初始化、未被赋值,业务应用场景如果没处理这种情况就会出现NullpointerException异常。
解决办法
1.覆盖readResolve让通信对象自己来进行初始化、对特定数据变量进行较验。
2.业务服务层解决,繁琐影响面太多,不规范。