|
|
@@ -0,0 +1,424 @@ |
|
|
|
<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> <para>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. </para></listitem> |
|
|
|
<listitem> <para>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. </para></listitem> |
|
|
|
<listitem> <para>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. </para></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 id="weaving-class-files-more-than-once" xreflabel="weaving-class-files-more-than-once"> |
|
|
|
<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> |
|
|
|
<para><!-- FIXME AV -->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.</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> <para>All aspects to be used for weaving must be defined to the weaver before any |
|
|
|
types to be woven are loaded.</para></listitem> |
|
|
|
<listitem> <para>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.</para></listitem> |
|
|
|
<listitem><para>A class loader may only weave classes that it defines. It may not weave |
|
|
|
classes loaded by a delegate or parent class loader.</para></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 id="enabling-load-time-weaving" xreflabel="enabling-load-time-weaving"> |
|
|
|
<title>Enabling Load-time Weaving</title> |
|
|
|
<para> 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. </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. Configuration for the supported environments is discussed |
|
|
|
later in this chapter.</para> |
|
|
|
<para> |
|
|
|
Using Java 5 JVMTI you can specify the <literal>-javaagent:pathto/aspectjweaver.jar</literal> option |
|
|
|
to the JVM.</para><para> |
|
|
|
Using BEA JRockit and Java 1.3/1.4, the very same behavior can be obtained using BEA JRockit JMAPI features with |
|
|
|
the <literal>-Xmanagement:class=org.aspectj.weaver.loadtime.JRockitAgent</literal> |
|
|
|
</para> |
|
|
|
</listitem> |
|
|
|
</varlistentry> |
|
|
|
<!-- FIXME: must be made consistent (aop.xml , CL hierarchy etc) --> |
|
|
|
<!-- <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 id="configuring-load-time-weaving-with-aopxml-files" xreflabel="configuring-load-time-weaving-with-aopxml-files"> |
|
|
|
<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.*"/> |
|
|
|
<dump within="somepack.*"/><!-- will dump weaved classes to the "./_ajdump" folder on disk (for diagnostic purpose) --> |
|
|
|
</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> |
|
|
|
<emphasis> |
|
|
|
Note: concrete-aspect is not available in AspectJ 1.5 M3. |
|
|
|
</emphasis> |
|
|
|
</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> |
|
|
|
<!-- FIXME AV - looks like we can refine conf in a child CL - not good --> |
|
|
|
<listitem> <para>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).</para></listitem> |
|
|
|
<listitem> <para>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.</para></listitem> |
|
|
|
<listitem> <para> 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.</para></listitem> |
|
|
|
<listitem> <para> 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.</para></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> |
|
|
|
|
|
|
|
<!-- TODO someone implement that --> |
|
|
|
<!-- |
|
|
|
<sect2 id="configuring-load-time-weaving-with-properties-files" xreflabel="configuring-load-time-weaving-with-properties-files"> |
|
|
|
<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 id="weaver-options" xreflabel="weaver-options"> |
|
|
|
<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>-verbose</literal> |
|
|
|
</entry> |
|
|
|
<entry>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 <literal>-XmessageHandlerClass:...</literal> not ready yet), |
|
|
|
you can use the option <literal>-Daj.weaving.verbose=true</literal> on the JVM startup command line. Messages will then be printed |
|
|
|
on stderr as long as the message handler class is not ready. |
|
|
|
</entry> |
|
|
|
</row> |
|
|
|
<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>-Xlintfile:pathToAResource</literal> |
|
|
|
</entry> |
|
|
|
<entry>Configure lint messages as specified in the given resource (visible from this aop.xml file' classloader)</entry> |
|
|
|
</row> |
|
|
|
<row> |
|
|
|
<entry> |
|
|
|
<literal>-Xlint:default, -Xlint:ignore, ...</literal> |
|
|
|
</entry> |
|
|
|
<entry>Configure lint messages, refer to documentation for meaningfull values</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>-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>-XmessageHandlerClass:...</literal> |
|
|
|
</entry> |
|
|
|
<entry>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 |
|
|
|
<literal>org.aspectj.bridge.IMessageHandler</literal> |
|
|
|
and that is visible from where the <literal>aop.xml</literal> 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. |
|
|
|
</entry> |
|
|
|
</row> |
|
|
|
</tbody> |
|
|
|
</tgroup> |
|
|
|
</informaltable> |
|
|
|
</sect2> |
|
|
|
</sect1> |
|
|
|
|
|
|
|
<sect1 id="ltw-specialcases"> |
|
|
|
<title>Special cases</title> |
|
|
|
<para> |
|
|
|
Those classes are not exposed to the LTW infrastructure, no matter |
|
|
|
the configuration of the <literal>aop.xml</literal> file(s): |
|
|
|
<itemizedlist> |
|
|
|
<listitem> <para>All <literal>org.aspectj.*</literal> classes (and subpackages) - as those are needed by the infrastructure itself</para></listitem> |
|
|
|
<listitem> <para>All <literal>java.*</literal> and <literal>javax.*</literal> classes (and subpackages)</para></listitem> |
|
|
|
<listitem> <para>All <literal>sun.reflect.*</literal> classes - as those are JDK specific classes used when reflective calls occurs</para></listitem> |
|
|
|
</itemizedlist> |
|
|
|
</para> |
|
|
|
<para> |
|
|
|
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. |
|
|
|
</para> |
|
|
|
<para> |
|
|
|
Note that dynamic proxy representations are exposed to the LTW infrastructure and are not considered |
|
|
|
a special case. |
|
|
|
</para> |
|
|
|
</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 id="jvmti" xreflabel="jvmti"> |
|
|
|
<title>JVMTI</title> |
|
|
|
<para> 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): </para> |
|
|
|
<programlisting><![CDATA[ |
|
|
|
-javaagent:pathto/aspectjweaver.jar |
|
|
|
]]></programlisting> |
|
|
|
</sect2> |
|
|
|
<sect2 id="jrockit" xreflabel="jrockit"> |
|
|
|
<title>JRockit with Java 1.3/1.4 (use JVMTI on Java 5)</title> |
|
|
|
<para> The JRockit agent is configured with the following JVM option: </para> |
|
|
|
<programlisting><![CDATA[ |
|
|
|
-Xmanagement:class=org.aspectj.weaver.loadtime.JRockitAgent |
|
|
|
]]></programlisting> |
|
|
|
</sect2> |
|
|
|
</sect1> |
|
|
|
</chapter> |
|
|
|
|