]> source.dussan.org Git - aspectj.git/commitdiff
updates for ltw and annotations
authoracolyer <acolyer>
Wed, 19 Jan 2005 09:35:55 +0000 (09:35 +0000)
committeracolyer <acolyer>
Wed, 19 Jan 2005 09:35:55 +0000 (09:35 +0000)
docs/adk15ProgGuideDB/adk15notebook.xml
docs/adk15ProgGuideDB/ataspectj.xml [new file with mode: 0644]
docs/adk15ProgGuideDB/ltw.xml [new file with mode: 0644]

index d3f71630cb0dd2f94a0f2ac412a6e5269619525e..61252e6289fa38e4061b052a5e7a7950c7479b4c 100644 (file)
@@ -11,6 +11,8 @@
 <!ENTITY covariance         SYSTEM "covariance.xml">
 <!ENTITY varargs            SYSTEM "varargs.xml">
 <!ENTITY pertypewithin      SYSTEM "pertypewithin.xml">
+<!ENTITY ltw                SYSTEM "ltw.xml">
+<!ENTITY ataspectj          SYSTEM "ataspectj.xml">
 <!ENTITY miscellaneous      SYSTEM "miscellaneous.xml">
 <!ENTITY reflection         SYSTEM "reflection.xml">
 <!ENTITY grammar            SYSTEM "grammar.xml">]>
@@ -35,8 +37,9 @@
     <abstract>
       <para>
         This guide describes the changes to the AspectJ language
-        and tools in AspectJ 5. These changes are primarily, but not exclusively,
-        to support Java 5 (Tiger) features.
+        and tools in AspectJ 5. These include support for Java 5 (Tiger) features,
+        enhancements to load-time weaving, an support for an annotation-based
+        development style for aspects.
         If you are new to AspectJ, we recommend you start 
         by reading the programming guide.
       </para>
   &varargs;
   &enumeratedtypes;
   &pertypewithin;
+  &ataspectj;
   &reflection;
   &miscellaneous;
+  &ltw;
   &grammar;
 
 </book>
diff --git a/docs/adk15ProgGuideDB/ataspectj.xml b/docs/adk15ProgGuideDB/ataspectj.xml
new file mode 100644 (file)
index 0000000..0801990
--- /dev/null
@@ -0,0 +1,655 @@
+<chapter id="ataspectj" xreflabel="AtAspectJ">
+
+  <title>An Annotation Based Development Style</title>
+  
+  <sect1 id="ataspectj-intro">
+      <title>Introduction</title>
+      
+      <para>In addition to the familiar AspectJ code-based style of aspect
+      declaration, AspectJ 5 also supports an annotation-based style of 
+      aspect declaration. We informally call the set of annotations that
+      support this development style the "@AspectJ" annotations.</para>
+      
+      <para>
+          AspectJ 5 allows aspects and their members to be specified using
+          either the code style or the annotation style. Whichever style you
+          use, the AspectJ weaver ensures that your program has exactly the
+          same semantics. It is, to quote a famous advertising campaign, 
+          "a choice, not a compromise". The two styles can be mixed within
+          a single application, and even within a single source file, though
+          we doubt this latter mix will be recommended in practice.       
+      </para>
+      
+      <para>
+          The use of the @AspectJ annotations means that there are large 
+          classes of AspectJ applications that can be compiled by a regular
+          Java 5 compiler, and subsequently woven by the AspectJ weaver (for
+          example, as an additional build stage, or as late as class load-time).
+          In this chapter we introduce the @AspectJ annotations and show how
+          they can be used to declare aspects and aspect members.
+      </para>
+                        
+  </sect1>
+  
+  <sect1 id="ataspectj-aspects">
+      <title>Aspect Declarations</title>
+      
+      <para>
+      Aspect declarations are supported by the 
+      <literal>org.aspectj.lang.annotation.Aspect</literal> annotation. 
+      The declaration:      
+      </para>
+      
+     <programlisting><![CDATA[
+     @Aspect
+     public class Foo {}
+      ]]></programlisting>
+      
+      <para>Is equivalent to:</para>
+
+     <programlisting><![CDATA[
+     public aspect Foo {}
+      ]]></programlisting>
+
+    <para>Privileged aspects are declared as:</para>
+
+     <programlisting><![CDATA[
+     @Aspect(isPrivileged=true)
+     public class Foo {}
+     
+     is equivalent to...
+     
+     public privileged aspect Foo {}
+      ]]></programlisting>
+
+    <para>To specify an aspect an aspect instantiation model (the default is
+    singleton), use the <literal>instantionModel</literal> and
+    <literal>perClausePattern</literal> attributes. For example:</para>
+    
+     <programlisting><![CDATA[
+     @Aspect(instantiationModel=AspectInstantiationModel.PERTHIS,
+             perClausePattern="execution(* abc..*(..))")
+     public class Foo {}
+     
+     is equivalent to...
+     
+     public aspect Foo perthis(execution(* abc..*(..))) {}
+      ]]></programlisting>
+    
+    <para>The full definitions of the Aspect annotation type and the
+        AspectInstantiationModel enumerated type are:</para>
+
+     <programlisting><![CDATA[
+     /**
+      * Use to indicate that a class should be treated as an aspect by
+      * AspectJ's weaver.
+      */
+     @Target({ElementType.TYPE})
+     public @interface Aspect {
+       AspectInstantiationModel instantiationModel() default AspectInstantiationModel.SINGLETON;
+       String perClausePattern() default "";
+               boolean isPrivileged() default false;
+     }
+     
+     /**
+      * The different aspect instantiation models supported by AspectJ
+      */
+     public enum AspectInstantiationModel {
+      SINGLETON,
+      PERTHIS,
+      PERTARGET,
+      PERCFLOW,
+      PERCFLOWBELOW,
+      PERTYPEWITHIN
+     }
+      ]]></programlisting>
+
+  </sect1>
+  
+  <sect1 id="ataspectj-pcadvice">
+      <title>Pointcuts and Advice</title>
+      
+      <para>
+          Pointcut and advice declarations can be made using the 
+          <literal>Pointcut, Before, After, AfterReturning, AfterThrowing,</literal>
+          and <literal>Around</literal> annotations.                    
+      </para>
+      
+      <sect2>
+          <title>Pointcuts</title>
+          
+          <para>
+              Pointcuts are specified using the 
+              <literal>org.aspectj.lang.annotation.Pointcut</literal> annotation
+              on a method declaration. The method should have a <literal>void</literal>
+              return type. The parameters of the method correspond to the parameters
+              of the pointcut. The modifiers of the method correspond to the modifiers
+              of the pointcut. The method body should be empty and there should be no
+              throws clause.
+          </para>
+          
+          <para>A simple example:</para>
+
+     <programlisting><![CDATA[     
+     @Pointcut("call(* *.*(..))")
+     void anyCall() {}
+     
+     is equivalent to...
+     
+     pointcut anyCall() : call(* *.*(..));
+      ]]></programlisting>
+          
+          <para>An example with modifiers:</para>
+          
+     <programlisting><![CDATA[
+     @Pointcut("")
+     protected abstract void anyCall();
+     
+     is equivalent to...
+     
+     protected abstract pointcut anyCall();
+      ]]></programlisting>
+          
+          <para>
+          Using the code style, types referenced in pointcut expressions are 
+          resolved with respect to the imported types in the compilation unit.
+          When using the annotation style, types referenced in pointcut 
+          expressions are resolved in the absence of any imports and so have
+          to be fully qualified if they are not by default visible to the
+          declaring type (outside of the declaring package and java.lang). This
+          to not apply to type patterns with wildcards, which are always resolved
+          in a global scope.            
+          </para>
+          
+          <para>
+          Consider the following compilation unit:
+          </para>
+          
+     <programlisting><![CDATA[
+     package org.aspectprogrammer.examples;
+     
+     import java.util.List;
+     
+     public aspect Foo {
+     
+       pointcut listOperation() : call(* List.*(..));
+      
+       pointcut anyUtilityCall() : call(* java.util..*(..));
+           
+     }
+      ]]></programlisting>
+      
+      <para>
+      Using the annotation style this would be written as:      
+      </para>
+      
+     <programlisting><![CDATA[
+     package org.aspectprogrammer.examples;
+     
+     import java.util.List; // redundant but harmless
+     
+     @Aspect
+     public class Foo {
+     
+       @Pointcut("call(* java.util.List.*(..))") // must qualify
+       void listOperation() {}
+      
+       @Pointcut("call(* java.util..*(..))")
+       void anyUtilityCall() {}
+           
+     }
+      ]]></programlisting>
+      
+      <para>The <literal>value</literal> attribute of the 
+      <literal>Pointcut</literal> declaration may contain any valid
+      AspectJ pointcut declaration.</para>
+          
+      </sect2>
+      
+      <sect2>
+          <title>Advice</title>
+          
+          <para>In this section we first discuss the use of annotations for 
+          simple advice declarations. Then we show how <literal>thisJoinPoint</literal>
+          and its siblings are handled in the body of advice and discuss the 
+          treatment of <literal>proceed</literal> in around advice.</para>
+          
+          <para>Using the annotation style, an advice declaration is written as
+          a regular Java method with one of the <literal>Before, After, AfterReturning,
+          AfterThrowing,</literal> or <literal>Around</literal> annotations. Except in
+          the case of around advice, the method should return void. The method should 
+          be declared public.</para>
+             
+          <para>A method that has an advice annotation is treated exactly as an
+          advice declaration by AspectJ's weaver. This includes the join points that
+          arise when the advice is executed (an adviceexecution join point, not a 
+          method execution join point), and the restriction that advice cannot be
+          invoked explicitly (the weaver will issue an error if an advice method
+          is explicitly invoked).</para>
+          
+          <para>The following example shows a simple before advice declaration in
+          both styles:</para>
+
+     <programlisting><![CDATA[
+     before() : call(* org.aspectprogrammer..*(..)) && this(Foo) {
+       System.out.println("Call from Foo");
+     }
+     
+     is equivalent to...
+     
+     @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)")
+     public void callFromFoo() {
+       System.out.println("Call from Foo");
+     }
+      ]]></programlisting>
+          
+          <para>Notice one slight difference between the two advice declarations: in
+          the annotation style, the advice has a name, "callFromFoo". Even though
+          advice cannot be invoked explicitly, this name is useful in join point
+          matching when advising advice execution. For this reason, and to preserve
+          exact semantic equivalence between the two styles, we also support the
+          <literal>org.aspectj.lang.annotation.AdviceName</literal> annotation.
+          The exact equivalent declarations are:</para>
+
+     <programlisting><![CDATA[
+     @AdviceName("callFromFoo")
+     before() : call(* org.aspectprogrammer..*(..)) && this(Foo) {
+       System.out.println("Call from Foo");
+     }
+     
+     is equivalent to...
+     
+     @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)")
+     public void callFromFoo() {
+       System.out.println("Call from Foo");
+     }
+      ]]></programlisting>
+          
+          <para>If the advice body needs to know which particular <literal>Foo</literal>
+          was doing the calling, just add a parameter to the advice declaration.</para>
+
+     <programlisting><![CDATA[
+     @AdviceName("callFromFoo")
+     before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) {
+       System.out.println("Call from Foo: " + foo);
+     }
+     
+     is equivalent to...
+     
+     @Before("call(* org.aspectprogrammer..*(..)) && this(foo)")
+     public void callFromFoo(Foo foo) {
+       System.out.println("Call from Foo: " + foo);
+     }
+      ]]></programlisting>
+          
+          <para>If the advice body needs access to <literal>thisJoinPoint</literal>,
+          <literal>thisJoinPointStaticPart</literal>, 
+          <literal>thisEnclosingJoinPointStaticPart</literal> then these need to 
+          be declared as additional method parameters when using the annotation
+          style. In AspectJ 1.5.0 we require that these parameters be declared
+          first in the parameter list, in later releases we may relax this
+          requirement.</para>
+
+     <programlisting><![CDATA[
+     @AdviceName("callFromFoo")
+     before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) {
+       System.out.println("Call from Foo: " + foo + " at " 
+                          + thisJoinPoint);
+     }
+     
+     is equivalent to...
+     
+     @Before("call(* org.aspectprogrammer..*(..)) && this(foo)")
+     public void callFromFoo(JoinPoint thisJoinPoint, Foo foo) {
+       System.out.println("Call from Foo: " + foo + " at " 
+                          + thisJoinPoint);
+     }
+      ]]></programlisting>
+          
+          <para>Advice that needs all three variables would be declared:</para>
+
+     <programlisting><![CDATA[
+     @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)")
+     public void callFromFoo(JoinPoint thisJoinPoint, 
+                             JoinPoint.StaticPart thisJoinPointStaticPart,
+                             JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart) {
+         // ...                             
+     }
+      ]]></programlisting>
+      
+      <para>
+          <literal>JoinPoint.EnclosingStaticPart</literal> is a new (empty) sub-interface
+          of <literal>JoinPoint.StaticPart</literal> which allows the AspectJ weaver to 
+          distinguish based on type which of <literal>thisJoinPointStaticPart</literal> and
+          <literal>thisEnclosingJoinPointStaticPart</literal> should be passed in a given
+          parameter position.
+      </para>
+          
+      <para><literal>After</literal> advice declarations take exactly the same form
+      as <literal>Before</literal>, as do the forms of <literal>AfterReturning</literal>
+      and <literal>AfterThrowing</literal> that do not expose the return type or
+      thrown exception respectively.</para>
+      
+      <para>
+      To expose a return value with after returning advice simply declare the returning
+      parameter as a parameter in the method body and bind it with the "returning"
+      attribute:
+      </para>
+      
+      <programlisting><![CDATA[      
+      after() returning : criticalOperation() {
+        System.out.println("phew");
+      }
+      
+      after() returning(Foo f) : call(Foo+.new(..)) {
+        System.out.println("It's a Foo: " + f);
+      }
+      
+      can be written as...
+      
+      @AfterReturning("criticalOperation()")
+      public void phew() {
+        System.out.println("phew");
+      }
+      
+      @AfterReturning(value="call(Foo+.new(..))",returning="f")
+      public void itsAFoo(Foo f) {
+        System.out.println("It's a Foo: " + f);
+      }            
+      ]]></programlisting>
+      
+      <para>(Note the need for the "value=" prefix in front of the pointcut
+      expression in the returning case).</para>
+      
+      <para>After throwing advice works in a similar fashion, using the 
+      <literal>throwing</literal> attribute when needing to expose a 
+      thrown exception.</para>
+      
+      <para>For around advice, we have to tackle the problem of <literal>proceed</literal>.
+      One of the design goals for the annotation style is that a large class of
+      AspectJ applications should be compilable with a standard Java 5 compiler.
+      A straight call to <literal>proceed</literal> inside a method body:</para>
+
+     <programlisting><![CDATA[
+     @Around("call(* org.aspectprogrammer..*(..))")
+     public Object doNothing() {
+       return proceed(); // CE on this line                            
+     }
+      ]]></programlisting>
+      
+      
+      <para>will result in a "No such method" compilation error. For this 
+      reason AspectJ 5 defines a new sub-interface of <literal>JoinPoint</literal>, 
+      <literal>ProceedingJoinPoint</literal>. </para>
+      
+     <programlisting><![CDATA[
+     public interface ProceedingJoinPoint extends JoinPoint {
+       public Object proceed(Object... args);
+     }
+      ]]></programlisting>
+      
+      <para>The around advice given above can now be written as:</para>
+
+     <programlisting><![CDATA[
+     @Around("call(* org.aspectprogrammer..*(..))")
+     public Object doNothing(ProceedingJoinPoint thisJoinPoint) {
+       return thisJoinPoint.proceed();                             
+     }
+      ]]></programlisting>
+      
+      <para>Here's an example that uses parameters for the proceed call:</para>
+
+     <programlisting><![CDATA[
+     public aspect ProceedAspect {
+       pointcut setAge(int i): call(* setAge(..)) && args(i);
+    
+       Object around(int i): setAge(i) {
+         return proceed(i*2);
+       }
+     }
+     
+     can be written as...
+     
+     @Aspect
+     public class ProceedAspect {
+     
+       @Pointcut("call(* setAge(..)) && args(i)")
+       void setAge(int i) {}
+     
+       @Around("setAge(i)")
+       public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint, int i) {
+         return thisJoinPoint.proceed(i*2);
+       }
+     
+     }          
+      ]]></programlisting>
+      
+      </sect2>
+      
+  </sect1>
+  
+  <sect1 id="ataspectj-itds">
+      <title>Inter-type Declarations</title>
+      
+      <para>
+      Inter-type declarations are challenging to support using an annotation style.
+      It's very important to preserve the exact same semantics between the code style
+      and the annotation style. We also want to support compilation of a large set
+      of AspectJ applications using a standard Java 5 compiler. For these reasons, in
+      the initial release of AspectJ 5 we will only support inter-type declarations
+      on interfaces using the annotation style.
+      </para>
+      
+      <para>
+      Consider the following aspect:
+      </para>
+      
+     <programlisting><![CDATA[
+     public aspect MoodIndicator {
+      
+        public interface Moody {};
+        
+        private Mood Moody.mood = Mood.HAPPY;
+        
+        public Mood Moody.getMood() {
+          return mood;
+        }
+     
+        declare parents : org.xyz..* implements Moody;
+        
+        before(Moody m) : execution(* *.*(..)) && this(m) {
+           System.out.println("I'm feeling " + m.getMood());
+        }
+     }
+      ]]></programlisting>
+      
+      <para>
+      This declares an interface <literal>Moody</literal>, and then makes two
+      inter-type declarations on the interface - a field that is private to the
+      aspect, and a method that returns the mood. Within the body of the inter-type
+      declared method <literal>getMoody</literal>, the type of <literal>this</literal>
+      is <literal>Moody</literal> (the target type of the inter-type declaration).
+      </para>
+      
+      <para>Using the annotation style this aspect can be written:
+      </para>
+
+     <programlisting><![CDATA[
+     @Aspect
+     public class MoodIndicator {
+      
+        public interface Moody {
+          Mood getMood();
+        };
+        
+        @DeclareParents("org.xzy..*")
+        class MoodyImpl implements Moody {
+           private Mood mood = Mood.HAPPY;
+           
+           public Mood getMood() {
+             return mood;
+           }
+        }
+
+        @Before("execution(* *.*(..)) && this(m)")     
+        void feelingMoody(Moody m) {
+           System.out.println("I'm feeling " + m.getMood());
+        }
+     }
+      ]]></programlisting>
+      
+      <para>
+      This is very similar to the mixin mechanism supported by AspectWerkz. The 
+      effect of the <literal>@DeclareParents</literal> annotation is equivalent to
+      a declare parents statement that all types matching the type pattern implement
+      the interface implemented by the annotated class. In addition, the member
+      declarations within the annotated class are treated as inter-type declarations
+      on the implemented interface. Note how this scheme operates within the constraints
+      of Java type checking and ensures that <literal>this</literal> has access
+      to the exact same set of members as in the code style example.</para>
+      
+      <para>The annotated class may only extend <literal>Object</literal>, and may
+      only implement a single interface. The interface implemented by the class may
+      itself extend other interfaces.
+      </para>
+      
+  </sect1>
+  
+  <sect1 id="ataspectj-declare">
+      <title>Declare statements</title>
+      
+      <para>The previous section on inter-type declarations covered the case
+      of declare parents ... implements. The 1.5.0 release of AspectJ 5 will
+      not support annotation style declarations for declare parents ... extends
+      and declare soft (programs with these declarations would not in general
+      be compilable by a regular Java 5 compiler, reducing the priority of
+      their implementation). These may be supported in a future release.</para>
+      
+      <para>Declare precedence and declare annotation <emphasis>will</emphasis>
+       be supported. For declare precedence, use the <literal>@DeclarePrecedence</literal>
+       annotation as in the following example:</para>
+
+     <programlisting><![CDATA[     
+     public aspect SystemArchitecture {
+       declare precedence : Security*, TransactionSupport, Persistence;
+       
+       // ...
+     }
+     
+     can be written as:
+     
+     @Aspect
+     @DeclarePrecedence("Security*,org.xyz.TransactionSupport,org.xyz.Persistence")
+     public class SystemArchitecture {
+     
+       // ...
+     }
+      ]]></programlisting>
+     
+     <para>
+     Declare annotation is supported via annotations on a dummy type member. If the
+     <literal>Target</literal> specification of the annotation allows it, use a field,
+     otherwise declare a member of the type required by the <literal>Target</literal>.
+     For example:
+     </para>  
+     
+     <programlisting><![CDATA[
+     public aspect DeclareAnnotationExamples {
+       declare annotation : org.xyz.model..* : @BusinessDomain;
+       
+       declare annotation : public * BankAccount+.*(..) : @Secured(role="supervisor");
+       
+       declare anotation : * DAO+.* : @Persisted;
+     
+     }
+     
+     can be written as...
+     
+     @Aspect
+     public class DeclareAnnotationExamples {
+     
+       @DeclareAnnotation("org.xyz.model..*)
+       @BusinessDomain Object modelClass;
+       
+       // this example assumes that the @Secured annotation has a Target
+       // annotation with value ElementType.METHOD
+       @DeclareAnnotation("public * org.xyz.banking.BankAccount+.*(..)")
+       @Secured(role="supervisor) void bankAccountMethod();
+       
+       @DeclareAnnotation("* DAO+.*")
+       @Persisted Object daoFields;     
+     }     
+      ]]></programlisting>
+     
+     <para>We also support annotation style declarations for declare warning and
+     declare error - any corresponding warnings and errors will be emitted at
+     weave time, not when the aspects containing the declarations are compiled.
+     (This is the same behaviour as when using declare warning or error with the
+     code style). Declare warning and error declarations are made by annotating
+     a string constant whose value is the message to be issued.</para>
+     
+     <programlisting><![CDATA[
+       declare warning : call(* javax.sql..*(..)) && !within(org.xyz.daos..*)
+                       : "Only DAOs should be calling JDBC.";
+                       
+       declare error : execution(* IFoo+.*(..)) && !within(org.foo..*)
+                     : "Only foo types can implement IFoo";
+                     
+       can be written as...
+       
+       @DeclareWarning("call(* javax.sql..*(..)) && !within(org.xyz.daos..*)")
+       static final String aMessage = "Only DAOs should be calling JDBC.";
+       
+       @DeclareError("execution(* IFoo+.*(..)) && !within(org.foo..*)")
+       static final String badIFooImplementors = "Only foo types can implement IFoo";
+     
+      ]]></programlisting>
+     
+       
+  </sect1>
+  
+  <sect1 id="ataspectj-aspectof">
+      <title>aspectOf() and hasAspect() methods</title>
+      
+      <para>A central part of AspectJ's programming model is that aspects
+      written using the code style and compiled using ajc support 
+      <literal>aspectOf</literal> and <literal>hasAspect</literal> static
+      methods. When developing an aspect using the annotation style and compiling
+      using a regular Java 5 compiler, these methods will not be visible to the 
+      compiler and will result in a compilation error if another part of the
+      program tries to call them.</para>
+      
+      <para>To provide equivalent support for AspectJ applications compiled with
+          a standard Java 5 compiler, AspectJ 5 defines the <literal>Aspects</literal>
+          utility class:
+      </para>
+      
+      <programlisting><![CDATA[
+      public class Aspects {
+      
+        /* variation used for singleton, percflow, percflowbelow */
+        static<T> public static T aspectOf(T aspectType) {...} 
+
+        /* variation used for perthis, pertarget */
+        static<T> public static T aspectOf(T aspectType, Object forObject) {...} 
+
+        /* variation used for pertypewithin */
+        static<T> public static T aspectOf(T aspectType, Class forType) {...} 
+      
+        /* variation used for singleton, percflow, percflowbelow */
+        public static boolean hasAspect(Object anAspect) {...}
+        
+        /* variation used for perthis, pertarget */
+        public static boolean hasAspect(Object anAspect, Object forObject) {...}
+        
+        /* variation used for pertypewithin */
+        public static boolean hasAspect(Object anAspect, Class forType) {...}
+      }
+      ]]></programlisting>
+      
+      <para>When the AspectJ weaver sees calls to these methods, it will convert
+      them into the most efficient form possible (to get performance equivalent
+      to a direct <literal>MyAspect.aspectOf()</literal> call).</para>      
+  </sect1>
+</chapter>
+
diff --git a/docs/adk15ProgGuideDB/ltw.xml b/docs/adk15ProgGuideDB/ltw.xml
new file mode 100644 (file)
index 0000000..1f0bb9d
--- /dev/null
@@ -0,0 +1,361 @@
+<chapter id="ltw" xreflabel="Load-Time Weaving">
+    <title>Load-Time Weaving</title>
+    
+    <sect1 id="ltw-introduction">
+        <title>Introduction</title>
+        
+        <para> The AspectJ 5 weaver takes class files as input and produces class files as output.
+            The weaving process itself can take place at one of three different times: compile-time,
+            post-compile time, and load-time. The class files produced by the weaving process (and
+            hence the run-time behaviour of an application) are the same regardless of the approach
+            chosen. </para>
+            
+        <itemizedlist>
+            <listitem> Compile-time weaving is the simplest approach. When you have the source code
+                for an application, ajc will compile from source and produce woven class files as
+                output. The invocation of the weaver is integral to the ajc compilation process. The
+                aspects themselves may be in source or binary form. </listitem>
+            <listitem> Post-compile weaving (also sometimes called binary weaving) is used to weave
+                existing class files and JAR files. As with compile-time weaving,
+                the aspects used for weaving may be in source or binary form. </listitem>
+            <listitem> Load-time weaving (LTW) is simply binary weaving defered until the point that
+                a class loader loads a class file and defines the class to the JVM. To support this,
+                one or more "weaving class loaders", either provided explicitly by the run-time
+                environment or enabled through a "weaving agent" are required. </listitem>
+        </itemizedlist>
+        
+        <para> You may also hear the term "run-time weaving". We define this as the weaving of
+            classes that have already been defined to the JVM (without reloading those
+            classes). AspectJ 5 does not provide explicit support for run-time weaving although
+            simple coding patterns can support dynamically enabling and disabling advice in aspects. </para>
+        
+        <sect2>
+            <title>Weaving class files more than once</title>
+        
+            <para> By default a class file that has been woven by the AspectJ compiler cannot
+                subsequently be rewoven (passed as input to the weaver). If you are developing
+                AspectJ applications that are to be used in a load-time weaving environment, you
+                need to specify the <literal>-Xreweavable</literal> compiler option when building
+                them. This causes AspectJ to save additional state in the class files that is used
+                to support subsequent reweaving. </para>
+        </sect2>
+    </sect1>
+    
+    <sect1 id="ltw-rules">
+        <title>Load-time Weaving Requirements</title>
+    
+        <para> All load-time weaving is done in the context of a class loader, and hence the set of
+            aspects used for weaving and the types that can be woven are affected by the class
+            loader delegation model. This ensures that LTW complies with the Java 2 security model.
+            The following rules govern the interaction of load-time weaving with class loading: </para>
+    
+        <orderedlist>
+            <listitem> All aspects to be used for weaving must be defined to the weaver before any
+                types to be woven are loaded.</listitem>
+            <listitem> All abstract and concrete aspects visible to the weaver
+                are available for extending (abstract aspects) and using for weaving. 
+                A visible aspect is one defined by the
+                weaving class loader or one of its parent class loaders.</listitem>
+            <listitem>A class loader may only weave classes that it defines. It may not weave
+                classes loaded by a delegate or parent class loader.</listitem>    
+        </orderedlist>
+        
+    </sect1>
+    
+    <sect1 id="ltw-configuration">
+        <title>Configuration</title>
+        <para>AspectJ 5 supports a number of mechanisms designed to make load-time weaving as
+        easy to use as possibe. The load-time weaving mechanism is chosen through JVM startup options. 
+        Configuration files determine the set of aspects to be used for weaving and which 
+        types will be woven. Additional diagnostic options allow the user to debug the configuration and 
+        weaving process. </para>
+        
+        <sect2>
+            <title>Enabling Load-time Weaving</title>
+            <para> AspectJ 5 supports three different ways of enabling load-time weaving for
+            an application: agents, a command-line launch script, and a set of interfaces for
+            integration of AspectJ load-time weaving in custom environments. </para>
+            <variablelist>
+                <varlistentry>
+                    <term>Agents</term>
+                    <listitem>
+                        <para>AspectJ 5 ships with a number of load-time weaving agents that
+                            enable load-time weaving. These agents and their configuration
+                            are execution environment dependent.
+                            Using Java 5 for example, you can specify the "-javaagent" option
+                            to the JVM. Configuration for the supported environments is discussed
+                            later in this chapter. AspectJ 5
+                            has several agents including those that use JVMTI, and the 
+                            JRockit MAPI. </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>Command line</term>
+                    <listitem>
+                        <para> AspectJ includes a script "aj" that allows programs executed at
+                            the command line to take advantage of load-time weaving. 
+                            The script is customized when AspectJ is installed depending on the chosen 
+                            JDK. For example, for JDK 1.4 the script uses the
+                            <literal>-Djava.system.class.loader</literal> system property to replace
+                            the system class loader with a weaving class loader allowing classes 
+                            loaded from the CLASSPATH to be woven. 
+                            For JDK 1.5 the JVMTI weaving agent is used allowing classes loaded by all
+                            class loaders to be woven. Versions of the JDK prior to 1.3 are not
+                            supported by the "aj" mechanism. </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>Custom Integration</term>
+                    <listitem>
+                        <para> A public interface is provided to allow a user written class loader
+                            to instantiate a weaver and weave classes after loading and before
+                            defining them in the JVM. This enables load-time weaving to be supported in
+                            environments where no weaving agent is available. It also allows the
+                            user to explicity restrict by class loader which classes can be woven. </para>
+                    </listitem>
+                </varlistentry>
+            </variablelist>
+        </sect2>
+        
+        <sect2>
+            <title>Configuring Load-time Weaving with aop.xml files</title>
+            
+            <para>The weaver is configured using one or more <literal>META-INF/aop.xml</literal>
+                files located on the class loader search path. Each file may define a list of
+                concrete aspects to be used for weaving, type patterns describing which types
+                should woven, and a set of options to be passed to the weaver. In addition AspectJ 5
+                supports the definition of concrete aspects in XML. Aspects defined in this way
+                must extend an abstract aspect visible to the weaver. The abstract aspect
+                may define abstract pointcuts (but not abstract
+                methods). The following example shows a simple aop.xml file: </para>
+            <programlisting><![CDATA[
+          <aspectj>
+          
+            <aspects>
+              <!-- declare two existing aspects to the weaver -->
+              <aspect name="com.MyAspect"/>
+              <aspect name="com.MyAspect.Inner"/>
+
+              <!-- define a concrete aspect inline -->
+              <concrete-aspect name="com.xyz.tracing.MyTracing" extends="tracing.AbstractTracing">
+                <pointcut name="tracingScope" expression="within(org.maw.*)"/>
+              </concrete-aspect>
+                         
+              <!-- Of the set of aspects known to the weaver, use aspects matching
+                   the type pattern "com..*" for weaving. -->
+              <include within="com..*"/>
+                         
+              <!-- Do not use any aspects with the @CoolAspect annotation for weaving -->
+              <exclude within="@CoolAspect *"/>        
+                         
+            </aspects>
+
+            <weaver options="-verbose -XlazyTjp">
+              <!-- Weave types that are within the javax.* or org.aspectj.*
+                   packages. Also weave all types in the foo package that do
+                   not have the @NoWeave annotation. -->
+              <include within="javax.*"/>
+              <include within="org.aspectj.*"/>
+              <include within="(!@NoWeave foo.*) AND foo.*"/>
+            </weaver>
+          
+          </aspectj>
+          
+                 ]]></programlisting>
+          
+            <para>
+                An aop.xml file contains two key sections: "aspects" defines one
+                or more aspects to the weaver and controls which aspects are to be
+                used in the weaving process; "weaver" defines weaver options and which
+                types should be woven.
+            </para>
+            
+            <para>
+                The simplest way to define an aspect to the weaver is to 
+                specify the fully-qualified name of the aspect type in an aspect element. 
+                You can also
+                declare (and define to the weaver) aspects inline in the aop.xml file.
+                This is done using the "concrete-aspect" element. A concrete-aspect
+                declaration must provide a pointcut definition for every abstract 
+                pointcut in the abstract aspect it extends. This mechanism is a 
+                useful way of externalizing configuration for infrastructure and
+                auxiliary aspects where the pointcut definitions themselves can be
+                considered part of the configuration of the service.
+            </para>
+            
+            <para>
+                The aspects element may optionally contain one or more include and
+                exclude elements (by default, all defined aspects are used for weaving).
+                Specifying include or exclude elements restricts the set of defined
+                aspects to be used for weaving to those that are matched by an include
+                pattern, but not by an exclude pattern. The 'within' attribute accepts
+                a type pattern of the same form as a within pcd, except that &amp;&amp;
+                and || are replaced by 'AND' and 'OR'.
+            </para>
+            
+            <para>
+                The weaver element is used to pass options to the weaver and to specify
+                the set of types that should be woven. If no include elements are specified
+                then all types seen by the weaver will be woven.
+            </para>
+          
+          
+            <para> When several configuration files are visible from a given weaving class loader
+                their contents are conceptually merged (this applies to both aop.xml files
+                and to aop.properties files as described in the next section). 
+                The files are merged in the order they are
+                found on the search path (regular <literal>getResourceAsStream</literal> lookup)
+                according to the following rules: </para>
+            <itemizedlist>
+                <listitem> The set of available aspects is the set of all
+                    declared and defined aspects (<literal>aspect</literal> and
+                    <literal>concrete-aspect</literal> elements of the <literal>aspects</literal>
+                    section).</listitem>
+                <listitem>The set of aspects used for weaving is the subset of the available
+                    aspects that are matched by at least one include statement and are not matched
+                    by any exclude statements. If there are no include statements then all non-excluded
+                    aspects are included.</listitem>
+                <listitem> The set of types to be woven are those types matched by at
+                    least one weaver <literal>include</literal> element and not matched by any 
+                    weaver <literal>exclude</literal> element. If there are no weaver include
+                    statements then all non-excluded types are included.</listitem>
+                <listitem> The weaver options are derived by taking the union of the
+                    options specified in each of the weaver options attribute specifications. Where an
+                    option takes a value e.g. <literal>-warn:none</literal> the most recently defined value
+                    will be used.</listitem>
+            </itemizedlist>
+
+            <para>It is not an error for the same aspect to be defined to the weaver in 
+                more than one visible <literal>META-INF/aop.xml</literal> file. 
+                However, if a declarative concrete aspect
+                is declared in more than aop.xml file then an error will be issued.
+                 A concrete aspect 
+                defined in this way will be used to weave types loaded by the
+                class loader that loaded the aop.xml file in which it was defined. 
+                </para>
+            
+            <para> A <literal>META-INF/aop.xml</literal> file will automatically be generated when
+                using the <literal>-outjar</literal> option of the AspectJ compiler. 
+                It will simply contain a (possibly empty) set of aspect elements, one for
+                each concrete aspect included in the JAR. </para>
+        </sect2>
+        
+        <sect2>
+            <title>Configuring Load-time Weaving with Properties Files</title>
+            <para> For memory constrained environments or those without support for XML a simple
+                Java Properties file can be used to configure LTW. Just like XML files,
+                <literal>META-INF/aop.properties</literal> files are loaded from the class loader
+                search path. Everything that can be configured through XML can be configured using a
+                Properties file, with the exception of declarative concrete aspects. For example: </para>
+            <programlisting><![CDATA[
+          aspects.names=com.MyAspect,com.MyAspect.Inner
+          aspects.include=com..*
+          aspects.exclude=@CoolAspect
+
+          weaver.options=-verbose -XlazyTjp
+          weaver.include=javax.* OR org.aspectj.*
+                 ]]></programlisting>
+        </sect2>
+        
+        <sect2>
+            <title>Weaver Options</title>
+            <para> The table below lists the AspectJ options supported by LTW. All other options
+                will be ignored and a warning issued. </para>
+            <informaltable>
+                <tgroup cols="2">
+                    <thead>
+                        <row>
+                            <entry>Option</entry>
+                            <entry>Purpose</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry>
+                                <literal>-1.5</literal>
+                            </entry>
+                            <entry>Run the weaver in 1.5 mode (supports autoboxing in
+                            join point matching)</entry>
+                        </row>
+                        <row>
+                            <entry>
+                                <literal>-XlazyTjp</literal>
+                            </entry>
+                            <entry>Performance optimization for aspects making use
+                            of thisJoinPoint (non-static parts)</entry>
+                        </row>
+                        <row>
+                            <entry>
+                                <literal>-nowarn, -warn:none</literal>
+                            </entry>
+                            <entry>Suppress warning messages</entry>
+                        </row>
+                        <row>
+                            <entry>
+                                <literal>-proceedOnError</literal>
+                            </entry>
+                            <entry>Continue weaving even if errors occur (for example,
+                             "... already woven" errors)</entry>
+                        </row>
+                        <row>
+                            <entry>
+                                <literal>-verbose</literal>
+                            </entry>
+                            <entry>Issue informational messages about the weaving process</entry>
+                        </row>
+                        <row>
+                            <entry>
+                                <literal>-Xreweavable</literal>
+                            </entry>
+                            <entry>Produce class files that can subsequently be rewoven</entry>
+                        </row>
+                        <row>
+                            <entry>
+                                <literal>-Xnoinline</literal>
+                            </entry>
+                            <entry>Don't inline around advice.</entry>
+                        </row>
+                        <row>
+                            <entry>
+                                <literal>-showWeaveInfo</literal>
+                            </entry>
+                            <entry>Issue informational messages whenever the weaver touches a class file</entry>
+                        </row>
+                        <row>
+                            <entry>
+                                <literal>-XmessageHolderClass</literal>
+                            </entry>
+                            <entry>Provide alternative output destination to stderr for all weaver messages</entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </informaltable>
+        </sect2>
+    </sect1>
+    
+    <sect1 id="ltw-packaging">
+        <title>Runtime Requirements for Load-time Weaving</title>
+        <para> To use LTW the <literal>aspectjweaver.jar</literal> library must be added to the
+            classpath. This contains the AspectJ 5 runtime, weaver, weaving class loader and
+            weaving agents. It also contains the DTD for parsing XML weaving configuration files. </para>
+    </sect1>
+    
+    <sect1 id="ltw-agents">
+        <title>Supported Agents</title>
+        <sect2>
+            <title>JVMTI</title>
+            <para> When using JDK 1.5 the JVMTI agent can be used by starting the JVM with the
+                following option: </para>
+            <programlisting><![CDATA[
+                       -javaagent=aspectjweaver.jar          
+                 ]]></programlisting>
+        </sect2>
+        <sect2>
+            <title>JRockit</title>
+            <para> The JRockit agent is configured with the following JVM option: </para>
+            <programlisting><![CDATA[
+                       -Xmanagement:class=org.aspectj.weaver.tools.JRockitWeavingAgent
+                 ]]></programlisting>
+        </sect2>
+    </sect1>
+</chapter>