几个简单的例子让你读懂什么是JAVA的堆栈跟踪

时间:2022-07-04 10:27:35

 

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

简单的例子

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

我们来看看堆栈跟踪:

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代码就这么简单&lpar;三&rpar;完结篇

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

  6. 【转载】读懂IL代码就这么简单&lpar;三&rpar;完结篇

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

  7. 简单的例子了解自定义ViewGroup&lpar;一&rpar;

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

  8. CSharpGL&lpar;1&rpar;从最简单的例子开始使用CSharpGL

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

  9. 读懂IL代码就这么简单&lpar;二&rpar;

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

随机推荐

  1. 模拟赛1030d2

    他[问题描述]一张长度为N的纸带, 我们可以从左至右编号为0 − N( 纸带最左端标号为0). 现在有M次操作, 每次将纸带沿着某个位置进行折叠, 问所有操作之后纸带的长度是多少.[输入格式]第一行两 ...

  2. LOD设置

    Level of detail: 使用多个不同复杂度的mesh来表示一个object,当物体离摄像机越远时,就是用更加low-detail的mesh,反之越近就越使用越精细的mesh. 组件:LOD ...

  3. 利用多写Redis实现分布式锁原理与实现分析(转)

    利用多写Redis实现分布式锁原理与实现分析   一.关于分布式锁 关于分布式锁,可能绝大部分人都会或多或少涉及到. 我举二个例子:场景一:从前端界面发起一笔支付请求,如果前端没有做防重处理,那么可能 ...

  4. http 超文本传输协议

    超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准.设计HTTP最初的目的是为了提供一种发布和接 ...

  5. &lbrack;微软&rsqb;technet与msdn

    我们搜索一个微软术语,有时定位到technet页面,有时定位到msdn页面.我直观的理解就是technet教人们如何使用微软产品,而msdn指导人们如何开发基于微软产品的软件.那么微软对它们具体定位是 ...

  6. nodejs快速入门

    目录: 编写第一个Node.js程序: 异步式I/O和事件循环: 模块和包: 调试. 1. 编写第一个Node.js程序: Node.js 具有深厚的开源血统,它诞生于托管了许多优秀开源项目的网站—— ...

  7. 【原创】tyvj1038 忠诚 &amp&semi; 计蒜客 管家的忠诚 &amp&semi; 线段树&lpar;单点更新,区间查询&rpar;

    最简单的线段树之一,中文题目,不翻译.... 注释讲的比较少,这已经是最简单的线段树,如果看不懂真的说明最基础的理论没明白 推荐一篇文章http://www.cnblogs.com/liwenchi/ ...

  8. POJ--1056 IMMEDIATE DECODABILITY &amp&semi;&amp&semi; POJ--3630 Phone List(字典树)

    题目链接 题目大意 看输入的每个字符串中是否有一个字符串是另一个字符串的前缀 #include<iostream> #include<cstring> #include< ...

  9. MPI Maelstrom(East Central North America 1996)(poj1502)

    MPI Maelstrom 总时间限制:  1000ms 内存限制:  65536kB 描述 BIT has recently taken delivery of their new supercom ...

  10. Codeforces 781D Axel and Marston in Bitland

    题目链接:http://codeforces.com/contest/781/problem/D ${F[i][j][k][0,1]}$表示是否存在从${i-->j}$的路径走了${2^{k}} ...