Wednesday, June 10, 2009

JBoss AOP in a Real World scenario

See the following statement:

" Tell me what is happening between your Application Server and your Database"


AOP is not something really new, besides you can use AOP for many real scenarios nowadays, like the proposed above, so, lets do it.
Installing JBoss AOP distro in your JBoss AppServer

Download the latest JBoss AOP binary, unzip this in your hard disk, in the jboss-aop folder, you have 2 options for updating, one for JBoss 4.x and other for 5.x.
  • /jboss-aop-2.1.1.GA/jboss-40-install/jboss-aop-jdk50.deployer or
  • /jboss-aop-2.1.1.GA/jboss-50-install/jboss-aop-jdk50.deployer
Both contains a build.properties, which you must edit it and inform the following properties:
  • jboss.home= put here your App Server directory home
  • jboss.config= put here the profile which you will update the AOP capabilities (eg: aop)
In your shell, in the appropriated deployer installer dir, you will call the "ant " command, it will update your JBoss Profile.
Enabling AOP in your JBoss Profile

In your profile, in the folder $jboss_home/$profile/deploy/jboss-aop-jdk50.deployer/META-INF, you will edit the file jboss-service.xml , will change the EnableLoadtimeWeaving attribute to true, according the following image:

After you change the AOP service, you must copy to the bin directory of your JBoss, the jar file called pluggable-instrumentor.jar that is in the lib folder of your JBoss AOP home directory.

The last step, you must add the following parameter in the JAVA_OPTS in the run.conf file:

-javaagent:pluggable-instrumentor.jar

Done, your AOP is updated in your JBoss AppServer.

Intecepting every JDBC Call made from your AppServer

JBoss AOP is an AOP Framework, which combined with AppServer make this kind of task really easy, where once you have a .aop file, it is a "deployable" file, that JBoss will deploy and make our aspects live in the App Server.

We will create a simple Interceptor, which is a simple class that implements org.jboss.aop.advice.Interceptor , that everything we need, is present , see the following source code:

public class JDBCMetricInterceptor implements Inteceptor {

public JDBCMetricInterceptor() {

}

public Object invoke(Invocation invocation) throws Throwable {

StringBuilder builder = new StringBuilder();
try {
builder.append("\n\t============== JDBC CALL ===============");


if (invocation instanceof MethodInvocation) {
MethodInvocation mi = (MethodInvocation) invocation;
builder.append("\n\ttype: Method Invocation");
builder.append("\n\tmethod: " + mi.getMethod().getName());

Object[] args = mi.getArguments();

if (null != args && args.length > 0) {

builder.append(String.format("\n\tHey, I saw %s parameter(s)",
args.length));
for (Object object : args) {
builder.append(String.format(
"\n\tParameters sent: %s of %s",   object,  (null==object)? "Null parameter": object.getClass().getName()));

}

}


}

return invocation.invokeNext();
} finally {
builder.append("\n\tJDBC Invocation end");
builder.append("\n\t========================================");
logger.info(builder.toString());
}
}

}



First of all, you might think: "We can intercept the java.sql.Statement class... and that's all", but JBoss AOP can't do that with "Java Standard Classes". So we will define a "definition" that our target will be: "Every class inside the package of the HSQLDB driver , which is org.hsqldb.jdbc, besides these classes must implement the class java.sql.Connection, which we assume that will execute the SQL to the database", right? See the code of the jboss-aop.xml file:



*(..))">




Once you deploy the generated aop file, when you boot the AppServer, you will see the AOP logging our messages:

Ofcourse, create anything with JBoss AOP is easier when we have in Brazilian office some help from Flavia Rainone, thanks Flavia.

Have fun with AOP, and keep in mind that you may use that in many real scenarios, is not necessary to be so geek for find out some opportunity to use it.