2012-05-18 9 views
5

Quiero escribir un simple agente de Java que puede imprimir el nombre de un método llamado por el programa Java instrumentado.¿Cómo instrumentar los métodos de Java?

Por ejemplo, mi programa Java Quiero instrumento es:

public class TestInstr { 

public static void sayHello() { 
    System.out.println("Hello !"); 
} 

public static void main(String args[]) { 
    sayHello(); 
    sayHello(); 
    sayHello(); 
} 

} 

me gustaría mostrar algo como esto:

method sayHello has been called 
Hello ! 
method sayHello has been called 
Hello ! 
method sayHello has been called 
Hello ! 

Gracias por su ayuda!

+0

http://stackoverflow.com/questions/10562769/record-every-method-execution –

Respuesta

8

Puede usar una biblioteca de instrumentación como Javassist para hacer eso.

Déjeme darle un ejemplo para un solo método, se puede extender esto a todos los métodos que utilizan Javassist o la reflexión:

ClassPool pool = ClassPool.getDefault(); 
CtClass cc = pool.get("TestInstr"); 
CtMethod m = cc.getDeclaredMethod("sayHello"); 
m.insertBefore("{ System.out.println(\"method sayHello has been called\"); }"); 
cc.writeFile(); 

Comprobar este enlace para obtener más información: http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/tutorial/tutorial2.html#intro

+0

¡Gracias! Echaré un vistazo a javassist. – kdelemme

1

En el método se podría añadir

public class TestInstr { 

public static void sayHello() { 
System.out.println("method sayHello has been called"); 
System.out.println("Hello !"); 
} 

public static void main(String args[]) { 
sayHello(); 
sayHello(); 
sayHello(); 
} 
} 

usted podría utilizar esto para conseguir el método actual

public String getCurrentMethodName() { 
StackTraceElement stackTraceElements[] = 
     (new Throwable()).getStackTrace(); 
return stackTraceElements[1].toString(); 
} 

No estoy seguro si esto es lo que estás buscando.

4

Parece que recuerdo que AspectJ puede hacer cosas como esta; No tengo experiencia con eso, sin embargo, ¡entonces explorar las posibilidades depende de usted! : D

+0

No lo he usado, pero por lo que he escuchado, estoy de acuerdo en que podría ser útil ver AspectJ. – SJuan76

+1

Además, si desea un control completo, use cglib o javassist. Pero considere usar Spring y "consejos sobre" – Xeon

1

No creo que sea fácil.

La única opción que puedo pensar sería implementar un cargador de clases y reemplazar las clases originales con trozos creados por usted (Hibernate/JPA hace algo así para la carga diferida). Los stubs realizarán la operación que necesita y luego llamará a las clases originales para realizar el trabajo. Significaría una pesada carga (las llamadas de reflexión no son baratas).

0

Si su necesidad es simplemente para grabar un método fue llamado o no, entonces la programación orientada a aspectos es exactamente lo que necesita, sin importar AspectJ (estático) o Spring AOP (dinámico), ambos proporcionan una poderosa capacidad para hacer eso. Sin embargo, es posible que necesite algunas librerías de instrumentos en caso de que quiera hacer más cosas sobre instrumentos, tales como rastrear el tiempo de ejecución, la pista de llamadas. Espero que ayude.

Cuestiones relacionadas