How to read and understand a Java Stacktrace
Tags: java, beginners, errors
Published: 2019-06-03 12:42:46

---
title: How to read and understand a Java Stacktrace
published: true
tags: java, beginners, errors
canonical_url: https://www.twilio.com/blog/how-to-read-and-understand-a-java-stacktrace
cover_image: https://static.gilliard.lol/breakfast-2017647_960_402.jpg
---

When things go wrong in a running Java application, often the first sign you will have is lines printed to the screen that look like this:

```
Exception in thread "main" java.lang.RuntimeException: Something has gone wrong, aborting!
  at com.myproject.module.MyProject.badMethod(MyProject.java:22)
  at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)
  at com.myproject.module.MyProject.anotherMethod(MyProject.java:14)
  at com.myproject.module.MyProject.someMethod(MyProject.java:10)
  at com.myproject.module.MyProject.main(MyProject.java:6)
```

This is a **Stacktrace** , and in this post I'll explain what they are, how they are made and how to read and understand them. If that looks painful to you then read on...

## Anatomy of a Stacktrace

Usually a Stacktrace is shown when an [Exception](https://www.baeldung.com/java-exceptions) is not handled correctly in code. This may be one of the [built-in Exception types](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Exception.html), or a [custom Exception](https://www.baeldung.com/java-new-custom-exception) created by a program or a library.

The Stacktrace contains the  **Exception’s type**  and a **message** , and a list of **all the method calls**  which were in progress when it was thrown.

Let’s dissect that Stacktrace. The first line tells us the details of the Exception:

![](https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/9oHmXuXT7nRpdSueZHD8I3sK2yLPdkPLBv6Kj8kjzfkELh.width-500.png)

This is a good start. Line 2 shows what code was running when that happened:

![](https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/Hrwf15FHX0DEpuBEw73N5Xy_7icjNt1TLXRaNiu_D82aHY.width-500.png)

 

That helps us narrow down the problem, but what part of the code called `badMethod`? The answer is on the next line down, which can be read in the exact same way. And how did we get there? Look on the next line. And so on, until you get to the last line, which is the `main` method of the application.  Reading the Stacktrace from bottom to top you can trace the exact path from the beginning of your code, right to the Exception.

## What went wrong?

![](https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/A9ZDocG2PU43VT16UFxIBCXS5sGAf7lIYDH4UqDIqZLU-G.width-500.jpg)

The thing that causes an Exception is usually an explicit `throw` statement. Using the file name and line number you can check exactly what code threw the Exception. It will probably look something like this:

```
  throw new RuntimeException("Something has gone wrong, aborting!");
```

This is a great place to start looking for the underlying problem: are there any if statements around that? What does that code do? Where does the data used in that method come from?

It is also possible for code to throw an Exception without an explicit `throw` statement, for example you can get:

- NullPointerException if `obj` is `null` in code which calls `obj.someMethod()`
- ArithmeticException if a division by zero happens in integer arithmetic, ie `1/0`  - curiously there is no Exception if this is a floating-point calculation though, `1.0/0.0` returns `infinity` _just fine!_
- NullPointerException if a `null` Integer is unboxed to an `int` in code like this: `Integer a=null; a++;`
- There are some other examples in the [Java Language Specification](https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.6), so it’s important to be aware that Exceptions _can_ arise without being explicitly thrown.

## Dealing with Exceptions Thrown by Libraries

One of the great strengths of Java is the huge number of libraries available. Any popular library will be well tested so generally when faced with an Exception from a library, it’s best to check first whether the error is caused by how our code uses it.

For example, if we're using the [Fraction](https://commons.apache.org/proper/commons-lang/javadocs/api-3.4/org/apache/commons/lang3/math/Fraction.html) class from [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/) and pass it some input like this:

```
  Fraction.getFraction(numberOfFoos, numberOfBars);
```

If `numberOfBars` is zero, then the Stacktrace will be like this:

```
Exception in thread "main" java.lang.ArithmeticException: The denominator must not be zero
  at org.apache.commons.lang3.math.Fraction.getFraction(Fraction.java:143)   
  at com.project.module.MyProject.anotherMethod(MyProject.java:17)
  at com.project.module.MyProject.someMethod(MyProject.java:13)
  at com.project.module.MyProject.main(MyProject.java:9)
```

Many good libraries provide [Javadoc](https://en.wikipedia.org/wiki/Javadoc#Structure_of_a_Javadoc_comment) which includes information about what kinds of Exceptions may be thrown and why. In this case `Fraction.getFraction` has documented [will throw an ArithmeticException if a Fraction has a zero denominator](https://commons.apache.org/proper/commons-lang/javadocs/api-3.4/org/apache/commons/lang3/math/Fraction.html#getFraction(int,%20int)). Here it's also clear from the message, but in more complicated or ambiguous situations the docs can be a great help.

To read this Stacktrace, start at the top with the Exception's type - `ArithmeticException` and message `The denominator must not be zero`. This gives an idea of what went wrong, but to discover what code caused the Exception, skip down the Stacktrace looking for something in the package `com.myproject` (it’s on the 3rd line here), then scan to the end of the line to see where the code is (`MyProject.java:17`). That line will contain some code that calls `Fraction.getFraction`. This is the starting point for investigation: What is passed to `getFraction`? Where did it come from?

In big projects with many libraries, Stacktraces can be hundreds of lines long so if you see a big Stacktrace, practise scanning the list of `at ... at ... at ...` looking for your own code - it’s a useful skill to develop.

## Best Practice: Catching and Rethrowing Exceptions

Let's say we are working on a big project that deals with fictional `FooBars`, and our code is going to be used by others. We might decide to catch the ArithmeticException from `Fraction` and re-throw it as something project-specific, which looks like this:

```
  try {
    ....
    Fraction.getFraction(x,y);
    ....
  } catch ( ArithmeticException e ){ 
    throw new MyProjectFooBarException("The number of FooBars cannot be zero", e);
  }
```

Catching the `ArithmeticException` and rethrowing it has a few benefits:

- Our users are shielded from having to care about the `ArithmeticException` - giving us flexibility to change how commons-lang is used.
- More context can be added, eg stating that it’s _the number of FooBars_ that is causing the problem.
- It can make Stacktraces easier to read, too, as we’ll see below.

It isn't necessary to catch-and-rethrow on _every_ Exception, but where there seems to be a jump in the layers of your code, like calling into a library, it often makes sense.

Notice that the constructor for `MyProjectFooBarException` takes 2 arguments: a message and the Exception which caused it. Every Exception in Java has a `cause` field, and when doing a _catch-and-rethrow_ like this then you should _always_ set that to help people debug errors. A Stacktrace might now look something like this:

```
Exception in thread "main" com.myproject.module.MyProjectFooBarException: The number of FooBars cannot be zero
  at com.myproject.module.MyProject.anotherMethod(MyProject.java:19)
  at com.myproject.module.MyProject.someMethod(MyProject.java:12)
  at com.myproject.module.MyProject.main(MyProject.java:8)
Caused by: java.lang.ArithmeticException: The denominator must not be zero
  at org.apache.commons.lang3.math.Fraction.getFraction(Fraction.java:143)
  at com.myproject.module.MyProject.anotherMethod(MyProject.java:17)
  ... 2 more
```

The most recently thrown Exception is on the first line, and the location where it was thrown is still on line 2. However, this type of Stacktrace can cause confusion because the _catch-and-rethrow_ has changed the order of method calls compared to the Stacktraces we saw before. The main method is no longer at the bottom, and the code which _first_ threw an Exception is no longer at the top. When you have multiple stages of catch-and-rethrow then it gets bigger but the pattern is the same:

_Check the sections from first to last looking for your code, then read relevant sections from bottom to top._

## Libraries vs Frameworks

The difference between a Library and a Framework in Java is:

- Your code _calls_ methods in a Library
- Your code _is called by_ methods in a Framework

A common type of Framework is a web application server, like [SparkJava](http://sparkjava.com/) or [Spring Boot](https://spring.io/guides/gs/spring-boot/). Using SparkJava and [Commons-Lang](https://commons.apache.org/proper/commons-lang/) with our code we might see a Stacktrace like this:

```
com.framework.FrameworkException: Error in web request
    at com.framework.ApplicationStarter.lambda$start$0(ApplicationStarter.java:15)
    at spark.RouteImpl$1.handle(RouteImpl.java:72)
    at spark.http.matching.Routes.execute(Routes.java:61)
    at spark.http.matching.MatcherFilter.doFilter(MatcherFilter.java:134)
    at spark.embeddedserver.jetty.JettyHandler.doHandle(JettyHandler.java:50)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1568)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:503)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: com.project.module.MyProjectFooBarException: The number of FooBars cannot be zero
    at com.project.module.MyProject.anotherMethod(MyProject.java:20)
    at com.project.module.MyProject.someMethod(MyProject.java:12)
    at com.framework.ApplicationStarter.lambda$start$0(ApplicationStarter.java:13)
    ... 16 more
Caused by: java.lang.ArithmeticException: The denominator must not be zero
    at org.apache.commons.lang3.math.Fraction.getFraction(Fraction.java:143)
    at com.project.module.MyProject.anotherMethod(MyProject.java:18)
    ... 18 more
```

OK that is getting quite long now. As before we should suspect our own code first, but it's getting harder and harder to find _where that is_. At the top there is the Framework's Exception, at the bottom the Library's and right in the middle is our own code. Phew!

A complex Framework and Library can create a dozen or more `Caused by:` sections, so a good strategy is to jump down those looking for your own code: `Caused by: com.myproject...` Then read that section in detail to isolate the problem.

## In Summary

Learning how to understand Stacktraces and read them quickly will let you home in on problems and makes debugging much less painful. It's a skill which improves with practise, so next time you see a big Stacktrace don't be intimidated - there is a lot of useful information there if you know how to extract it.

![](https://s3.amazonaws.com/com.twilio.prod.twilio-docs/original_images/EoZw5ArTbpyelA35Ks8FjjsrJCRq3tIDTNNjszf3qXJoCWIW63b0ePJMSNAXFlwfafRE2kFyKkL4Gy)

If you have any tips or tricks about dealing with Java Stacktraces I'd love to hear about them so get in touch with me and let's share what we know.

mgilliard@twilio.com
[@MaximumGilliard](https://twitter.com/maximumgilliard)