I want to write a java annotation which times the method call. something like this:
@TimeIt
public int someMethod() { ... }
and when this method is invoked, it should output on console how long this method took
I know how to do it in python, this is what I want it to do:
from time import time, sleep
def time_it(func):
def wrapper(*args, **kwargs):
start = time()
func(*args, **kwargs)
stop = time()
print "The function", func.__name__, " took %.3f" % (stop - start)
wrapper.__name__ = func.__name__
return wrapper
@time_it
def print_something(*args, **kwargs):
print "before sleeping"
print args, kwargs
sleep(3) # wait 3 seconds
print "after sleeping"
print_something(1, 2, 3, a="what is this?")
So my questions are?
Where do I find some documentation to write something like this, I tried apt
documentation, had no luck with it.
can someone help with writing something like this?
It isn't nearly as easy in Java. The basic idea would be this:
This article would get you started: http://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html .
You might also be able to use BTrace to make this even easier: http://kenai.com/projects/btrace/pages/Home
Despite all the nay-sayers, you can do this. Java annotations cannot change the source or class files they operate on, so your options are:
1) Use a super class. The annotation processor can generate a super-class that times an abstract method. Your actual class implements this method. The downsides is that the method you want to time has to be renamed so that the super-class can provide an implementation. The result might look like this
and the annotation process would generate:
By using a naming convention to indicate which methods should be timed as the prefix "bench_" was used in my example.
2) Use a ClassFileTranformer as well as an Annotation The approach would be to create a runtime annotation that can be used to mark the methods you are interested in timing. At runtime a ClassFileTransformer is specified on the command line and it transforms the byte code to insert the timing code.
Unless you like working with byte code, using AOP is the better bet, but it IS possible.
I wondered the same thing several time and ended by writting the following start:
The annotation:
An object's interface:
An invocation handler:
An finally an entry point to test this:
This needs an improvement, since it requires Proxy to instantiate our object and so you can't really use it for "generic already written" code. But it might leads you to something more complete.