Gson ParameterizedTypeImpl初始化校验参
2017-12-25 本文已影响0人
zcliu
问题背景
今天在对某个接口做junit测试时,报如下错误
image.png发生错误的本质就是:某个bean在初始化时使用了gson做参数类型映射, 旗下ParameterizedTypeImpl 解析泛型数据时出错,导致创建bean失败,从而导致spring 容器启动失败
而奇怪的是,通过gradle打包运行却是正常的,但跑junit测试却一直报错。
分析
从堆栈错误可以看到,是在初始化ParameterizedTypeImpl时,调用checkArgument方法时报错, 这时用的gson版本是2.2.2。找到对应的源码位置
image.png
然后再来看看客户端初始化ParameterizedTypeImpl传入的参数:
image.png
- ownerType是null
- rawType是ClientService类下的一个静态内部类Response
第一个checkArgument校验,ownerType不为null或者rawType不是内部类的条件明显不满足,所以就是在这里抛的illegalArgumentException。
通过gradle打包方式运行,发现使用的是gson 2.8.0(这里注意一下,我们的系统同时存在2.2.2, 2.6.2以及2.8.0版本的gson,gralde解决版本冲突的策略是选取最新的那个版本),没有抛错,而2.8.0对应ParameterizedTypeImpl初始化的代码
image.png
可以看到2.8.0对应的校验条件发生了变化:
- ownerType不为null 或
- rawType是静态类,或者不是内部类
我们的Response类是静态类,所以通过校验,没有报错。
解决办法
- 强制使用gson 2.8.0,具体参考 Gradle ResolutionStrategy
总结
- ParameterizedTypeImpl初始化从2.3.0版本开始更改了校验参数的方式的,如果你在使用的时候发现出现参数校验异常,并且使用的是2.2.2及之前的版本,可以考虑升级gson版本