Friday, 18 July 2008

Aspect Oriented Programming; A diffrent aspect.

Yesterday I was having a meeting about a new project startup. At some level the meeting was stuck at on argument of logging. Well I suggested the same thing as any over than mid level 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, well although the examples i found were confusing what I achieved was very simple and easy.
Here is a basic tutorial on how to enabling and using aspects...

Lets 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 needed parameters 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 you just register (or give a naming pattern) of the methods and aspects will watch execution or exiting of your methods. So lets code..

This our test servlet 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 eclipse update site.

Right click your project and click to Convert to AspectJ Project. Now we 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 simple, the pointcut just captures all doGet methods of all classes in all packages and the before and after methods just print 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 go more advanced we want to 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 future requests of your boss or customer. All you need to change is either before or after block. If this is not agile can please someone tell me what is...

Tuesday, 15 July 2008

IBM, Rational and EJB3

This week I am attending a course at IBM. First of all I did not enroll for this class since the subject is something i already know but my company has some free seats and requested me to join. The course is Developing EJBs with Rational Developer 7. I have used RAD6 but mostly WID6 so what I thought was RAD7 must be a new version which is capable of JavaEE5 since Websphere Application Server 7 includes EJB3 support and since even there is a EJB3 pack for WAS6. Few minutes after the course started I find out I am wrong. The lecturer said RAD7 doesn't have EJB3 support but IBM is preparing version 7.5 with EJB3 support. Actually after I google some i find out the ide doesnt complain when you develop EJB3 but also it doesn't help. Actually I find it weird to have EJB support on the underlying server but not on the tool since both are from the same vendor. Beside IBM still teaching EJB 2.1 where EJB3 has been on market for years and EJB3.1 will be out soon.
Well, don't rush IBM.. please don't..