org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.StackOverflowError
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1082)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
...
Caused by: java.lang.StackOverflowError
at com.alibaba.fastjson.serializer.JSONSerializer.setContext(JSONSerializer.java:136)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:83)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:44)
at com.alibaba.fastjson.serializer.ListSerializer.write(ListSerializer.java:135)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:271)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:44)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:271)
... // 以下均是类似循环。
Press Q or Ctrl+C to abort.
Affect(class count: 14 , method count: 28) cost in 6407 ms, listenerId: 20
ts=2024-09-05 23:00:55;thread_name=http-nio-7001-exec-11;id=1549;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@408d5c64;trace_id=2107569217255484514404015e3ba7;rpc_id=0.1.1
@com.alibaba.fastjson.serializer.MapSerializer.write()
at com.alibaba.fastjson.serializer.ListSerializer.write(ListSerializer.java:135)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:271)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:44)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:271)
...
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:271)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:44)
at com.alibaba.fastjson.serializer.FieldSerializer.writeValue(FieldSerializer.java:318)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:472)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:154)
at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:312)
at com.alibaba.fastjson.JSON.writeJSONStringWithFastJsonConfig(JSON.java:1059)
at com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter.writeInternal(FastJsonHttpMessageConverter.java:314)
at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:227)
# ⭕️⭕️⭕️ 异常发生点
at com.xxx.xxx.xxx.fastjson.support.spring.FastJsonHttpMessageConverter.write(FastJsonHttpMessageConverter.java:246)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:183)
at com.xxx.xxx.xxx.JsonEscapeReturnValueHandler.handleReturnValue(JsonEscapeReturnValueHandler.java:50)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:135)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)
tag: user-case
如何定位 StackOverflowError
示例异常堆栈
发生 StackOverflowError 时,堆栈里往往看不到是哪里触发了该异常,比如上面的case中,从
DispatcherServlet.doDispatch
到Caused by: java.lang.StackOverflowError
之间发生了什么?看不出来。思路
-b
(在方法调用前)执行示例arthas命令 下面的case是判断调用堆栈深度500。
示例输出
定位到异常点之后,就可以review相关代码,再配合该行进行watch 进行具体的分析了。
PS: 这里的case 是 启用了 fastjson 1.x 的
SerializerFeature.DisableCircularReferenceDetect
特性后,关闭循环引用检测,再遇到有循环引用的数据造成的。 fastjson 1.x 默认是不使用该功能的。故可以保持默认输出下参数,检测"$ref"
出现的位置:该case 的单元测试验证如下:
第一部分的输出如下: