Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
The SecurityManager class contains a handy method that returns the class context of the current method call. In other words, it gives you an
array of Class objects that represent the classes involved in making the current method call. For example, if Foo invoked
a method in Bar, and Bar invoked a Baz, the class context for the method call in Baz would contain Baz, Bar, and Foo, in that
order. The most recent class is always the first class in the list. The name of this method is getClassContext.
Unfortunately, with getClassContext there's one hangup: It's a protected method. However, you can violate another OO principle by exposing a protected method
through a subclass. The following DummySM class does just this:
public class DummySM extends SecurityManager
{ public Class[] context()
{ return getClassContext(); }
}
Now a method that wants to see what classes have called it can use the context method. The ShowCaller object prints the entire class context for the callme method. It checks first to see if DummySM is being used as the SecurityManager class.
public class ShowCaller extends Object
{ public ShowCaller() { }
public void callme() {
// Get the current security manager SecurityManager sm =
System.getSecurityManager();
// Make sure the security manager is a DummySM
if (sm instanceof DummySM) {
DummySM dummy = (DummySM) sm;
// Get the class context
Class classes[] = dummy.context();
// Print the context
System.out.println("Callme context:");
for (int i=0; i < classes.length; i++) {
System.out.println(classes[i]);
}
}
}
}
Following is a pair of dummy classes used for testing ShowCaller.java. Given a ShowCaller object, these objects invoke the
callme method in ShowCaller.
public class FooCaller extends Object
{ ShowCaller caller;
public FooCaller(ShowCaller caller)
{ this.caller = caller; }
public void callme()
{ caller.callme(); }
}
public class BarCaller extends Object
{ ShowCaller caller;
public BarCaller(ShowCaller caller)
{ this.caller = caller; }
public void callme()
{ caller.callme(); }
}
Finally, here is a test program to demonstrate this:
public class TestContext extends Object
{ public static void main(String[] args) {
// Set DummySM as the security manager for this program
System.setSecurityManager(new DummySM());
ShowCaller sc = new ShowCaller();
FooCaller foo = new FooCaller(sc);
BarCaller bar = new BarCaller(sc);
foo.callme();
bar.callme(); }
}
This debugging technique is useful only for standalone applications because you are not allowed to override the security manager for an applet. A note of caution: If you end up using this mechanism as part of your actual class design, you should seriously reconsider your design. During normal operation, an object should not have to know what is invoking it.
Read more about Tools & Methods in JavaWorld's Tools & Methods section.