Obtenir la trace de pile actuelle en Java
Comment puis-je obtenir la trace de pile actuelle en Java, comme dans . NET vous pouvez faire Environment.StackTrace
?
BTW, Thread.dumpStack()
n'est pas ce que je veux - je veux récupérer la trace de pile , pas l'imprimer.
22 answers
Vous pouvez utiliser Thread.currentThread().getStackTrace()
.
Qui renvoie un tableau de StackTraceElement
s qui représentent actuellement la trace de la pile d'un programme.
Thread.currentThread().getStackTrace();
Est bien si vous ne vous souciez pas du premier élément de la pile.
new Throwable().getStackTrace();
Aura une position définie pour votre méthode actuelle, si cela compte.
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
Thread.currentThread().getStackTrace();
Est disponible depuis JDK1.5.
Pour une version plus ancienne, vous pouvez rediriger exception.printStackTrace()
pour un StringWriter()
:
StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
Vous pouvez utiliser les commons d'Apache pour cela:
String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
Sur Android, un moyen beaucoup plus facile est d'utiliser ceci:
import android.util.Log;
String stackTrace = Log.getStackTraceString(exception);
Pour obtenir la trace de la pile de tous les threads, vous pouvez utiliser l'utilitaire jstack, JConsole ou envoyer un signal kill-quit (sur un système d'exploitation Posix).
Cependant, si vous voulez le faire par programme, vous pouvez essayer d'utiliser ThreadMXBean:
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] infos = bean.dumpAllThreads(true, true);
for (ThreadInfo info : infos) {
StackTraceElement[] elems = info.getStackTrace();
// Print out elements, etc.
}
Comme mentionné, si vous voulez seulement la trace de pile du thread actuel, c'est beaucoup plus facile - Utilisez simplement Thread.currentThread().getStackTrace()
;
Une autre solution (seulement 35 31 caractères):
new Exception().printStackTrace();
new Error().printStackTrace();
Idiot moi, c'est Thread.currentThread().getStackTrace();
Tony, en commentaire de la réponse acceptée, a donné ce qui semble être la meilleure réponse qui répond en fait à la question de l'OP :
Arrays.toString(Thread.currentThread().getStackTrace());
... l'OP n'PAS demandez comment obtenir un String
à partir de la trace de la pile d'un Exception
. Et bien que je sois un grand fan d'Apache Commons, quand il y a quelque chose d'aussi simple que ce qui précède, il n'y a aucune raison logique d'utiliser une bibliothèque extérieure.
Pour enchaîner avec la goyave:
Throwables.getStackTraceAsString(new Throwable())
Je suggère que
Thread.dumpStack()
Est un moyen plus facile et a l'avantage de ne pas réellement construire d'exception ou de lancer quand il n'y a peut-être pas de problème du tout, et est considérablement plus au point.
J'ai une méthode utilitaire qui renvoie une chaîne avec le 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();
}
Et juste logit comme...
...
catch (FileNotFoundException e) {
logger.config(getStackTrace(e));
}
Dans Java 9, il y a une nouvelle façon:
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 );
}
try {
}
catch(Exception e) {
StackTraceElement[] traceElements = e.getStackTrace();
//...
}
Ou
Thread.currentThread().getStackTrace()
Peut-être que vous pourriez essayer ceci:
catch(Exception e)
{
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
String errorDetail = writer.toString();
}
La chaîne 'errorDetail' contient le stacktrace.
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
Le dernier élément du tableau représente le bas de la pile, qui est l'invocation de méthode la moins récente de la séquence.
A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName().
Parcourez StackTraceElement et obtenez le résultat souhaité.
for (StackTraceElement ste : stackTraceElements )
{
//do your stuff here...
}
Vous pouvez utiliser l'utilitaire jstack si vous souhaitez vérifier la pile d'appels actuelle de votre processus.
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
J'ai utilisé des réponses d'en haut et ajouté un formatage
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);
}
}
Obtenir stacktrace:
StackTraceElement[] ste = Thread.currentThread().getStackTrace();
Empilement d'impression (JAVA 9+):
Arrays.asList(ste).stream().forEach(System.out::println);
Impression stacktrage (JAVA 7):
StringBuilder sb = new StringBuilder();
for (StackTraceElement st : ste) {
sb.append(st.toString() + System.lineSeparator());
}
System.out.println(sb);
Ceci est un ancien post, mais voici ma solution:
Thread.currentThread().dumpStack();
Plus d'informations et plus de méthodes là-bas : http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html
System.out.println(Arrays.toString(Thread.currentThread().getStackTrace()));
Cela vous aidera à imprimer la trace de la pile sans boucle.