| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> |
| <html> <head> |
| <title>AspectJ 1.6.9 Readme</title> |
| <style type="text/css"> |
| <!-- |
| P { margin-left: 20px; } |
| PRE { margin-left: 20px; } |
| LI { margin-left: 20px; } |
| H4 { margin-left: 20px; } |
| H3 { margin-left: 10px; } |
| --> |
| </style> |
| </head> |
| |
| <body> |
| <div align="right"><small> |
| © Copyright 2010 Contributors. |
| All rights reserved. |
| </small></div> |
| |
| <h1>AspectJ 1.6.9 Readme</h1> |
| |
| <p>The full list of resolved issues in 1.6.9 is available <a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced;bug_status=RESOLVED;bug_status=VERIFIED;bug_status=CLOSED;product=AspectJ;target_milestone=1.6.9;target_milestone=1.6.9M1;target_milestone=1.6.9M2;target_milestone=1.6.9RC1">here</a></h2> |
| |
| <h2>Features</h2> |
| |
| <h3>declare annotation supports compound signature patterns: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287613">287613</a></h3> |
| <p>Until now it wasn't possible to express a compound pattern in any of the declare annotation constructs that |
| take a member signature. For example, if you wanted to attach an annotation to all your getter like methods, you needed |
| two constructs</p> |
| <pre><code> |
| declare @method: * is*(): @FooBar; |
| declare @method: * get*(): @FooBar; |
| </code></pre> |
| <p>Now AspectJ allows compound patterns for declare @method/@constructor/@field.</p> |
| <pre><code> |
| declare @method: (* is*()) || (* get*()): @FooBar; |
| </code></pre> |
| |
| <h3>Intertype declaration of member types</h3> |
| |
| <p>It is now possible to ITD member types. The syntax is as would be expected. This example introduces a new member type called |
| Inner into type Foo:</p> |
| <pre><code>public class Foo { |
| public static void main(String[] args) { |
| new Inner().run(); |
| } |
| } |
| |
| aspect Magic { |
| public static class Foo.Inner { |
| public void run() { |
| System.out.println("Inner.run() executing"); |
| } |
| } |
| }</code></pre> |
| <p>Only static member types are supported.</p> |
| |
| <h3>'Optional' aspects: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=310506">310506</a></h3> |
| |
| <p>It is not uncommon to ship a library aspect separately to a jar upon which it depends. In the case of Spring there is |
| an aspect library containing a multitude of aspects that attach different technologies (transactions/persistence/etc) to your |
| application. Normally an aspect will fail with a "can't find type" style message if a weaver is told to use it and yet it |
| references some missing dependency. This can be annoying and require you to include jars on your classpath (or in your maven |
| configuration) that you don't actually use, they are *only* there to avoid problems with the aspect. In 1.6.9 you can add |
| a setting to these aspects in the aop.xml that makes them optional. The setting mentions a type and if that type cannot be found |
| the aspect immediately shuts itself down. This basically means that the aspect is only going to do its job if the type being |
| mentioned in the setting is around. This enables the aspect library to be on the aspect path but any aspects within it to |
| switch-off if there is nothing for them to do. |
| </p> |
| <p>Here is an example, 'AspectA' will switch itself off if the type 'a.b.c.Anno' cannot be found:</p> |
| <code><pre> |
| <aspect name="AspectA" requires="a.b.c.Anno"/> |
| </pre></code> |
| |
| <h3>Reduction in class file sizes: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=312839">312839</a></h3> |
| |
| <p>More details here: <a href="http://andrewclement.blogspot.com/2010/05/aspectj-size-is-important.html">http://andrewclement.blogspot.com/2010/05/aspectj-size-is-important.html</a> |
| but basically some work has been done to improve the serialized form of aspects. As an example, a compiled Roo petclinic sample (which |
| uses lots of aspects and ITDs) is down from 1Meg (AspectJ 1.6.9m2) to 630k (AspectJ 1.6.9rc1).</p> |
| |
| <h3>Transparent weaving: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=309743">309743</a></h3> |
| <p>In a further step towards transparent weaving, support for the AjType reflection system is now being made optional. |
| This means if intending to use the AjTypeSystem to reflect on woven code, then the code must be built with the |
| option -makeAjReflectable. This change is being made because the reflection supporting metadata that |
| enables the AjTypeSystem to work can break other tools that are just using regular reflection on the classes. These |
| days many more users are processing classes using standard reflection than are using AjTypeSystem. The related bugzilla |
| discussing this issue is <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=309743">309743</a>.</p> |
| |
| <h3>Overweaving: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293450">293450</a></h3> |
| |
| <p>Preliminary support for overweaving was added in AspectJ 1.6.7, but now in AspectJ 1.6.9m2 it is much more reliable. |
| Basically it is an alternative to reweaving when needing to weave a class multiple times. Overweaving can cope with |
| 'other tools' modifying the bytecode in between AspectJ weaves, whereas reweaving cannot. More details are in the related |
| bugzilla <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293450">293450</a> and in this |
| <a href="http://andrewclement.blogspot.com/2010/05/aspectj-overweaving.html">blog article</a>. A weaver is switched |
| into overweaving mode by the option -Xset:overWeaving=true - which can be specified on the command line or in the weaver |
| options section of aop.xml. There is still more work to be done on this feature - any feedback is welcome.</p> |
| |
| <h3>AOP Scoping: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=124460">124460</a></h3> |
| |
| <p>Another feature that had preliminary support a while ago is aspect scoping in aop.xml. This has also been improved in |
| AspectJ1.6.9m2. For those not aware of it, it is the ability to specify a scope against aspects defined in your loadtime |
| weaving aop.xml file. A scope effectively enables the user to limit the applicability of your aspect to some subset of all those |
| types included by the weaver include section. Why is it needed? It can be useful when taking an aspect that did not |
| originally scope itself properly (using a within clause) and needing to limit its effect in a load time weaving context. |
| Think of it as a within |
| pattern that you can put into the aop.xml that augments all the pointcuts defined in the original aspect.</p> |
| |
| <p>Here is an example:</p> |
| <code><pre> |
| <aspectj> |
| <aspects> |
| <aspect name="X"/> |
| <aspect name="Y" scope="com.foo..*"/> |
| </aspects> |
| <weaver> |
| <include within="com..*"/> |
| </weaver> |
| </aspectj> |
| </pre></code> |
| <p>In this example the weaver include section specifies all the types in com..* should be woven and the |
| aspects to be used are X and Y. The new 'scope' setting on aspect Y's definition allows finer control, and specifies that |
| Y should in fact only be applied to com.foo..* types.</p> |
| |
| <h3>Message inserts for declare warning/error messages</h3> |
| |
| <p>It is now possible to use joinpoint context in the messages attached to declare warning and declare error constructs. Some |
| examples:</p> |
| |
| <code><pre> |
| declare warning: execution(* A.m(..)): "joinpoint is {joinpoint}"; |
| declare warning: execution(* A.m(..)): "joinpoint kind is '{joinpoint.kind}'"; |
| declare warning: get(int *) && within(A): "joinpoint signature is {joinpoint.signature}"; |
| declare warning: execution(* A.m(..)): "joinpoint declaring type is {joinpoint.signature.declaringType}"; |
| declare warning: execution(* A.m(..)): "signature name for method is {joinpoint.signature.name}"; |
| declare warning: execution(* A.m(..)): "joinpoint location is {joinpoint.sourcelocation.sourcefile}:{joinpoint.sourcelocation.line}"; |
| declare warning: execution(* A.m(..)): "joinpoint line is '{joinpoint.sourcelocation.line}'"; |
| |
| declare warning: get(int *): "warning is from aspect {advice.aspecttype}"; |
| declare warning: execution(* A.m(..)): "warning sourcelocation is {advice.sourcelocation.sourcefile}:{advice.sourcelocation.line}"; |
| </pre></code> |
| |
| <p>The syntax is to enclose the relevant key within curly brackets within the message. Please raise an enhancement request |
| if you need other keys - the set supported so far are all those shown in the example above.</p> |
| |
| |
| <h3>declare warning/error for type patterns</h3> |
| |
| <p>It is now possible to use a type pattern with declare warning and declare error. For example:</p> |
| |
| <code><pre> |
| declare warning: I+ && !hasfield(int i): "Implementations of I are expected to have a int field called i"; |
| </pre></code> |
| |
| <h3>Type category type patterns</h3> |
| |
| <p>This is the ability to narrow the types of interest so that interfaces can be ignored, or inner |
| types, or classes or aspects. There is now a new is() construct that enables this:</p> |
| |
| <code><pre> |
| execution(* (!is(InnerType)).m(..)) {} |
| !within(* && is(InnerType)) {} |
| </pre></code> |
| |
| <p>Options for use in is() are: ClassType, AspectType, InterfaceType, InnerType, AnonymousType, EnumType, AnonymousType.</p> |
| <p>Note: It is important to understand that "!within(is(InnerType))" and "within(!is(InnerType))" are not the same. The latter one is |
| unlikely to be what you want to use. For example here: |
| <code><pre> |
| class Boo { |
| void foo() {} |
| class Bar { |
| void foo() {} |
| } |
| } |
| </pre></code> |
| <p>Bar.foo() will match within(!is(InnerType)) because within considers all surrounding types (so although Bar doesn't match the |
| pattern, the surrounding Boo will match it). Bar.foo() will not match !within(is(InnerType)) because Bar will match the pattern |
| and then the result of that match will be negated.</p> |
| |
| <h3>Intertype fields preserve visibility and name</h3> |
| |
| <p>Some users always expect this:</p> |
| |
| <code><pre> |
| class C { |
| } |
| |
| aspect X { |
| private int C.someField; |
| } |
| </pre></code> |
| |
| <p>To cause a private field called 'someField' to be added to C. This is conceptually what happens during compilation but if any |
| user then later attempts to access someField via reflection or runs a javap against the class file, they will see that isn't |
| what happens in practice. A public member is added with a mangled name. For code attempting to access someField built with ajc, |
| the visibility of the declaration will, of course, be respected. But for frameworks accessing the code later (typically through |
| reflection), it can cause confusion. With AspectJ 1.6.9 the name and visibility are now preserved. Compile time semantics |
| remain the same, it is only the weaving process that has changed to produce slightly different output.</p> |
| <p>Here is the output of javap when that is built with 1.6.8:</p> |
| <code><pre> |
| class C extends java.lang.Object{ |
| public int ajc$interField$X$someField; |
| C(); |
| } |
| </pre></code> |
| <p>Here is the output of javap when that is built with 1.6.9:</p> |
| <code><pre> |
| class C extends java.lang.Object{ |
| private int someField; |
| C(); |
| public static int ajc$get$someField(C); |
| public static void ajc$set$someField(C, int); |
| } |
| </pre></code> |
| <p>The name 'someField' is preserved. The visibility is also preserved but because of that we also need to generate some accessors |
| to get at the field.</p> |
| |
| <h3>AspectJ snapshots in a maven repo</h3> |
| |
| <p>To ease how AspectJ development builds can be consumed, they are now placed into a maven repo. When a new version of AspectJ |
| is put into AJDT it is also put into the maven.springframework.org repo. |
| The maven compatible repo is <code>maven.springframework.org/snapshot/org/aspectj</code> - and if you browse to it you will |
| see it currently contains 1.6.9 dev builds under the name 1.6.9.BUILD-SNAPSHOT. |
| |
| The repo is added with this magic:</p> |
| |
| <code><pre> |
| <repository> |
| <id>maven.springframework.org</id> |
| <name>SpringSource snapshots</name> |
| <url>http://maven.springframework.org/snapshot</url> |
| </repository> |
| </pre></code> |
| <p> |
| and then the version to depend upon is: |
| |
| 1.6.9.BUILD-SNAPSHOT</p> |
| |
| <hr> |
| |
| <h4> |
| <!-- ============================== --> |
| </body> |
| </html> |