Pregunta

Quiero escribir una visualización simple de un programa Java mostrando las llamadas a métodos del programa como ramas de un árbol. Esto se puede hacer simplemente haciendo que el programa diga a la visualización lo que está haciendo, pero quiero poder hacerlo con cualquier método / clase Java y no solo con los que modifico para hacerlo.

Lo que necesito es la capacidad de ver los métodos que llama un programa y qué métodos se llaman dentro de ese método y así sucesivamente. Obviamente, los seguimientos de pila proporcionan exactamente esta funcionalidad:

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

Así que pensé en que el programa que quiero monitorear se ejecute en un hilo y luego solo mire la pila de ese hilo. Sin embargo, la clase de subproceso realmente no admite esto. Solo admite imprimir la pila actual.

Por supuesto, pensé en simplemente cambiar PrintStream de la clase System para que el hilo imprimiera su pila en my PrintStream, pero esto se siente un poco mal.

¿Hay una mejor manera de hacer esto? ¿Hay alguna clase / método preexistente que pueda usar?

Además, actualmente estoy descargando el código fuente de Java, para comprobar cómo exactamente la clase de thread imprime su pila para poder subclasificar e imitar el método dumpStack () con mi propio método getStack ().

¿Fue útil?

Solución 2

Oh, dispara, mirando a través del código fuente, noté que la clase de subproceso tiene un método público StackTraceElement [] getStackTrace (), simplemente no estaba en la documentación que estaba leyendo. Ahora me siento tonto.

Así que sí, esa parece ser la solución.

Otros consejos

Vea también VisualVM, incluido con las últimas versiones de Java.

Un enfoque podría ser usar algo como BCEL para preprocesar el código de bytes objetivo para insertar llamadas a su propio código en cada entrada y salida de método (probablemente lo mejor es salir envolviendo todo el método en un bloque try / finally, para capturar salidas de excepción). A partir de esto, puede deducir el árbol de llamadas exactamente como sucede.

Puede usar AspectJ para eso. Eche un vistazo a esta descripción de exactamente tu caso de uso.

Echa un vistazo a la ThreadMXBean . necesitas. Esencialmente, usted:

  • llame a ManagementFactory.getThreadMXBean () para obtener una instancia de ThreadMXBean;
  • llame a getAllThreadIds () en el ThreadMXBean resultante para enumerar los subprocesos actuales;
  • llame a getThreadInfo () para obtener los elementos de seguimiento de la pila n superior de una lista dada de hilos.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top