1. 前言
最近在進(jìn)行測(cè)試的時(shí)候,無意間出現(xiàn)了一個(gè)問題:
java.lang.VerifyError: (class: com/alibaba/fastjson/parser/deserializer/FastjsonASMDeserializer_731_Order, method: deserialze signature: (Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;Ljava/lang/Object;I)Ljava/lang/Object;) Accessing value from uninitialized register 85 at java.lang.Class.getDeclaredConstructors0(Native Method) at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671) at java.lang.Class.getConstructor0(Class.java:3075) at java.lang.Class.getConstructor(Class.java:1825) at com.alibaba.fastjson.parser.deserializer.ASMDeserializerFactory.createJavaBeanDeserializer(ASMDeserializerFactory.java:82) at com.alibaba.fastjson.parser.ParserConfig.createJavaBeanDeserializer(ParserConfig.java:639) at com.alibaba.fastjson.parser.ParserConfig.getDeserializer(ParserConfig.java:491) at com.alibaba.fastjson.parser.ParserConfig.getDeserializer(ParserConfig.java:348) at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:639) at com.alibaba.fastjson.JSON.parseObject(JSON.java:350) at com.alibaba.fastjson.JSON.parseObject(JSON.java:254) at com.alibaba.fastjson.JSON.parseObject(JSON.java:467) at com.test.FastjsonTest.testFastjson(FastjsonTest.java:16)
可以看到,是fastjson轉(zhuǎn)換問題,其中Fastjson版本是:1.2.28。
2. 問題排查
首先可以看到,這段代碼是使用fastjson將json字符串轉(zhuǎn)換為Order對(duì)象的:
return JSON.parseObject(getJson(), Order.class);
這段代碼以前的時(shí)候是正常運(yùn)行的,最近唯一的改動(dòng)就是轉(zhuǎn)換的對(duì)象中添加了一個(gè)字段,其他是沒有修改的。
因?yàn)槭窃诜?wù)器上出現(xiàn)的問題,所以先在本地用main方法重現(xiàn)下:
- 首先想辦法拿到這個(gè)json字符串;
- 在代碼中創(chuàng)建一個(gè)應(yīng)用程序,在main方法中手動(dòng)將json轉(zhuǎn)換為Order對(duì)象,看一下有沒有報(bào)錯(cuò);
- 然后將對(duì)象中新添加的該字段給刪除,再跑一下,看是否還報(bào)錯(cuò);如果不報(bào)錯(cuò),說明是該字段的問題;
- 然后換下字段名稱或類型,再看下是否還報(bào)錯(cuò),如果不報(bào)錯(cuò),說明是該字段類型或名稱的問題;如果還報(bào)錯(cuò),說明不是字段本身有什么問題,而是添加字段導(dǎo)致的問題;
試過后可以看到,該字段本身類型并沒有什么問題,而是加了該字段后出現(xiàn)的問題,然后在網(wǎng)上簡(jiǎn)單搜下,就發(fā)現(xiàn)了:
Fastjson1.2.28版本下,在json反序列化的時(shí)候,當(dāng)字段數(shù)量為32或者64時(shí),會(huì)反序列化報(bào)錯(cuò)。
具體可以看下Fastjson的issue:https://github.com/alibaba/fastjson/issues/1092
基于此,先數(shù)了下Order對(duì)象的數(shù)量,恰好32個(gè);然后本地調(diào)試下,當(dāng)數(shù)量+1或者-1的時(shí)候,都是正確的。
3. 解決方式
解決方式也就很簡(jiǎn)單了:
- a. 升級(jí)fastjson到1.2.28之后的版本;
- b. 將字段數(shù)量在32位/64位基礎(chǔ)上加1;
最終采用臨時(shí)方式,添加一個(gè)冗余字段來解決。因?yàn)槭蔷€上的服務(wù),版本不能隨便神升級(jí),如果升級(jí)的話,還要測(cè)試進(jìn)行回歸。