2012-05-18 13 views
5

Voglio scrivere un semplice agente java che può stampare il nome di un metodo chiamato dal programma java instrumentato.Come utilizzare i metodi java?

Per esempio, il mio programma Java che voglio strumento è:

public class TestInstr { 

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

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

} 

Vorrei visualizzare qualcosa di simile:

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

Grazie per il vostro aiuto!

+0

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

risposta

8

È possibile utilizzare una libreria di strumentazione come Javassist per farlo.

Lasciate che vi faccia un esempio per un singolo metodo, è possibile estendere questo a tutti i metodi che utilizzano Javassist o riflessione:

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

controllare questo link per ulteriori informazioni: http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/tutorial/tutorial2.html#intro

+0

Grazie! Daro un'occhiata al javassista. – kdelemme

1

Nel metodo si potrebbe aggiungere

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

si potrebbe usare questo per ottenere l'attuale metodo

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

Non sono sicuro se questo è quello che stai cercando.

4

Mi sembra di ricordare che AspectJ può fare cose del genere; Non ho esperienza con esso, tuttavia, quindi esplorare le possibilità dipende da voi! : D

+0

Non l'ho usato ma da quello che ho sentito concordo che potrebbe essere utile guardare AspectJ. – SJuan76

+1

Anche se si desidera il controllo completo, utilizzare cglib o javassist. Ma considera l'utilizzo di Spring e "around-advice" – Xeon

1

Non credo sia facile.

L'unica opzione che posso pensare sarebbe implementare un programma di caricamento classi e sostituire le classi originali con stub creati dall'utente (Hibernate/JPA fa qualcosa del genere per il caricamento lento). Gli stub eseguiranno l'operazione richiesta e quindi chiameranno le classi originali per eseguire il lavoro. Significherebbe un pesante fardello (le chiamate di riflessione non sono economiche).

0

Se la vostra necessità è semplicemente per registrare un metodo è stato chiamato o meno, quindi la programmazione orientata all'aspetto è esatta di quello che ti serve, non importa AspectJ (statico) o Spring AOP (dinamico), entrambi forniscono potenti capacità per farlo. Tuttavia potrebbe essere necessario disporre di alcune librerie di strumenti nel caso in cui si vogliano fare più strumenti, come ad esempio tracciare il tempo di esecuzione, chiamata traccia. Spero che aiuti.

Problemi correlati