Runtime performance monitoring made easy

JETM AspectWerkz integration

The following how-to is a basic introduction to the JETM AspectWerkz integration.

AspectWerkz is an AOP framework that can be used to modify Java™ bytecode on-the-fly. With its help it is possible to add performance measurement code to existing Java applications purely by declaration. Even though AspectWerkz seems to lose momentum right now (because of the merger with AspectJ) it is still a very useful and mature AOP framework.

The AspectWerkz XML configuration syntax makes it very easy to add or remove performance monitoring code at compile or application load time. The so-called weaving process enhances existing Java™ classes based on the config file aop.xml that describes all monitored code fragments.

Prerequisuites

In order to use AspectWerkz you need the AspectWerkz runtime and it's dependencies. You can download AspectWerkz here. For both compile time or load time weaving add all jars below {ASPECTWERKZ_DOWLOAD}/lib to your classpath.*

The binary distribution of JETM contains source code for this howto. If you did not download JETM so far get the current distribution here and locate the sources at samples/aop/aspectwerkz.

Describe measurement points

Lets assume you have a number of service classes and database interactions you want to monitor. So the method executions you are interested in are all public methods of classes that end with Service and all public methods of classes that implement the interface Dao.

Now with AspectWerkz you can describe these points of interest using its expression language. The example below shows a so-called pointcut (which is more or less a description of code blocks). This pointcut includes both our Services classes and DAOs.

Service classes execution(public * example.aop.aspectwerkz.*Service.*(..))
DAOs execution(public * example.aop.aspectwerkz.Dao+.*(..))
<!DOCTYPE aspectwerkz PUBLIC "-//AspectWerkz//DTD 2.0//EN"
          "http://aspectwerkz.codehaus.org/dtd/aspectwerkz2.dtd">

<aspectwerkz>
  <system id="weaving-example">

    <aspect class="etm.contrib.aop.aspectwerkz.EtmAspectWerkzAspect"
            deployment-model="perJVM">

      <pointcut name="etmExample" expression="

        execution(public * example.aop.aspectwerkz.*Service.*(..))
          OR
          execution(public * example.aop.aspectwerkz.Dao+.*(..))

      "/>

      <advice name="monitor" type="around" bind-to="etmExample"/>

    </aspect>

  </system>
</aspectwerkz>

This XML configuration basically describes that we want to add performance monitoring code to our defined pointcut. The performance monitoring code itself is represented by the class EtmAspectWerkzAspect that intercepts method calls and measures execution times.

The fragment above should be saved as aop.xml to the directory META-INF and added to the application classpath. You will find the same file in src/java/META-INF in the JETM AspectWerkz example.

Weave Java™ classes and test it

Now we are ready to weave our classes and run the demo. While AspectWerkz supports several options to do so this how-to demonstrates load time weaving using the JDK 5.0 JVMTI agent facility and offline weaving using a custom ant task. For a full list of available weaving options see AspectWerkz weaving documentation.

Load-time weaving using JDK 5.0 JVMTI

If you are using JDK 5.0 you may add performance monitoring transparently. AspectWerkz ships with an JMVTI agent that can transform classes at load-time based on an aop.xml configuration file. The agent can be activated using the javaagent directive that points to the file aspectwerkz-jdk5-x.x.jar (part of the AspectWerkz distribution). The command line would look like this:

java -javaagent:/path/to/lib/aspectwerkz-jdk5-x.x.jar -cp CLASSPATH 
     example.aop.aspectwerkz.AspectWerkzExample

Please note you have to use JDK 5.0 and include the compiled example classes, META-INF/aop.xml, all AspectWerkz libraries*, jetm.jar and jetm-optional.jar to the launch CLASSPATH.

To shorten up things load-time weaving can be tested using the provided ant build file. Therefore you need to alter the file build.properties in the example root directory example/aop/aspectwerkz. Ensure the property aspectwerkz.dist.path points to a valid AspectWerkz distribution and execute the ant target loadtime-weaving. This target will compile our demo and run it with the javaagent directive providing performance monitoring results.

Offline weaving using Ant

Even though load-time weaving can add performance monitoring on demand it is sometimes better to activate this capability at project build time. Luckily AspectWerkz supports offline-weaving. Besides other options offline-weaving can be triggerd by an custom ant task. The task AspectWerkzCTask will process any kind of jar file or Java™ class and weave them according to the configuration found in META-INF/aop.xml.

The following ant snippet demonstrates offline weaving:

<!-- path that contains our demo classes -->
<path id="compile.path" location="build/classes" />

<!-- classpath that contains aspectwerkz and jetm libraries -->
<path id="library.classpath">
 <fileset dir="${aspectwerkz.dist.path}/lib"
          includes="**/*.jar"
          excludes="**/ant*.jar"/>
 <fileset dir="${jetm.dist.path}/lib"
          includes="**/*.jar"/>
</path>
  
<!-- introduce aspectwerkz ant task -->
<taskdef name="awc"
         classname="org.codehaus.aspectwerkz.compiler.AspectWerkzCTask"
         classpathref="library.classpath"/>

<!-- weave classes in compile.path -->
<awc verbose="true"
     definition="src/java/META-INF/aop.xml"
     classpathref="library.classpath"
     targetpathref="compile.path"
/>

Similar to load-time weaving you can test offline weaving using the provided ant build file. Simply execute the ant target offline-weaving in the example root directory. It will compile all example classes, post process them using the awc task and execute the example. (Again ensure that aspectwerkz.dist.path in the file build.properties points to a valid AspectWerkz distribution.)

Attention: Due to some unknown reason it is required to deploy a valid aop.xml with your application. So always ensure to have the used aop.xml in the application classpath located at META-INF/aop.xml.

*Note: Not all libraries will be required at runtime. Please check AspectWerkz manual for weaving and runtime dependencies.