2012-05-18 7 views
5

Ich möchte einen einfachen Java-Agenten schreiben, der den Namen einer vom java-Programm aufgerufenen Methode ausgeben kann.Wie instrumentiere ich Java-Methoden?

Zum Beispiel mein Java-Programm I Instrument wollen, ist:

public class TestInstr { 

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

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

} 

Ich möchte so etwas wie dies anzuzeigen: für Ihre Hilfe

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

Dank!

+0

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

Antwort

8

Sie können dafür eine Instrumentierungsbibliothek wie z. B. Javassist verwenden.

Lassen Sie mich Ihnen ein Beispiel für eine einzelne Methode, können Sie dies auf alle Methoden erweitern mit Javassist oder Reflexion:

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(); 

prüfen Link für Details: http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/tutorial/tutorial2.html#intro

+0

Danke! Ich schaue mir Javassist an. – kdelemme

1

Bei dem Verfahren kann man

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(); 
} 
} 

hinzufügen Sie diese verwenden könnte die aktuelle Methode

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

Ich bin mir nicht sicher, ob dies ist, was Sie suchen zu bekommen.

4

Ich glaube mich zu erinnern, dass AspectJ Sachen so machen kann; Ich habe jedoch noch keine Erfahrung damit. : D

+0

Ich habe es nicht verwendet, aber von dem, was ich gehört habe, stimme ich zu, dass es nützlich sein könnte, auf AspectJ zu schauen. – SJuan76

+1

Auch wenn Sie vollständige Kontrolle wollen, verwenden Sie cglib oder javassist. Aber denken Sie daran, Frühling und "Rund-Beratung" zu verwenden – Xeon

1

Ich denke nicht, dass es einfach ist.

Die einzige Option, die ich mir vorstellen kann, würde ein Klassenladeprogramm implementieren und die ursprünglichen Klassen durch Stubs ersetzen, die von Ihnen erstellt wurden (Hibernate/JPA macht so etwas zum Lazy Loading). Die Stubs führen die gewünschte Operation aus und rufen dann die ursprünglichen Klassen auf, um die Arbeit auszuführen. Es würde eine schwere Bürde bedeuten (Reflektionsrufe sind nicht billig).

0

Wenn Ihre Notwendigkeit ist einfach Um eine Methode aufzuzeichnen wurde aufgerufen oder nicht, dann Aspect-orientierte Programmierung ist genau das, was Sie brauchen, egal AspectJ (statisch) oder Spring AOP (dynamisch), beide bieten leistungsstarke Möglichkeiten, das zu tun. Sie benötigen jedoch einige Instrumentenbibliotheken für den Fall, dass Sie mehr Instrumentenmaterial wie zB die Ausführungszeit verfolgen oder den Track aufrufen möchten. Hoffe es hilft.