问题场景:
团险契约质检问题件导入个险契约系统,个险提供jar包。其中有一个类在通过esb调用个险出现反序列化错误,报 java.io.InvalidClassException: local class incompatible: stream classdesc serialVersionUID = xxxx, local class serialVersionUID = yyyy。
问题排查:
1.这个类在升级之前没有显式指定serialVersionUID,在增加若干属性之后,升级Jar包,报serialVersionUID不一致,可能因为没有显式指定serialVersionUID,调用方和被调用方jdk版本或者eclipse和idea不一致,隐式自动生成的serialVersionUID不一致导致反序列化错误。
2.在类上新增显式指定serialVersionUID,升级jar包,调用方和被调用方引用的类的serialVersionUID一致还是报相同异常,问题没有得到解决。
3.排查是否存在缓存,有三种情况
a)调用方存在缓存
b)Esb存在缓存
c)被调用方存在缓存
首先异常信息是在被调用方方法头esb反序列化为入参时抛出,所以应该不是被调用方的程序存在缓存,异常信息提示:local class incompatible: stream classdesc serialVersionUID = xxxx, local class serialVersionUID = yyyy,xxx和调用方的类的serialVersionUID一致,所以不是调用方存在缓存,所以有可能是否esb存在缓存,不过经排查,esb不大可能存在缓存,此情况做最后一步考虑。
4.排查是否由于类路径不一样导致的反序列化失败,通过抽取类,排除不是该情况
5.由于异常提示中的local class serialVersionUID与类中的serialVersionUID不一致,所以异常还是出现在被调用方。
a)进入jenkins查看被调用方的构建版本,工程代码,工程代码确实是最新的代码,
但是,构建时的工作空间没有清空就构建,可能这里存在不干净的问题
b)清空工作空间构建,构建完毕,进入rancher更新,问题没有解决
6.考虑重新新建一个干净的镜像,重新部署一次,然而,就在准备重新构建的时候,进入rancher发现该系统的引用的镜像更新的时候竟然没有更改到最新的镜像!!!所以之前在Jenkins重新构建的版本完全没用,没有被引用。于是更换镜像,更新,测试,问题解决。
总结:
联调时出现问题首先要确定是谁出现的问题,确定哪里的问题后,出现跟预期修改情况不一致时,首先要确认是否真正的更新了,是否存在没有清除缓存的情况,重启等等。确认完毕之后没有解决的话,再去逐步深入代码排查问题,这样可以减少由于粗心带来的时间浪费。 关于序列化,一定要显式指定一个serialVersionUID