天天看點

異常java.io.InvalidClassException Java對象反序列化失敗

java.io.InvalidClassException: com.xxx.yyy.bean.FlightComfortHistory; local class incompatible: stream classdesc serialVersionUID = -5421295868054627327, local class serialVersionUID = 4801854336781333672
        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:617) ~[na:1.7.0_45]
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1622) ~[na:1.7.0_45]
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517) ~[na:1.7.0_45]
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771) ~[na:1.7.0_45]
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350) ~[na:1.7.0_45]
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370) ~[na:1.7.0_45]
        at java.util.ArrayList.readObject(ArrayList.java:771) ~[na:1.7.0_45]
        at sun.reflect.GeneratedMethodAccessor75.invoke(Unknown Source) ~[na:na]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_45]
        at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_45]
--
        at com.xxx.yyy.service.RedisService.decompress(RedisService.java:200) ~[RedisService.class:na]
        at com.xxx.yyy.service.RedisService.getFlightComfortHistory(RedisService.java:66) ~[RedisService.class:na]
        at com.xxx.yyy.service.FlightComfortService.generateNationWithHistoryWithAv(FlightComfortService.java:482) ~[FlightComfortService.class:na]
        at com.xxx.yyy.service.FlightComfortService.access$000(FlightComfortService.java:66) ~[FlightComfortService.class:na]
        at com.xxx.yyy.service.FlightComfortService$GenerateNationComfortByHistoryTask.run(FlightComfortService.java:831) ~[FlightComfortService$GenerateNationComfortByHistoryTask.class:na]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_45]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_45]
        at java.lang.Thread.run(Thread.java:744) [na:1.7.0_45]
           

異常描述:

新代碼在FlightComfortHistory類中加了一個新字段,測試時候新資料存取都是沒問題的。

但是上線後發現,redis中的老資料反序列化時會報異常。

異常原因:

老版本代碼中,FlightComfortHistory這個類實作了Serializable接口,卻沒有指定serialVersionUID

序列化時該類的serialVersionUID是JVM根據類名及其屬性的哈希值生成的。

當類的屬性有變動時,serialVersionUID也會相應變動,進而導緻redis中的老資料反序列化為FlightComfortHistory對象時,serialVersionUID比對不上而失敗

異常解決:

1、如果不考慮新老資料相容問題,可以直接用IDEA給類自動生成一個serialVersionUID(光标放在類名上alter/option + enter)

2、如果考慮資料相容,找到老資料的serialVersionUID。

比如本次異常中,stream classdesc serialVersionUID = -5421295868054627327

就表示redis中現存的序列化對象的serialVersionUID為-5421295868054627327,我們隻要将該類的serialVersionUID手動設為-5421295868054627327L 就行

異常java.io.InvalidClassException Java對象反序列化失敗

教訓:

請務必記得給需要序列化的類生成一個serialVersionUID,不然不知道什麼時候就會踢你一腳!