Ottieni traccia dello stack corrente in Java

Come ottengo la traccia dello stack corrente in Java, come in .NET si può fare Environment.StackTrace ?

BTW, Thread.dumpStack() non è quello che voglio: voglio recuperare la traccia dello stack , non stamparla.

È ansible utilizzare Thread .currentThread().getStackTrace() .

Ciò restituisce una matrice di StackTraceElement che rappresenta la traccia di stack corrente di un programma.

 Thread.currentThread().getStackTrace(); 

va bene se non ti interessa quale sia il primo elemento della pila.

 new Throwable().getStackTrace(); 

avrà una posizione definita per il tuo metodo attuale, se questo è importante.

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

è disponibile da JDK1.5.

Per una versione precedente, è ansible redirect exception.printStackTrace() a un StringWriter() :

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

Puoi usare i comuni di Apache per questo:

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

Su Android un modo molto più semplice è quello di utilizzare questo:

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

Per ottenere la traccia dello stack di tutti i thread è ansible utilizzare l’utilità jstack, JConsole o inviare un segnale kill -quit (su un sistema operativo Posix).

Tuttavia, se vuoi farlo a livello di codice, puoi provare a utilizzare ThreadMXBean:

 ThreadMXBean bean = ManagementFactory.getThreadMXBean(); ThreadInfo[] infos = bean.dumpAllThreads(true, true); for (ThreadInfo info : infos) { StackTraceElement[] elems = info.getStackTrace(); // Print out elements, etc. } 

Come accennato, se si desidera solo la traccia dello stack del thread corrente è molto più semplice – Basta usare Thread.currentThread().getStackTrace() ;

Un’altra soluzione (solo 35 31 caratteri):

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

Silly me, è Thread.currentThread().getStackTrace();

Per stringere con guava:

 Throwables.getStackTraceAsString(new Throwable()) 

Tony, come commento alla risposta accettata, ha dato quella che sembra la migliore risposta che in realtà risponde alla domanda dell’OP :

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

… l’OP NON ha chiesto come ottenere una String dallo stack trace da Exception . E anche se sono un grande fan di Apache Commons, quando c’è qualcosa di semplice come sopra non c’è motivo logico per usare una libreria esterna.

Ho un metodo di utilità che restituisce una stringa con lo 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(); } 

E solo logit come …

 ... catch (FileNotFoundException e) { logger.config(getStackTrace(e)); } 

Lo suggerisco

  Thread.dumpStack() 

è un modo più semplice e ha il vantaggio di non build effettivamente un’eccezione o un lancio quando non ci può essere alcun problema ed è molto più importante.

 try { } catch(Exception e) { StackTraceElement[] traceElements = e.getStackTrace(); //... } 

o

 Thread.currentThread().getStackTrace() 

In Java 9 c’è un nuovo modo:

 public static void showTrace() { List frames = StackWalker.getInstance( Option.RETAIN_CLASS_REFERENCE ) .walk( stream -> stream.collect( Collectors.toList() ) ); for ( StackFrame stackFrame : frames ) System.out.println( stackFrame ); } 

Forse potresti provare questo:

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

La stringa ‘errorDetail’ contiene lo stacktrace.

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

L’ultimo elemento dell’array rappresenta la parte inferiore dello stack, che è l’invocazione del metodo meno recente nella sequenza.

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

passare attraverso StackTraceElement e ottenere il risultato desiderato.

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

È ansible utilizzare l’utilità jstack se si desidera verificare lo stack di chiamate corrente del processo.

 Usage: jstack [-l]  (to connect to running process) jstack -F [-m] [-l]  (to connect to a hung process) jstack [-m] [-l]   (to connect to a core file) jstack [-m] [-l] [server_id@] (to connect to a remote debug server) Options: -F to force a thread dump. Use when jstack  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 

Ho usato le risposte di cui sopra e ho aggiunto la formattazione

 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); } } 

Ottenere stacktrace:

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

Stampa stacktrace (JAVA 9+):

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

Stampa stacktrage (JAVA 7):

 StringBuilder sb = new StringBuilder(); for (StackTraceElement st : ste) { sb.append(st.toString() + System.lineSeparator()); } System.out.println(sb); 

Questo è un vecchio post, ma ecco la mia soluzione:

 Thread.currentThread().dumpStack(); 

Maggiori informazioni e più metodi lì: http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html

System.out.println(Arrays.toString(Thread.currentThread().getStackTrace()));

Questo ti aiuterà a stampare la traccia dello stack senza loop.