web-dev-qa-db-fra.com

Obtenir la trace de la pile actuelle dans Java

Comment obtenir la trace de pile actuelle en Java, comme dans . NET , vous pouvez le faire Environment.StackTrace ?

BTW, Thread.dumpStack() n'est pas ce que je veux - je veux obtenir le trace de la pile , pas l'imprimer.

945
ripper234

Vous pouvez utiliser Thread.currentThread().getStackTrace().

Cela retourne un tableau de StackTraceElement s qui représente la trace de pile actuelle d'un programme.

1105
jjnguy
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.

253
Yishai
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
    System.out.println(ste);
}
177
Leif Gruenwoldt
Thread.currentThread().getStackTrace();

est disponible depuis JDK1.5.

Pour une version plus ancienne, vous pouvez rediriger exception.printStackTrace() vers un StringWriter():

StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
60
RealHowTo

Vous pouvez utiliser les communs d'Apache pour cela:

String fullStackTrace = org.Apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
39
stikkos

Sur Android, un moyen bien plus simple consiste à utiliser ceci:

import Android.util.Log;
String stackTrace = Log.getStackTraceString(exception); 
24
Vicky Kapadia

Une autre solution (seulement 35 31 caractères):

new Exception().printStackTrace();   
new Error().printStackTrace();
21
kukis

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 faire cela 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é précédemment, si vous ne voulez que la trace de pile du thread actuel, c'est beaucoup plus facile - Utilisez simplement Thread.currentThread().getStackTrace();

20
Adamski

Tony, en tant que commentaire sur la réponse acceptée, a donné ce qui semble être la meilleure réponse à laquelle il faut effectivement répondre la question du PO:

Arrays.toString(Thread.currentThread().getStackTrace());

... l'OP a fait PAS demander comment obtenir une String de la trace de la pile à partir d'un Exception. Et bien que je sois un grand fan d’Apache Commons, quand il ya 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.

17
mike rodent

Silly moi, c'est Thread.currentThread().getStackTrace();

15
ripper234

Je suggère que

  Thread.dumpStack()

est un moyen plus facile et présente l’avantage de ne pas construire une exception ou de ne pas être jetable quand il n’ya pas de problème du tout, et est beaucoup plus pertinent.

14
Thomas Adkins

Dans Java 9, il existe un nouveau moyen:

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 );
}
11
Christian Ullenboom

Pour corder avec de la goyave:

Throwables.getStackTraceAsString(new Throwable())
10
Zitrax

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));
}
9
try {
}
catch(Exception e) {
    StackTraceElement[] traceElements = e.getStackTrace();
    //...
}

ou

Thread.currentThread().getStackTrace()
8
butterchicken

Obtention de stacktrace:

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

Impression de la pile (Java 8 +):

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

Impression de stacktrage (Java 7):

StringBuilder sb = new StringBuilder();

for (StackTraceElement st : ste) {
    sb.append(st.toString() + System.lineSeparator());
}
System.out.println(sb);
7
Witold Kaczurba

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.

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

Le dernier élément du tableau représente le bas de la pile, qui correspond à l'appel de méthode le moins récent 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...
}
5
Xar E Ahmer

J'ai utilisé les réponses ci-dessus et ajouté le 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);
    }
}
3
user8290063

Vous pouvez utiliser l'utilitaire jstack si vous souhaitez vérifier la pile d'appels en cours 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
2
Sampath

Ceci est un ancien post, mais voici ma solution:

Thread.currentThread().dumpStack();

Plus d'infos et plus de méthodes ici: http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-Java-thread.html

0
Manov