« The Ted Neward Challenge (AOP without the buzzwords) | Main | Fancy a weekend in Vancouver? (and learn about AOP too...) »

June 01, 2004

AspectJ Hacks - #1 From System.out.println to switchable debug output

As an antidote to yesterday's entry, today I thought I'd just show you a simple basic hack. This isn't great coding style, and you wouldn't want to leave it in your source code for long, but it's a damn useful short-term tactic some times.

I was working in a test class that kicked off lots of asynchronous background operations. The background operations took a ProgressMonitor argument, and called done() on the ProgressMonitor when they had completed. Because this was part of a test case, I needed to block until the asynchronous operations had completed so that I could verify their results. To cut a long story short, I had some wait-and-notify stuff going on, and a whole lot of println() statements littered throughout the code to help me make sure I'd got it right (yes, I confess, I do still sometimes use System.out.printlns when I'm debugging). I now wanted to get rid of all the println statements so that the test case could run without printing lots of unwanted output to the console. Rather than delete all of the statements, or comment them out, I used an aspect to control their execution via a debug flag.

Let's pretend that the following handy class actually does something useful - it's certainly sufficient to illustrate the technique. The real class I was working with had a lot more printlns in it than this.

public class AHandyClass { public static void main(String[] args) { AHandyClass handy = new AHandyClass(); handy.doSomeComplexFunction(); } public AHandyClass() { System.out.println("Making a handy object for you"); } public void doSomeComplexFunction() { System.out.println("I'm doing the complex bit now..."); } }

Instead of deleting (I knew I'd need them again soon) or commenting out (too tedious with so many entries littered around) the println calls, I added a simple inner-aspect to the class:

public class AHandyClass { private static aspect Debug { public static final boolean debugEnabled = false; void around() : call(* PrintStream.print*(..)) && within(AHandyClass) { if (debugEnabled) proceed(); } } public static void main(String[] args) { AHandyClass handy = new AHandyClass(); handy.doSomeComplexFunction(); } public AHandyClass() { System.out.println("Making a handy object for you"); } public void doSomeComplexFunction() { System.out.println("I'm doing the complex bit now..."); } }

This works by using around advice on all the calls to print* methods on a PrintStream. The around advice only calls proceed if the debugEnabled flag is set to true, so when debug is turned off none of the calls to println get a chance to execute. The "&& within(AHandyClass)" portion of the pointcut is important as it limits the debug control to just this one class. Normally I wouldn't use around advice to simply 'remove' an unwanted call, but as a working hack it's quick and effective in this case.

It's a very short and simple program - why not cut-and-paste the source into your editor and have a play with it using the AspectJ compiler, or better still, use AJDT?

Posted by adrian at June 1, 2004 03:23 PM [permalink]

Comments

Post a comment

Thanks for signing in, . Now you can comment. (sign out)

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)


Remember me?