Como obtenho o rastreamento de pilha atual em Java, como no .NET você pode fazer Environment.StackTrace?
Encontrei, Thread.dumpStack()mas não é o que eu quero - quero recuperar o rastreio da pilha, não imprimi-lo.
Como obtenho o rastreamento de pilha atual em Java, como no .NET você pode fazer Environment.StackTrace?
Encontrei, Thread.dumpStack()mas não é o que eu quero - quero recuperar o rastreio da pilha, não imprimi-lo.
Respostas:
Você pode usar Thread.currentThread().getStackTrace().
Isso retorna uma matriz de StackTraceElements que representa o rastreamento de pilha atual de um programa.
String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e); stackoverflow.com/a/10620951/11236
new Throwable().getStackTrace()é muito mais rápido, porque ele não precisa verificar this != Thread.currentThread()e ignora potenciais despesas gerais JVM de chamá-lo através de classe criança ( Exception extends Throwable)
Thread.currentThread().getStackTrace();
é bom se você não se importa qual é o primeiro elemento da pilha.
new Throwable().getStackTrace();
terá uma posição definida para o seu método atual, se isso interessar.
(new Throwable()).getStackTrace()também está executando mais rapidamente (consulte bugs.sun.com/bugdatabase/view_bug.do?bug_id=6375302 )
(new Exception()).getStackTrace()quando o rastreamento de pilha solicitado está no encadeamento atual (o que sempre será o caso paraThread.currentThread().getStackTrace();
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
new Exception().printStackTrace(System.out)que me lembro, o loop for, provavelmente tem menos sobrecarga, mas você só deve usar isso como uma coisa depuração de qualquer maneira ...
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { if(ste.toString().contains("mypackages")){ System.out.println(ste); } }
Thread.currentThread().getStackTrace();
está disponível desde o JDK1.5.
Para uma versão mais antiga, você pode redirecionar exception.printStackTrace()para StringWriter():
StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
new Throwable().getStackTrace()está disponível desde JDK1.4…
Você pode usar os recursos comuns do Apache para isso:
String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
org.apache.commons.lang3, a linha completa é:org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
org.apache.commons.lang3, o qual eu inicialmente ignorei - a importação usa em lang3vez de lange substitui getFullStackTracepor getStackTrace.
ExceptionUtils.getStackTrace(new Throwable())expressão para obter o rastreamento de pilha.
No android, uma maneira muito mais fácil é usar isso:
import android.util.Log;
String stackTrace = Log.getStackTraceString(exception);
Para obter o rastreio da pilha de todos os encadeamentos, você pode usar o utilitário jstack, JConsole, ou enviar um sinal de kill-quit (em um sistema operacional Posix).
No entanto, se você quiser fazer isso programaticamente, tente usar o ThreadMXBean:
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] infos = bean.dumpAllThreads(true, true);
for (ThreadInfo info : infos) {
StackTraceElement[] elems = info.getStackTrace();
// Print out elements, etc.
}
Como mencionado, se você deseja apenas o rastreamento de pilha do encadeamento atual, é muito mais fácil - basta usar Thread.currentThread().getStackTrace();
System.err.println(elems[i])em cada um). A segunda linha do trecho está faltando bean.antes do, dumpAllThreadsmas acho que a maioria das pessoas poderia resolver isso.
Outra solução (apenas 35 31 caracteres):
new Exception().printStackTrace();
new Error().printStackTrace();
Tony, como comentário à resposta aceita, deu a que parece ser a melhor resposta que realmente responde à pergunta do OP :
Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );
... o OP NÃO perguntou como obter um Stringdo rastreamento de pilha de um Exception. E embora eu seja um grande fã do Apache Commons, quando há algo tão simples quanto o descrito acima, não há razão lógica para usar uma biblioteca externa.
Thread.getAllStackTraces()que lhe dá a Map<Thread, StackTraceElement[]>. O ponto de acesso apontará com segurança todos os threads sempre que precisar apontar com segurança um. O Zing pode levar segmentos individuais a um ponto seguro sem incomodar o outro. Obter um rastreamento de pilha requer um ponto seguro. Thread.getAllStackTraces()obtém todos os rastreamentos de pilha e para todos os threads apenas uma vez. Obviamente, você deve descobrir em qual mapeamento você realmente está interessado.
Eu sugiro que
Thread.dumpStack()
é uma maneira mais fácil e tem a vantagem de não criar uma exceção ou uma ação de lançar quando não pode haver nenhum problema e é consideravelmente mais direto ao ponto.
new Exception("Stack trace").printStackTrace();por isso é realmente construir um Throwable
Obtendo o stacktrace:
StackTraceElement[] ste = Thread.currentThread().getStackTrace();
Rastreio de pilha de impressão (JAVA 8+):
Arrays.asList(ste).forEach(System.out::println);
Stacktrage de impressão (JAVA 7):
StringBuilder sb = new StringBuilder();
for (StackTraceElement st : ste) {
sb.append(st.toString() + System.lineSeparator());
}
System.out.println(sb);
No Java 9, há uma nova maneira:
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 );
}
Eu tenho um método utilitário que retorna uma seqüência de caracteres com o 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 apenas logit como ...
...
catch (FileNotFoundException e) {
logger.config(getStackTrace(e));
}
java.util.logging.Logger#log(Level, String, Throwable)já faz isso. Isso está reescrevendo coisas que já existem na biblioteca padrão Java desnecessariamente e está apontando novos desenvolvedores na direção errada, o que está longe da documentação. Ao fazer isso agora, você forçou o Stacktrace a ser formatado de uma certa maneira, onde a loggingAPI permite variar a formatação da instrução de log dinamicamente conforme você a especifica. Que eu saiba, log4jtambém tem um comportamento semelhante. Não reinvente a roda porque você acaba perdendo coisas como eu expliquei.
Throwablede Handlers para Formatters em 2012, que era Java7, mais do que eu listei aqui.E essas funções datam de muito mais tempo que o Java7 existe; daí o J2SE 5.0 javadocs)
Talvez você possa tentar o seguinte:
catch(Exception e)
{
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
String errorDetail = writer.toString();
}
A sequência 'errorDetail' contém o rastreamento de pilha.
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
O último elemento da matriz representa a parte inferior da pilha, que é a invocação de método menos recente na sequência.
A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName().
percorrer StackTraceElement e obter o resultado desejado.
for (StackTraceElement ste : stackTraceElements )
{
//do your stuff here...
}
Usei as respostas acima e adicionei formatação
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);
}
}
Você pode usar o utilitário jstack se quiser verificar a pilha de chamadas atual do seu processo.
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
Este é um post antigo, mas aqui está a minha solução:
Thread.currentThread().dumpStack();
Mais informações e mais métodos lá: http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html
Thread.dumpStack()diretamente porque é um método estático.
System.out.println(Arrays.toString(Thread.currentThread().getStackTrace()));
Isso ajudará você a imprimir o rastreamento de pilha sem loop.