Applying AspectJ to an Existing Codebase

AspectJ comes as a standalone toolkit including the AspectJ compiler and a runtime jar that is required to execute AOP programs. AJDT is the AspectJ plugin for Eclipse. It builds on the standalone toolkit providing further support for AOP inside Eclipse through specialized editors and views.

As an Eclipse user my first inclination was to try AJDT to get the benefits of an IDE I am used to such as typing support, syntax checking, incremental compilation, navigation, etc. After trying AJDT on an existing project I was generally impressed with what AOP can do and wanted to keep experimenting. However I also realized that working with existing especially larger code bases can be problematic.

For once the AspectJ compiler, which needs to examine all classes targeted for code weaving is hungry for memory. While the standalone compiler releases memory as soon as it's done compiling, the AJDT plugin used the same amount of memory but didn't release it. Furthermore, the overall performance of Eclipse was impacted adversely when various views (especially the Project Explorer view) came in and out of view.

Since I was really keen on using AspectJ on a real-world, living codebase the above issues were unacceptable to me. I needed to find a way I could conveniently apply AspectJ to my existing Java projects without converting them to the AJDT project type hence bringing the potential to disrupt my regular work.

After some experimentation I arrived at a solution utilizing only the AspectJ toolkit and an Ant build file. The solution allows you to keep experimenting with AspectJ on an existing codebase while retaining the flexibility to run without any aspects at all. With it I still use Eclipse to organize aspect source files as well as to run the Ant build. However, I no longer take advantage of specialized AOP viewing and editing features inside Eclipse. This is okay because the AspectJ compiler can produce sufficient information for me to be able to look at what classes aspects were woven into.

Here is a high-level description of the solution:

A few slightly more detailed tips:

Here is a sample ant target for invoking the AspectJ compiler supporting the above guidelines :

<target name="compile">
  <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
    <classpath>
      <pathelement location="${aspectj.home}/lib/aspectjtools.jar"/>
    </classpath>
  </taskdef>
  
  <iajc destDir="${aop.output}" Xlintwarnings ="true" showWeaveInfo="true">
    <argfiles>
    <pathelement location="${aop.project}/myAspectSources.lst"/>
    <pathelement location="${aop.project}/myPointcutSources.lst"/>
    </argfiles>
    <inpath>
      <pathelement location="${java.output}"/>
    </inpath>
    <classpath>
      <pathelement location="${aspectj.home}/lib/aspectjrt.jar"/>
      <path refid="java.classpath"/>
    </classpath>
  </iajc>      
</target>

Things to notice in the above ant target: