Interesting trick to finding Java caller 17
Have you ever wondered how to find the Class that has just called your class? Well, now you can (or rather you always could) by using this little trick that I got from my friend and former co-worker Leo.
Class.forName(new Throwable().getStackTrace()[2].getClassName()));
This will retrieve the caller name from the stacktrace and then you can get the actual class using Class.forName(). He uses this in an interesting way for logging.
private static final Log getLog() {
try {
return LogFactory.getLog(Class.forName(new Throwable().getStackTrace()[2].getClassName()));
}
catch (Exception e) {
return LogFactory.getLog(FormattedLogger.class);
}
}
Which he then imports as static methods so that he can just do:
info("Some intereting INFO logging going on here");
Pretty slick and an interesting use of the Java libraries.
Trackbacks
Use the following link to trackback from your own site:
http://www.warneronstine.com/blog/articles/trackback/312

You can also just ask the current thread for its stack trace rather than creating the exception.
This is cool. Now...how do you get the calling Object?
It's a Throwable, but it's also probably getting the stack trace from the current Thread, so that's a good idea.
Also attainable from the StackTraceElement is the method name in case you want to know who's calling you. It's useful if you want supergeneric recursion or callback by convention.
It used to be that Thread.getStackTrace accompished its task by doing the throw too. I suspect things haven't changed.
Nicely done.
hi there,
I didn't understand how getLog() gets used in info() call. Sorry for being dense -- can you explain with lil more details -- probably there are others who might not get it.
I've been using the new Throwable() trick for a long time but this one I don't grok.
BR, ~A
@anjun Here's how
info()worksWhich you can do a static import on:
and then directly reference in your class. This way you no longer have to do
LogFactory.getLog(MyClass.class), this will do it for you automatically.@Andy The credit belongs all to Leo :-).
I've used this numerous times as a means to achieve IOC during DBUnit tests, inject test data into the database by tracing the class and test method and load data from a file named the same.
Stack trace creation is a heavy operation isn't it, i wonder about the performance aspects of this?
@Gagan it must be pretty costly also I never mesure the performance it. It would probably be usefull to cache the Logger in a way or another.
I use the Exception trick to store when a connection was open to detect not close exception years ago - the state was capture in the finalizer, which print the stack trace to indicate where the leak came from -.
You've really got to be asking yourself why you are writing ugly hacks like this. It's expensive and clumsy. What if you want to use AOP to intercept calls?
Seems ok for test code but if it makes it to your production code you've got to question your design.
@Warner: sorry, but there is previous art. This is an old javaspecialists column: http://www.javaspecialists.co.za/archive/newsletter.do?issue=137
Lots of logging frameworks, like log5j, are already doing this.
@Notafan: it is already being used in my production code, and works like a charm (of course, I just use it for logging, but anyways). It works fine with aspects, but needs some tweaking to work with -javaagent (JavaRebel, for example).
@Andy: You're right! You can just do Thread.getStackTrace()!
I thought that getStackTrace() was an instance method, so I assumed you had to get the currentThread first. It's not though. It's static, so this makes things a little easier.
I did some digging and I found that the StackTraceElement[] creation is so so heavyweight. Keep in mind StackTraceElement is pretty much a bean and the array is created from a stack dump. This means there are 2 ways to tune this, so the overhead is not so great.
Sorry. In my previous comment, #2 might have been a silly suggestion. After thinking about it, decreasing the size of your stack could have really bad side-effects, and a smaller stack doesn't necessarily mean smaller StackTraceElement[] because StackTraceElement[] isn't reporting on the entire stack.
I got this from J2SE 6.0 Javadocs on the Thread class.
I looked at the J2SE sourcecode for Throwable, and I'm going to state an opinion. I don't think getStackTrace() is very heavy weight. I just did a quick test with 2 milliseconds margin of error from reporting the start and stop time to verify my assumption. The test took 4 milliseconds consistently, so getStackTrace() is negligible.
I found that getStackTraceElement() used in Throwable is a native call. getStackTraceDepth() is also native. getStackTrace() loops calls to getStackTraceElement() to create StackTraceElement[]. This is the intersting part though. Before returning, getStacktrace() does stacktrace.clone().
This is interesting because there can be two reason for doing this:
If #2 is true, then a StackTraceElement[100] is no more difficult to create than simply looping from 0 to 99. It is the clone that is the heaviest part. I think this is probably really efficient from the test that I did.
I'm going to side with new Throwable().getStackTrace() as being pretty lean in contrast to what people think. I also found that if you're really concerned about performance, some can be gained by not using Thread.getStackTrace() because it does checks to verify the currentThread. Since new Throwable().getStackTrace() uses thread-safe calls, I don't see anything to gain from Thread.getStackTrace() since it calls new Throwable().getStackTrace().
Another JVM specific way to do with is
sun.reflect.Reflection.getCallerClass(2)