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.
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.
You can use Thread.currentThread().getStackTrace()
.
That returns an array of StackTraceElement
s that represent the current stack trace of a program.
StackTraceElement[] st = Thread.currentThread().getStackTrace();
is fine if you don't care what the first element of the stack is.
StackTraceElement[] st = new Throwable().getStackTrace();
will have a defined position for your current method, if that matters.
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste + "\n");
}
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();
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.
You can use Apache's commons for that:
String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
On android a far easier way is to use this:
import android.util.Log;
String stackTrace = Log.getStackTraceString(exception);
Another solution (only 35 31 characters):
new Exception().printStackTrace();
new Error().printStackTrace();
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()
;
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.
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 );
}
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);
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));
}
try {
}
catch(Exception e) {
StackTraceElement[] traceElements = e.getStackTrace();
//...
}
or
Thread.currentThread().getStackTrace()
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.
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...
}
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
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);
}
}
For people, who just want to get the current stacktrace to their logs, I would go with:
getLogger().debug("Message", new Throwable());
Cheers
You can also use exception to print stack instead of taking pain of putting new line char:
Exception e = new Exception();
e.setStackTrace(Thread.currentThread().getStackTrace());
loggr.info(e);
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