Dubbo还有这样的bug,你能忍?
本文场景基于dubbo-2.5.3版本。
如果你对StackOverflowError有一定的了解,就可以知道出现这个问题的主要原因就是调用栈太深,比如常见的无限递归调用。那本文要介绍的Dubbo抛出的这个StackOverflowError又是什么原因呢?且往下看。
重现问题
话不多说,直入主题。这次碰到的StackOverflowError非常好重现,只需要如下简短的代码即可。需要注意的是这里调用的是com.alibaba.dubbo.common.json.JSON,而不是fastjson中的com.alibaba.fastjson.JSON:
Dubbo还有这样的bug,你能忍?
运行这段代码能得到如下异常:
Dubbo还有这样的bug,你能忍?
分析原因
由这个异常堆栈信息,我们很容易知道在GenericJSONConverter中的第73行和129行之间出现了无限递归调用,打开dubbo源码并debug,发现在调用GenericJSONConverter中的writeValue()方法时,首先会判断需要序列化的对象的类型。当对象是如下类型时会特殊处理:
原生类型或者封装类型;
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,你能忍?
- 中搜这样的大公司居然还有这样的bug
- [随文杂记]windows的记事本想不到还有这样的BUG
- 原来还有这样的记词方法_Java版记不规则动词_博主推荐
- epoll的简单用法示例(程序还有bug,但只是为了示例epoll的用法就不改了)
- 想不到!结束进程还有这样的妙用
- java dubbo服务导出excel数据量过大解决方案--2(bug修复)
- 这样的错误竟然能得到正确的值,这个bug藏的够深的。
- 博客园 FreeTextBox 还有一个 bug, 请 dudu 解决一下
- ie6的3像素bug其实还有一层错误。
- 居然还有这样的地方
- dubbo这样的RPC接口与HTTP接口相比,有什么优势,以及HTTP请求中的三次握手
- 查新功能的一些bug点还有开发需要注意的事项
- 这样明目张胆地抄袭,还有良知吗
- 微服务架构Spring Cloud和Dubbo 还有EDAS
- 内存池的C++实现。可能还有小bug。欢迎指正
- 像这样用hadoop恢复一棵树,你还有更好的办法吗?
- 使用了 :before 等伪元素中的其中一个来做 animation 动画; 在 animation 动画改变了其中的某个 rem 的值; 在这样的前提下,又是使用有这个 bug 的版本浏览器,那么就
- 修复x宝的dubbo在springboot中的bug
- 三目运算符bug?原来是这样的!
- 还有这样耍流氓的,真的被雷倒了