AspectWerkz - Plain Java AOP

##### General Information

- Overview
- Features
- License
- Downloads

##### Documentation

- New features in 2.x
- Introduction
- Tutorials
- Implementation issues
- General definition issues
- Annotation definition
- XML definition
- Annnotation driven development
- Deployment
- Weaving
- Dynamic AOP
- AOP container extensions
- Examples
- IDE integration
- JavaDoc
- FAQ

##### Misc.

- Releases & Release notes
- Build & install
- CVS access
- Mailing lists
- Tasks
- Papers, articles & talks

##### Project Documentation

- About AspectWerkz - Plain Java AOP
- Project Info
- Project Reports
- Development Process

## XML definition

What is important to understand is that both the Annotation and the XML definition are just different views of the same underlying model. This means that they can easily co-exist and can succesfully be used together. The XML definition can be used as a replacement to the Annotation definition or as a complement. It can be used to refine and override definitions made in annotations as well as resolve missing pieces (for example pointcut definitions referenced but not defined) in the annotation definition. See the Choosing a definition model section for best practices.

## Table of Contents

1. Aspects
2. Pointcuts
3. System wide pointcuts
4. Deployment scope
5. System wide deployment scope
6. Advice
7. Passing parameters to aspects
8. Introductions
9. Package namespaces
10. Transformation scopes
11. DTD for XML definition
12. Example of an XML definition

## Aspects

An aspect is defined in XML using the `aspect` element, which has the following attributes:

- `class` - [mandatory] specifies a fully qualified class name for the aspect implementation class.
- `deployment-model` - specifies the deployment model for the aspect. The default is `perJVM` if not specified
  - `perJVM` - deploys the aspect as perJVM.
  - `perClass` - deploys the aspect as perClass.
  - `perInstance` - deploys the aspect as perInstance.
- `name` - optional unique name of the aspect in the `system`. It will default to the fully qualified class name of the aspect.

Inside the `aspect` elements you then define the poincuts and advice.

## Pointcuts

The pointcut is the construct that picks out join points, i.e. selects sets of well-defined points in the program flow. In the XML definition pointcuts are defined using the `pointcut` element.

When defining a `pointcut` there are two attributes that need to be specified:

- `name` - [mandatory] specifies the name of the pointcut. Needs to be composed of a first part also called pointcut name, unique throughout the aspect defininition, and an optional second part called the pointcut signature : `name="<pointcut name>[(<pointcut signature>)]"`. The signature must name its parameters (as if it was some source code).

  Caution: pointcut names must be valid Java identifiers (only consist of these characters: `[A-Z]`, `[a-z]`, `[0-9]` and the characters `$` and `_`; not for example `-` or `/`).
  The optional `pointcut signature` must be compatible with the `args(), this() and target()` pointcuts designators when used. The abbreviations for `java.lang.*` can be used as described here.
- `expression` - [mandatory unless body is used] specifies the expression for the pointcut. This is the pattern that picks out the join points that should be included in the pointcut. This attribute is "optional". If not specified, the `<pointcut>` element must have the expression in its body.

  See the Join point selection pattern language section for a detailed description on how these patterns are written and see the Pointcut definition and Pointcut composition sections for details on how pointcuts are defined and composed.

Example of some `pointcut` definitions:

    <aspect ...>
        <pointcut name="pc1" expression="execution(* foo.Bar.method(..))"/>
        <pointcut name="pc2" expression="set(* foo.Bar.m_field)"/>
        <pointcut name="pc3" expression="get(* foo.Bar.m_field)"/>
        <pointcut name="pc4" expression="handler(java.lang.Exception)AND withincode(foo.bar.*.new(..))"/>
        <pointcut name="pc5" expression="call(String foo.Callee.method()) AND within(foo.bar.*)"/>
        <pointcut name="pc6" expression="cflow(execution(* Transaction.begin(..)))"/>
        ...
        <!-- do not use a pointcut name more than once (pcArg1) -->
        <pointcut name="pcArg1(String s)" expression="execution(* foo.Bar.method(..)) AND args(s, ..)"/>
        <pointcut name="pcArg1Same(String s)" expression="pc1 AND args(s, ..)"/>
        <pointcut name="pcArg1Other(com.Foo foo, String[] s)" expression="execution(* foo.Bar.method(..)) AND args(foo, int, .., s)"/>

        <!-- use element body instead -->
        <pointcut name="pcMultiLine">
            execution(int com.Do.foo(..))
            OR execution(int come.Done.bar(..))
        </pointcut>
    </aspect>

## System wide pointcuts

The pointcuts can also be "system-wide", which means that you can define pointcuts outside the aspects, within the `system` tags. These can then be used by all `aspects` in the system defintion.

## Deployment Scope

The `deployment-scope` element within the `aspect` can be used to define and name a pointcut that will be later used to hotdeploy and undeploy Aspects. The attributes and their meaning is the same as for the `pointcut` elements.

- `name` - the name of the deployment scope
- `expression` - the pointcut expression

See the specific hotdeployment section.

## System wide deployment Scope

The `deployment-scope` element within the `system` can be used to define and name a pointcut that will be later used to hotdeploy and undeploy Aspects. The attributes and their meaning is the same as for the `pointcut` elements.

- `name` - the name of the deployment scope
- `expression` - the pointcut expression

See the specific hotdeployment section.

## Advice

In the XML definition advice are defined using the `advice` element.

When defining the `advice` there are three attributes that need to be specified:

- `name` - [mandatory] the name of the advice is the name of the method in the aspect class that implements the advice, with an optional method signature if pointcut with signature are used. Abbreviations can be used in this signature, including for the `JoinPoint` or `StaticJoinPoint`parameter. The signature must name its parameters (as if it was some source code) like `advice3(JoinPoint jp, int i)`. The method defined this way must exist with the same signature in the aspect class hierarchy.
- `type` - the type defines the type of the advice. Valid types are:
  - `around` - defines an around advice
  - `before` - defines an before advice
  - `after` - defines an after (finally) advice
  - `after finally` - defines an after finally advice
  - `after returning` - defines an after returning advice
  - `after throwing` - defines an after throwing advice
  - `after returning(..)` - defines an after returning advice and filters out or bind the returned value
  - `after throwing(..)` - defines an after throwing advice and filters out or bind the throwned exception
- `bind-to` - binds the advice to a `pointcut` by referencing the name of the `pointcut` or by defining an anonymous pointcut. If the pointcut has a signature (with `args(), this() and/or target() or after returning(..), after throwing(..)`), then those must be refered as named in the advice name signature part.

For after returning and after throwing, you can filter out based on the returned value / exception thrown or use explicit binding.

after returning [TYPE] advice is executed if the method returns normally (without throwing an exception) and the actual type that is returned is of the type that is specified in the advice declaration.
If no return type is specified then it applies to all invocations that return normally, e.g. not when throwing an exception.

    <advice type="after returning(@Service *..*)"
            bind-to="execution(@TxRequired * *.*(..))"
            name="txCommitReturningService"/>

    <advice type="after returning(returned)"
            bind-to="execution(@TxRequired * *.*(..))"
            name="txCommitReturningService(String returned)"/>

after throwing [TYPE] advice is executed if the returns with an exception and the actual type of the exception that is thrown is of the type that is specified in the advice declaration.
If no exception type is specified then it applies to all invocations that returns with an exception.

    <advice type="after throwing(SecurityException+)"
            bind-to="execution(@TxRequired * *.*(..))"
            name="txRollbackOnRuntimeException"/>

    <advice type="after throwing(thrownedException)"
            bind-to="execution(@TxRequired * *.*(..))"
            name="txRollbackOnRuntimeException(SecurityException thrownedException)"/>

Example:

    <advice name="advice1"
            type="before"
            bind-to="(pc1 || pc2) AND pc3"/>

    <advice name="advice2"
            type="around"
            bind-to="execution(int examples.caching.Pi.getPiDecimal(int))"/>

    <advice name="advice3(JoinPoint jp, int i)"
            type="around"
            bind-to="pc1 AND args(i, String[], foo.Bar)"/>

    <advice name="advice4(org.codehaus.aspectwerkz.joinpoint.JoinPoint jp, int i)"
            type="around"
            bind-to="execution(int examples.caching.Pi.getPiDecimal(..)) AND args(i)"/>

## Passing parameters to aspects

You have the option of passing parameters to your aspects. This can be very convenient if you want to reuse the same aspect but with a different configuration without using aspect inheritance. To pass a parameter to the aspect you simply add a `param` tag to the `aspect` definition, like this:

    <aspect ... >
        <param name="timeout" value="10"/>
    </aspect>

From within an `Aspect` subclass use the API `AspectContext.getParameter("timeout")` to retrieve the parameter value as a String.

## Introductions

### Interface only introductions

Interface only introductions are defined within the `aspect` element using an `introduce` elemement. When defining the interface only introduction the following attributes can be used:

- `class` - [mandatory] the class name of the introduced interface
- `bind-to` - [mandatory] binds the introduction to a class using the `within(...), hasmethod(...) and/or hasfield(...)` pointcuts

The `introduce` element supports nested `bind-to` elements.

     <aspect ...>
    	  ...
    	  <introduce class="java.io.Serializable" bind-to="within(test.some.ToBeSerializable)"/>
    	  ...
     </aspect>

### Mixins

Mixin allows to introduce both interface(s) and implementation(s) of it. The `mixin` element within the `system` element is then used to declare the mixin. The mixin itself can be Annotation defined or XML defined.

The `mixin` element in the XML definition (in the `META-INF/aop.xml` file) can be used for three different purposes:

- Only to define which mixins should be used. Similar to how you declare which aspects should be used.) This can be the option if the mixin is defined in annotations. Then you only need to use the `class` attribute, e.g. `<mixin class="foo.bar.MyMixinImpl"/>`. See below for details.
- To completely define the mixin. See below for all the attributes that can be used.
- To override and/or resolve ad definition made using annotations. See below for all the attributes that can be used.

To define the mixin using the XML definition, use the `mixin` element. It has five attributes that can be used:

- `class` [mandatory] - defines which class to use as the implementation class. Has to be the fully qualified name of the class.
- `deployment-model` (optional) - defines the deployment model. Can be one of `perJVM`, `perClass` or `perInstance` (defaults).
- `transient` (optional) - defines the mixin as `transient` or not.
- `factory` (optional) - defines the custom mixin factory implementation to use with the specific mixin.
- `bind-to` (optional) - defines to which class set the mixin should be applied to, using the `within(...)`, `hasmethod(...)` and/or `hasfield(...)` pointcuts.

Example:

    <mixin class="foo.bar.MyMixinImpl"/>

    <mixin class="foo.bar.MyOtherMixinImpl"
           deployment-model="perClass"
           transient="true"
           factory="factories.MyMixinFactory"
           bind-to="within(*..domain.*)"/>

## Package namespaces

Package namespaces provide a way to simplify the creation/modification of the XML definition file so that it is not necessary to prefix all `class` with the complete package information.
You have two ways of defining a package namespace:

- using the `base-package` attribute in the `system` element. This defines a global package namespace for all elements defined within the `system` element.
- using the `package` element. This element has one attribute; `name`, which defines the package namespace.

The package name will be used as a prefix for all nested elements.

Example

    <aspectwerkz>
        <system id="foodemo" base-package="foo">
            <!-- All classes are prefixed by 'foo' -->

            <package name="bar">
                <!-- All classes within these 'package' tags are prefixed by 'foo.bar' -->
            </package>

            <package name="baz.buzz">
                <!-- All classes within these 'package' tags are prefixed by 'foo.baz.buzz' -->
            </package>
        </system>
    </aspectwerkz>

## Transformation scopes

Using transformation scopes you can choose to perform the transformation within certain packages only. E.g. filter out all classes from all other packages in the transformation process. This can speed up the transformation process a lot as well as assures you that only classes within the packages you have defined are getting transformed no matter how freely you have defined your pointcut patterns.

A transformation scope is defined using the `exclude` and `include` element which have one attribute `package` where you define the package name. You can define as many transformation scopes as you want.
The `package` attribute supports only `.*` as an ending pattern (package and all sub package).

During the transformation process (online or offline), a class might be transformed (depending on the pointcuts) if

1. the class does not belong to any `exclude` packages if any
and
2. the class belongs to at least one `include` packages if any

Note that when `include` is used the selection is much more restrictive. This selection mechanism should be used as most as possible especially in online mode since it enables an early filtering.

Example

    <aspectwerkz>
        <system id="sample">
            <!--
                Transformations will only take place within the 'org.codehaus.package' package and its subpackages
            -->
            <include package="org.codehaus"/>
            <include package="org.codehaus.*"/> <!-- synonymous of org.codehaus -->
            <exclude package="com.oracle.*"/>
            ...
        </system>
    </aspectwerkz>

## DTD for XML definition

Each distribution comes with a bundled DTD so that it is not looked for on the web at runtime. The XML is not validated against its DTD at runtime so be cautious to provide a valid XML defintion.

When you write your XML definition file, add the following at the top of your XML to reference the latest release:

    <!DOCTYPE aspectwerkz PUBLIC
        "-//AspectWerkz//DTD//EN"
        "http://aspectwerkz.codehaus.org/dtd/aspectwerkz2.dtd">

It is possible to specify a specific released version number as well (starting with 0.8)

    <!DOCTYPE aspectwerkz PUBLIC
        "-//AspectWerkz//DTD 2.0//EN"
        "http://aspectwerkz.codehaus.org/dtd/aspectwerkz_2_0.dtd">

and for 1.x

    <!DOCTYPE aspectwerkz PUBLIC
        "-//AspectWerkz//DTD 1.0//EN"
        "http://aspectwerkz.codehaus.org/dtd/aspectwerkz_1_0.dtd">

## Example of an XML definition

Here is an example where all the definitions are put together into a single `AspectWerkz` XML definition file.

    <aspectwerkz>
        <system id="sample">

            <pointcut name="systemWide" expression="execution(int com.Do.foo(..))"/>

            <pointcut name="mutliLine">
                call(int com.Do.foo(..))
                AND within(com.ToDO)
            </pointcut>

            <deployment-scope name="mutliLineScope">
                within(com.DynamicAOP)
            </deployment-scope>

            <!-- package prefix "examples." will be used for class=".."
                 attributes of <aspect> and <mixin> elements -->
            <package name="examples">

                <aspect class="caching.CachingAspect" deployment-model="perInstance">
                    <param name="timeout" value="10"/>

                    <introduce class="IntroductionTestAspect$MarkerInterface"
                               bind-to="within(test.mixin.perinstance.ToBeIntroduced)"/>

                    <pointcut name="callee"
                              expression="execution(int examples.caching.Pi.getPiDecimal(int))"/>

                    <pointcut name="caller"
                              expression="call(int examples.caching.Pi.getPiDecimal(int)) && within(examples.caching.*)"/>

                    <advice name="invocationCounter"
                            type="before"
                            bind-to="caller"/>

                    <advice name="cache"
                            type="around"
                            bind-to="callee"/>

                    <!-- use of args() -->
                    <pointcut name="calleeArgFiltered(int i)"
                              expression="callee AND args(i)"/>

                    <advice name="traceArg(JoinPoint jp, int theArg)"
                            type="around"
                            bind-to="calleeArgFiltered(theArg)"/>

                </aspect>

                <mixin
                    class="caching.MyMixin"
                    deployment-model="perClass"
                    bind-to="within(test.mixin.perinstance.ToBeAffectedByMixin)"/>

                <!-- annotation defined mixin -->
                <mixin
                    class="caching.MyMixinAnnotationDefined"/>

            </package>
        </system>
    </aspectwerkz>