Thursday, June 23, 2005

AspectJ, @Aspect and Java 1.3

(imported from http://blogs.codehaus.org/people/avasseur, read comments there)

Following the Backport175 release that Jonas and I have done some days ago, and since AspectJ 1.5 upcoming M3 and especially the @Aspect style is starting to take shape after some month of hard work on my side, I think it is a good timing to also explain that this @Aspect sytle, despite its name tied to these Java 5 annotations, is not at all tied to Java 5, and will bring the plain Java aspect concept to all of you using Java 1.3 and 1.4 (from the real world).



The @Aspect style is also referred as @AJ, or annotation style, or this way to write aspect with annotation that we came up with thru AspectWerkz.
It mainly means that AspectJ allows you to write an aspects using wether the well known code style or the AspectWerkz like annotation style.




// code style
public aspect SomeAspect {
void before() : execution(* Foo.bar()) {
// do some stuff
// use thisJoinPoint etc
}
}





// annotation style, here with Java 5
@Aspect
public class SomeAspect {
@Before("execution(* Foo.bar())")
void before(JoinPoint thisJoinPoint) {
// do some stuff
// use thisJoinPoint etc
}
}




And since Backport175 brings annotations to Java 1.3 while preserving the bytecode format that the Java 5 specification describes, it seamlessly allows you to use the very same AspectJ version to write @Aspect on Java 1.3 as well (but please don't call it the doclet style!)




// annotation style, backported to Java 1.3 or 1.4
/**
* @Aspect
*/
public class SomeAspect {
/**
* @Before("execution(* Foo.bar())")
*/
void before(JoinPoint thisJoinPoint) {
// do some stuff
// use thisJoinPoint etc
}
}




For the Java 1.3 to work, you just need an single little jar that contains the AspectJ defined annotations (like @interface Aspect) backported to Java 1.3 in the form of regular interfaces (ie interface Aspect) and then make sure you have those classes first when doing the weaving.
Aside, since AJC (the AspectJ compiler) is not yet integrated in the doclet parsing pipeline, you need to follow a binary weaving strategy ie:


  • develop the aspect and the application with Java 1.3 (remember it's plain Java so you can use IntelliJ if you want)

  • compile the sources with regular javac

  • post-compile with Backport175 to handle the annotations

  • binary weave with AJC

  • run





That sounds a bit cumbersome but some simple Ant script is of great help. Aside Backport175 comes with plugins for Eclipse and IntelliJ so you end up with just the binary weaving step - that is rather common.



I have made this little AspectJ extension available here (that can be used with Java 1.3)



You can also grab the source code for it, that includes a small demo here.



Just set aj.root in the build.properties to the folder that contains aspectjrt.jar and aspectjtools.jar from a recent nightly build (will work for M3, does not for M2, so use a recent one!).
Then run ant clean test.



Check the build.xml file to understand how the different build steps are performed.



In the IDE it will also popup pretty well. See for example the little green
@ signs in the margin in this IntelliJ screenshot.
@AspectJ in IntelliJ, with Java 1.3



So now we have AspectJ @Aspect straight in IntelliJ.
Off course, you'd better use Eclipse AJDT to benefit from the rich user experience that it provides when dealing with software modularity thru AOP and AspectJ.



Using Backport175 also allows to use custom annotations in the pointcuts under Java 1.3 to define stronger contract between the aspect and the application, as Adrian describes here as the Holy Trinity (when you further add dependency injection)
(the demo don't include that but I let you try it).



In a follow-up post I will also explain how the new AspectJ enhanced load time weaving ala AspectWerkz can work with Java 1.3 and 1.4 as well - since it has been a recurrent question.