Realsolve Logo
Articles
 

Using AspectWerkz within Eclipse

How to get AspectWerkz to work within the Eclipse IDE

By Phil Zoio, January 10, 2005

AspectWerkz is a powerful, high-performance Aspect-Oriented Programming (AOP) container which allow you to decorate the functionality of Java classes, allowing code reuse in situations not well handled by OOP. The purpose of this article is not to introduce aspects, but to describe how to set up a development environment for AspectWerkz in Eclipse. The article assumes you are reasonably familiar with working with Eclipse, and also assumes you have read some of the introductory material available on the AspectWerkz web site (http://aspectwerkz.codehaus.org/). It is assumed that you are familiar with terms such as joinpoints, advice and pointcuts.

This article has been written for the following environment:

  • JDK 1.4.2
  • AspectWerkz 2.0 (RC2)
  • Eclipse 3.1

The main focus of this article is getting the AspectWerkz "Hello World" tutorial application to run in the Eclipse environment. The article assumes that you have already installed or the AspectWerkz AOP framework, or built in from source within Eclipse, as shown here.

Background

When you're working with standalone Java classes the typical build/test cycle happens in two steps; first, compile using javac, then run using the java command. When using an AOP container, the process may be not quite as straightforward. For pure reflection based AOP containers, no additional steps are necessary. However, to improve performance and add advanced features, some containers introduce new dependencies into the build or runtime environment, including additional compilation steps and modifications to the boot classpath. When integrating an AOP container into your IDE-based development environment, these dependencies need to be taken into account.

In the case of AspectWerkz, the steps involved in the build/test cycle are as follows:

In short, the development process is a more complex. There are two approaches to dealing with this problem. The more sophisticated approach is to use an Eclipse plugin. A good plugin can hide the fiddly details of deployment, allowing for a more seamless development experience. AspectWerkz will include a plugin for the first time as part of the version 2.0 release. This plugin is currently in beta, and is at a relatively early stage of development. We'll cover the usage of this plugin in the article.

The second means of integration is to use an ANT build file which includes tasks which reflect each of the steps in deployment. We'll cover the ANT build file usage next.

Integration Using ANT

1. Write an ANT build file

What makes Eclipse IDE integration a little tricky is that some of the key commands that need to be executed in an AspectWerkz development environment are in the batch file bin/aspectwerkz.bat (Windows) and bin/aspectwerkz (Unix). Running a batch file typically works well when your'e working with the command line, but is a bit clunky when working within an IDE.

We can solve this problem by creating a wrapper ANT script which can be used to execute the aspectwerkz batch file commands. Eclipse comes with good ANT integration out the box, so this option works nicely.

We start by creating a new project aw-demo which contains the following files:

In addition, the project's class path is set up to the AspectWerkz dependencies, which are found in the lib folder of the AspectWerkz home directory.

The project files are available for download here. Note that you will still need to modify your project classpath to add the required dependencies correctly before this project will build successfully.

Let's take a look at the build file. It shows a little more than we need to see right now, but its always useful to view the full listing:

<project name="Run Exec" default="offline" basedir=".">
  <description>
        Runs various tasks related to using AspectWerkz. Suitable for use in a standalone 
        environment or within an IDE such as Eclipse
    </description>
  <property file="aw.properties" />
  <property environment="env" />
  <property name="full.aw.exe" value="${aw.home}/bin/${aw.exe}" />
  <property name="offline.arg.line" value="-offline ${aop.file} 
    -cp ${classes.dir} ${classes.dir}" />
  <property name="annotation.arg.line" value="-offline ${aop.file} 
    -cp ${classes.dir} ${classes.dir}" />
  <property name="online.arg.line" value="-Daspectwerkz.definition.file=${aop.file} 
    -cp ${classes.dir} ${main.class}" />

  <path id="project.class.path">
    <pathelement location="${classes.dir}" />
    <pathelement location="${aw.home}/lib/${aw.jar}" />
    <pathelement path="${java.class.path}" />
    <fileset dir="${lib.dir}">
      <include name="*.jar" />
    </fileset>
  </path>

  <target name="clean">
    <delete dir="${classes.dir}" />
    <mkdir dir="${classes.dir}" />
  </target>

  <target name="compile">
    <javac srcdir="${src.dir}" destdir="${classes.dir}" debug="on">
      <classpath refid="project.class.path" />
    </javac>
  </target>

  <target name="annotation" depends="compile">
    <java classname="org.codehaus.aspectwerkz.annotation.AnnotationC" fork="true">
      <arg line="-src ${src.dir} -classes ${classes.dir} -verbose" />
      <classpath refid="project.class.path" />
    </java>
  </target>

  <target name="offline" depends="compile">
    <echo message="Executing ${full.aw.exe} from directory '${aop.file.dir}' with args '${offline.arg.line}'" />
    <exec dir="${aop.file.dir}" executable="${full.aw.exe}">
      <arg line="${offline.arg.line}" />
    </exec>
  </target>

  <target name="online" depends="compile">
    <echo message="Executing ${full.aw.exe} from directory '${aop.file.dir}' with args '${online.arg.line}'" />
    <exec dir="${aop.file.dir}" executable="${full.aw.exe}">
      <arg line="${online.arg.line}" />
    </exec>
  </target>

</project>  

We mentioned earlier that the build file reflects each of the steps involved in the AspectWerkz development cycle. Our key targets are as follows:

In order to get this build script working, we simply need to set up an ANT build configuration for each of the following targets: offline, annotation and online (compile is automatically called by each of the others). We see a view of this setup in the screenshot below:

ANT runtime configuration

2. Set environment properties

Of course, the build file is not going to execute successfully unless until we set up the build properties correctly for our development environment. This is the role of the entries in the file aw.properties, shown below:

aw.exe=aspectwerkz.bat
aw.home=F:/development/projects/libraries/aspectwerkz_2_0_2
aw.jar=aspectwerkz-2.0.RC2.jar
aop.file.dir=F:/development/projects/aspectwerkz/aw-demo/src/META-INF
aop.file=annotations.xml
src.dir=F:/development/projects/aspectwerkz/aw-demo/src
lib.dir=F:/development/projects/aspectwerkz/aw-demo/lib
classes.dir=F:/development/projects/aspectwerkz/aw-demo/bin
main.class=testAOP.HelloWorld

Most of these properties should be fairly self-explanatory:

Regarding the choice of the AspectWerkz definition files, there is one point to note. Any mappings defined in the file META-INF/aop.xml contained on the classpath will automatically be processed by AspectWerkz. The need for explicitly specifying aop.file.dir and aop.file is only to provide an additional (or substitute mapping file. See http://aspectwerkz.codehaus.org/deployment.html for a discussion on this.

Before running the AspectWerkz command file, you will need to set the ASPECTWERKZ_HOME environment variable. In our case, this would be set to F:/development/projects/libraries/aspectwerkz_2_0_2.

3. Set the execution properties

Finally, we need to set up our development environment to allow for execution of the target class. Of course, if we're using online weaving, this is not necessary. However, if weaving is offline, we still need to execute our target class TestAOP.HelloWorld using the java executable. Here, we simply set up an Eclipse Java application configuration for HelloWorld, with two modifications:

The screenshot below shows how this configuration is applied:

AspectWerkz runtime configuration

If we execute the application using this configuration, we get the result we expect after reading the tutorial: our decorated "Hello World" message:

before greeting...
Hello World!
after greeting ...

Running the same class using the online weaving ANT configuration, we get the not very pretty but still effective output.

Buildfile: F:\development\projects\aspectwerkz\aw-demo\src\build.xml
compile:
online:
     [echo] Executing F:/development/projects/libraries/aspectwerkz_2_0_2/bin/aspectwerkz.bat 
      from directory 'F:/development/projects/aspectwerkz/aw-demo/src/META-INF' with args 
      '-Daspectwerkz.definition.file=annotations.xml 
      -cp F:/development/projects/aspectwerkz/aw-demo/bin testAOP.HelloWorld'
     [exec] F:\jdk1.4.2\jre\bin\java -Xrunjdwp:transport=dt_socket,suspend=y,address=9300,server=y 
      -Xdebug 
      -Xbootclasspath/p:"F:\development\projects\libraries\aspectwerkz_2_0_2\lib\
      aspectwerkz-core-2.0.RC2.jar" 
      -Daspectwerkz.home="F:\development\projects\libraries\aspectwerkz_2_0_2" 
      -Daspectwerkz.definition.file=annotations.xml  
      -cp ".;F:\development\projects\libraries\aspectwerkz_2_0_2\lib\aspectwerkz-extensions-2.0.RC2.jar;
      F:\development\projects\libraries\aspectwerkz_2_0_2\lib\aspectwerkz-2.0.RC2.jar;
      F:\development\projects\libraries\aspectwerkz_2_0_2\lib\aspectwerkz-jdk14-2.0.RC2.jar;
      F:\development\projects\libraries\aspectwerkz_2_0_2\lib\dom4j-1.4.jar;
      F:\development\projects\libraries\aspectwerkz_2_0_2\lib\qdox-1.4.jar;
      F:\development\projects\libraries\aspectwerkz_2_0_2\lib\concurrent-1.3.1.jar;
      F:\development\projects\libraries\aspectwerkz_2_0_2\lib\trove-1.0.2.jar;
      F:\development\projects\libraries\aspectwerkz_2_0_2\lib\jrexx-1.1.1.jar;
      F:/development/projects/aspectwerkz/aw-demo/bin" testAOP.HelloWorld
     [exec] AspectWerkz - INFO - Pre-processor org.codehaus.aspectwerkz.transform.AspectWerkzPreProcessor 
      loaded and initialized
     [exec] AOP: before hello ...
     [exec] Hello World!
     [exec] AOP: after hello ...
BUILD SUCCESSFUL
Total time: 3 seconds

Notice how the AspectWerkz library is added to the boot classpath during execution.

4. Debug the application

High on the list of reasons for wanting to develop using an IDE is debugging support. Once you've gone through all the previous steps, setting up a debugging configuration for the offline woven HelloWorld application is trivial; just click on the debug toolbar button and the most recently executed application will be run in debug mode.

A problem with byte code modification-based AOP is the imprecise correspondence between source code and executed byte code makes debugging more tricky. Suppose you are presented with a library of source code which extensively uses aspects. It's quite difficult to find out which aspects are used just for a particular target class simply by "stepping" through the code, because many of the executed statements will not be available in source format.

The workaround is to place breakpoints in methods of any aspect classes that you suspect are bound to the target join points. Using this technique, you can quickly discover whether a binding exists between a particular aspect and join point.

The screenshot below shows the execution in debug mode of MyAspect prior to calling the HelloWorld greet() method. I was a little relieved to find that no debugging information appeared to be lost; all the debug breakpoints were reached and variable values were preserved.

Debug display

5. ANT build next steps

The build environment we have set up applies for a fairly restricted development environment, with one aspect configuration file, one target class and a single set of source and output folders. An obvious next step would be to improve the build.xml script to allow it to be more easily applied to different configurations. You could, for example, change build.xml to support loading build properties from any one of a set of properties files, and use another property as a switch for determining which properties file to load.

Integration using the AspectWerkz Plugin

While the ANT script gives you a lot of flexibility and valuable for continuous integration and automated testing, it is a bit cumbersome to use. For example, offline weaving needs to be launched manually before each execution of the target class. An Eclipse plugin offers the possibility of a much smoother integration of AspectWerkz framework into Eclipse. A beta version of an Eclipse plugin is now available from the AspectWerkz team. Instructions on how to obtain and install the plugin are available from the AspectWerkz documentation site http://docs.codehaus.org/display/AW/Eclipse+plugin.

The AspectWerkz plugin contains the following features:

The plugin is quite basic, but makes a good start in making AspectWerkz easier to use within Eclipse, and is very simple to install and get started with. The main limitation is that support is only provided for Aspect definitions described or annotations referenced in the META-INF/aop.xml file. The -Daspectwerkz.definition.file system property is not supported.

The following section describe how to set up and use the plugin:

1. Installation

The plugin can be installed from the AspectWerkz update site, http://aspectwerkz.codehaus.org/downloads/eclipse. From the Eclipse workbench, use the menus Help -> Software Updates -> Find and Install to navigate through the dowload screens. Once the plugin has been downloaded, Eclipse will restart. After that, AspectWerkz support can be added to any Java project by right clicking on the project name, then selecting the 'Enable AspectWerkz AOP' button.

We can use the same example project that we used for our ANT step-by-step guide. The libraries needed to compile, weave and run AspectWerkz applications are included in the plugin download (in the plugin's lib directory). However, these dependencies are not automatically added to the project when it is enabled. They need to be manually added to the project if not already present.

2. Running AOP Applications using the Plugin

We mentioned earlier that the AspectWerkz plugin automatically performs weaving when a project is loaded or when classes are modified. All we need to do is to set up a runtime configuration. Here you have two choices. You can either:

Before attempting to use the AspectWerkz plugin runtime configuration, make sure the JDK library tools.jar is included in your project classpath. This library can be found in the bin folder of your Java home directory. To set up an AspectWerkz plugin runtime configuration, right click on the HelloWorld class, the use the menus Use the menus Run As -> Run ... -> to get to the screen shown below:

Plugin runtime configuration

Simply add a new configuration, rename it as required, and select 'Run'

2. Viewing Aspect Markers

The AspectWerkz plugin includes source code markers for identifying how aspects have been applied to classes. This is probably the area where a plugin can add the most value; by making it easy to identify aspect usage and navigate between aspects and target pointcuts, the plugin can greatly facilitate the developer's ability to understand how AOP has been applied to a project.

The screenshot below shows how this is applied for the HelloWorld example:

Plugin navigation</< P>

The marker text hover is displayed by clicking on the arrow marker icon, or by selecting the method header and using the keys Ctrl + 1. From the marker resolution it is possible to navigate directly to the corresponding aspect file.

The markers are applied to target classes, not to aspects. There are is no corresponding aspect-centric view or marker which displays all matching pointcuts for a particular aspect. I'd expect this feature to be added in a future version, as well as other features which help to view and navigate between aspects and their target pointcuts.

Discussion

The question some may be asking is when does it make sense to use ANT, and when to use the plugin. The short answer is both. The plugin is very simple to install and get started with, and adds some obviously useful features. It is small and non-intrusive in the way that it integrates with the Eclipse workbench. The ANT script is still useful in two respects: if necessary, it can be easily adapted to overcome any restriction that may be imposed by a limitation of the plugin (such as only supporting the META-INF/aop.xml file), and can be used to support continuous integration and automated test builds.

Conclusion

AspectWerkz is a very powerful tool for developing AOP-based Java applications. However, developing using AOP takes many developers out of their comfort zone in a number of ways. One of these is that the build and execution environment is more complex. This is reflected in the tasks involved in setting up a simple AspectWerkz project in Eclipse. This tutorial has attempted to provide a reasonably simple, pragmatic approach to getting AspectWerkz to work within the IDE using ANT, and to demonstrate how to use the new AspectWerkz plugin.

This is a working document. If there are any errors, or if you disagree with anything which I have said, or have any suggestions for improvements please email me at philzoio@realsolve.co.uk.