fastjson在kotlin+java混合项目中的bug
环境
kotlin 1.3 + java 8 + fastjson 1.2.62
问题
最近在项目中遇到一个问题,测试小伙伴反馈在测试环境用着用着突然就接口调用失败,查看日志是报这个错误:
image
试了一下其他接口,也是一样的问题,可就在几分钟前还一切OK,开发本地调试也一切完好,就访问云端的镜像报错。找这个报错的原因,已经写得很明白了,fastjson反序列化时没有找到默认构造函数。
看起来似乎是在调用云端镜像时某个时刻触发了一个事件,导致云端应用状态变化,进而导致后续的接口调用失败。
基于此猜测我们重启了云端应用进行验证,果不其然,重启后一切恢复正常。那么是触发了什么事件导致后续调用失败呢?
于是开发小哥尝试复现问题,正在尝试复现,测试小伙伴又反馈报错了,赶紧抓住现场!
一番沟通后还原测试小伙伴的操作,果然,某个操作会导致一个异常:
image
出现此异常后,后续的接口调用都会失败。但此异常不影响业务,所以在客户端不易被察觉。
原因分析
分析上诉抛出的异常是在fastjson的TypeUtils.java中:
image
进一步分析,为什么constructor为null?
留意一下发现这里clazz变量的类型时kotlin.Unit,这相当于java中的void
/**
* The type with only one value: the `Unit` object. This type corresponds to the `void` type in Java.
*/
public object Unit {
override fun toString() = "kotlin.Unit"
}
用了object关键字进行对象声明,是不带构造函数的,所以迭代器变量it中没有迭代对象,constructor就为null了。于是代码逻辑进入到catch,在catch中会把kotlin_error置为true,后续的请求到这里就直接返回null了:
image
为什么会出现kotlin.Unit的序列化操作呢?
kotlin默认把没有返回值的函数当做返回kotlin.Unit,如果把没有返值的函数丢给fastjson反序列化就会导致此问题。
网友评论