Again, I would like to endorse the usage of aspect oriented programming because it may ease development significantly. That’s almost always the case with crosscutting concerns like logging and in this post we’ll develop a solution with AspectJ. So, adding logging to your application is as easy as this:
- implement this
AbstractLoggingAspect
and define the methods you’d like to monitor - declare advice
before
,after
oraround
the logging pointcut andprintln
your logging tostdout
.
Once you’re finished with this you’ve got logging in your application without touching the original code. We’ll have a look at the details in the next sections.
If you’d like to check out the code that accompanies this post you can download the Eclipse project as tar.gz or zip; make sure to install the AspectJ Development Tools. You can browse the code online here.
The logging template
The abstract aspect I wrote was inspired by the IndentedLogging
aspect from the book AspectJ in Action by Ramnivas Laddad. My AbstractLoggingAspect
class does the following:
- indents logging and
- supplies an abstract method.
The abstract method needs to be implemented by an aspect, that defines things that should be monitored. The advice for this logging method should just print messages to stdout
with System.out
‘s println
– this way they’re getting indented.
Implementing the aspect
A subclass of AbstractLoggingAspect
implements the logging
method and uses a pointcut to define join points that should be monitored. I wrote one for the sample code like so:
@Pointcut("(execution(* *.*doEverything()) || execution(* *.*doSomething())) && !within(*Test)") protected void logging() {} |
Every execution of the methods doEverything
and doSomething
that isn’t inside a test class will be matched. After that we can write an around advice to print some logging information. If you would run the sample code it would print the following:
Entering [MyLogic.doEverything()] Doing everything... Entering [A.doSomething()] Doing : A Leaving [A.doSomething()] Entering [B.doSomething()] Doing : B Leaving [B.doSomething()] Leaving [MyLogic.doEverything()]
The calls to the different methods are logged and indented.
Conclusion
Adding fancy indented logging to your application with AspectJ is very easy: subclass the AbstractLoggingAspect
and customize the logging to your needs. After that you’ve logging in your application without changing the original code – all the work gets done inside the aspects.
hi i tried another exmaple of urs …. i have A.java, B.java, MyLogic.java and DoSomething.java
in nother package i have AbstractLoggingAspect.java and MyLoggingAspect.java where i have aspects defined
so what to do next. how to run this application? this is my question
Hi ramkumar,
run the Method
doEverything()
from theMyLogic
class – I prepared this here:MyLogicTest
. Run the latter as a JUnit test and everything should be executed just fine.If you haven’t installed the AspectJ Development Tools for Eclipse, the aspects won’t be weaved into the code and nothing special will happen. If you don’t use Eclipse or Maven2 at all, don’t forget to call the AspectJ compiler by hand.
Cheers,
Christian
Hi Christian,
I have a question about AOP and GUI:
My problem is about capturing events associated to the input (for instance, click on a button, scrolling a list, and so on). The problem is mainly related to the anonymous classes. I tried a lost of solutions, but none is good for me :
– tracing all the actionPerformed. It works quite well, BUT for my projects I want to trace only some widget, for instance the OK button, the Print button and a JTree, but nothing else on the GUI…
– modifying the GUI code in MVC or Observer pattern. OK, but I don’t want to change the programmer’s habits…
– modifying the GUI code to transform methods from anonymous classes into public methods of the associated view. OK, but I don’t want to change the programmer’s habits…
– centralizing all the actionPerformed methods into one public method of the view. OK, but I don’t want to change the programmer’s habits…
Do you have a solution to this problem?
Hi,
Can I use this approach in EJB 2.0?
Thanks,
Arjie
Dear arjie,
I haven’t tried this myself but the FAQ sounds like this should be working without any issues. Simply give it a try.