Configuration
Prev | Chapter 5. Load-Time Weaving | Next

## Configuration

New in AspectJ 5 are a number of mechanisms to make load-time weaving easy to use. 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.

### Enabling Load-time Weaving

AspectJ 5 supports several 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.

Agents

  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. Configuration for the supported environments is discussed later in this chapter.

  Using Java 5 JVMTI you can specify the `-javaagent:pathto/aspectjweaver.jar` option to the JVM.

  Using BEA JRockit and Java 1.3/1.4, the very same behavior can be obtained using BEA JRockit JMAPI features with the `-Xmanagement:class=org.aspectj.weaver.loadtime.JRockitAgent`

Command-line wrapper scripts `aj`

  The aj command runs Java programs in Java 1.4 or later by setting up `WeavingURLClassLoader` as the system class loader. For more information, see aj.

  The aj5 command runs Java programs in Java 5 by using the `-javaagent:pathto/aspectjweaver.jar` option described above. For more information, see aj.

Custom class loader

  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 explicitly restrict by class loader which classes can be woven. For more information, see aj and the API documentation and source for `WeavingURLClassLoader` and `WeavingAdapter`.

### Configuring Load-time Weaving with aop.xml files

The weaver is configured using one or more `META-INF/aop.xml` files located on the class loader search path. Each file may declare a list of 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:

              <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"
                                   precedence="com.xyz.first, *">
                    <pointcut name="tracingScope" expression="within(org.maw.*)"/>
                  </concrete-aspect>

                  <!-- Of the set of aspects declared to the weaver
                       use aspects matching the type pattern "com..*" for weaving. -->
                  <include within="com..*"/>

                  <!-- Of the set of aspects declared to the weaver
                       do not use any aspects with the @CoolAspect annotation for weaving -->
                  <exclude within="@CoolAspect *"/>

                </aspects>

                <weaver options="-verbose">
                  <!-- 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.*"/>

                  <!-- Do not weave types within the "bar" pakage -->
                  <exclude within="bar.*"/>

                  <!-- Dump all types within the "com.foo.bar" package
                       to the "./_ajdump" folder on disk (for diagnostic purposes) -->
                  <dump within="com.foo.bar.*"/>

                  <!-- Dump all types within the "com.foo.bar" package and sub-packages,
                       both before are after they are woven,
                       which can be used for byte-code generated at runtime
                  <dump within="com.foo.bar..*" beforeandafter="true"/>
                </weaver>

              </aspectj>

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.

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. Refer to the next section for more details.

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'.

Note that `include` and `exclude` elements affect all aspects declared to the weaver including those in other aop.xml files. To help avoid unexpected behaviour a lint warning is issued if an aspect is not declared as a result of of applying these filters. Also note `aspect` and `concrete-aspect` elements must be used to declare aspects to the weaver i.e. `include` and `exclude` elements cannot be used find aspects on the class loader search path.

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 visible to the weaver will be woven. In addition the `dump` element can be used capture on disk byte-code of woven classes for diagnostic purposes both before, in the case of those generated at runtime, and after the weaving process.

When several configuration files are visible from a given weaving class loader their contents are conceptually merged. The files are merged in the order they are found on the search path (with a regular `getResourceAsStream` lookup) according to the following rules:

- The set of available aspects is the set of all declared and defined aspects (`aspect` and `concrete-aspect` elements of the `aspects` section).

- 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.

- The set of types to be woven are those types matched by at least one weaver `include` element and not matched by any weaver `exclude` element. If there are no weaver include statements then all non-excluded types are included.

- 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. `-warn:none` the most recently defined value will be used.

It is not an error for the same aspect to be defined to the weaver in more than one visible `META-INF/aop.xml` file. However, if the same concrete aspect is defined in more than one 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.

A `META-INF/aop.xml` can be generated by using either the `-outxml` or `-outxmlfile` options of the AspectJ compiler. It will simply contain a (possibly empty) set of aspect elements; one for each abstract or concrete aspect defined. When used in conjuction with the `-outjar` option a JAR is produced that can be used with the aj5 command or a load-time weaving environment.

### Using Concrete Aspects

It is possible to make an abstract aspect concrete by means of the `META-INF/aop.xml` file. This is useful way to implement abstract pointcuts at deployment time, and also gives control over precedence through the `precedence` attribute of the `concrete-aspect` XML element. Consider the following:

                package mypack;

                @Aspect
                public abstract class AbstractAspect {

                    // abstract pointcut: no expression is defined
                    @Pointcut
                    abstract void scope();

                    @Before("scope() && execution(* *..doSome(..))")
                    public void before(JoinPoint jp) {
                       ....
                    }
                }

This aspect is equivalent to the following in code style:

                package mypack;

                public abstract aspect AbstractAspect {

                    // abstract pointcut: no expression is defined
                    abstract pointcut scope();

                    before() : scope() && execution(* *..doSome(..)) {
                       ....
                    }
                }

This aspect (in either style) can be made concrete using `META-INF/aop.xml`. It defines the abstract pointcut `scope()`. When using this mechanism the following rules apply:

- The parent aspect must be abstract. It can be an @AspectJ or a regular code style aspect.

- Only a simple abstract pointcut can be implemented i.e. a pointcut that doesn't expose state (through `args(), this(), target(), if()`). In @AspectJ syntax as illustrated in this sample, this means the method that hosts the pointcut must be abstract, have no arguments, and return void.

- The concrete aspect must implement all inherited abstract pointcuts.

- The concrete aspect may not implement methods so the abstract aspect it extends may not contain any abstract methods.

A limitation of the implementation of this feature in AspectJ 1.5.0 is that aspects defined using aop.xml are not exposed to the weaver. This means that they are not affected by advice and ITDs defined in other aspects. Support for this capability will be considered in a future release.

If more complex aspect inheritance is required use regular aspect inheritance instead of XML. The following XML definition shows a valid concrete sub-aspect for the abstract aspects above:

                <aspectj>
                    <aspects>
                        <concrete-aspect name="mypack.__My__AbstractAspect" extends="mypack.AbstractAspect">
                            <pointcut name="scope" expression="within(yourpackage..*)"/>
                        </concrete-aspect>
                    <aspects>
                </aspectj>

It is important to remember that the `name` attribute in the `concrete-aspect` directive defines the fully qualified name that will be given to the concrete aspect. It must a valid class name because the aspect will be generated on the fly by the weaver. You must also ensure that there are no name collisions. Note that the concrete aspect will be defined at the classloader level for which the aop.xml is visible. This implies that if you need to use the `aspectof` methods to access the aspect instance(s) (depending on the perclause of the aspect it extends) you have to use the helper API `org.aspectj.lang.Aspects.aspectOf(..)` as in:

                    // exception handling omitted
                    Class myConcreteAspectClass = Class.forName("mypack.__My__AbstractAspect");

                    // here we are using a singleton aspect
                    AbstractAspect concreteInstance = Aspects.aspectOf(myConcreteAspectClass);

### Using Concrete Aspects to define precedence

As described in the previous section, the `concrete-aspect` element in `META-INF/aop.xml` gives the option to declare the precedence, just as `@DeclarePrecedence` or `declare precedence` do in aspect source code.

Sometimes it is necessary to declare precedence without extending any abstract aspect. It is therefore possible to use the `concrete-aspect` element without the `extends` attribute and without any `pointcut` nested elements, just a `precedence` attribute. Consider the following:

                    <aspectj>
                        <aspects>
                            <concrete-aspect name="mypack.__MyDeclarePrecedence"
                                             precedence="*..*Security*, Logging+, *"/>
                        </aspects>
                    </aspectj>

This deployment time definitions is only declaring a precedence rule. You have to remember that the `name` attribute must be a valid fully qualified class name that will be then reserved for this concrete-aspect and must not conflict with other classes you deploy.

### Weaver Options

The table below lists the AspectJ options supported by LTW. All other options will be ignored and a warning issued.

Option | Purpose
--- | ---
`-verbose` | Issue informational messages about the weaving process. Messages issued while the weaver is being bootstrapped are accumulated until all options are parsed. If the messages are required to be output immediately you can use the option `-Daj.weaving.verbose=true` on the JVM startup command line.
`-debug` | Issue a messages for each class passed to the weaver indicating whether it was woven, excluded or ignored. Also issue messages for classes defined during the weaving process such as around advice closures and concrete aspects defined in `META-INF/aop.xml`.
`-showWeaveInfo` | Issue informational messages whenever the weaver touches a class file. This option may also be enabled using the System property `-Dorg.aspectj.weaver.showWeaveInfo=true`.
`-Xlintfile:pathToAResource` | Configure lint messages as specified in the given resource (visible from this aop.xml file' classloader)
`-Xlint:default, -Xlint:ignore, ...` | Configure lint messages, refer to documentation for meaningfull values
`-nowarn, -warn:none` | Suppress warning messages
`-Xreweavable` | Produce class files that can subsequently be rewoven
`-XnoInline` | Don't inline around advice.
`-XmessageHandlerClass:...` | Provide alternative output destination to stdout/stderr for all weaver messages. The given value must be the full qualified class name of a class that implements the `org.aspectj.bridge.IMessageHandler` interface and is visible to the classloader with which the weaver being configured is associated. Exercise caution when packaging a custom message handler with an application that is to be woven. The handler (as well as classes on which it depends) cannot itself be woven by the aspects that are declared to the same weaver.

Prev | Home | Next
Load-time Weaving Requirements | Up | Special cases