Chapter 14. Instrumentation Modes

Since it's inception JBoss AOP has introduced different modes of weaving. While the base functionality is the same, the weaving mode introduced in JBoss AOP 2.0.0 allows for more functionality. This chapter will explain a bit about the pros and cons of the different weaving modes, and what functionalities are offered.

14.1. Classic Weaving

This original weaving mode offers the full basic functionality, and comes in two flavours: 'non-optimized' and 'optimized'.

14.1.1. Non-optimized

This is the original weaving mode. It generates a minimum amount of woven code, only modyfying the target joinpoints. However, the the invocation classes end up calling the target joinpoint using reflection. Hence it will have minimum overhead at weaving time, but incur the extra cost of calling via reflection at runtime.

To use not-optimized classic weaving at compile-time, you need to specify the following parameters to the aopc ant task.

  • optimized - false
  • jboss.aop.instrumentor - org.jboss.aop.instrument.ClassicInstrumentor

An example is shown in the following build.xml snippet. Only the relevant parts are shown.

   <aopc optimized="false" compilerclasspathref="...">
      <sysproperty key="jboss.aop.instrumentor" \
         value="org.jboss.aop.instrument.ClassicInstrumentor"/>
      ...
   </aopc>
                  
         

To turn this weaving mode on when using load-time weaving, you need to specify the same flags as system properties when running your woven application. Here is an example:

   java -Djboss.aop.optimized=false \
      -Djboss.aop.instrumentor=org.jboss.aop.instrument.ClassicInstrumentor \
      [other aop and classpath settings] MyClass
         

14.1.2. Optimized

This is a development of the original weaving mode. Like the non-optimized flavour, it modifies the target joinpoints, but in addition it generates an invocation class per woven joinpoint, which calls the target joinpoint normally, avoiding the cost of calling via reflection.

To use optimized classic weaving at compile-time, you need to specify the following parameters to the aopc ant task.

  • optimized - true
  • jboss.aop.instrumentor - org.jboss.aop.instrument.ClassicInstrumentor

An example is shown in the following build.xml snippet. Only the relevant parts are shown.

   <aopc optimized="true" compilerclasspathref="...">
      <sysproperty key="jboss.aop.instrumentor" \
         value="org.jboss.aop.instrument.ClassicInstrumentor"/>
      ...
   </aopc>
                  
         

To turn this weaving mode on when using load-time weaving, you need to specify the same flags as system properties when running your woven application. Here is an example:

   java -Djboss.aop.optimized=true \
      -Djboss.aop.instrumentor=org.jboss.aop.instrument.ClassicInstrumentor \
      [other aop and classpath settings] MyClass
         

14.2. Generated Advisor Weaving

This is the weaving mode that is used by default in JBoss AOP 2.0.x. In addition to generating the invocation classes, it also generates the 'advisors'. These contain the internal book-keeping code that keeps track of the advice chains for the varoius woven joinpoints). At runtime, this means that there is less overhead of looking things up. This mode also allows for some new features in JBoss AOP 2.0.x.

This weaving mode is used by default, so you don't have to specify any extra parameters. This may change in future, so for completeness the parameter you would to pass in to the aopc ant task is.

  • jboss.aop.instrumentor - org.jboss.aop.instrument.GeneratedAdvisorInstrumentor

An example is shown in the following build.xml snippet. Only the relevant parts are shown.

   <aopc optimized="true" compilerclasspathref="...">
      <sysproperty key="jboss.aop.instrumentor" \
         value="org.jboss.aop.instrument.GeneratedAdvisorInstrumentor"/>
      ...
   </aopc>
                  
      

Similarly, for load-time weaving, the default is to use this weaving mode. If you were to need to turn it one you would pass in the GeneratedAdvisorInstrumentor when starting the JVM:

   java -Djboss.aop.instrumentor=org.jboss.aop.instrument.GeneratedAdvisorInstrumentor \
      [other aop and classpath settings] MyClass
      

Now we will look at some of the features that are available using this weaving mode.

14.2.1. Lightweight Aspects

The use of the before, after, after-throwing and finally advices as mentioned in Section 4.2, “Before/After/After-Throwing/Finally Advices” is only supported in this weaving mode.

14.2.2. Improved Instance API

The improved instance api mentioned in Section 7.4, “Improved Instance API” is only available in this weaving mode.

14.2.3. Chain Overriding of Inherited Methods

This will be explained with an example. Consider the following case:

   public class Base{
      void test(){}
   }

   public class Child{
   }

   public class ChildTest{
      void test(){}
   }
               
         
   <aop>
      <prepare expr="execution(* POJO->test())"/>
      <bind pointcut="execution(* Base->test())">
         <interceptor class="BaseInterceptor"/>
      </bind>
      <bind pointcut="execution(* Child*->test())">
         <interceptor class="ChildInterceptor"/>
      </bind>
   </aop>
   
         

Base base = new Base();                  //1
Child child = new Child();               //2
ChildTest childTest = new ChildTest();   //3

base.test();                             //4
child.test();                            //5
childTest.test();                        //6

         

With the "old" weaving we needed an exact match on methods for advices to get bound, meaning that:

  • Call 4 would get intercepted by BaseInterceptor
  • Call 5 would get intercepted by BaseInterceptor
  • Call 6 would get intercepted by ChildInterceptor

The discrepancy is between calls 5 and 6, we get different behaviour depending on if we have overridden the method or are just inheriting it, which in turn means we have to have some in-depth knowledge about our hierarchy of classes and who overrides/inherits what in order to have predictable interception.

The new weaving model matches differently, and treats inherited methods the same as overridden methods, so:

  • Call 4 would get intercepted by BaseInterceptor
  • Call 5 would get intercepted by ChildInterceptor
  • Call 6 would get intercepted by ChildInterceptor

Note that for this to work, the parent method MUST be woven. In the previous example Base.test() has been prepared.