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,你能忍?

相关文章
相关标签/搜索