aboutsummaryrefslogtreecommitdiffstats
path: root/docs/devguide/ltw.adoc
diff options
context:
space:
mode:
Diffstat (limited to 'docs/devguide/ltw.adoc')
-rw-r--r--docs/devguide/ltw.adoc482
1 files changed, 482 insertions, 0 deletions
diff --git a/docs/devguide/ltw.adoc b/docs/devguide/ltw.adoc
new file mode 100644
index 000000000..81d25ee3c
--- /dev/null
+++ b/docs/devguide/ltw.adoc
@@ -0,0 +1,482 @@
+[[ltw]]
+== Load-Time Weaving
+
+[[ltw-introduction]]
+=== Introduction
+
+The AspectJ 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. If the aspects are required for the affected classes to
+compile, then you must weave at compile-time. Aspects are required,
+e.g., when they add members to a class and other classes being compiled
+reference the added members.
+* 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, and may
+themselves be woven by aspects.
+* 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
+
+As of AspectJ 5 aspects (code style or annotation style) and woven
+classes are reweavable by default. If you are developing AspectJ
+applications that are to be used in a load-time weaving environment with
+an older version of the compiler 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.
+
+[[ltw-rules]]
+=== 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:
+
+[arabic]
+. All aspects to be used for weaving must be defined to the weaver
+before any types to be woven are loaded. This avoids types being
+"missed" by aspects added later, with the result that invariants across
+types fail.
+. All aspects visible to the weaver are usable. A visible aspect is one
+defined by the weaving class loader or one of its parent class loaders.
+All concrete visible aspects are woven and all abstract visible aspects
+may be extended.
+. A class loader may only weave classes that it defines. It may not
+weave classes loaded by a delegate or parent class loader.
+
+[[ltw-configuration]]
+=== 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 load-time weaving agent that enables load-time
+weaving. This agent and its configuration is 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.
++
+Since AspectJ 1.9.7, the obsolete Oracle/BEA JRockit agent is no
+longer part of AspectJ. JRockit JDK never supported Java versions
+higher than 1.6. Several JRockit JVM features are now part of HotSpot
+and tools like Mission Control available for OpenJDK and Oracle JDK.
+
+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 xref:#aj[`aj`, the AspectJ load-time weaving launcher].
++
+The `aj5` command runs Java programs in Java 5 by using the
+`-javaagent:pathto/aspectjweaver.jar` option described above. For more
+information, see xref:#aj[`aj`, the AspectJ load-time weaving launcher].
+
+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 xref:#aj[`aj`, the AspectJ load-time weaving launcher] and the API
+documentation and source for `WeavingURLClassLoader` and
+`WeavingAdapter`.
+
+[[configuring-load-time-weaving-with-aopxml-files]]
+==== 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:
+
+[source, xml]
+....
+<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>
+....
+
+The DTD defining the format of this file is available here:
+https://www.eclipse.org/aspectj/dtd/aspectj.dtd.
+
+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.
+
+[[concrete-aspect]]
+==== 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:
+
+[source, java]
+....
+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:
+
+[source, java]
+....
+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:
+
+[source, xml]
+....
+<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:
+
+[source, java]
+....
+// exception handling omitted
+Class myConcreteAspectClass = Class.forName("mypack.__My__AbstractAspect");
+
+// here we are using a singleton aspect
+AbstractAspect concreteInstance = Aspects.aspectOf(myConcreteAspectClass);
+....
+
+[[concrete-aspect-precedence]]
+==== 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:
+
+[source, xml]
+....
+<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]]
+==== Weaver Options
+
+The table below lists the AspectJ options supported by LTW. All other
+options will be ignored and a warning issued.
+
+[cols=",",options="header",]
+|===
+|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.
+|===
+
+[[ltw-specialcases]]
+=== Special cases
+
+The following classes are not exposed to the LTW infrastructure
+regardless of the `aop.xml` file(s) used:
+
+* 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.
+
+Some lint options behave differently when used under load-time weaving.
+The `adviceDidNotMatch` won't be handled as a warn (as during compile
+time) but as an info message.
+
+[[ltw-packaging]]
+=== 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.
+
+[[ltw-agents]]
+=== 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):
+
+[source, text]
+....
+-javaagent:pathto/aspectjweaver.jar
+....
+
+[[jrockit]]
+==== JRockit with Java 1.3/1.4 (use JVMTI on Java 5)
+
+Since AspectJ 1.9.7, the obsolete Oracle/BEA JRockit agent is no longer
+part of AspectJ. JRockit JDK never supported Java versions higher than
+1.6. Several JRockit JVM features are now part of HotSpot and tools like
+Mission Control available for OpenJDK and Oracle JDK.