1037
votes

How do I get the current stack trace in Java, like how in .NET you can do Environment.StackTrace?

I found Thread.dumpStack() but it is not what I want - I want to get the stack trace back, not print it out.

22
I allways use "new Exception().printStackTrace()" as a watch expression when I'm debugging in Eclipse. That's handy when you suspend at a breakpoint and want to know where you came from.Tim Büthe
@TimBüthe: isn't Eclipse already telling you the Stack Trace when you are in debug mode? I think so.Luigi Massa Gallerano
Arrays.toString(Thread.currentThread().getStackTrace()); simple enough.Ajay
@Arkanon It refers to java, and is showing how they would do it in .net and what the equivalent is in java.Pokechu22
To print it nicely you can use apache StringUtils: StringUtils.join(currentThread().getStackTrace(), "\n");Art

22 Answers

1209
votes

You can use Thread.currentThread().getStackTrace().

That returns an array of StackTraceElements that represent the current stack trace of a program.

273
votes
Thread.currentThread().getStackTrace();

is fine if you don't care what the first element of the stack is.

new Throwable().getStackTrace();

will have a defined position for your current method, if that matters.

190
votes
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
    System.out.println(ste);
}
61
votes
Thread.currentThread().getStackTrace();

is available since JDK1.5.

For an older version, you can redirect exception.printStackTrace() to a StringWriter() :

StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
41
votes

You can use Apache's commons for that:

String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
36
votes

Tony, as a comment to the accepted answer, has given what seems to be the best answer which actually answers the OP's question:

Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );

... the OP did NOT ask how to get a String from the stack trace from an Exception. And although I'm a huge fan of Apache Commons, when there is something as simple as the above there is no logical reason to use an outside library.

24
votes

On android a far easier way is to use this:

import android.util.Log;
String stackTrace = Log.getStackTraceString(exception); 
23
votes

Another solution (only 35 31 characters):

new Exception().printStackTrace();   
new Error().printStackTrace();
22
votes

To get the stack trace of all threads you can either use the jstack utility, JConsole or send a kill -quit signal (on a Posix operating system).

However, if you want to do this programmatically you could try using ThreadMXBean:

ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] infos = bean.dumpAllThreads(true, true);

for (ThreadInfo info : infos) {
  StackTraceElement[] elems = info.getStackTrace();
  // Print out elements, etc.
}

As mentioned, if you only want the stack trace of the current thread it's a lot easier - Just use Thread.currentThread().getStackTrace();

17
votes

Silly me, it's Thread.currentThread().getStackTrace();

16
votes

In Java 9 there is a new way:

public static void showTrace() {

  List<StackFrame> frames =
    StackWalker.getInstance( Option.RETAIN_CLASS_REFERENCE )
               .walk( stream  -> stream.collect( Collectors.toList() ) );

  for ( StackFrame stackFrame : frames )
    System.out.println( stackFrame );
}
16
votes

Getting stacktrace:

StackTraceElement[] ste = Thread.currentThread().getStackTrace();

Printing stacktrace (JAVA 8+):

Arrays.asList(ste).forEach(System.out::println);

Printing stacktrage (JAVA 7):

StringBuilder sb = new StringBuilder();

for (StackTraceElement st : ste) {
    sb.append(st.toString() + System.lineSeparator());
}
System.out.println(sb);
15
votes

I suggest that

  Thread.dumpStack()

is an easier way and has the advantage of not actually constructing an exception or throwable when there may not be a problem at all, and is considerably more to the point.

11
votes

To string with guava:

Throwables.getStackTraceAsString(new Throwable())
10
votes

I have a utility method that returns a string with the stacktrace:

static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw, true);
    t.printStackTrace(pw);
    pw.flush();
    sw.flush();
    return sw.toString();
}

And just logit like...

... 
catch (FileNotFoundException e) {
    logger.config(getStackTrace(e));
}
8
votes
try {
}
catch(Exception e) {
    StackTraceElement[] traceElements = e.getStackTrace();
    //...
}

or

Thread.currentThread().getStackTrace()
5
votes

Maybe you could try this:

catch(Exception e)
{
    StringWriter writer = new StringWriter();
    PrintWriter pw = new PrintWriter(writer);
    e.printStackTrace(pw);
    String errorDetail = writer.toString();
}

The string 'errorDetail' contains the stacktrace.

5
votes
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();

The last element of the array represents the bottom of the stack, which is the least recent method invocation in the sequence.

A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName().

loop through StackTraceElement and get your desired result.

for (StackTraceElement ste : stackTraceElements ) 
{
    //do your stuff here...
}
4
votes

You can use jstack utility if you want to check the current call stack of your process.

Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message
4
votes

I used answers from above and added formatting

public final class DebugUtil {

    private static final String SEPARATOR = "\n";

    private DebugUtil() {
    }

    public static String formatStackTrace(StackTraceElement[] stackTrace) {
        StringBuilder buffer = new StringBuilder();
        for (StackTraceElement element : stackTrace) {
            buffer.append(element).append(SEPARATOR);
        }
        return buffer.toString();
    }

    public static String formatCurrentStacktrace() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        return formatStackTrace(stackTrace);
    }
}
0
votes

This is an old post, but here is my solution :

Thread.currentThread().dumpStack();

More info and more methods there : http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html

0
votes

For people, who just want to get the current stacktrace to their logs, I would go with:

getLogger().debug("Message", new Throwable());

Cheers