Java - How to output stack trace (Throwable, Exception)

In Java, you can output the callstack as a Throwable object. Stack trace shows which functions have passed through to the current code position.

You can get or print Trace using the following methods of Throwable.

// Throwable.java
public void printStackTrace()
public void printStackTrace(PrintStream s)
public StackTraceElement[] getStackTrace()

If you look at the Java code, the Exception class inherits the Throwable class. Thats why Exception objects can also use Throwables methods.

public class Exception extends Throwable {
  ...
}

output stack trace

Usually, exceptions are handled using the try-catch pattern. Here, if Exception.printStackTrace() is called, a stack trace is output to the log.

try {
    Exception e = new Exception();
    e.initCause(new IOException("No space memory"));
    throw e;
} catch(Exception e) {
    e.printStackTrace();
}

result

java.lang.Exception
	at example.StackTrace$AAA.ccc(StackTrace.java:21)
	at example.StackTrace$AAA.bbb(StackTrace.java:14)
	at example.StackTrace$AAA.aaa(StackTrace.java:10)
	at example.StackTrace.main(StackTrace.java:47)
Caused by: java.io.IOException: No space memory
	at example.StackTrace$AAA.ccc(StackTrace.java:22)
	... 3 more

Throwable also supports printStackTrace(PrintWriter s) method.

You can add a Trace to a PrintWriter by passing a PrintWriter as an argument as follows:

try {
    Exception e = new Exception();
    e.initCause(new IOException("No space memory"));
    throw e;
} catch(Exception e) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);

    pw.append("+++Start printing trace:\n");
    e.printStackTrace(pw);
    pw.append("---Finish printing trace");
    System.out.println(sw.toString());
}

result

+++Start printing trace:
java.lang.Exception
	at example.StackTrace$AAA.fff(StackTrace.java:50)
	at example.StackTrace$AAA.bbb(StackTrace.java:22)
	at example.StackTrace$AAA.aaa(StackTrace.java:12)
	at example.StackTrace.main(StackTrace.java:75)
Caused by: java.io.IOException: No space memory
	at example.StackTrace$AAA.fff(StackTrace.java:51)
	... 3 more
---Finish printing trace

Output stack trace without exception

The above codes can only be used when an Exception occurs.

If you just want to print a trace for debugging purposes, create a Throwable object as shown below and call printStackTrace(). Its not a throw`, so only the log is output and the object is destroyed.

// print stack trace
(new Throwable()).printStackTrace();

result

java.lang.Throwable
	at example.StackTrace$AAA.eee(StackTrace.java:39)
	at example.StackTrace$AAA.bbb(StackTrace.java:16)
	at example.StackTrace$AAA.aaa(StackTrace.java:10)
	at example.StackTrace.main(StackTrace.java:47)

Import as String without outputting trace

You can get the Trace as a String object without outputting it to the log.

When getStackTrace() is called as shown below, StackTraceElement array is returned. StackTraceElement object holds trace information, and the more stacks are stacked, the longer the array length. You can output the items of this object as a String.

// get stack trace and print
StackTraceElement[] stacks = (new Throwable()).getStackTrace();
for (StackTraceElement element : stacks) {
    System.out.println(element);
}

result

example.StackTrace$AAA.ddd(StackTrace.java:31)
example.StackTrace$AAA.bbb(StackTrace.java:15)
example.StackTrace$AAA.aaa(StackTrace.java:10)
example.StackTrace.main(StackTrace.java:47)

example

The code below is the code used as an example above.

package example;


import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

public class StackTrace {

    static class AAA {
        void aaa() {
            bbb();
        }

        void bbb() {
            ccc();
            sleep(1000);
            ddd();
            sleep(1000);
            eee();
            sleep(1000);
            fff();
        }

        void ccc() {
            try {
                Exception e = new Exception();
                e.initCause(new IOException("No space memory"));
                throw e;
            } catch(Exception e) {
                e.printStackTrace();
            }
        }

        void ddd() {
            // get stack trace and print
            StackTraceElement[] stacks = (new Throwable()).getStackTrace();
            for (StackTraceElement element : stacks) {
                System.out.println(element);
            }
        }

        void eee() {
            // print stack trace
            (new Throwable()).printStackTrace();
        }

        void fff() {
            try {
                Exception e = new Exception();
                e.initCause(new IOException("No space memory"));
                throw e;
            } catch(Exception e) {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);

                pw.append("+++Start printing trace:\n");
                e.printStackTrace(pw);
                pw.append("---Finish printing trace");
                System.out.println(sw.toString());
            }
        }

        void sleep(long ms) {
            try {
                Thread.sleep(ms);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String args[]) {
        AAA a = new AAA();
        a.aaa();
    }
}

Reference

codechachaCopyright ©2019 codechacha