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 就行
教訓:
請務必記得給需要序列化的類生成一個serialVersionUID,不然不知道什麼時候就會踢你一腳!