记一次奇葩的问题排查经历(fastjson Tomcat)

问题背景

这个问题奇葩之处在于IDE中没问题,发到Tomcat容器中报错。在测试类中没问题,嵌入业务流程报错。解决问题简单,但是排查问题花了很长时间,一直搞到晚上9点。站长觉得有必要梳理下这个过程,特此发到博客网站,以供大家参考。异常信息:

[com.dbsoft.whjd.action.DetectionCommisionSheetAction]java.lang.ClassCastException: java.lang.String cannot be cast to com.alibaba.fastjson.JSONArray

网上对这个问题的解决方案也是一大堆,但是尝试之后并不理想。

站长从以下几个方面进行了排查:

代码问题(Debug一步步跟进,定位报错行)

测试类(抽取出有关代码,放到测试类中执行,正常)

业务流中(即原始代码,eclipse中正常运行,但是打成war包发到Tomcat报错)

数据库问题(是否是不同测试数据造成的)

本地库(放弃)

远程库(连接同一数据库,测试同一条数据,同样报错,数据本身没问题)

Tomcat容器问题(测试不同版本)

本地(Tomcat8.0,同样报错)

远程(Tomcat8.5,同样报错)

依赖工具包问题(检查是否有jar包冲突、版本过低问题)

fastjson(放弃,全部采用hutool工具解析json)

hutool(使用:4.1.3,最新:5.3.6,hutool推荐使用的JDK是1.8)

JDK版本(检查是否是JDK版本问题,机动车项目使用的版本较低,若更换JDK风险巨大,最后排查)

1.6(实际使用版本,上产环境如此,历史遗留问题)

1.8(开发测试版本)

其他问题

代码风格不统一:一个类很多人修改,光JSON解析工具就引入了三种。

代码修改后未生效:clean/update

记一次奇葩的问题排查经历(fastjson Tomcat)

尝试方法:

1)拿到接口返回json数据后,根据网上常见解决方案,仔细检查格式是否正确。(检查格式无误,排除数据问题)

2)解压war包,检查是否缺失jar包,比如hutool包,fastjson包等。(检查不缺失,排除引入问题)

3)反编译class,检查代码是否和eclipse中一致。(检查一致,排除打包问题)

4)测试是否是Tomcat问题,把war包发给同事,在其Tomcat中测试。(检查同样有问题,排除Tomcat问题)

5)抽取问题代码到单独的测试类,用的解析工具为hutool4.1.3版本。(测试没问题,此时用的JDK是1.8)

6)将原始代码换成上面的测试类代码运行,同时注释掉fastjson相关的引入。(报一个JDK内部的异常,无详细说明,怀疑是版本不兼容)

7)去hutool官网查看最新版本,引入替换掉项目中的老版本。(问题解决)

 附代码:

// 根据车牌号和颜色判断是否在遥感黑名单
String getDetectRepair = "http://60.xxx.58.xx:8x/api/DetectDataApi/GetDetectRepair";
// M站竣工出厂合格证(根据车牌号和颜色)
String getCertificate = "http://60.xxx.58.xx:8x/api/DetectDataApi/GetCertificate"; 
//同事原来代码
com.alibaba.fastjson.JSONObject jsonObjectBlack = new com.alibaba.fastjson.JSONObject();
jsonObjectBlack.put("plateNum", detectionCommisionSheetPage.getLicence());
jsonObjectBlack.put("plateColor", detectionCommisionSheetPage.getLicenseColor().trim().substring(0, 1));
//修改后代码
Map param2 = new HashMap<Object, Object>();
param2.put("plateNum", detectionCommisionSheetPage.getLicence());
param2.put("plateColor", detectionCommisionSheetPage.getLicenseColor().trim().substring(0, 1));
//hutool工具类
String getDetectRepairResponse = HttpUtil.post(getDetectRepair,param2);
String getCertificateResponse = HttpUtil.post(getCertificate,param2);

单独测试类

//单独测试类
Map param = new HashMap<>();
param.put("plateNum", "皖B01958");
param.put("plateColor", "蓝");
//hutool工具类
String result = HttpUtil.post(getDetectRepair,param);
String result2 = HttpUtil.post(getCertificate,param);
JSONObject resultObj = JSONUtil.parseObj(result2);
JSONObject data = resultObj.getJSONArray("Data").getJSONObject(0);
System.out.println(data);