123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- = AspectJ 1.6.9
-
- _© Copyright 2010 Contributors. All rights reserved._
-
- The full list of resolved issues in 1.6.9 is available
- 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]
-
- == Features
-
- === declare annotation supports compound signature patterns: https://bugs.eclipse.org/bugs/show_bug.cgi?id=287613[287613]
-
- 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
-
- [source, java]
- ....
- declare @method: * is*(): @FooBar;
- declare @method: * get*(): @FooBar;
- ....
-
- Now AspectJ allows compound patterns for declare
- @method/@constructor/@field.
-
- [source, java]
- ....
- declare @method: (* is*()) || (* get*()): @FooBar;
- ....
-
- === Intertype declaration of member types
-
- 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:
-
- [source, java]
- ....
- 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");
- }
- }
- }
- ....
-
- Only static member types are supported.
-
- === 'Optional' aspects: https://bugs.eclipse.org/bugs/show_bug.cgi?id=310506[310506]
-
- 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.
-
- Here is an example, 'AspectA' will switch itself off if the type
- 'a.b.c.Anno' cannot be found:
-
- [source, xml]
- ....
- <aspect name="AspectA" requires="a.b.c.Anno"/>
- ....
-
- === Reduction in class file sizes: https://bugs.eclipse.org/bugs/show_bug.cgi?id=312839[312839]
-
- More details here:
- https://andrewclement.blogspot.com/2010/05/aspectj-size-is-important.html
- 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).
-
- === Transparent weaving: https://bugs.eclipse.org/bugs/show_bug.cgi?id=309743[309743]
-
- 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
- https://bugs.eclipse.org/bugs/show_bug.cgi?id=309743[309743].
-
- === Overweaving: https://bugs.eclipse.org/bugs/show_bug.cgi?id=293450[293450]
-
- 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
- https://bugs.eclipse.org/bugs/show_bug.cgi?id=293450[293450] and in this
- https://andrewclement.blogspot.com/2010/05/aspectj-overweaving.html[blog
- article]. 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.
-
- === AOP Scoping: https://bugs.eclipse.org/bugs/show_bug.cgi?id=124460[124460]
-
- 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.
-
- Here is an example:
-
- [source, xml]
- ....
- <aspectj>
- <aspects>
- <aspect name="X"/>
- <aspect name="Y" scope="com.foo..*"/>
- </aspects>
- <weaver>
- <include within="com..*"/>
- </weaver>
- </aspectj>
- ....
-
- 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.
-
- === Message inserts for declare warning/error messages
-
- It is now possible to use joinpoint context in the messages attached to
- declare warning and declare error constructs. Some examples:
-
- [source, java]
- ....
- 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}";
- ....
-
- 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.
-
- === declare warning/error for type patterns
-
- It is now possible to use a type pattern with declare warning and
- declare error. For example:
-
- [source, java]
- ....
- declare warning: I+ && !hasfield(int i): "Implementations of I are expected to have a int field called i";
- ....
-
- === Type category type patterns
-
- 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:
-
- [source, java]
- ....
- execution(* (!is(InnerType)).m(..)) {}
- !within(* && is(InnerType)) {}
- ....
-
- Options for use in is() are: ClassType, AspectType, InterfaceType,
- InnerType, AnonymousType, EnumType, AnonymousType.
-
- 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:
-
- [source, java]
- ....
- class Boo {
- void foo() {}
- class Bar {
- void foo() {}
- }
- }
- ....
-
- 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.
-
- === Intertype fields preserve visibility and name
-
- Some users always expect this:
-
- [source, java]
- ....
- class C {
- }
-
- aspect X {
- private int C.someField;
- }
- ....
-
- 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.
-
- Here is the output of javap when that is built with 1.6.8:
-
- [source, java]
- ....
- class C extends java.lang.Object{
- public int ajc$interField$X$someField;
- C();
- }
- ....
-
- Here is the output of javap when that is built with 1.6.9:
-
- [source, java]
- ....
- 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);
- }
- ....
-
- 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.
-
- === AspectJ snapshots in a maven repo
-
- 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 `maven.springframework.org/snapshot/org/aspectj` -
- 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:
-
- [source, xml]
- ....
- <repository>
- <id>maven.springframework.org</id>
- <name>SpringSource snapshots</name>
- <url>https://maven.springframework.org/snapshot</url>
- </repository>
- ....
-
- and then the version to depend upon is: 1.6.9.BUILD-SNAPSHOT
-
- '''''
|