Platinum Partner
java,logging,aspectj

Aspect Oriented Programming - A Different Aspect.

Yesterday I was having a meeting about a new project startup. At some level the meeting was stuck on an argument of logging. Well I suggested the same thing as any experienced developer would suggest... "Why don't we use the Aspects?".

Our project is running on Websphere Application Server and using JDK 1.4 which means we won't be using EJB3 or annotations. So I just tried AspectJ - although I found the examples were confusing, what I achieved was very simple and easy. Here is a basic tutorial on how to enable and using Aspects.

Let's say we have a web application running on any server consisting of several servlets and we want to know the count of servlet calls and we also want to log the parameters received. If we are in the beginning of the project we can just copy several lines of codes to all doGet or doPost methods. Seems easy but what if the project is at the end we need to add that feature and what if the required parameters are subject to change. In this case everytime we need to visit every single doGet method and change everything again.

Aspects are interceptors - you may just imagine registering an invisible listener to the methods you want to watch and Aspects just do whatever you need. What makes them great for logging is that you just register (or give a naming pattern) of the methods and from there the Aspects will watch execution or exiting of your methods. So lets code..

This our test servlet, so just imagine we have hundreds of those with different parameters and codes.

import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AspectTest extends HttpServlet implements Servlet {

public AspectTest() {
super();
}

public void doGet(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
System.out.println("*******************servlet running");
}
}


Now lets enable AspectJ, I assume you are using Eclipse and already installed AspectJ plugin. If not just use the Eclipse update site.

Right click your project and click to Convert to AspectJ Project. Now we have added AspectJ support. Next click select New > Aspect. We can code our aspect now.

public aspect AutoLog {
pointcut loggableCalls() : execution(public * *.doGet(..));

before() : loggableCalls(){
System.out.println("***getting in "+ thisJoinPoint.getSignature().toString());
}

after() : loggableCalls(){
System.out.println("***getting out "+ thisJoinPoint.getSignature().toString());
}
}


So simply, the pointcut just captures all doGet methods of all classes in all packages and then before and after methods just prints the class and method name. We can now deploy our project on server and test our servlet.
[7/18/08 10:18:59:162 EEST] 0000005f SystemOut O ***getting in void AspectTest.doGet(HttpServletRequest, HttpServletResponse)
[7/18/08 10:18:59:162 EEST] 0000005f SystemOut O *******************servlet running
[7/18/08 10:18:59:162 EEST] 0000005f SystemOut O ***getting out void AspectTest.doGet(HttpServletRequest, HttpServletResponse)


Now lets get more advanced and log all parameters going into our servlet. We only need to change our before block.

before() : loggableCalls(){
System.out.println("***getting in "+ thisJoinPoint.getSignature().toString());

Object[] obj = thisJoinPoint.getArgs();
HttpServletRequest request=(HttpServletRequest)obj[0];
Enumeration enumeration=request.getParameterNames();
while (enumeration.hasMoreElements()){
String param=enumeration.nextElement().toString();
System.out.println(param+": "+request.getParameter(param));
}
}


After we publish, lets run the servlet with some parameters...
https://localhost:9444/AspectWEB/AspectTest?a=aa&b=bb&c=mneokjnfvjr&d=nnnnnıerhvnj

And the output is..

[7/18/08 10:18:59:162 EEST] 0000005f SystemOut O ***getting in void AspectTest.doGet(HttpServletRequest, HttpServletResponse)
[7/18/08 10:18:59:162 EEST] 0000005f SystemOut O b: bb
[7/18/08 10:18:59:162 EEST] 0000005f SystemOut O a: aa
[7/18/08 10:18:59:162 EEST] 0000005f SystemOut O d: nnnnnierhvnj
[7/18/08 10:18:59:162 EEST] 0000005f SystemOut O c: mneokjnfvjr
[7/18/08 10:18:59:162 EEST] 0000005f SystemOut O *******************servlet running
[7/18/08 10:18:59:162 EEST] 0000005f SystemOut O ***getting out void AspectTest.doGet(HttpServletRequest, HttpServletResponse)



Very simple and very efficient, don't worry about the future requests of your boss or customer. All you need to change is either the before or after block. If this is not agile can please someone tell me what is?

Published at DZone with permission of {{ articles[0].authors[0].realName }}, DZone MVB. (source)

Opinions expressed by DZone contributors are their own.

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}