去年9月份時候fastjson出現過一個漏洞,須要升級到1.2.60,舊版本是1.2.12,測試環境驗證完畢後上線,上線幾分鐘瞬間幾百封報錯郵件,當時瞬間內心特緊張,可是表面上得裝着沒事,咱能搞定,哈哈,還好迅速定位並解決了問題。java
出問題模塊流程比較簡單,須要查詢一些數據,先從Redis查詢,沒有再查詢數據庫並把結果放到Redis中緩存。面試
報錯異常信息以下:sql
java.io.InvalidClassException: com.alibaba.fastjson.JSONObject; local class incompatible: stream classdesc serialVersionUID = -7894253080042154647, local class serialVersionUID = 1
複製代碼
看到報錯可能你已經明白了,反序列化時候版本不一致致使的問題,那麼問題是如何產生的呢?數據庫
Fastjson1.2.60源碼的JSONObject類裏有下面一行代碼:json
private static final long serialVersionUID = 1L;
複製代碼
而1.2.12版本源碼的JSONObject類裏沒有定義serialVersionUID。緩存
Java的序列化機制是經過判斷類的serialVersionUID來驗證版本一致性的,在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體類的serialVersionUID進行比較,若是相同就認爲是一致的,能夠進行反序列化,不然就會出現序列化版本不一致的異常bash
當實現java.io.Serializable接口的類沒有顯式地定義一個serialVersionUID變量時候,Java序列化機制會根據編譯的Class自動生成一個serialVersionUID做序列化版本比較用,這種狀況下,若是Class文件(類名,方法明等)沒有發生變化(增長空格,換行,增長註釋等等),就算再編譯屢次,serialVersionUID也不會變化的。微信
問題緣由找到了,系統返回實體裏存放了JSONObject的對象,系統上線後用戶訪問時候若是緩存有數據,就會出現反序列化版本不一致的狀況,致使出現異常。cookie
先說下個人方案,使用新版本的jar包,把設置緩存代碼裏key的前綴修改下,這樣就不會使用舊的緩存進行反序列化,問題解決。session
例如:
//原始代碼
@CacheEvict(value="RedisCache11",key="'user:test:'+#obj.id",beforeInvocation=true)
//修改後代碼
@CacheEvict(value="RedisCache11",key="'user:test2020:'+#obj.id",beforeInvocation=true)
複製代碼
以上是個人一種的解決方案,若是你有其餘的方案,歡迎留言溝通哦!
推薦閱讀
5.原創 | 我是如何解決POI解析Excel出現的OOM問題的?
若是以爲文章不錯,但願能夠隨手轉發或者」在看「哦,很是感謝哈!
關注下方公衆號後回覆「1024」,有驚喜哦!