Load-Time Weaving
Introduction
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.
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.
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.
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.
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.
Weaving class files more than once
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 -Xreweavable compiler option when building
them. This causes AspectJ to save additional state in the class files that is used
to support subsequent reweaving.
As per AspectJ 1.5.0 M3 aspects (code style or annotation style) are
reweavable by default, and weaved classes may be as well in 1.5.0 final.
Load-time Weaving Requirements
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:
All aspects to be used for weaving must be defined to the weaver before any
types to be woven are loaded.
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.
A class loader may only weave classes that it defines. It may not weave
classes loaded by a delegate or parent class loader.
Configuration
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.
Enabling Load-time Weaving
AspectJ 5 supports several 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.
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
Custom Integration
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.
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 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:
]]>
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.
Note: concrete-aspect is not available in AspectJ 1.5 M3.
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'.
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.
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 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 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.
A META-INF/aop.xml file will automatically be generated when
using the -outjar 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.
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. If ever you need to have information
when the load time weaving engine is bootstrapped (hence its logger as per -XmessageHandlerClass:... not ready yet),
you can use the option -Daj.weaving.verbose=true on the JVM startup command line. Messages will then be printed
on stderr as long as the message handler class is not ready.
-1.5
Run the weaver in 1.5 mode (supports autoboxing in
join point matching)
-XlazyTjp
Performance optimization for aspects making use
of thisJoinPoint (non-static parts)
-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
-proceedOnError
Continue weaving even if errors occur (for example,
"... already woven" errors)
-Xreweavable
Produce class files that can subsequently be rewoven
-XnoInline
Don't inline around advice.
-showWeaveInfo
Issue informational messages whenever the weaver touches a class file
-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
org.aspectj.bridge.IMessageHandler
and that is visible from where the aop.xml is packed.
If more than one such options are used,
the first occurence only is taken into account.
You must also be very cautious about using a custom handler since it is likely that it will be invoked
(as well as all its third parties) while the weaving is done, which means that f.e. it cannot be weaved
by the aspects that are configured within the same deployment unit.
Special cases
Those classes are not exposed to the LTW infrastructure, no matter
the configuration of the aop.xml file(s):
All org.aspectj.* classes (and subpackages) - as those are needed by the infrastructure itself
All java.* and javax.* classes (and subpackages)
All sun.reflect.* classes - as those are JDK specific classes used when reflective calls occurs
Despite these restrictions, it is perfectly possible to match call join points for calls to these types providing the calling
class is exposed to the weaver. Subtypes of these excluded types that are exposed to the weaver may of course be woven.
Note that dynamic proxy representations are exposed to the LTW infrastructure and are not considered
a special case.
Runtime Requirements for Load-time Weaving
To use LTW the aspectjweaver.jar 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.
Supported Agents
JVMTI
When using Java 5 the JVMTI agent can be used by starting the JVM with the
following option (adapt according to the path to aspectjweaver.jar):
JRockit with Java 1.3/1.4 (use JVMTI on Java 5)
The JRockit agent is configured with the following JVM option: