简单的来说,堆栈跟踪就是我们的程序在抛出异常时使用的方法调用列表。

简单的例子

通过问题中给出的示例,我们可以准确地确定应用程序中抛出异常的位置。

我们来看看堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException

at com.example.myproject.Book.getTitle(Book.java:16)

at com.example.myproject.Author.getBookTitles(Author.java:25)

at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

这是一个非常简单的异常-空指针异常,同样也是最简单的堆栈跟踪。如果我们从第一行“at ...”开始读,我们就可以知道错误发生在哪里。我们正在寻找的是最重要的方法调用,这是我们应用程序的一部分。在这种情况下,它是:

at com.example.myproject.Book.getTitle(Book.java:16)

要调试这个,我们可以打开Book.java并查看行16,如下:

15   public String getTitle() {

16      System.out.println(title.toString());

17      return title;

18   }

这就表明某些东西空指针异常(可能title)在上面的代码中。

我们再看一个异常链的例子

有时应用程序会捕获异常并重新抛出这个异常来作为另一个异常的原因。

通常如下:

public void getBookIds(int id) {

35      try {

36         book.getId(id);    // this method it throws a NullPointerException on line 22

37      } catch (NullPointerException e) {

38         throw new IllegalStateException("A book has a null property", e)

39      }

40   }

这可能会给你一个堆栈跟踪,比如说:

Exception in thread "main" java.lang.IllegalStateException: A book has a null property

at com.example.myproject.Author.getBookIds(Author.java:38)

at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

Caused by: java.lang.NullPointerException

at com.example.myproject.Book.getId(Book.java:22)

at com.example.myproject.Author.getBookIds(Author.java:36)

... 1 more

这个和刚才例子最大的不同就是多了个“Caused by”。有时也会有多个“Caused by”部分。对于这种异常,你通常需要找到 “root cause”。

在我们这一个例子中,它是:

Caused by: java.lang.NullPointerException <-- root cause

at com.example.myproject.Book.getId(Book.java:22) <-- important line

同样,在这个例子中,我们要去看看行22的Book.java,看看有什么可能影响NullPointerException的代码。

更让人头疼的library库抛异常的例子

通常来说堆栈跟踪其实比上述两个例子复杂得多。我们这里再分析一个很长的例子,但是这个例子包含了几个级别的链接异常:

javax.servlet.ServletException: Something bad happened

at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:60)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)

at com.example.myproject.ExceptionHandlerFilter.doFilter(ExceptionHandlerFilter.java:28)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)

at com.example.myproject.OutputBufferFilter.doFilter(OutputBufferFilter.java:33)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)

at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)

at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)

at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)

at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)

at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)

at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)

at org.mortbay.jetty.Server.handle(Server.java:326)

at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)

at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)

at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)

at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)

at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)

at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)

at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

Caused by: com.example.myproject.MyProjectServletException

at com.example.myproject.MyServlet.doPost(MyServlet.java:169)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)

at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)

at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:30)

... 27 more

Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [com.example.myproject.MyEntity]

at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)

at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)

at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:64)

at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2329)

at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2822)

at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)

at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)

at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)

at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)

at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)

at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)

at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)

at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)

at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)

at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)

at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:705)

at org.hibernate.impl.SessionImpl.save(SessionImpl.java:693)

at org.hibernate.impl.SessionImpl.save(SessionImpl.java:689)

at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:344)

at $Proxy19.save(Unknown Source)

at com.example.myproject.MyEntityService.save(MyEntityService.java:59) <-- relevant call (see notes below)

at com.example.myproject.MyServlet.doPost(MyServlet.java:164)

... 32 more

Caused by: java.sql.SQLException: Violation of unique constraint MY_ENTITY_UK_1: duplicate value(s) for column(s) MY_COLUMN in statement [...]

at org.hsqldb.jdbc.Util.throwError(Unknown Source)

at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)

at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)

at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:57)

... 54 more

在这个例子后面还有很多的” Caused by”。但是我们最关心的是寻找来自我们自己代码的错误,就是我们自己的com.example.myproject包中的任何东西。从第二个例子中,我们首先看看抛出的异常,它是:

Caused by: java.sql.SQLException

但是,所有的方法调用都是第三方库代码。所以我们将转到上面的“Caused by”,并寻找来自我们自己的代码的第一个方法调用,它是:

at com.example.myproject.MyEntityService.save(MyEntityService.java:59)

就像在前面的例子中,我们应该看看MyEntityService.java第59行,因为这是此错误的起源,那么通过代码的排查我们最终就能发现并解决相关问题。

文章原创。

若转载,请注明出处:“来自蜗牛学院cto李懿老师”。

若没有按照以上注明出处,一经发现必追究。

作者:蜗牛学院CTO李懿老师

互联网人才孵化基地,商业项目孵化,IT团队培育。

几个简单的例子让你读懂什么是JAVA的堆栈跟踪的更多相关文章

  1. LC滤波器简单设计法 - 一文读懂LC滤波器简单设计方法及原理介绍,LC值计算方法

    LC滤波器概述 LC滤波器也称为无源滤波器,是传统的谐波补偿装置.LC滤波器之所以称为无源滤波器,顾名思义,就是该装置不需要额外提供电源.LC滤波器一般是由滤波电容器.电抗器和电阻器适当组合而成,与谐 ...

  2. 一文读懂什么是Java中的自动拆装箱

    基本数据类型 基本类型,或者叫做内置类型,是Java中不同于类(Class)的特殊类型.它们是我们编程中使用最频繁的类型. Java是一种强类型语言,第一次申明变量必须说明数据类型,第一次变量赋值称为 ...

  3. 【并发编程】一文带你读懂深入理解Java内存模型(面试必备)

    并发编程这一块内容,是高级资深工程师必备知识点,25K起如果不懂并发编程,那基本到顶.但是并发编程内容庞杂,如何系统学习?本专题将会系统讲解并发编程的所有知识点,包括但不限于: 线程通信机制,深入JM ...

  4. 如何读懂statspack报告

    前言:这篇文章是我从网上找到的,但可惜不知道是哪位大侠写(译)的,因此这里无法注明了.仔细看了看,这篇文章对初学者应该很有帮助,写的比较详细,通俗易懂,因此整理一下,便于阅读:内容略有调整,不单做调整 ...

  5. 读懂IL代码就这么简单(三)完结篇

    一 前言 写了两篇关于IL指令相关的文章,分别把值类型与引用类型在 堆与栈上的操作区别详细的写了一遍 这第三篇也是最后一篇,之所以到第三篇就结束了,是因为以我现在的层次,能理解到的都写完了,而且个人认 ...

  6. 【转载】读懂IL代码就这么简单(三)完结篇

    一 前言 写了两篇关于IL指令相关的文章,分别把值类型与引用类型在 堆与栈上的操作区别详细的写了一遍这第三篇也是最后一篇,之所以到第三篇就结束了,是因为以我现在的层次,能理解到的都写完了,而且个人认为 ...

  7. 简单的例子了解自定义ViewGroup(一)

    在Android中,控件可以分为ViewGroup控件与View控件.自定义View控件,我之前的文章已经说过.这次我们主要说一下自定义ViewGroup控件.ViewGroup是作为父控件可以包含多 ...

  8. CSharpGL(1)从最简单的例子开始使用CSharpGL

    CSharpGL(1)从最简单的例子开始使用CSharpGL 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo ...

  9. 读懂IL代码就这么简单(二)

    一 前言 IL系列 第一篇写完后 得到高人指点,及时更正了文章中的错误,也使得我写这篇文章时更加谨慎,自己在了解相关知识点时,也更为细致.个人觉得既然做为文章写出来,就一定要保证比较高的质量,和正确率 ...

随机推荐

  1. 使用JS开发桌面端应用程序NW.js-2-开发问题小记

    前言 本文为开发nw中遇到的各种问题,仅以记录供备忘以及遇到相同问题的人的一点点解决思路. 1. package.json中的window字段无效 原因:package.json中的window字段, ...

  2. HDU 1051 Wooden Sticks 贪心||DP

    Wooden Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  3. Android可更换布局的换肤方案

    换肤,顾名思义,就是对应用中的视觉元素进行更新,呈现新的显示效果.一般来说,换肤的时候只是更新UI上使用的资源,如颜色,图片,字体等等.本文介绍一种笔者自己使用的基于布局的Android换肤方案,不仅 ...

  4. 京东JOS API 接入使用笔记

    商户开设了京东店.淘宝店,最近打算使用京东物流,需要使用京东仓库(京东店的订单使用京仓发货,淘宝等其他店使用京东云仓)发货,所以得从自家的ERP与京东沧海(ECLP)API对接,实现收发存. 首先得在 ...

  5. CJOJ 1331 【HNOI2011】数学作业 / Luogu 3216 【HNOI2011】数学作业 / HYSBZ 2326 数学作业(递推,矩阵)

    CJOJ 1331 [HNOI2011]数学作业 / Luogu 3216 [HNOI2011]数学作业 / HYSBZ 2326 数学作业(递推,矩阵) Description 小 C 数学成绩优异 ...

  6. HDU 2255 奔小康赚大钱(带权二分图最大匹配)

    HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...

  7. Domains域

    一个域是一个criteria(度量标准)列表,每个criterion(标准尺度)是一个三元列表或者元组:field_name,operator,value. field_name(str) 当前模型的 ...

  8. Java并发包基石-AQS详解

    目录 1 基本实现原理 1.1 如何使用 1.2 设计思想 2 自定义同步器 2.1 同步器代码实现 2.2 同步器代码测试 3 源码分析 3.1 Node结点 3.2 独占式 3.3 共享式 4 总 ...

  9. nodejs 搭建 RESTful API 服务器的常用包及其简介

    常用包 框架: yarn add express 数据库链接: yarn add sequelize yarn add mysql2 处理 favicon: yarn add serve-favico ...

  10. node 控制 树莓派做的天气闹钟

    node 控制 树莓派做的天气闹钟 在成都上班,下雨天堵车,迟到的概率会很大. 正好手上有一块树莓派 ,做了一个晴雨闹钟. 下雨天 早上 7:00叫我起床 晴天 早上 7:30叫我起床 将自己喜欢的歌 ...