本文場景基於dubbo-2.5.3版本。git
若是你對StackOverflowError有必定的瞭解,就能夠知道出現這個問題的主要緣由就是調用棧太深,好比常見的無限遞歸調用。那本文要介紹的Dubbo拋出的這個StackOverflowError又是什麼緣由呢?且往下看。github
重現問題web
話很少說,直入主題。此次碰到的StackOverflowError很是好重現,只須要以下簡短的代碼便可。須要注意的是這裏調用的是com.alibaba.dubbo.common.json.JSON,而不是fastjson中的com.alibaba.fastjson.JSON:apache
Dubbo還有這樣的bug,你能忍?json
運行這段代碼能獲得以下異常:數組
Dubbo還有這樣的bug,你能忍?app
分析緣由ide
由這個異常堆棧信息,咱們很容易知道在GenericJSONConverter中的第73行和129行之間出現了無限遞歸調用,打開dubbo源碼並debug,發如今調用GenericJSONConverter中的writeValue()方法時,首先會判斷須要序列化的對象的類型。當對象是以下類型時會特殊處理:spa
原生類型或者封裝類型;debug
JSONNode類型;
枚舉;
數組;
Map;
集合類型;
若是須要序列化的對象是其餘類型,好比這裏的Locale類型,序列化邏輯以下所示:
Dubbo還有這樣的bug,你能忍?
經過這段源碼的分析,咱們大概能夠知道Locale的屬性中確定有Locale類型的屬性。因爲有Locale類型的屬性,致使繼續調用GenericJSONConverter中的writeValue()方法,從而無限遞歸下去,讓咱們繼續Debug源碼驗證這個猜測。
Debug到String pns[] = w.getPropertyNames();,咱們經過查看Locale的屬性pns[]能夠驗證咱們前面的猜測,以下圖所示。Locale屬性availableLocales的類型仍是Locale,從而出現死循環直到拋出StackOverflowError:
Dubbo還有這樣的bug,你能忍?
解決問題
那麼如何解決這個問題呢?很簡單,不要使用dubbo中的JSON,改成使用fastjson中的JSON,或者jackson和GSON均可以:
Dubbo Fix
筆者翻看dubbo issue歷史,發現dubbo在2018-05-09修復了這個問題,對應的dubbo版本是2.6.3,描述爲:add Locale serialize & deserialize support。pull地址以下:https://github.com/apache/dubbo/pull/1761/commits。
修復的代碼片斷以下所示,主要改動點有:
若是序列化對象是Locale類型,那麼序列化方式就是調用toString()方法;
若是反序列化目標對象類型是Locale,那麼將value如下劃線分割,而後構造Locale對象,用法參考:JSON.parse("zhCN", Locale.class);
Dubbo還有這樣的bug,你能忍?