fasterxml 循环引用导致StackOverflowError线程栈错误

来源:互联网 发布:windows.com stopcode 编辑:程序博客网 时间:2024/06/05 19:22

有时候,需要将对象json串化,转换成字符串,便于前后端数据传输,或者多平台系统交互。但一不小心,待转换成json串的对象,居然引用到系统对象,比如Spring系统对象RequestContext,然后重量级对象,数据结构是相当复杂的,各种繁杂的对象相互引用,那必然会出现递归寻找。

错误案例一:

com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: java.util.LinkedHashMap["springMacroRequestContext"]->org.springframework.web.servlet.support.RequestContext["model"]->java.util.LinkedHashMap["springMacroRequestContext"]->org.springframework.web.servlet.support.RequestContext["model"]-

……此处省略一大堆

Caused by: java.lang.StackOverflowError: null
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_91]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_91]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_91]


错误案例二:

com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]->StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]->StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]->StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]->StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]->StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]-

……此处省略一大堆

Caused by: java.lang.StackOverflowError: null
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_91]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_91]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_91]

来一段手动制造的循环引用,学生Student 引用 班级StuClass,班级StuClass里再引用Student。如下图:

import org.apache.commons.lang3.StringUtils;import java.util.ArrayList;import java.util.List;/** * Created by changle on 16/10/26. */@Slf4jpublic class TestCommon {    private static final ObjectMapper mapper = new ObjectMapper();    @Data    static class StuClass {        String name;        Integer pepoleNum;        List<Student> stus;    }    @Data    static class Student {        String name;        StuClass stuClass;    }    public static void main(String[] args){        Student student = new Student();        student.setName("张三");        StuClass stuClass = new StuClass();        stuClass.setName("高三(一)班");        stuClass.setPepoleNum(50);        stuClass.setStus(new ArrayList<>());        stuClass.getStus().add(student);        student.setStuClass(stuClass);        log.info(getJsonStr(student));    }    private static<T> String getJsonStr(T o){        String result = "";        try {            result = mapper.writeValueAsString(o);        } catch (Exception e) {            log.error("getJsonStr(T o) happened error! ",e);        }        return result;    }}

上图必抛StackOverflowError错误!

原因很清楚: 被序列化的对象引用了复杂大对象或本身出现相互引用,最终导致线程栈嵌套层次太深,抛出StackOverflowError


原创粉丝点击