<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>BlackBox : Interesting trick to finding Java caller</title>
    <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Where technology and art disappear</description>
    <item>
      <title>Interesting trick to finding Java caller</title>
      <description>&lt;p&gt;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 &lt;a href="http://www.u.arizona.edu/~przybyls/"&gt;Leo&lt;/a&gt;. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Class.forName(new Throwable().getStackTrace()[2].getClassName()));
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will retrieve the caller name from the stacktrace and then you can get the actual class using &lt;code&gt;Class.forName()&lt;/code&gt;. He uses this in an interesting way for logging.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private static final Log getLog() {
    try {
        return LogFactory.getLog(Class.forName(new Throwable().getStackTrace()[2].getClassName()));
    }
    catch (Exception e) {
        return LogFactory.getLog(FormattedLogger.class);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which he then imports as static methods so that he can just do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;info("Some intereting INFO logging going on here");
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pretty slick and an interesting use of the Java libraries.&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 10:13:13 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:110ed7c9-0eb1-491f-9803-a7cd1f187ef8</guid>
      <author>Warner Onstine</author>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller</link>
      <category>programming</category>
      <category>java</category>
      <trackback:ping>http://www.warneronstine.com/blog/articles/trackback/312</trackback:ping>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Peter Lawrey</title>
      <description>&lt;p&gt;Another JVM specific way to do with is&lt;/p&gt;

&lt;p&gt;sun.reflect.Reflection.getCallerClass(2)&lt;/p&gt;</description>
      <pubDate>Sun, 30 Mar 2008 02:18:30 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:d267271e-5e4d-49e4-af8c-0f9632fb87f0</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-116</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Leo</title>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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().&lt;/p&gt;

&lt;p&gt;This is interesting because there can be two reason for doing this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;StackTraceElement is extremely volatile and a copy is made not to mess with the original native reference.&lt;/li&gt;
&lt;li&gt;StackTraceElement has within it direct references on the stack.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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(). &lt;/p&gt;</description>
      <pubDate>Sat, 29 Mar 2008 10:49:52 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:08a438e9-7491-419f-92b3-f8915811a87f</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-111</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Leo</title>
      <description>&lt;p&gt;I got this from J2SE 6.0 Javadocs on the Thread class. &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;On some platforms, specifying a higher value for the stackSize parameter may allow a thread to achieve greater recursion depth before throwing a StackOverflowError. Similarly, specifying a lower value may allow a greater number of threads to exist concurrently without throwing an OutOfMemoryError (or other internal error). The details of the relationship between the value of the stackSize parameter and the maximum recursion depth and concurrency level are platform-dependent. On some platforms, the value of the stackSize parameter may have no effect whatsoever.&lt;/p&gt;
    
    &lt;p&gt;The virtual machine is free to treat the stackSize parameter as a suggestion. If the specified value is unreasonably low for the platform, the virtual machine may instead use some platform-specific minimum value; if the specified value is unreasonably high, the virtual machine may instead use some platform-specific maximum. Likewise, the virtual machine is free to round the specified value up or down as it sees fit (or to ignore it completely). "&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <pubDate>Sat, 29 Mar 2008 10:08:42 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:c97e3660-7819-4b41-8be6-8af4b797206c</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-110</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Leo</title>
      <description>&lt;p&gt;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.&lt;/p&gt;</description>
      <pubDate>Sat, 29 Mar 2008 10:01:24 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:bb363e22-f476-416f-8c86-a7e0ab9c534b</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-109</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Leo</title>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Turn off debug. The -debug option in the compiler will add extra information the the stack and as a result the StackTraceElement. Line numbers for example. Basically, when you deploy your application into production, you're going to build with debug off and rest assured that this getStackTrace() becomes more efficient.&lt;/li&gt;
&lt;li&gt;Configure the size of the stack at runtime. -Xss option lets you set a size for your stack. This is the size of the stack maintained during runtime. The smaller this is, the smaller StackTraceElement[] is going to be. I'm not sure how this effects other aspects of the VM, but it will make it so getStackTrace() runs lightweight depending on what value you set.&lt;/li&gt;
&lt;/ol&gt;</description>
      <pubDate>Sat, 29 Mar 2008 09:47:17 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:f3510ee6-10a2-46ed-b922-25b29dacd932</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-108</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Leo</title>
      <description>&lt;p&gt;@Andy: You're right! You can just do Thread.getStackTrace()!&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;</description>
      <pubDate>Fri, 28 Mar 2008 11:38:02 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:c5fcb0bd-5f15-4956-a1f5-a887a0420cc1</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-102</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Ignacio Coloma</title>
      <description>&lt;p&gt;@Warner: sorry, but there is previous art. This is an old javaspecialists column:
&lt;a href="http://www.javaspecialists.co.za/archive/newsletter.do?issue=137" rel="nofollow"&gt;http://www.javaspecialists.co.za/archive/newsletter.do?issue=137&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lots of logging frameworks, like log5j, are already doing this.&lt;/p&gt;

&lt;p&gt;@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).&lt;/p&gt;</description>
      <pubDate>Fri, 28 Mar 2008 06:39:48 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:9d63e255-5cd9-4953-a7b5-8fd42708d4c1</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-101</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Notafan</title>
      <description>&lt;p&gt;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? &lt;/p&gt;

&lt;p&gt;Seems ok for test code but if it makes it to your production code you've got to question your design.&lt;/p&gt;</description>
      <pubDate>Fri, 28 Mar 2008 04:19:59 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:b48320d5-d9b6-4f24-8984-bd2eafe2bce6</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-100</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Arnaud</title>
      <description>&lt;p&gt;@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.&lt;/p&gt;

&lt;p&gt;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 -.&lt;/p&gt;</description>
      <pubDate>Fri, 28 Mar 2008 03:30:06 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:b364d8d1-5bef-40e6-a8d3-9b05de9180a4</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-99</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Gagan</title>
      <description>&lt;p&gt;Stack trace creation is a heavy operation isn't it, i wonder about the performance aspects of this?&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 19:28:30 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:2fe16e3f-ecc3-46a2-9f41-458d3dcac4ac</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-98</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Casper</title>
      <description>&lt;p&gt;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.&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 15:45:42 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:88d534ca-335d-472e-87d6-99381fa09027</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-97</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Warner Onstine</title>
      <description>&lt;p&gt;@anjun
Here's how &lt;code&gt;info()&lt;/code&gt; works&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public static final void info(String pattern, Object ... objs) {
    getLog().debug(getMessage(pattern, objs));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which you can do a static import on:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import static FormattedLogging.info
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and then directly reference in your class. This way you no longer have to do &lt;code&gt;LogFactory.getLog(MyClass.class)&lt;/code&gt;, this will do it for you automatically.&lt;/p&gt;

&lt;p&gt;@Andy
The credit belongs all to Leo :-).&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 13:51:39 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:ebe8c61e-6917-4276-ba5a-ae98e8ddad83</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-96</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by anjan bacchu</title>
      <description>&lt;p&gt;hi there,&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;I've been using the new Throwable() trick for a long time but this one I don't grok.&lt;/p&gt;

&lt;p&gt;BR,
~A&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 13:26:54 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:e3c19c59-033d-47a5-a12e-71f2e7417145</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-95</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Andy</title>
      <description>&lt;p&gt;It used to be that Thread.getStackTrace accompished its task by doing the throw too. I suspect things haven't changed. &lt;/p&gt;

&lt;p&gt;Nicely done.&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 13:15:43 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:1642e896-f8a9-4652-b6a1-64c503933d54</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-94</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Leo</title>
      <description>&lt;p&gt;It's a Throwable, but it's also probably getting the stack trace from the current Thread, so that's a good idea.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 12:29:37 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:3cf46cbd-e29d-42bf-85a7-254078d1c576</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-93</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by James</title>
      <description>&lt;p&gt;This is cool.  Now...how do you get the calling Object?&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 12:14:30 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:abe9d405-cfb1-42af-bd7b-18920795c685</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-92</link>
    </item>
    <item>
      <title>"Interesting trick to finding Java caller" by Brian</title>
      <description>&lt;p&gt;You can also just ask the current thread for its stack trace rather than creating the exception.&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 12:09:34 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:ac47ada8-1532-436a-8e16-d8aa91d3d476</guid>
      <link>http://www.warneronstine.com/blog/articles/2008/03/27/interesting-trick-to-finding-java-caller#comment-91</link>
    </item>
  </channel>
</rss>
