fastjson2在国产CPU上遇到诡异的错误

一个JDK8的老项目中偶然发现的,涉及到使用fastjson2,具体版本是2.0.64,一开始测试一切正常,但后来涉及切换国产化时,在鲲鹏920的CPU环境下会发现非常奇怪的JSON解析错误,具体表现为使用JSON.parseObject()时,明明输入的String或byte[]都没有问题,但却报解析失败,而且还给出了一个明确的错误位置,比如:

com.alibaba.fastjson2.JSONException: offset 12, character s, line 1, column 12, fastjson-version 2.0.64 {"name":"test","type":3,"ver":1,"dept":"sys"}

这个错误非必现,但运行一段时间后就会出现。更换OracleJDK和OpenJDK的不同版本均无法解决。特意写了一个测试程序做验证:

 1 import com.alibaba.fastjson2.JSON;
 2 import com.alibaba.fastjson2.JSONObject;
 3 
 4 import java.io.IOException;
 5 import java.nio.charset.StandardCharsets;
 6 import java.nio.file.Files;
 7 import java.nio.file.Paths;
 8 
 9 public class FastjsonTest {
10 
11     public static void main(String[] args) {
12         String filePath = args[0];
13         long maxLoops = args.length >= 2 ? Long.parseLong(args[1]) : Long.MAX_VALUE;
14 
15         String content;
16         try {
17             content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
18         } catch (IOException e) {
19             System.err.println("读取文件失败: " + e.getMessage());
20             e.printStackTrace();
21             System.exit(3);
22             return;
23         }
24 
25         long loop = 0;
26         while (loop < maxLoops) {
27             loop++;
28             String serialized1 = null;
29             String serialized2 = null;
30             try {
31                 // 第一次解析
32                 JSONObject obj1 = JSON.parseObject(content);
33 
34                 // 第一次序列化
35                 serialized1 = obj1.toJSONString();
36 
37                 // 第二次解析
38                 JSONObject obj2 = JSON.parseObject(serialized1);
39 
40                 // 第二次序列化,用于对比前后是否一致
41                 serialized2 = obj2.toJSONString();
42 
43             } catch (Throwable t) {
44                 System.err.println("==================== 第 " + loop + " 次循环失败 ====================");
45                 System.err.println("原始文件内容:");
46                 System.err.println(content);
47                 System.err.println("-------------------- 第一次序列化结果 (serialized1) --------------------");
48                 System.err.println(serialized1);
49                 System.err.println("-------------------- 第二次序列化结果 (serialized2) --------------------");
50                 System.err.println(serialized2);
51                 System.err.println("-------------------- 错误详情 --------------------");
52                 t.printStackTrace(System.err);
53 
54                 System.exit(1);
55             }
56        }
57 
58         System.out.println("循环结束,共执行 " + loop + " 次,未发现解析失败。");
59     }
60 }

 

准备了一个极简的json文件,内容如下:

{"name":"test","type":3,"ver":1,"dept":"sys"}


准备好fastjson2-2.0.64.jar,执行上面的测试,跑1000次:

java -cp ".:*" FastjsonTest 1.json 1000

 

很容易就复现异常:

==================== 第 319 次循环失败 ====================
原始文件内容:
{"name":"test","type":3,"ver":1,"dept":"sys"}
-------------------- 第一次序列化结果 (serialized1) --------------------
{"name":"test","type":3,"ver":1,"dept":"sys"}
-------------------- 第二次序列化结果 (serialized2) --------------------
null
-------------------- 错误详情 --------------------
com.alibaba.fastjson2.JSONException: offset 12, character s, line 1, column 12, fastjson-version 2.0.64 {"name":"test","type":3,"ver":1,"dept":"sys"}
    at com.alibaba.fastjson2.JSONReader.read(JSONReader.java:3460)
    at com.alibaba.fastjson2.JSON.parseObject(JSON.java:476)
    at FastjsonTest.main(FastjsonTest.java:38)

 

而相同的程序在x64上就无法复现问题,换jackson也无法复现。受限于环境,还没有在更多场景下测试。一直听说fastjson的BUG多,这回算是体会到了。

 

posted on 2026-10-20 09:25  BoyTNT  阅读(20)  评论(0)    收藏  举报

导航