Wednesday, October 11, 2006

My Experience Integrating Load Time Weaving

I use JetBrainsIntelliJ IDEA to develop Java web applications. Because of the lack of AspectJ support, I was forced to find my own solution. Reluctant to give up my highly adored refactorings and productivity tools for an IDE like Eclipse that integrates AspectJ, I set out to find a workaround. At first I tried using LTW because it seemed like the quickest, easiest, and least invasive solution. However, I was met with disaster: stack traces a mile long, resulting in a heap exception. I searched Google for solutions to the LTW stack explosion, but to no avail. Accustomed to hitting seemingly insurmountable roadblocks (after all, I am a Software Engineer), I pressed on. Next I turned to the AJC compiler; “surely I can change which compiler I use,” I thought. Quite to the contrary; for reasons unknown to me, IDEA only lets you choose between two compilers: javac and jikes. I even looked inside the .bat file and properties files for IDEA. To solve this problem I turned to using an ant script that runs post-compilation to weave my classes. However, you can only have one post-compilation task and I had more than one module that I wanted to weave. My natural reaction at this point was to hit the Google searches. After an hour of searching on how to change my compiler in IDEA to AJC I decided to reinvestigate why LTW was croaking. After a mere fifteen minutes I found a mailing list posting by Adrian Colyer, explaining what had happened: aspectj-users@eclipse.org/msg0032. Apparently there was a bug in the 1.5.2 release that caused an issue with pointcuts that match based on annotations (which Spring 2.0 does), and there was now a 1.5.2a release to address the issue. Downloading the bugfix release and plopping it into my libraries folder fixed the problem.


The forehead slap occurred when I realized that including the spring-aspects.jar implies that you want to weave both the AnnotationBeanConfigurerAspect and AnnotationTransactionAspect aspects because Spring includes an aop.xml in the META-INF inside their jar. Simply placing <exclude within="org.springframework.transaction.aspectj.AnnotationTransactionAspect" /> in your aop.xml will tell AspectJ not to use the @Transactional support from spring-aspects.jar


Using IDEA, the only change I had to make was to add the following to my JVM args in the Run/Debug dialog: -javaagent:lib/aspectjweaver.jar. See a great blog post by Adrian: A Practical Guide to Using an Aspect Library (part 1). Next, I needed to configure Tomcat for LTW in order for my webapp to function. This was as simple as adding the same JVM arg (changing the path to the jar) to my startup script. I can now sleep soundly at night, not worrying about having to abandon my beloved IDE. Now if only they’d let me write AspectJ code natively… I’ll save that one for another post.

No comments: