如何阅读和理解 java 堆栈跟踪? [复制]

Posted

技术标签:

【中文标题】如何阅读和理解 java 堆栈跟踪? [复制]【英文标题】:How to read and understand the java stack trace? [duplicate] 【发布时间】:2012-09-23 04:12:35 【问题描述】:

例如,我得到了这样的堆栈跟踪:

java.lang.NullPointerException
abc.investxa.presentation.controllers.UnixServerJobController.handleRequest(UnixServerJobController.java:66)
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

那么这个异常的根本原因是什么? 从堆栈跟踪中,我发现OncePerRequestFilter 类中的doFilter 函数存在问题!但是,当我在那里设置断点时,程序永远不会在该断点处停止。

谁能解释一下这个!? 在一般情况下,我应该如何使用该堆栈案例进行调试(从下到上或从上到下阅读)!

【问题讨论】:

【参考方案1】:

您通常应该从顶部阅读 - 因此在这种情况下,在 UnixServerJobController 的第 66 行,handleRequest 方法中存在 NullPointerException。该方法由SimpleControllerHandlerAdapter.handle调用,由DispatcherServlet.doDispatch等调用。

但是,在这种特殊情况下,堆栈跟踪的第一帧可能就是您所需要的。查看UnixServerJobController 的第66 行,找出可能为null 的内容,然后采取相应措施。

请注意,有时一个异常会包含在另一个异常中(后者可能又会包含在另一个异常中,等等)。在这种情况下,您应该查看 每个 堆栈跟踪 - 通常它是“最嵌套”的异常,它提供了最有用的信息,因为这是根本原因。

【讨论】:

“很可能堆栈跟踪的第一帧就是你所需要的”,除非库抛出异常,因为你提供了错误的参数集。 当异常被包装并重新抛出时,导入行是hidden in the middle @JanDvorak:我指的是这个特定的堆栈跟踪 - 会更清楚。 嗨乔恩,我一直很钦佩你。有你回答我的问题真是太好了。 :D @JoshBjelovuk:是的 - 真正造成这一切的人。【参考方案2】:

通常Exception 的确切原因位于堆栈跟踪的第一行,有关该异常原因的更多信息,您需要逐渐向下移动,并且通常可以在附近的某个地方找到根本原因堆栈跟踪的底部。

但在大多数情况下,你甚至可以从前几行得到异常的原因..

因此,在这种情况下,您的异常位于 handleRequest 方法,当您向下移动时,这些是调用您之前的方法的方法(堆栈跟踪中当前方法上方的那个)

【讨论】:

否决的选民可以评论我错在哪里吗?? 在企业级java中,调用栈的底层往往是库函数,不值得研究。 @JanDvorak.. 可能不需要经常调查,但这是root 的原因,对吧?那么,我说错在哪里?? 从堆栈跟踪中可以看出,库中有九个堆栈帧,只有最上面的帧是用户函数(并且很可能受到责备)。这往往是原因在顶部附近的情况。 “接近底部”不正确。 “经常接近底部”可能会被轻描淡写。 “可以接近底部”当然是真的,但并不能说明太多。【参考方案3】:

This 教程可能会阐明您的问题并帮助您更好地理解问题。

根据您的问题,您似乎在 Unix 服务器作业控制器类的第 66 行有一个空指针异常。

【讨论】:

哦,太好了,我正在寻找这个教程,谢谢:D【参考方案4】:

我发现本教程对我非常有用 https://forums.bukkit.org/threads/how-to-read-stack-traces-and-troubleshoot-your-own-plugins-by-yourself.32457/

【讨论】:

这基本上是一个仅链接的答案,这几乎不是一个好主意。 (例如,如果链接页面被删除,它将变得毫无用处。)您应该至少引用帖子中最重要的部分。

以上是关于如何阅读和理解 java 堆栈跟踪? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

虚拟机和无虚拟机 - 堆栈和跟踪

深入理解Java虚拟机——Java堆栈跟踪工具(jstack)

如何阅读和理解一个怪物异常(例如这个)

Ruby 异常处理:反向堆栈跟踪顺序

JAVA电子邮件跟踪像素跟踪阅读时间

实验二 深入理解系统调用