Presents your JAVA E-NEWSLETTER for June 3, 2002 FIND THE CALLING CLASS BY THROWING AN EXCEPTION Good object-oriented programming involves the creation of many generic components. Sometimes, when debugging these, it's useful to be able to print out the line of code that was called. In Java, if you want to output the name of the previous object for debugging purposes, throw an Exception to find out. When an Exception is thrown, a stack-trace is created. This stack-trace consists of a list of all the method calls that occurred within its current Thread. Depending on the compilation state of the class the code is in, it will also include the code file and the line number of the method call. This is a good start, but just throwing an Exception isn't much help, because the code stops and only the one Exception is displayed. The code needs to catch the Exception, analyze the stack-trace, and output the caller information. Since the current method is on the top, this means going back one level on the stack-trace. Here's an example of a class that performs this fairly generic action. It goes back two levels to include the introduction of another method call into the fray: public class Debugging { static public String getCaller( ) { try { throw new RuntimeException("Temporary Exception"); } catch(RuntimeException re) { // catch the trace in a StringWriter StringWriter sw = new StringWriter( ); PrintWriter pw = new PrintWriter(sw); re.printStackTrace(pw); pw.flush( ); // manipulate the trace to find the right line. // the right line is two levels back on the trace. String str = sw.toString( ); int idx = str.indexOf(')'); idx = str.indexOf(')', idx + 1); idx = str.indexOf(')', idx + 1); int ldx = str.lastIndexOf(' ', idx); return str.substring(ldx+1, idx+1); } } } The method you use to find the right line in the trace, such as parsing '\n' characters, is not important. NOTE: Not all Java Virtual Machines (JVMs) use this format, plus new versions of the Java Runtime Environment (JRE) may have a different output. The generic action is a nice static method, and it's easy to use from anywhere, such as: public class Example { public static void main(String[ ] args) { Example example = new Example(); example.one( ); } public void one( ) { two( ); } public void two( ) { System.err.println( Debugging.getCaller( ) ); } } This example will output: java Example Example.one(Example.java:9) Building on the simple debugging class allows you to perform debugging with ease. However, the code shouldn't go to a production system, since throwing an Exception per debug statement is time consuming. ----------------------------------------