kdelemme
kdelemme

Reputation: 433

How to instrument java methods?

I want to write a simple java agent which can print the name of a method called by the java program instrumented.

For example, my java program I want to instrument is:

public class TestInstr {

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

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

}

I would like to display something like this :

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

Thanks for your help!

Upvotes: 6

Views: 8501

Answers (5)

swimmingfisher
swimmingfisher

Reputation: 921

If your need is simply to record a method was called or not, then aspect-oriented programming is exact what you need, no matter AspectJ(static) or Spring AOP(dynamic), both provide powerful capability to do that. However you may need some instrument libraries in case you want to do more instrument stuff, such like track the execution time, calling track. Hope it helps.

Upvotes: 0

Hakan Serce
Hakan Serce

Reputation: 11256

You can use an instrumentation library such as Javassist to do that.

Let me give you an example for a single method, you can extend this to all methods using Javassist or reflection:

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

Check this link for details: http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/tutorial/tutorial2.html#intro

Upvotes: 11

SJuan76
SJuan76

Reputation: 24780

I do not think it is easy.

The only option I can think of would be implementing a class loader and replacing the original classes with stubs created by you (Hibernate / JPA does something like that for lazy loading). The stubs would perform the operation you require and then call the original classes to perform the work. It would mean a heavy burden (reflection calls are not cheap).

Upvotes: 1

BenCole
BenCole

Reputation: 2112

I seem to remember that AspectJ can do stuff like this; I have no experience with it, however, so exploring possibilities is up to you! :D

Upvotes: 4

DCSoft
DCSoft

Reputation: 237

In the method you could add

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

You could use this to get the current method

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

I'm not sure if this is what you're looking for.

Upvotes: 1

Related Questions