¿Cómo obtengo el seguimiento de la pila actual en Java, como en .NET que puede hacer?Environment.StackTrace
?
Encontré, Thread.dumpStack()
pero no es lo que quiero, quiero recuperar el seguimiento de la pila, no imprimirlo.
¿Cómo obtengo el seguimiento de la pila actual en Java, como en .NET que puede hacer?Environment.StackTrace
?
Encontré, Thread.dumpStack()
pero no es lo que quiero, quiero recuperar el seguimiento de la pila, no imprimirlo.
Respuestas:
Puedes usar Thread.currentThread().getStackTrace()
.
Eso devuelve una matriz de StackTraceElement
s que representa la traza de pila actual de un programa.
String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e);
stackoverflow.com/a/10620951/11236
new Throwable().getStackTrace()
es mucho más rápido, porque no necesita verificar this != Thread.currentThread()
y omite los posibles gastos generales de JVM de llamarlo a través de child-class ( Exception extends Throwable
)
Thread.currentThread().getStackTrace();
está bien si no te importa cuál es el primer elemento de la pila.
new Throwable().getStackTrace();
tendrá una posición definida para su método actual, si eso es importante.
(new Throwable()).getStackTrace()
también se ejecuta más rápido (vea bugs.sun.com/bugdatabase/view_bug.do?bug_id=6375302 )
(new Exception()).getStackTrace()
cuando el seguimiento de la pila solicitada está en el hilo actual (que siempre será el caso paraThread.currentThread().getStackTrace();
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
new Exception().printStackTrace(System.out)
lo que puedo recordar, el bucle for probablemente tenga menos sobrecarga, pero de todos modos solo debe usar esto como una depuración ...
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { if(ste.toString().contains("mypackages")){ System.out.println(ste); } }
Thread.currentThread().getStackTrace();
está disponible desde JDK1.5.
Para una versión anterior, puede redirigir exception.printStackTrace()
a StringWriter()
:
StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
new Throwable().getStackTrace()
está disponible desde JDK1.4 ...
Puede usar los comunes de Apache para eso:
String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
org.apache.commons.lang3
, la línea completa es:org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
org.apache.commons.lang3
, lo que inicialmente pasé por alto: la importación usa en lang3
lugar de lang
y reemplaza getFullStackTrace
con getStackTrace
.
ExceptionUtils.getStackTrace(new Throwable())
expresión para obtener el seguimiento de la pila.
En Android, una forma mucho más fácil es usar esto:
import android.util.Log;
String stackTrace = Log.getStackTraceString(exception);
Para obtener el seguimiento de la pila de todos los hilos, puede usar la utilidad jstack, JConsole o enviar una señal kill -quit (en un sistema operativo Posix).
Sin embargo, si desea hacer esto mediante programación, puede intentar usar ThreadMXBean:
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] infos = bean.dumpAllThreads(true, true);
for (ThreadInfo info : infos) {
StackTraceElement[] elems = info.getStackTrace();
// Print out elements, etc.
}
Como se mencionó, si solo desea el seguimiento de la pila del hilo actual, es mucho más fácil: solo use Thread.currentThread().getStackTrace()
;
System.err.println(elems[i])
en cada uno). Falta bean.
la segunda línea del fragmento antes del, dumpAllThreads
pero supongo que la mayoría de la gente podría resolverlo.
Otra solución (solo 35 31 caracteres):
new Exception().printStackTrace();
new Error().printStackTrace();
Tony, como comentario a la respuesta aceptada, ha dado lo que parece ser la mejor respuesta que realmente responde a la pregunta del OP :
Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );
... el OP NO preguntó cómo obtener un String
seguimiento de la pila de un Exception
. Y aunque soy un gran fanático de Apache Commons, cuando hay algo tan simple como lo anterior, no hay una razón lógica para usar una biblioteca externa.
Thread.getAllStackTraces()
que le da a Map<Thread, StackTraceElement[]>
. Hotspot salvaguardará todos los subprocesos siempre que sea necesario. Zing puede llevar hilos individuales a un punto seguro sin molestar al otro. Obtener un stacktrace requiere un punto seguro. Thread.getAllStackTraces()
obtiene todos los rastros de la pila y detiene todos los hilos solo una vez. Por supuesto, debes averiguar en qué mapeo estás realmente interesado.
Sugiero que
Thread.dumpStack()
es una manera más fácil y tiene la ventaja de no construir realmente una excepción o lanzarla cuando puede que no haya ningún problema, y es considerablemente más importante.
new Exception("Stack trace").printStackTrace();
así que en realidad está construyendo un Throwable
Obteniendo stacktrace:
StackTraceElement[] ste = Thread.currentThread().getStackTrace();
Impresión de stacktrace (JAVA 8+):
Arrays.asList(ste).forEach(System.out::println);
Impresión de stacktrage (JAVA 7):
StringBuilder sb = new StringBuilder();
for (StackTraceElement st : ste) {
sb.append(st.toString() + System.lineSeparator());
}
System.out.println(sb);
En Java 9 hay una nueva forma:
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 );
}
Tengo un método de utilidad que devuelve una cadena con el 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();
}
Y solo logit como ...
...
catch (FileNotFoundException e) {
logger.config(getStackTrace(e));
}
java.util.logging.Logger#log(Level, String, Throwable)
Ya hace esto. Esto está reescribiendo cosas que ya existen en la biblioteca estándar de Java innecesariamente y está apuntando a los nuevos desarrolladores en la dirección incorrecta, que está lejos de la documentación. Al hacer esto ahora, ha obligado a Stacktrace a formatearse de cierta manera, ya que la logging
API le permite variar el formato de la instrucción de registro dinámicamente a medida que la especifica. Que yo sepa, log4j
también tiene un comportamiento similar también. No reinventes la rueda porque terminas perdiendo cosas como te he explicado.
Throwable
fuera a los Handler
s a través de las Formatter
s en 2012 que era Java7, más de lo que he enumerado aquí Y estas funciones se remontan mucho más tiempo que Java7 ha existido;. por lo tanto, J2SE 5.0 javadocs)
try {
}
catch(Exception e) {
StackTraceElement[] traceElements = e.getStackTrace();
//...
}
o
Thread.currentThread().getStackTrace()
Quizás podrías intentar esto:
catch(Exception e)
{
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
String errorDetail = writer.toString();
}
La cadena 'errorDetail' contiene el stacktrace.
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
El último elemento de la matriz representa la parte inferior de la pila, que es la invocación de método menos reciente en la secuencia.
A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName().
recorra StackTraceElement y obtenga el resultado deseado.
for (StackTraceElement ste : stackTraceElements )
{
//do your stuff here...
}
Usé respuestas de arriba y agregué formato
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);
}
}
Puede usar la utilidad jstack si desea verificar la pila de llamadas actual de su proceso.
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
Esta es una publicación antigua, pero aquí está mi solución:
Thread.currentThread().dumpStack();
Más información y más métodos allí: http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html
Thread.dumpStack()
directamente porque es un método estático.
System.out.println(Arrays.toString(Thread.currentThread().getStackTrace()));
Esto lo ayudará a imprimir el seguimiento de la pila sin bucle.