Domanda

Voglio scrivere una semplice visualizzazione di un programma Java visualizzando le chiamate del metodo del programma come rami di un albero. Questo potrebbe essere fatto semplicemente facendo in modo che il programma stesso dica alla visualizzazione cosa sta facendo, ma voglio essere in grado di farlo con qualsiasi metodo / classe Java e non solo con quelli che modifico per farlo.

Ciò di cui ho bisogno è la capacità di guardare i metodi che un programma chiama e quali metodi vengono chiamati all'interno di quel metodo e così via. Ovviamente, le tracce dello stack forniscono esattamente questa funzionalità:

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

Quindi ho pensato di far funzionare il programma che voglio monitorare in un thread e poi guardare lo stack di quel thread. Tuttavia, la classe thread non supporta davvero questo. Supporta solo stampa lo stack corrente.

Ora, ovviamente, ho pensato di cambiare semplicemente PrintStream della classe System in modo che il thread stampasse il suo stack in my PrintStream, ma questo sembra un po 'sbagliato.

C'è un modo migliore per farlo? Esistono classi / metodi preesistenti che posso usare?

Inoltre, sto attualmente scaricando il codice sorgente Java, per verificare esattamente come la classe thread stampa il suo stack in modo da poter sottoclassare il thread e imitare il metodo dumpStack () con il mio metodo getStack ().

È stato utile?

Soluzione 2

Oh spara, guardando attraverso il codice sorgente ho notato che la classe thread ha un metodo StackTraceElement pubblico [] getStackTrace (), semplicemente non era nella documentazione che stavo leggendo. Ora mi sento stupido.

Quindi sì, questa sembra essere la soluzione.

Altri suggerimenti

Guarda anche VisualVM, fornito con le ultime versioni di Java.

Un approccio potrebbe essere quello di utilizzare qualcosa come BCEL per preelaborare il bytecode di destinazione per inserire chiamate a il tuo codice su ogni metodo entry e exit (probabilmente è meglio fare exit avvolgendo l'intero metodo in un blocco try / finally, per rilevare le eccezioni). Da questo, puoi dedurre l'albero delle chiamate esattamente come accade.

Puoi usare AspectJ per questo. Dai un'occhiata a questa descrizione di esattamente il tuo caso d'uso.

Dai un'occhiata alla ThreadMXBean - posso fornire cosa hai bisogno. In sostanza, tu:

  • chiama ManagementFactory.getThreadMXBean () per ottenere un'istanza di ThreadMXBean;
  • chiama getAllThreadIds () sul ThreadMXBean risultante per enumerare i thread correnti;
  • chiama getThreadInfo () per ottenere i primi n stack elementi di traccia da un determinato elenco di thread.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top