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多,这回算是体会到了。
浙公网安备 33010602011771号