--- /dev/null
+<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>
+
--- /dev/null
+<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 &&
+ 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>