Dubbo還有這樣的bug,你能忍?

本文場景基於dubbo-2.5.3版本。git

若是你對StackOverflowError有必定的瞭解,就能夠知道出現這個問題的主要緣由就是調用棧太深,好比常見的無限遞歸調用。那本文要介紹的Dubbo拋出的這個StackOverflowError又是什麼緣由呢?且往下看。github

重現問題web

話很少說,直入主題。此次碰到的StackOverflowError很是好重現,只須要以下簡短的代碼便可。須要注意的是這裏調用的是com.alibaba.dubbo.common.json.JSON,而不是fastjson中的com.alibaba.fastjson.JSONapache

webp

Dubbo還有這樣的bug,你能忍?json

運行這段代碼能獲得以下異常:數組

webp

Dubbo還有這樣的bug,你能忍?app

分析緣由ide

由這個異常堆棧信息,咱們很容易知道在GenericJSONConverter中的第73行和129行之間出現了無限遞歸調用,打開dubbo源碼並debug,發如今調用GenericJSONConverter中的writeValue()方法時,首先會判斷須要序列化的對象的類型。當對象是以下類型時會特殊處理:spa

  1. 原生類型或者封裝類型;debug

  2. JSONNode類型;

  3. 枚舉;

  4. 數組;

  5. Map;

  6. 集合類型;

若是須要序列化的對象是其餘類型,好比這裏的Locale類型,序列化邏輯以下所示:

webp

Dubbo還有這樣的bug,你能忍?

經過這段源碼的分析,咱們大概能夠知道Locale的屬性中確定有Locale類型的屬性。因爲有Locale類型的屬性,致使繼續調用GenericJSONConverter中的writeValue()方法,從而無限遞歸下去,讓咱們繼續Debug源碼驗證這個猜測。

Debug到String pns[] = w.getPropertyNames();,咱們經過查看Locale的屬性pns[]能夠驗證咱們前面的猜測,以下圖所示。Locale屬性availableLocales的類型仍是Locale,從而出現死循環直到拋出StackOverflowError:

webp

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

修復的代碼片斷以下所示,主要改動點有:

  1. 若是序列化對象是Locale類型,那麼序列化方式就是調用toString()方法;

  2. 若是反序列化目標對象類型是Locale,那麼將value如下劃線分割,而後構造Locale對象,用法參考:JSON.parse("zhCN", Locale.class);

webp

Dubbo還有這樣的bug,你能忍?

相關文章
相關標籤/搜索