Getting started with AspectJ
J.M. Vanel 2006-03

Summary

Introduction

See the first episode (Adding some AOP in the eXist database).
I read the classic book "AspectJ in Action" . The old Xerox manual is useful also ( the AspectJ TM Programming Guide). Also here you'll find an apetizing list of uses for the AOP ( Aspect Oriented Programming ) :
http://www.eclipse.org/aspectj/doc/next/progguide/starting-development.html
I install the AJDT eclipse plugin ( see My eclipse plugins ) .

I also try the command line with the standard distribution (non-eclipse) of AspectJ :
cd /home/jmv/apps/aspectj1.5
bin/ajc -classpath lib/aspectjrt.jar Permission.aj

Introducing Aspects in the eXist XML database

Setting up a real eclipse project

I begin right away to work on a real software, namely our eXist database . The first step is to convert an existing eXist eclipse project :-) into an AspectJ project ( in the right-click pulldown : AspectJ tools / convert to AspectJ project ) .

Note that the AspectJ plugin does a global weaving at this time, which can take some time .


It's not good to use alternatively an eclipse project as AspectJ or non-AspectJ . So I made a linked copy eXist-1.0-linked of the source, libraries, and runtime files , to share just that , while the build and eclipse configuration are distinct :
mkdir eXist-1.0-linked
cd eXist-1.0-linked
ln -s ../eXist-1.0/src .
ln -s ../eXist-1.0/lib .
ln -s ../eXist-1.0/thirdparty/ .
ln -s ../eXist-1.0/conf.xml .
ln -s ../eXist-1.0/webapp .
ln -s ../eXist-1.0/tools .
cp ../eXist-1.0/.classpath .
cp ../eXist-1.0/.project .

Doing some aspects

Then I can right away try a first simple aspect, that just logs the call without accessing the targeted object :
        public pointcut dataModification1() :                 
call( * org.exist.xupdate.*.process(Txn) );
before() : dataModification1() {
System.out.println("pointcut dataModification0() ! ");
}
The pointcut declaration intercepts the calls to any method process() in any class in package org.exist.xupdate, with an argument Txn.
The before() declaration adds behaviour before each such call . Note that that the view "Cross References" in the lower right shows the impacted calls .

Then serious things begin : enhance that with an access to the targeted object . You see here that the parenthesis in the pointcut declaration and in the before() declaration are like an arguments list.
public pointcut dataModification2(Modification m) :
target(m) &&
call( * org.exist.xupdate.*.process(Txn) );

before(Modification m) : dataModification2(m) {
System.out.println("pointcut dataModification2() !" );
ModificationPermission.checkPermission(m);
}


This pointcut does not work : it doesn't catch anything. The reason is that Modification is abstract: its never called.

This also doesn't  match any call :  TODO explain ?????????????????

public pointcut dataModification3(Modification m) :
target(m) &&
call( * org.exist.xupdate.Modification+.process(Txn) );

before(Modification m) : dataModification3(m) {
System.out.println("pointcut dataModification() !" );
ModificationPermission.checkPermission(m);
}

Note the + after Modification meaning: "Modification or any derived class".


Now I try the another way of matching a method: with the keyword execution() :

	public pointcut test_execution() : 
execution( * org.exist.xupdate.*.process(Txn) );
before() : test_execution() {
System.out.println( "pointcut test_execution !" );
System.out.println( thisJoinPoint.getTarget().getClass() );
}

The advantage is that just the matching calls get woven, the AspectJ compiler doesn't have to check all classes for possible calls. However probably the AJDT plugin has indexed all the code probably ... TODO is this really quicker to compile ????????????


Problems with AJDT

I had memory (600M ! ) and CPU problems during a fisrt test by an old 3.2M5 eclipse with lots of plugins and a workspace shared by another instance . I wrote:

Note that the AspectJ plugin does a global weaving at this time, which can take some time .
Note also that the memory consumed raises quite a lot: with normal eclipse projects and 500 Mb of memory, I could have 2 eXist working directories opened, plus other things . Now with AspectJ 500Mb is not enough, I switched to 700Mb. It is the time to raise my computer memory from 1Gb to 2Gb . Note also that the weaving after a simple modification is quite long (about 4 minutes! ), so a quicker processor would also be handy. I currently have a Celeron at 2.4GHz .

Now with eclipse 3.2M5a and the latest zip ajdt_1.4.0.20060313055733_archive.zip I have less problems : memory 204M for 154 in a normal project . But very often when I modifiy an aspect I get :
java.lang.OutOfMemoryError
OutOfMemoryError thrown: Java heap space


Build kind = FULLBUILD
Project=eXist-1.0         kind of build requested =Full AspectJ compilation
Builder: Tidied output folder, deleted 1387 .class files from /home/jmv/src/eXist-1.0/build/classes
AJC: Starting new build for project eXist-1.0
Exception in thread "Java indexing" java.lang.OutOfMemoryError: Java heap space


I've filled a bug report :
https://bugs.eclipse.org/bugs/show_bug.cgi?id=132462

that got a positive reaction: eXist might become a test case for the AJDT compiler !

Conclusion

I have to think about all problems related to migrating an application to AspectJ:

I have no fear about the CPU load, because adding some code by hand or letting the weaving do the same in the bytecode is just equivalent. I also have no fear about the portability on several JVM, because standard bytecode is generated.

The potential applications of AspectJ in an XML database like eXist are :
Have you noticed that the AJDT plugin is among the most downloaded plugins from eclipse ?