Pergunta

Eu quero escrever um simples visualização de um programa Java, exibindo chamadas de método do programa como galhos de uma árvore. Isso poderia ser feito muito simplesmente por ter o programa em si contar a visualização o que está fazendo, mas eu quero ser capaz de fazer isso com qualquer Java método / classe e não apenas aqueles que modificam a fazê-lo.

O que eu preciso é a capacidade de assistir os métodos de um programa chama e que métodos são chamados dentro desse método e assim por diante. Obviamente, os rastreamentos de pilha fornecer exatamente essa funcionalidade:

 java.lang.NullPointerException
     at MyClass.mash(MyClass.java:9)
     at MyClass.crunch(MyClass.java:6)
     at MyClass.main(MyClass.java:3)

Então eu pensei em ter o programa que eu quero para monitorar execução em um fio e, em seguida, basta olhar para pilha que thread. No entanto, a classe thread não realmente apoiar esta. Ele suporta apenas imprimir a pilha atual.

Agora eu, é claro, pensou em simplesmente mudando a PrintStream da classe do sistema para o segmento iria imprimir sua pilha em minha PrintStream, mas este se sente tipo de errado.

Existe uma maneira melhor de fazer isso? Há algum pré-existentes classes / métodos posso usar?

Além disso, estou atualmente transferir o código fonte Java, para verificar como exatamente a classe Thread imprime sua pilha para que eu pudesse fio talvez subclasse e imitar o método dumpStack () com o meu próprio método getStack ().

Foi útil?

Solução 2

Oh disparar, olhando através do código fonte notei a classe thread tem um método público StackTraceElement [] getStackTrace (), ele simplesmente não estava na documentação que estava lendo. Agora me sinto idiota.

Então, sim, que parece ser a solução.

Outras dicas

Veja também a VisualVM, fornecido com versões mais recentes de Java.

Uma abordagem seria usar algo como bytecode BCEL para pré-processar o alvo para inserir chamadas para seu próprio código em cada entrada método e saída (provavelmente melhor para fazer sair envolvendo o método inteiro em um try / finally bloco, às saídas de exceção captura). A partir daí, você pode deduzir a árvore de chamadas exatamente como isso acontece.

Você pode usar AspectJ para isso. Ter um olhar para este descrição de exatamente seu caso de uso.

Tenha um olhar para o ThreadMXBean classe - é o meu fornecer o que você precisa. Essencialmente, você:

  • chamada ManagementFactory.getThreadMXBean () para obter uma instância de ThreadMXBean;
  • getAllThreadIds de chamada () no ThreadMXBean resultando enumerar tópicos atuais;
  • chamar getThreadInfo () para obter o top n pilha oligoelementos de uma determinada lista de tópicos.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top