Once in a while I am involved in the recruitment process of Java developers (both junior & senior) and run the technical part of the first interview. After some time I realized that with just a handful of questions you can pretty much tell whether the candidate is trying to fool you or not.
To a candidate claiming 15+ years of experience with Java including the latest and greatest features of various frameworks, from Hibernate to EJB 3.1 (and the list looked quite long on the CV), I recently asked: “how would you measure the execution time of a method?”
Candidate: “Well, I’d get a timestamp at the beginning of the method, one at the end and then I’d print or log the difference.”
Me: “Alright (that’s the first answer you would expect from anyone). But what if you can’t (for any reason) modify the method’s body?”
Candidate after a minute or so: “You can’t. You would have to do it that way. It’s the only solution.”
I don’t pretend to be an expert of some sort but I was excepting a bit more from someone who five minutes earlier claimed to have extensive knowledge of EJB 3.
Here is what I was after (this might not be the best solution – and please comment on it – but it does work and answer the question).
First I would create an interceptor (a class with a single method that is going to wrap the call to the method we want to monitor).
public class MethodExecutionTimeInterceptor {
@javax.interceptor.AroundInvoke.AroundInvoke
public Object time(javax.interceptor.InvocationContext.InvocationContext ctx) throws Exception {
Logger logger = LoggerFactory.getLogger(ctx.getMethod().getDeclaringClass());
long start = System.currentTimeMillis();
try {
return ctx.proceed();
}
finally {
logger.info("method " + ctx.getMethod().getName() + " executed in " + (System.currentTimeMillis() - start) + " milliseconds");
}
}
}
And secondly I would just annotate the method I want to measure the execution time of with the @Interceptors annotation.
@Interceptors({MethodExecutionTimeInterceptor.class})
public List<String> getAllNames() {
// do something here and return a list of String
}
That’s it.