| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> <head> |
| <title>AspectJ Reference - Porting Notes</title> |
| </head> |
| <body> |
| |
| <div align=right><small> |
| © Copyright 1998-2002 Palo Alto Research Center Incorporated, |
| 2003-2004 Contributors. |
| All rights reserved. |
| </small></div> |
| |
| <h1>AspectJ Porting Notes</h1> |
| |
| <ul> |
| <li><a href="#pre-1.2">Pre-1.2 code</a></li> |
| <li><a href="#pre-1.1">Pre-1.1 code</a></li> |
| <li><a href="#pre-1.0.4">Pre-1.0.4 code</a></li> |
| <li><a href="#pre-1.0rc1">Pre-1.0rc1 code</a></li> |
| <li><a href="#pre-1.0beta1">Pre-1.0beta1 code</a></li> |
| <li><a href="#pre-1.0alpha1">Pre-1.0alpha1 code</a> |
| </li> |
| <li><a href="#pre08b3">Pre-0.8beta3 code</a></li> |
| |
| <li><a href="#pre08b1">Pre-0.8beta1 code</a></li> |
| |
| <li><a href="#pre07b11">Pre-0.7beta11 code</a></li> |
| |
| <li><a href="#pre07b10">Pre-0.7beta10 code</a></li> |
| </ul> |
| |
| <h2><a name="pre-1.2">Porting pre-1.2 code to AspectJ 1.2</a></h2> |
| <a href="README-12.html">README-12.html</a> contains a discussion |
| of the changes between 1.1 and 1.2. The key points are: |
| |
| <p><b>The default AspectJ compiler compliance level is now 1.4</b> (whereas in |
| previous releases the default compliance level was 1.3). This has a number |
| of implications: |
| </p> |
| <ul> |
| <li> class files generated by the compiler are now JRE v1.2 and upwards |
| compatible. (At compliance level 1.3, AspectJ generated class files that |
| were compatible with JRE 1.1 also).</li> |
| <li> <code>call</code> pointcuts may match more join points than in the same |
| program compiled at compliance level 1.3.</li> |
| </ul> |
| <p> |
| The AspectJ compiler can be restored to 1.3 compliance settings by specifying the |
| "-1.3" option on the command-line. |
| </p> |
| <p>The following example program illustrates the differences in join point matching |
| with the <code>call</code> pointcut designator between 1.4 and 1.3 compliance levels. |
| </p> |
| <pre> |
| <code> |
| 01 class A { |
| 02 public void doIt() {...}; |
| 03 } |
| 04 |
| 05 class B extends A { |
| 06 public void doThisToo() {...}; |
| 07 } |
| 08 |
| 09 |
| 10 public class CallsAandB { |
| 11 |
| 12 public static void main(String[] args) { |
| 13 B b = new B(); |
| 14 A bInDisguise = new B(); |
| 15 |
| 16 b.doIt(); // AspectJ 1.2 matches here |
| 17 bInDisguise.doIt(); // this is never matched |
| 18 } |
| 19 |
| 20 } |
| 21 |
| 22 aspect CallPCDMatchingExample { |
| 23 |
| 24 before() : call(* B.doIt(..)) { |
| 25 System.out.println("About to call B.doIt(...)"); |
| 26 } |
| 27 |
| 28 } |
| </code> |
| </pre> |
| <p> |
| When this program is compiled with AspectJ 1.2 using the default compiler options, |
| it will produce one line of output when it is executed: |
| </p> |
| <p><code>About to call B.doIt(...)</code></p> |
| <p>The same program compiled under AspectJ 1.1 (or using AspectJ 1.2 with the -1.3 flag specified) |
| does not produce any output when it is run. |
| </p> |
| |
| <p> |
| The reason for the additional call pcd match is that prior to compliance level 1.4, |
| Java compilers produced bytecodes that call A.doIt() (the defining type of the method), |
| rather than B.doIt() (the declared type in the program text). The generated call to |
| A.doIt() is not matched by the call pcd used in the before advice. At |
| compliance level 1.4, the bytecodes retain the declared type of the receiver in the |
| program source, generating a call to B.doIt(), which <i>is</i> matched by the call pcd. |
| </p> |
| |
| <p>This is a good example of why the recommended style is to use <code>call(* doIt(..)) && target(B)</code>, |
| which always matches based on the actual type of the receiver. |
| </p> |
| |
| <p><b>New warnings emitted by the compiler for unmatched call pcds.</b> Because users have found |
| the static type matching used for a type pattern specified in a <code>call</code> pcd confusing |
| (as evidenced by the example above), AspectJ 1.2 has a new Xlint warning which is enable by default. |
| The compiler will now produce a warning whenever a call pointcut designator does not match at a |
| join point, and a user may have expected it to. Compiling the above program using AspectJ 1.2 |
| produces the following compiler output: |
| </p> |
| |
| <pre> |
| <code> |
| <font color="red"> |
| CallsAandB.java:24 warning does not match because declaring type is A, if match desired use target(B) [Xlint:unmatchedSuperTypeInCall] |
| before() : call(* B.doIt(..)) { |
| ^^^^^^^^^^^^^^^ |
| |
| see also: CallsAandB.java:17 |
| </font> |
| <font color="blue"> |
| 1 warning |
| </font> |
| </code> |
| </pre> |
| |
| The warning is telling us that the call pointcut associated with the before advice on line 24 of the source file |
| does not match at a join point where the user may have expected it to. The source location |
| corresponding to the unmatched join point is indicated by the "see also" line - in this case line 17 of the |
| source file. At line 17 we find a call to <code>bInDisguise.doIt()</code>. Since the static type of |
| <code>bInDisguise</code> is <code>A</code>, this call will never be matched. The warning also tells us |
| a possible solution if we intended the pointcut to match at this join point: use |
| <code>call(* doIt(..) && target(B)</code>. |
| |
| <p>If you find warnings of this kind coming out when you use the AspectJ 1.2 compiler, the recommended fix is to |
| switch to using the <code>target</code> designator in place of a type pattern in the <code>call</code> pointcut |
| expression. Note that there is no loss of runtime efficiency here - runtime tests are only added in the cases |
| where it cannot be determined at compile time whether the type of the receiver will match the type specified in |
| the <code>target</code> expression. Note that <code>target</code> cannot be used in <code>declare</code> statements. |
| </p> |
| |
| <p><b>Use of non-statically determinable pointcut expressions in declare statements</b> has always been forbidden, |
| but prior to 1.2 the AspectJ compiler did not raise an error if they were used. The AspectJ Language |
| Semantics appendix states that <code>cflow, cflowbelow, this, target, args</code> and <code>if</code> pointcut |
| designators cannot be used directly or indirectly (through a user-defined pointcut) inside of a <code>declare</code> |
| statment. When moving code from 1.1 to 1.2, additional errors may be raised due to the stricter policing of this |
| rule. The solution is to recode the declare statement avoiding pointcut expressions that may require a run-time test. |
| </p> |
| |
| <p><b>Interface constructors no longer supported</b>. |
| Declaring a constructor on an interface is now (correctly) prohibited, |
| and there will no longer be a constructor-execution join point for the interface. |
| To initialize a field declared on an interface, use initialization, e.g., |
| </p> |
| <pre>int I.i; |
| after(I i) returning: initialization(I) && this(i) { i.i = 2; }</pre> |
| <p>To pick out the constructor-execution for any implementation of I, try |
| </p> |
| <pre>execution(I+.new(..))</pre> |
| |
| <p>For more information, see bug |
| <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=49295">49295</a>. |
| </p> |
| |
| <p><b>Declaring a static method on an interface</b> is now (correctly) prohibited. |
| One workaround is to define a static method on the aspect instead. |
| For more information, see bug |
| <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=47754">47754</a>. |
| </p> |
| |
| <p><b>Watch for problems due to incompatible BCEL versions.</b> |
| AspectJ 1.2 includes a different version of BCEL than AspectJ 1.1. If you have the older |
| version of BCEL available earlier on your classpath than the version included in the |
| 1.2 aspectjtools.jar then you will see errors like: |
| |
| <pre> |
| C:\work\test\TestAspect.aj error Internal compiler error |
| java.lang.NoSuchMethodError: org.apache.bcel.generic.InstructionFactory. |
| createNewArray(Lorg/apache/bcel/generic/Type;S)Lorg/apache/bcel/generic/Instruction; |
| </pre> |
| |
| This typically happens because the old version of BCEL has been included as a standard |
| extension in your JVM configuration. Ensure you have removed it from jre/lib/ext |
| under your JDK installation. |
| |
| <p>For more information, see bugs including |
| <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=60389">60389</a>, |
| <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=59921">59921</a>. |
| </p> |
| |
| |
| <h2><a name="pre-1.1">Porting pre-1.1 code to AspectJ 1.1</a></h2> |
| <a href="README-11.html">README-11.html</a> contains a discussion |
| of the language changes from 1.0 to 1.1. The high points: |
| |
| <p> |
| The <code>call(..)</code> pointcut designator is now implemented |
| only at the call site; by contrast, the AspectJ 1.0 compiler could |
| also implement it on the callee side. So in 1.0 if you |
| compiled a pointcut using <code>call(..)</code> but only passed |
| the compiler the code for the target of the call, the pointcut |
| could be implemented. This is not true for 1.1. To fix this, |
| use <code>execution(..)</code> in place of <code>call(..)</code>, |
| or include all calling clients in the compile. |
| (<a href="README-11.html#NO_CALLEE_SIDE_CALL">more info</a>) |
| |
| <p> |
| Type-patterns are no longer permitted for the defining |
| type of inter-type declarations. Replace the pattern with a |
| type. |
| In many cases, you can declare members on an interface type, |
| and then declare that the types picked out by the type-pattern |
| implement have the interface as their parent. |
| (<a href="README-11.html#SINGLE_INTERCLASS_TARGET">more info</a>) |
| <!-- todo code --> |
| |
| <p> |
| Type-patterns are no longer permitted when specifying |
| <code>declare soft</code>. |
| Replace the pattern with a literal type. |
| <!-- todo code --> |
| |
| <p> |
| Wildcards patterns (<code>foo..*</code>) are no longer |
| permitted for |
| <code>this()</code>, |
| <code>target()</code>, or |
| <code>args()</code>. |
| Replace the pattern with a literal type or |
| with a subtype wildcard (<code>Type+</code>). |
| (<a href="README-11.html#INSTANCEOF_ON_WILD">more info</a>) |
| <!-- todo code --> |
| <p> |
| Conflicts will be reported for no-argument constructors |
| generated by compilers when no constructor is defined |
| for a class. That means the following code will compile |
| in 1.0 but not in 1.1: |
| <pre> |
| class C {} |
| aspect A { |
| C.new() {} // permitted in 1.0; conflict in 1.1 |
| } |
| </pre> |
| One fix is to declare a non-conflicting constructor |
| by adding arguments (or defining a constructor in the |
| target class); a better fix might be to do the work of the |
| declared constructor in advice on the initialization |
| join point for the object. |
| (<a href="README-11.html#DEFAULT_CONSTRUCTOR_CONFLICT">more info</a>) |
| |
| <p> |
| The pointcut designators |
| <code>within()</code> and <code>withincode()</code> |
| will not pick out |
| code within the lexical extent of method-local |
| and anonymous inner types (because these are not |
| represented as such in bytecode form). Because |
| <code>within</code> forms specify staticly-determinable pointcuts, |
| they might be used in declare error or declare warning |
| statements, which might produce different results. |
| (<a href="README-11.html#WITHIN_MEMBER_TYPES">more info</a>) |
| |
| <p> |
| The compiler will report an error that |
| the form <code>aspect {name} dominates {list}...</code> |
| is no longer supported. It has |
| been replaced by a new declare statement: |
| <pre> |
| declare precedence : {name} {list}... |
| </pre> |
| (<a href="README-11.html#ASPECT_PRECEDENCE">more info</a>) |
| |
| <p> |
| The field set join point now has a return type of <code>void</code>. |
| Compiling programs using around advice on these join points might |
| cause errors unless the return type of the around advice |
| and the result of any proceed() call is |
| <code>Object</code> or <code>void</code>. |
| (<a href="README-11.html#VOID_FIELD_SET">more info</a>) |
| <p> |
| |
| The compiler cannot implement after or around advice for |
| the handler PCD because the end of exception handlers is |
| ambiguous in bytecode. Try to use before advice. |
| (<a href="README-11.html#AFTER_HANDLER">more info</a>) |
| <p> |
| |
| <h2><a name="pre-1.0.4">Porting pre-1.0.4 code</a></h2> |
| |
| <p>In versions of AspectJ prior to 1.0.4, the compiler was not |
| correctly implementing the AspectJ-1.0 language design for some uses |
| of after returning advice. |
| </p> |
| |
| <p> The main change that was made was of after returning advice for |
| constructor execution join points. Previously, this advice was legal: |
| </p> |
| |
| <PRE> |
| after() returning (Foo f): execution(Foo.new(..)) { ... } |
| </PRE> |
| |
| <p> However, it has always been a part of the 1.0 language design (and |
| of Java's language design) that constructors themselves (as opposed to |
| constructor calls) do not return the value of the new object. Rather, |
| <code>this</code> is bound to the new object, and the constructor |
| behaves like a void method. With that in mind, any code like the |
| above should be conveted to the form. </p> |
| |
| <PRE> |
| after(Foo f) returning: this(f) && execution(Foo.new(..)) { ... } |
| </PRE> |
| |
| <p> In compilers prior to 1.0.4, the following advice could pick out |
| join points |
| </p> |
| |
| <PRE> |
| after() returning (String s): call(void foo()) { ... } |
| </PRE> |
| |
| <p> This is no longer picked out. This pattern was most commonly used |
| in highly polymorphic contexts, such as |
| </p> |
| |
| <PRE> |
| after() returning (String s): call(* foo()) { ... } |
| </PRE> |
| |
| <p> If you want to capture all calls, binding null objects for those |
| that would otherwise have no value, you must use the |
| <code>Object</code> type. |
| </p> |
| |
| <PRE> |
| after() returning (Object o): call(* foo()) { ... } |
| </PRE> |
| |
| <p> Uses of both of these forms are highleted with compiler warnings |
| in the 1.0.4 compiler. |
| </p> |
| |
| |
| <hr /> |
| |
| <h2><a name="pre-1.0rc1">Porting pre-1.0rc1 code</a></h2> |
| |
| <p> Aspects can no longer be declared to implement the |
| <code>Serializable</code> or <code>Cloneable</code> interfaces. If |
| you previously used serializable or cloneable aspects, you should |
| refactor your code to keep the state you need to serialize or clone in |
| objects associated with the aspects. |
| </p> |
| |
| <hr /> |
| |
| <h2><a name="pre-1.0beta1">Porting pre-1.0beta1 code</a></h2> |
| |
| <p> The <code>static</code> modifier is no longer allowed on pointcut |
| declarations anywhere. Porting is simple; just remove the static |
| declarations when you find them. |
| </p> |
| |
| <p> Also, though the <code>returns</code> modifier on pointcuts has |
| not been part of the language since 1.0alpha1, the compiler still |
| accepted them until now. If you used this feature, now is the right |
| time to remove the <code>returns</code> modifier when the compiler |
| complains about it. |
| </p> |
| |
| <hr /> |
| |
| <h2><a name="pre-1.0alpha1">Porting pre-1.0alpha1 code </a></h2> |
| |
| |
| <p> The release of AspectJ 1.0alpha1 involved sweeping cleanups of the |
| language to bring it to 1.0 status. </p> |
| |
| <ul> |
| <li><a href="#1.0a1-pointcuts">Pointcuts</a></li> |
| <li><a href="#1.0a1-type-patterns">Type patterns</a></li> |
| <li><a href="#1.0a1-advice">Advice</a></li> |
| <li><a href="#1.0a1-introduction-and-static">Introduction and |
| static crosscutting</a></li> |
| <li><a href="#1.0a1-aspects">Aspects</a></li> |
| </ul> |
| |
| <h3><a name="1.0a1-pointcuts">Pointcuts</a></h3> |
| |
| <h4><a name="1.0a1-plural-to-singular">Removing the "s" from pointcuts</a></h4> |
| |
| <p> One of the most pervasive changes in porting code written before |
| 1.0alpha1 is the change in some of the pointcut names from plural to |
| singular, that is, they lose an "s". In one sense, making this change |
| in your programs is easy: just go through and whever you see uses of |
| the pointcuts |
| </p> |
| |
| <blockquote>calls executions gets sets handlers initializations |
| staticinitializations</blockquote> |
| |
| <p> Just take off the final "s", to make one of |
| </p> |
| |
| <blockquote>call execution get set handler initialization |
| staticinitialization</blockquote> |
| |
| <p> Often, there will be other changes you should make for each of |
| these pointcuts, but as for the name, just take off the "s". </p> |
| |
| <p> One risk you will have when doing this is creating name conflicts. |
| If, for example, you named a parameter of a pointcut "set", you should |
| (for your own sanity -- the compiler doesn't require it) rename it in |
| the rewritten pointcut. </p> |
| |
| <PRE> |
| pointcut sort(Collection set): calls(void addAll(set)); |
| ==> |
| pointcut sort(Collection mySet): call(void addAll(mySet)); |
| </PRE> |
| |
| <p> While converting to use singular nouns for the primitive |
| pointcuts, you may also want to remove the "s" from your user-defined |
| pointcuts. </p> |
| |
| <PRE> |
| pointcut publicCalls(): calls(public * *(..)); |
| ==> |
| pointcut publicCall(): call(public * *(..)); |
| </PRE> |
| |
| <p> Of course, your naming conventions are your own, but throughout |
| these porting notes we will be making these changes in our example |
| ports. </p> |
| |
| |
| <h4><a name="1.0a1-remove-receptions">Removing the receptions pointcut</a></h4> |
| |
| <p> Perhaps the largest semantic change in the 1.0 language is the |
| removal of receptions join points. They have been merged with call |
| join points in AspectJ 1.0, so now a call join point doesn't represent |
| the "caller-side" of a call, but the call itself, both caller and |
| receiver. </p> |
| |
| <p> Changing code that used the <code>receptions</code> pointcut should be |
| fairly straightforward, depending on whether the pointcut exposed state or |
| not. </p> |
| |
| <h5>Not exposing state</h5> |
| |
| <p> Receptions pointcuts that did not expose state can simply be |
| replaced by the new <code>call</code> and <code>target</code> pointcuts:</p> |
| |
| <PRE> |
| receptions(void Foo.m()) |
| ==> |
| target(Foo) && call(void m()) |
| </PRE> |
| |
| <h5>Exposing state</h5> |
| |
| <p> Some receptions pointcuts exposed the receiving object by |
| replacing the receiving type with a pointcut formal. These PCDs |
| should be rewritten to use the new <code>target</code> pointcut to expose |
| the receiving object. </p> |
| |
| <PRE> |
| pointcut fooCallees(Foo f): receptions(void f.m()); |
| ==> |
| pointcut fooCallee(Foo f): target(f) && call(void m()); |
| </PRE> |
| |
| <p> Like <a href="#1.0a1-fixing-state-access">other pointcuts</a>, |
| receptions pointcuts that exposed one or more arguments should be |
| rewritten to use the <code>args</code> pointcut: </p> |
| |
| <PRE> |
| pointcut intPassers(int i, int j): receptions(void Foo.m(i, j)); |
| ==> |
| pointcut intPasser(int i, int j): |
| args(i, j) && target(Foo) && call(void m(int, int)); |
| </PRE> |
| |
| <h5>Constructor receptions</h5> |
| |
| <p> There are two issues with constructor receptions in |
| particular. </p> |
| |
| <p>Like <a href="#1.0a1-constructor-calls">constructor calls</a>, |
| constructor receptions pointcuts had a dynamic character, in that |
| <code>receptions(C.new())</code> would capture constructions of not |
| only C classes, but also of classes that extended C. </p> |
| |
| <p> If you want this behaviour, then you need to use the new subtypes |
| operator, +, on the type name in question. So, |
| </p> |
| |
| <PRE> |
| receptions(C.new()) |
| ==> |
| call(C+.new()) |
| </PRE> |
| |
| <p>Also like <a href="#1.0a1-constructor-calls">constructor calls</a>, |
| constructor receptions allowed access to the constructed object in the |
| same way as any other object. Since the only advice possible on |
| constructor receptions join points was <code>after returning</code> |
| advice, the object was always guaranteed to be there. But since |
| constructor call join points allow all kinds of advice it may be that |
| the object isn't constructed yet (say, in before or around advice). |
| This is a benefit, in that it allows caching constructed objects </p> |
| |
| <PRE> |
| aspect Singleton { |
| private C theC = null; |
| |
| C around(): call(C.new(..)) { |
| if (c == null) theC = proceed(); |
| return theC; |
| } |
| } |
| </PRE> |
| |
| <p> but it does require some rewriting. The new object can be |
| accessed as the return value in after returning advice. So, </p> |
| |
| <PRE> |
| after(Point p) returning (): receptions(p.new(int, int)) { ... } |
| ==> |
| after() returning (Point p): call(Point+.new(int, int)) { ... } |
| </PRE> |
| |
| <h4><a name="1.0a1-fixing-state-access">Fixing state access</a></h4> |
| |
| <p> In previous versions of AspectJ, state such as the currently |
| executing object or a particular argument of a method call could be |
| accessed from the signatures of many pointcuts, leading to |
| difficult-to-read forms. In AspectJ 1.0, all state accesses now use |
| only three pointcuts </p> |
| |
| <blockquote>args this target</blockquote> |
| |
| <p> which pick out argument values, the currently executing object, |
| and the target object of a method call or field operation, |
| respectively. </p> |
| |
| <h5>Using args</h5> |
| |
| <p> Any time you have a pointcut that has a signature where one of the |
| arguments was a pointcut or advice formal, just replace that formal |
| with its type and add an <code>args</code> pointcut. |
| </p> |
| |
| <PRE> |
| pointcut intPassers(int i, int j): calls(void Foo.m(i, j)); |
| ==> |
| pointcut intPasser(int i, int j): args(i, j) && call(void Foo.m(int, int)); |
| </PRE> |
| |
| <PRE> |
| pointcut stringPassers(String s): receptions(void Foo.m(s, ..)); |
| ==> |
| pointcut stringPasser(String s): args(s, ..) && call(void Foo.m(String, ..)); |
| </PRE> |
| |
| <h5>Rewriting calls</h5> |
| |
| <p> If a calls pointcut exposed the the receiving object, such as </p> |
| |
| <PRE> |
| pointcut fooCallees(Foo f): calls(void f.m()); |
| </PRE> |
| |
| <p> then the new version should use the <code>target</code> pointcut |
| to get at that object |
| </p> |
| |
| <PRE> |
| pointcut fooCallee(Foo f): target(f) && call(void Foo.m()); |
| </PRE> |
| |
| <p> AspectJ's calls pointcut previously allowed the new object to be |
| exposed, even though it may not have been constructed yet. AspectJ |
| 1.0 no longer allows this; you can access the new instance only in |
| after returning advice, when it is guaranteed that the object was |
| successfully constructed. So instead of using the <code>target</code> |
| pointcut to expose the value, you should use the normal <code>after |
| returning</code> mechanism: |
| </p> |
| |
| <PRE> |
| after(Point p) returning (): calls(p.new(int, int)) { ... } |
| ==> |
| after() returning (Point p): call(Point+.new(int, int)) { ... } |
| </PRE> |
| |
| |
| <h5>Rewriting gets and sets</h5> |
| |
| <p> Exposing the target object of a <code>gets</code> or |
| <code>sets</code> pointcut should be done the same way it was for |
| <code>calls</code> pointcuts, with the new <code>target</code> |
| pointcut. </p> |
| |
| <PRE> |
| before(Frame f): gets(Color f.color) { ... } |
| ==> |
| before(Frame f): target(f) && get(Color Frame.color) { ... } |
| </PRE> |
| |
| <PRE> |
| before(Frame f): sets(Color f.color) { ... } |
| ==> |
| before(Frame f): target(f) && set(Color Frame.color) { ... } |
| </PRE> |
| |
| <p> In addition, the clumsy syntax for getting the old value of the |
| field has been eliminated. For before advice, the port is simple; |
| just access the field yourself in the body. Depending on the rest of |
| your system, you may need to restrict the advice from the aspect body |
| to eliminiate the circularity. </p> |
| |
| <PRE> |
| aspect A { |
| before(Frame f, Color c): gets(Color f.color)[c] { ... } |
| } |
| ==> |
| aspect A { |
| before(Frame f): |
| target(f) && get(Color Frame.color) && !within(A) { |
| Color c = f.color; |
| ... |
| } |
| } |
| </PRE> |
| |
| <p> The same can be done for <code>around</code> advice. However, the |
| only way to port after advice that needs the old value is to convert |
| it to around advice. |
| </p> |
| |
| <PRE> |
| aspect A { |
| after(Frame f, Color c) returning (): gets(Color f.color)[c] { ... } |
| } |
| ==> |
| aspect A { |
| void around(Frame f): |
| target(f) && get(Color Frame.color) && !within(A) { |
| Color c = f.color; |
| proceed(f); |
| ... |
| } |
| } |
| </PRE> |
| |
| <p> When porting <code>sets</code> pointcuts, the new value of a field |
| is still available, but not the way it was previously. Instead of |
| using the square bracket syntax, we use an <code>args</code> pointcut. |
| All set join points are assumed to have exactly one argument, which |
| holds the new value. So, </p> |
| |
| <PRE> |
| after(Color newColor): sets(Color Frame.color)[][newColor] { ... } |
| ==> |
| after(Color newColor): args(newColor) && set(Color Frame.color) { ... } |
| </PRE> |
| |
| <p> Also, if the field was declared private, in order to get at its |
| old value the aspect must be declared <code>privileged</code>. |
| </p> |
| |
| <h5>Rewriting handlers</h5> |
| |
| <p> The value of the exception at an exception handler join point is |
| now accessed through the <code>args</code> pointcut; all exception |
| handler join points are treated as having exactly one argument, the |
| exception value. So, |
| </p> |
| |
| <PRE> |
| before(NotFoundException e): handlers(e) { ... } |
| ==> |
| before(NotFoundException e): args(e) && handler(NotFoundException) { ... } |
| </PRE> |
| |
| <h5>Rewriting within</h5> |
| |
| <p> The <code>within</code> pointcut was not typically used to export |
| context. Though it was accidentally possible to do so in versions of |
| AspectJ before 1.0, it often didn't do what users expected it to. |
| This loophole has now been closed, and within can only take type |
| patterns, not pointcut or advice formals. A use of the |
| <code>this</code> pointcut will capture what previous implementations |
| did: </p> |
| |
| <PRE> |
| pointcut usesFoo(Foo f): within(f); |
| ==> |
| pointcut usesFoo(Foo f): this(f) && within(Foo); |
| </PRE> |
| |
| <h4><a name="1.0a1-no-subs-in-sigs">Understanding signatures</a></h4> |
| |
| <p> Now that we have <code>this</code>, <code>target</code>, and |
| <code>args</code> pointcuts, all of our signatures are composed of |
| just types, names, and wildcards; there are no more parameters. |
| </p> |
| |
| <p> Also, now that we have the <code>+</code> wildcard to pick out |
| <a href="#1.0a1-subtypes-to-plus">subtypes</a>, we can make signature |
| matching much more uniform.</p> |
| |
| <p> Previously, some signatures matched based on subtypes, some based |
| on instanceof, and some exactly. Now, we have made all signatures |
| match exactly. |
| </p> |
| |
| <p> What does this mean for your program? Well, it means that you |
| may have to add <code>+</code> to some of your signatures, depending |
| on what you meant them to match. |
| </p> |
| |
| <p> For example, the pointcut |
| </p> |
| |
| <pre> |
| calls(void m(Object)) |
| </pre> |
| |
| <p> previously picked out all method calls to a method named m that |
| took one argument, which was a subtype of Object. Now, however, it |
| will only pick out method calls to methods that are defined to take |
| exactly the type Object, which may be a lot fewer join points. If you |
| want the old behaviour, simply convert to </p> |
| |
| <pre> |
| call(void m(Object+)) |
| </pre> |
| |
| <h4><a name="1.0a1-fixing-instanceof">Removing the instanceof pointcut</a></h4> |
| |
| <p> The intanceof pointcut has been split into two different |
| pointcuts, <code>this</code> and <code>target</code>. </p> |
| |
| <p> Typically, the instanceof pointcut would only exist in a compound |
| pointcut, composed (with <CODE>&&</CODE>) with another |
| pointcut. If the other pointcut was a <code>receptions</code> |
| pointcut, then <code>instanceof</code> should be converted to |
| <code>target</code> (and <code>receptions</code> converted to |
| <code>call</code>). So, </p> |
| |
| <PRE> |
| pointcut stateChanges(Subject s): |
| instanceof(s) && receptions(void Button.click()); |
| ==> |
| pointcut stateChange(Subject s): |
| target(s) && call(void Button.click()); |
| </PRE> |
| |
| <p> In all other cases, <code>instanceof</code> referred to the |
| currently executing object, and so should be converted into |
| <code>this</code></p> |
| |
| <PRE> |
| before(Point p): instanceof(p) && executions(* makePolar(..)) { ... } |
| ==> |
| before(Point p): this(p) && execution(* makePolar(..)) { ... } |
| </PRE> |
| |
| <PRE> |
| pointcut setup(Client c): instanceof(c) && calls(Remote Naming.lookup(String)); |
| ==> |
| pointcut setup(Client c): this(c) && calls(Remote Naming.lookup(String)); |
| </PRE> |
| |
| <h4><a name="1.0a1-initializations">Rewriting the initializations pointcut</a></h4> |
| |
| <p> Object initialization join points are now more complicated, and |
| more true to Java's execution model. Now they bracket all of the |
| initialization that a class can do, after the return of its super |
| constructor call (before which no initialization can happen). Previous |
| versions of AspectJ had object initialization join points that only |
| included initialization that was made in dynamic initializers and |
| fields. </p> |
| |
| <p> The old behaviour can be recovered with a simple rewrite. |
| </p> |
| |
| <PRE> |
| initializations(A) |
| ==> |
| initialization(A.new(..)) && !execution(A.new(..)) |
| </PRE> |
| |
| <h4><a name="1.0a1-constructor-calls">Understanding constructor calls</a></h4> |
| |
| <p> Previously, constructor call join points were matched by subtypes, |
| so <code>calls(Foo.new())</code> would match both calls to create new |
| <code>Foo</code> objects, and new <code>SubFoo</code> objects. The |
| new <code>call</code> pointcut designator matches types exactly, so if |
| you want the old behaviour, you should write |
| <code>call(Foo+.new())</code>. </p> |
| |
| <p> Similarly, constructor execution join points were matched by |
| subtypes. So the old <code>executions(Foo.new())</code> is now |
| represented by <code>execution(Foo+.new())</code>. |
| </p> |
| |
| <p> In both of these cases, think before using the + operator; it may |
| be that you didn't intend subtype matching in the first place. </p> |
| |
| <h4><a name="1.0a1-hasaspect">Removing the hasaspect pointcut</a></h4> |
| |
| <p> The <code>hasaspect</code> pointcut is no longer defined, but you |
| can get the same behaviour using the new <code>if</code> pointcut. |
| </p> |
| |
| <p> If the aspect whose presense you are checking for was defined |
| <code>of eachcflow</code>, <code>of eachcflowbelow</code>, or, more |
| unlikely, <code>of eachJVM()</code>, then the conversion is simple: |
| </p> |
| |
| <PRE> |
| hasaspect(A) |
| ==> |
| if(A.hasAspect()) |
| </PRE> |
| |
| <p> If the aspect was defined <code>of eachobject</code>, then you |
| will have to expose the current object in your pointcut or advice |
| parameters: </p> |
| |
| <PRE> |
| pointcut cut(): hasaspect(A) ... ; |
| ==> |
| pointcut cut(Object o): this(o) && if(A.hasAspect(o)) ... ; |
| or |
| pointcut cut(Object o): target(o) && if(A.hasAspect(o)) ... ; |
| </PRE> |
| |
| <p> If you were using the <code>hasaspect</code> pointcut to expose |
| the state of the aspect, then you can get the same state by using |
| <code>A.aspectOf()</code> in the body of the advice. For example, if |
| the aspect A were defined <code>of eachcflow</code>, then |
| </p> |
| |
| <PRE> |
| before(A myA): hasaspect(myA) { |
| myA.checkStatus(); |
| } |
| ==> |
| before(): if(A.hasAspect()) { |
| A myA = A.aspectOf(); |
| myA.checkStatus(); |
| } |
| </PRE> |
| |
| <h4><a name="1.0a1-withinall">Removing the withinall pointcut</a></h4> |
| |
| <p> The withinall poinctut is no longer defined. You can use a |
| combination of within and the <a href="#1.0a1-subtypes-to-plus">new |
| subtypes operator</a>, +, instead. You'll save two characters and be |
| using a simpler and more orthogonal language. </p> |
| |
| <PRE> |
| withinall(Foo) |
| ==> |
| within(Foo+) |
| </PRE> |
| |
| <h4><a name="1.0a1-user-defined-returns">Removing returns modifier from pointcuts</a></h4> |
| |
| <p>The returns keyword is no longer necessary for user-defined |
| pointcuts. Simply remove it when you find it. </p> |
| |
| <PRE> |
| pointcut publicIntCalls() returns int: calls(public int *(..)); |
| ==> |
| pointcut publicIntCall(): call(public int *(..)); |
| </PRE> |
| |
| <h4><a name="1.0a1-static-pointcuts">Making some pointcuts static</a></h4> |
| |
| <p> In Java, only static members may be accessed by their declaring |
| type name, like the static method <code>Math.max()</code> can be |
| accessed. </p> |
| |
| <p> Pointcuts now have that property too. Pointcuts may be declared |
| to be static, in which case they can be accessed like |
| <code>MyAspect.move()</code>, or they can be left non-static, in which |
| case they can be overridden by a subaspect. </p> |
| |
| <p> In addition, while pointcuts can still be defined in classes, only |
| <code>static</code> pointcuts can be defined in classes. </p> |
| |
| <p> Porting should be straightforward; just make all your pointcuts in |
| classes <code>static</code>, and make any pointcut with a qualified |
| reference static. |
| </p> |
| |
| <h3><a name="1.0a1-type-patterns">Type patterns</a></h3> |
| |
| <h4><a name="1.0a1-new-wildcards">Understanding * and .. in type patterns</a></h4> |
| |
| <p> Previous versions of AspectJ treated * and .. too cleverly in type |
| patterns, placing restrictions based on what is a package and what is |
| a type, and basing their meanings on the definition of a package |
| hierarchy. </p> |
| |
| <p> In AspectJ 1.0, both of these wildcards are defined simply, and |
| textually: |
| </p> |
| |
| <ul> |
| <li> The * wildcard alone matches all types. </li> |
| |
| <li> The * wildcard in a pattern matches zero or more characters, |
| but will not match "." </li> |
| |
| <li> The .. wildcard matches any sequence of characters that begins |
| and ends with "." </li> |
| </ul> |
| |
| <p> That's it. |
| </p> |
| |
| <p> This change won't affect most programs, but it will make |
| understanding programs easier. There is one ugly idiom, however, that |
| this change disposes of. If your program includes the type pattern |
| <code>*..*</code>, which used to match all types, you can replace it with the |
| much simpler *. </p> |
| |
| <PRE> |
| pointcut unaryVoidMethods(): call(void *(*..*)); |
| ==> |
| pointcut unaryVoidMethod(): call(void *(*)); |
| </PRE> |
| |
| <h4><a name="1.0a1-subtypes-to-plus">Fixing subtypes in introduction</a></h4> |
| |
| <p> The new + operator is used to normalize the many places you want |
| to use subtypes of some types. |
| </p> |
| |
| <p> In introduction forms, you will need to replace |
| <code>subtypes(<var>TypePattern</var>)</code> type patterns with the |
| new subtype operator, +. In the case where you wrote |
| <code>subtypes(Foo)</code>, i.e., the subtypes of a single type, |
| simply replace this with <code>Foo+</code>. Otherwise, use the |
| + operator as appropriate in <var>TypePattern</var>. </p> |
| |
| <PRE> |
| public void (subtypes(Target0 || Target1)).accept(Visitor v) { |
| v.visit(this); |
| } |
| ==> |
| public void (Target0+ || Target1+).accept(Visitor v) { |
| v.visit(this); |
| } |
| </PRE> |
| |
| <h3><a name="1.0a1-advice">Advice</a></h3> |
| |
| <h4><a name="1.0a1-around-returns">Moving the return type of around</a></h4> |
| |
| <p> The returns keyword is no longer used for around advice. Instead, |
| the return type is declared as it is for methods. So, </p> |
| |
| <PRE> |
| around(Point p) returns void: setters(p) { ... } |
| ==> |
| void around(Point p): setter(p) { ... } |
| </PRE> |
| |
| <h4><a name="1.0a1-around-throws">Adding a throws clause to around</a></h4> |
| |
| <p> Around advice must now declare the checked exceptions it throws |
| with a <code>throws</code> clause, much like a method. |
| </p> |
| |
| <PRE> |
| char around(char c) throws java.io.CharConversionException: converter(c) { |
| char result; |
| try { result = proceed(); } |
| catch (Exception e) { |
| throw new java.io.CharConversionException(); |
| } |
| if (result == 0) throw new java.io.CharConversionException(); |
| return result; |
| } |
| </PRE> |
| |
| <h4><a name="1.0a1-advice-precedence">Understanding advice precedence</a></h4> |
| |
| <p> In previous versions of AspectJ, advice precedence within an |
| aspect was simple: if a piece of advice appeared before another piece, |
| it was more precedent. This made perfect sense for |
| <code>before</code> and <code>around</code> advice, but was the cause |
| of confusion (even among the AspectJ designers, more than once) for |
| <code>after</code> advice, as it seemed backward. </p> |
| |
| <p> In addition, advice was ordered by kind, in that around advice |
| always surrounded before and after advice. |
| </p> |
| |
| <p> AspectJ 1.0 has changed this; precedence for <code>after</code> |
| advice is inverted, and advice is no longer ordered by kind. |
| </p> |
| |
| <p>This won't matter to you unless you write pieces of advice in the |
| same aspect that apply to the same join point. </p> |
| |
| <p>If you do, here's what to think about: If you're looking at two |
| pieces of advice and want to know which has precedence, if either is |
| <code>after</code> advice, then the second one has precedence. |
| Otherwise, the first does. </p> |
| |
| <p> This allows interesting advice interaction. In the following |
| advice, for example, the <code>after throwing</code> advice will catch |
| the exception thrown by the <code>before</code> advice </p> |
| |
| <PRE> |
| aspect A { |
| before(): call(void main(..)) { |
| throw new RuntimeException(); |
| } |
| after() throwing(RuntimeException e): call(void main(..)) { |
| System.err.println("caught you!"); |
| } |
| } |
| </PRE> |
| |
| <p> But reversing the order will give the <code>before</code> advice |
| more precedence, making its exception uncatchable by the <code>after |
| throwing</code> advice |
| </p> |
| |
| <PRE> |
| aspect A { |
| after() throwing(RuntimeException e): call(void main(..)) { |
| System.err.println("missed you!"); |
| } |
| before(): call(void main(..)) { |
| throw new RuntimeException(); |
| } |
| } |
| </PRE> |
| |
| <p> Advice in <em>different</em> aspects is ordered by the normal aspect |
| precedence rules of subtyping and the <code>dominates</code> modifier. |
| </p> |
| |
| <h4><a name="1.0a1-after-returning">Fixing after returning</a></h4> |
| |
| <p> If you use after returning advice and do not need to expose the |
| return value, you no longer need to write an empty set of parentheses |
| to indicate that fact. So, </p> |
| |
| <pre> |
| after(<var>Formals</var>) returning (): <var>Pointcut</var> { ... } |
| ==> |
| after(<var>Formals</var>) returning: <var>Pointcut</var> { ... } |
| </pre> |
| |
| <p> The same syntax is now available for after throwing advice, in |
| case you do not care what <code>Throwable</code> is thrown. |
| </p> |
| |
| <pre> |
| after(<var>Formals</var>) throwing: <var>Pointcut</var> { ... } |
| </pre> |
| |
| <h4><a name="1.0a1-this-static-join-point">Renaming thisStaticJoinPoint</a></h4> |
| |
| <p> <code>thisStaticJoinPoint</code> has been renamed |
| <code>thisJoinPointStaticPart</code>, to reflect that it is now |
| exactly the static part of <code>thisJoinPoint</code>: It will return |
| the same object as <code>thisJoinPoint.getStaticPart()</code>. </p> |
| |
| <h4><a name="1.0a1-this-join-point">Converting access to thisJoinPoint</a></h4> |
| |
| <p> The <code>JoinPoint</code> object hierarchy has been folded into a |
| single class, <code>org.aspectj.lang.JoinPoint</code>. A common |
| pattern in logging, for example, was </p> |
| |
| <pre> |
| before() executions(* myMethod()) { |
| ExecutionJoinPoint jp = (ExecutionJoinPoint)thisJoinPoint; |
| CodeSignature jp = (CodeSignature)jp.getSignature(); |
| System.err.println(jp.getParameters()); |
| System.err.println(jp.getParameterNames()); |
| } |
| </pre> |
| |
| <p> While there is still a rich hierarchy for signatures, there is |
| only one <code>JoinPoint</code> type, so this can be rewritten as: |
| </p> |
| |
| <pre> |
| before() executions(* myMethod()) { |
| JoinPoint jp = thisJoinPoint; |
| CodeSignature jp = (CodeSignature)jp.getSignature(); |
| System.err.println(jp.getArgs()); |
| System.err.println(jp.getParameterNames()); |
| } |
| </pre> |
| |
| <p> Some of the method names of <code>JoinPoint</code> have been |
| reorganized, as well. </p> |
| |
| <h3><a name="1.0a1-introduction-and-static">Introduction and static crosscutting</a></h3> |
| |
| <h4><a name="1.0a1-plus-implements-extends">Removing +implements and +extends</a></h4> |
| |
| <p> The keywords <code>+implements</code> and <code>+extends</code> no |
| longer exist. Instead, AspectJ uses the <code>declare</code> |
| form for exactly the same functionality. </p> |
| |
| <PRE> |
| Point +implements Serializable; |
| => |
| declare parents: Point implements Serializable; |
| </PRE> |
| |
| <PRE> |
| MyButton +extends ButtonAdaptor; |
| => |
| declare parents: MyButton extends ButtonAdaptor; |
| </PRE> |
| |
| <h4><a name="1.0a1-now-use-soft">Using declare soft</a></h4> |
| |
| <p> Around advice advice no longer effects the static exception |
| checking of Java. This means that the following code previously |
| compiled: </p> |
| |
| <PRE> |
| class C { |
| void noExceptionDeclared() { |
| exceptionDeclared(); |
| } |
| void exceptionDeclared() throws IOException {} |
| } |
| aspect A { |
| around(): call(void C.exceptionDeclared()) { |
| try { proceed(); } |
| catch (IOException e) {} |
| } |
| } |
| </PRE> |
| |
| <p> even though the class C is not compilable on its own (because |
| noExceptionDeclared actually throws an Exception). |
| </p> |
| |
| <p> AspectJ now firmly places everything that affects the type system |
| of Java, including the declared-exception checking system, into the |
| space of introduction and declare. So, in order to state that the |
| call to exceptionDeclared() will not, actually, throw an exception, we |
| now "soften" that exception, that is, take it out of the space of |
| declared exceptions. </p> |
| |
| <pre> |
| declare soft: <var>ExceptionType</var>: <var>Pointcut</var>; |
| </pre> |
| |
| <p> The pointcuts allowed here are limited; you cannot use pointcuts |
| that would require runtime information. But picking out method calls |
| is just fine. So in order to make the above example work, one new |
| declaration is needed: |
| </p> |
| |
| <PRE> |
| declare soft: IOException: |
| call(void C.exceptionDeclared()) && |
| withincode(void noExceptionDeclared()); |
| </PRE> |
| |
| <h3><a name="1.0a1-aspects">Aspects</a></h3> |
| |
| <p> The syntax of "of each" modifiers has changed. For <code>of |
| eachcflow</code> and <code>of eachcflowbelow</code>, you can simply |
| replace "of each" with "per". So, </p> |
| |
| <PRE> |
| aspect A of eachcflow(...) { ... } |
| ==> |
| aspect A percflow(...) { ... } |
| </PRE> |
| |
| <p> If you have any aspects defined <code>of eachJVM()</code>, then |
| you should either remove that declaration entirely (because this is |
| the default behaviour), or replace the <code>of eachJVM()</code> |
| declaration with an <code>issingleton</code> declaration. |
| </p> |
| |
| <PRE> |
| aspect of eachJVM() { ... } |
| ==> |
| aspect A { ... } |
| or |
| aspect A issingleton { ... } |
| </PRE> |
| |
| <p> The <code>of eachobject(<var>Pointcut</var>)</code> modifier has |
| been split into two different forms, <code>of |
| perthis(<var>Pointcut</var>)</code> and <code>of |
| pertarget(<var>Pointcut</var>)</code>. Which one you replace with |
| depends on the <var>Pointcut</var> you use. |
| </p> |
| |
| <p> If you use a pointcut that picked out reception join points, then |
| use <code>pertarget</code>, and rewrite the pointcut to pick out call |
| join points. So |
| </p> |
| |
| <PRE> |
| aspect Shadow |
| of eachobject(receptions(void Point.setX(int)) || |
| receptions(void Point.setY(int))) { |
| ... |
| } |
| ==> |
| aspect Shadow pertarget(call(void Point.setX(int)) || |
| call(void Point.setY(int))) { |
| ... |
| } |
| </PRE> |
| |
| <p> Otherwise, in most cases, use <code>perthis</code>. When you |
| convert, remember the meaning of each of these modifiers. |
| <code>perthis(<var>Pointcut</var>)</code> indicates that an instance |
| of the aspect should be associated with every object that is |
| <code>this</code> at each of the join points picked out by |
| <var>Pointcut</var>, while <code>pertarget(<var>Pointcut</var>)</code> |
| associates with every object that is the target object at such join |
| points. </p> |
| |
| <!-- ==================================== --> |
| <!-- ==================================== --> |
| <!-- ==================================== --> |
| |
| <hr /> |
| |
| <h2><a name="pre08b3">Porting pre-0.8beta3 code</a></h2> |
| |
| <ul> |
| <li><a href="#cflowTerminology">Changing cflow terminology</a></li> |
| <li><a href="#abstractPointcuts">Overriding abstract pointcuts</a></li> |
| <li><a href="#recursiveAdvice">Limiting recursive advice</a></li> |
| </ul> |
| |
| |
| <p>The following changes are only required when porting code written |
| prior to the 0.8beta3 release of AspectJ.</p> |
| |
| <h3><a name="cflowTerminology">Changing cflow terminology</a></h3> |
| |
| <p> Changing pre-0.8beta3 code that uses AspectJ's control-flow-based |
| features only requires rewriting occurrences of |
| <code>eachcflowroot</code>, <code>cflow</code>, and |
| <code>cflowtop</code>. No editing of other aspect code is |
| necessary.</p> |
| |
| <h4>eachcflowroot</h4> |
| |
| <p> The aspect modifier "<code>of |
| eachcflowroot(<var>Pointcut</var>)</code>" should now be written more |
| as "<code>percflow(<var>Pointcut</var>)</code>". </p> |
| |
| <h4>cflow</h4> |
| |
| <p> In previous versions of AspectJ, the pointcut |
| <code>cflow(<var>Pointcut</var>)</code> picked out all join points in |
| the cflow below the join points of <var>Pointcut</var>. That is, it |
| did not include the join points of <var>Pointcut</var>, only the join |
| points in their control flow. |
| </p> |
| |
| <p> As of version 0.8beta3, |
| <code>cflowbelow(<var>Pointcut</var>)</code> has that behavior. |
| <code>cflow(<var>Pointcut</var>)</code> includes the join points of |
| <var>Pointcut</var>. </p> |
| |
| <p> In many cases, you may not care whether the points of |
| <var>Pointcut</var> are included or not, and so can safely leave |
| <code>cflow(<var>Pointcut</var>)</code> pointcut designators alone. |
| However, if you use the idiom |
| </p> |
| |
| <pre class="codeindent"> |
| <var>Pointcut</var> && ! cflow(<var>Pointcut</var>) |
| </pre> |
| |
| <p> to capture the non-recursive entries to a particular pointcut, you |
| will definitely want to rewrite that as |
| </p> |
| |
| <pre class="codeindent"> |
| <var>Pointcut</var> && ! cflowbelow(<var>Pointcut</var>) |
| </pre> |
| |
| <h4>cflowtop</h4> |
| |
| <p> The primitive pointcut designator |
| <code>cflowtop(<var>Pointcut</var>)</code> has been removed from the |
| language, as it is expressible with <code>cflow</code> or |
| <code>cflowbelow</code>. All uses of |
| <code>cflowtop(<var>Pointcut</var>)</code> can be rewritten as: |
| </p> |
| |
| <pre class="codeindent"> |
| cflowbelow(<var>Pointcut</var> && ! cflowbelow(<var>Pointcut</var>)) |
| </pre> |
| |
| <p> Though in most cases the following is sufficient |
| </p> |
| |
| <pre class="codeindent"> |
| cflow(<var>Pointcut</var> && ! cflowbelow(<var>Pointcut</var>)) |
| </pre> |
| |
| <h3><a name="abstractPointcuts">Overriding abstract pointcuts</a></h3> |
| |
| <p> In previous versions of AspectJ, a concrete aspect would |
| implicitly override all of its abstract pointcuts with an empty |
| pointcut. AspectJ 0.8beta3 enforces the restriction that a concrete |
| aspect may not have any abstract pointcuts. Thus the following |
| extension:</p> |
| |
| <pre class="codeindent"> |
| abstract aspect A { |
| abstract pointcut pc(); |
| } |
| |
| aspect B {} |
| </pre> |
| |
| <p> will no longer compile. |
| </p> |
| |
| <p> Adding the new empty pointcut designator |
| </p> |
| |
| <pre class="codeindent"> |
| pointcut <var>Id</var>(); |
| </pre> |
| |
| <p> in the declaration of the concrete aspect fixes this problem. |
| </p> |
| |
| <pre class="codeindent"> |
| abstract aspect A { |
| abstract pointcut pc(); |
| } |
| |
| aspect B { |
| pointcut pc(); |
| } |
| </pre> |
| |
| <h3><a name="recursiveAdvice">Limiting recursive advice</a></h3> |
| |
| <p> Previously, the compiler silently refrained from applying a piece |
| of advice to join points within its own advice body. So, for example, |
| in </p> |
| |
| <pre class="codeindent"> |
| class C { |
| static int i; |
| } |
| |
| aspect A { |
| before(): gets(int C.i) { |
| System.err.println("C.i was " + C.i) |
| } |
| } |
| </pre> |
| |
| <p> The advice would trace all references of the static field |
| <code>C.i</code> except those in the body of the before. </p> |
| |
| <p> The compiler has now removed this special case, and so running the |
| above example will now cause a <code>StackOverflowException</code> to |
| be thrown. </p> |
| |
| <p> Most cases of this error can be fixed by correctly specifying the |
| desired pointcut: In the above example, the intention is clearly not |
| to trace <em>all</em> references of <code>C.i</code>, just those |
| outside the aspect. |
| </p> |
| |
| <pre class="codeindent"> |
| class C { |
| static int i; |
| } |
| |
| aspect A { |
| before(): get(int C.i) && ! within(A) { |
| System.err.println("C.i was " + C.i) |
| } |
| } |
| </pre> |
| |
| <p> In a very few cases, you may want the advice to be applicable to |
| other code in the aspect, but not in the particular piece of advice. |
| In such cases, you can pull the body of the advice into a method and |
| restrict away from that method (and away from calls to that method): |
| </p> |
| |
| <pre class="codeindent"> |
| class C { |
| static int i; |
| } |
| |
| aspect A { |
| public static int getCi() { |
| return C.i; // will be traced |
| } |
| |
| before(): get(int C.i) && |
| ! withincode(void A.traceCi()) |
| ! call(void A.traceCi()) { |
| traceCi(); |
| } |
| private void traceCi() { |
| System.err.println("C.i was " + C.i) // will not be traced |
| } |
| } |
| </pre> |
| |
| |
| <!-- ============================== --> |
| |
| <hr /> |
| <h2><a name="pre08b1">Porting pre-0.8beta1 code</a></h2> |
| |
| <ul> |
| <li><a href="#introSyntax">Rewriting introductions</a></li> |
| <li><a href="#staticAdvice">Removing static advice</a></li> |
| <li><a href="#aspect-aspect">Fixing aspect-aspect inheritance</a></li> |
| <li><a href="#usingPrivateIntroduction">Using private introduction</a></li> |
| </ul> |
| |
| <p>The following changes are only required when porting code written |
| prior to the 0.8beta1 release of AspectJ.</p> |
| |
| <h3><a name="introSyntax">Rewriting introductions</a></h3> |
| |
| <h4>Syntax</h4> |
| |
| <p> The syntax of introduction has changed. Porting most programs |
| should require some simple editing. Anywhere you have an introduction |
| block</p> |
| |
| <pre class="codeindent"> |
| introduction <var>GTN</var> { |
| ... |
| } |
| </pre> |
| |
| <p> simply move the <var>GTN</var> down into the introduction |
| declarations and remove the block.</p> |
| |
| <p>For method introduction, place the <var>GTN</var> in front of the |
| method name, For field introduction, place the <var>GTN</var> in front |
| of the field name, and for constructor introduction, place the |
| <var>GTN</var> in front of the <code>new</code> identifier. </p> |
| |
| <pre class="codeindent"> |
| introduction Foo { |
| public void doStuff() { this.doStuffLater(); } |
| public int calorieCount = 3; |
| public new(int x) { super(); calorieCount = x; } |
| } |
| |
| ==> |
| |
| public void Foo.doStuff() { this.doStuffLater(); } |
| public int Foo.calorieCount= 3; |
| public Foo.new(int x) { super(); calorieCount = x; } |
| </pre> |
| |
| <p> For implements and extends introduction, move the <var>GTN</var> |
| in front of the new identifiers <code>implements</code> or |
| <code>extends</code>, and place that in a <code>declare parents</code> |
| form. |
| </p> |
| |
| <pre class="codeindent"> |
| introduction Foo { |
| implements Comparable; |
| extends Goo; |
| } |
| |
| ==> |
| |
| declare parents: Foo implements Comparable; |
| declare parents: Foo extends Goo; |
| </pre> |
| |
| <p> In all cases, if the <var>GTN</var> is just a type name, it can be |
| moved down on its own. However, if the <var>GTN</var> uses any of |
| <CODE>&&</CODE>, <code>||</code>, and <code>!</code>, it must |
| be parenthesized. </p> |
| |
| <pre class="codeindent"> |
| introduction subtypes(Foo) && !Goo { |
| int x; |
| } |
| |
| ==> |
| |
| int (Foo+ && !Goo).x; |
| </pre> |
| |
| |
| <h4>Access</h4> |
| |
| <p>If you had an introduction that was referring to private or |
| protected members of the target class, this will no longer work. You |
| will either need to modify your code to avoid this accessibility |
| issue, or you will need to use the <code>privileged</code> modifier on |
| the aspect that contains the introduction.</p> |
| |
| <pre class="codeindent"> |
| class Counter { |
| private int count = 2; |
| } |
| |
| aspect ExposeCountersPrivates { |
| introduction Counter { |
| public int getCount() { return count; } |
| } |
| } |
| |
| ==> |
| // in 0.8, only privileged aspects can expose a class's privates |
| privileged aspect ExposeCountersPrivates { |
| public int Counter.getCount() { return count; } |
| } |
| </pre> |
| |
| |
| <p> If you have introduced private or package-protected members, you |
| will probably have to re-write some code. Most previous uses of |
| introducing privates can be improved by using private introduction |
| instead.</p> |
| |
| <pre class="codeindent"> |
| class C { |
| } |
| |
| aspect AddCounter { |
| introduction C { |
| private int count; |
| public int getCount() { return count; } |
| } |
| } |
| |
| ==> |
| aspect AddCounter { |
| private int Counter.count; |
| public int Counter.getCount() { return count; } |
| } |
| </pre> |
| |
| <p> There is one case that we know of where the inability to perform |
| the introduction of private members makes 0.7 code difficult to |
| port to 0.8. If you were using the introduction of a <code>private |
| void writeObject(..)</code> or a <code>private void |
| readObject(..)</code> method to interact with Java's serialization |
| API, you will need to come up with an alternative design. Using some |
| combination of <code>Externalizable</code>, |
| <code>writeReplace(..)</code> and/or <code>readResolve(..)</code> |
| methods should allow you to port your code. If you find this isn't |
| the case, we'd like to hear about it. |
| |
| |
| <p> If you were introducing either a protected member or a |
| package-private member onto a class in order to override a protected |
| member that was inherited from a superclass, you will have to make |
| this introduction public. <p> |
| |
| |
| <h3><a name="staticAdvice">Removing static advice</a></h3> |
| |
| <p> Static advice has been removed from the language. Now, every |
| piece of advice is non-static, meaning that it will run in the context |
| of an aspect instance. |
| </p> |
| |
| <p> If you have an aspect that only contains static advice, has no |
| "of" clause or is declared "of eachJVM()", and is not extended by |
| another aspect, simply remove the keyword "static" from all pieces of |
| advice, and make sure the aspect is not defined with the "abstract" |
| modifier. </p> |
| |
| <pre class="codeindent"> |
| aspect Tracing { |
| static before(): executions(* *(..)) { |
| System.out.println("Got Here! " + thisJoinPoint); |
| } |
| } |
| |
| ==> |
| |
| aspect Tracing { |
| before(): execution(* *(..)) { |
| System.out.println("Got Here! " + thisJoinPoint); |
| } |
| } |
| </pre> |
| |
| <p> Otherwise, if you have an aspect contains both static and |
| non-static advice, is extended, or is "of eachObject(...)" or "of |
| eachcflowroot(...)", you should group your static advice together and |
| put it in a new aspect, possibly even an inner aspect. </p> |
| |
| <pre class="codeindent"> |
| aspect ComplexTracing of eachobject(cflow(executions(void Main.main(..)))) { |
| static before(): executions(* *(..)) { |
| System.out.println("Got Here! " + thisJoinPoint); |
| } |
| static after(): executions(* *(..)) { |
| System.out.println("Returned! " + thisJoinPoint); |
| } |
| |
| // some other dynamic advice, fields, etc |
| } |
| |
| ==> |
| |
| aspect ComplexTracing of eachobject(cflow(executions(void Main.main(..)))) { |
| static aspect AlwaysTracing { |
| before(): execution(* *(..)) { |
| System.out.println("Got Here! " + thisJoinPoint); |
| } |
| after(): execution(* *(..)) { |
| System.out.println("Returned! " + thisJoinPoint); |
| } |
| } |
| |
| // some other dynamic advice, fields, etc |
| } |
| </pre> |
| |
| <h3><a name="aspect-aspect">Fixing aspect-aspect inheritance</a></h3> |
| |
| <p> Aspects can now only extend abstract aspects. This restriction |
| may cause some redesign of aspect hierarchies. You will probably find |
| that for the majority of your code the most serious change this |
| requires is to add an explicit <code>abstract</code> modifier to a |
| super-aspect that was already implicitly abstract.</p> |
| |
| <pre class="codeindent"> |
| aspect BaseTracing { |
| abstract pointcut traced(); |
| before(): traced() { |
| System.out.println("Got Here! " + thisJoinPoint); |
| } |
| } |
| |
| ==> |
| |
| // make this abstract aspect explicitly abstract |
| abstract aspect BaseTracing { |
| ... |
| } |
| </pre> |
| |
| |
| <p> This change has also affected the <code>getAspect</code> static |
| method. Now, <code>getAspect</code> is only defined on non-abstract |
| aspects. Previously, you could call <code>getAspect</code> on an |
| abstract superaspect and (sometimes) get an instance of a subaspect |
| back. </p> |
| |
| <p>This pattern was used in the Spacewar example in the AspectJ |
| distribution. We had the class hierarchy </p> |
| |
| <pre> |
| SpaceObject (abstract) |
| |- Ship |
| |- Bullet |
| |- EnergyPellet |
| </pre> |
| |
| <p> And the aspect hierarchy |
| </p> |
| |
| <pre> |
| SpaceObjectDA (abstract) |
| |- ShipDA of eachobject(instanceof(Ship)) |
| |- BulletDA of eachobject(instanceof(Ship)) |
| |- EnergyPacketDA of eachobject(instanceof(Ship)) |
| </pre> |
| |
| <p> And we would call <code>SpaceObjectDA.getAspect(SpaceObject)</code> to access |
| the aspect associated with a ship, bullet, or energy pellet. This |
| pattern depended on the <code>SpaceObjectDA</code> aspect hierarchy |
| exactly mirroring the <code>SpaceObject</code> hierarchy, and being |
| maintained that way. </p> |
| |
| <p> A better way to implement this kind of design aspect is to use |
| private introduction, a new feature of AspectJ. |
| </p> |
| |
| <h3><a name="usingPrivateIntroduction">Using private introduction</a></h3> |
| |
| <p> A common pattern for AspectJ programs that need to associate some |
| state with every object of a particular type has been to use aspects |
| that are defined <code>of eachobject(instanceof(...))</code>. A prime |
| example of this was the <code>BoundPoint</code> aspect of the bean |
| example: which needed to associate each point with a |
| <code>PropertyChangeSupport</code> object. </p> |
| |
| <pre class="codeindent"> |
| aspect BoundPoint of eachobject(instanceof(Point)) { |
| |
| java.beans.PropertyChangeSupport support = null; |
| |
| after() returning(Point p): receptions(p.new(..)){ |
| support = new PropertyChangeSupport(myPoint); |
| } |
| |
| around(Point p) returns void: receptions(void p.set*(*)) { |
| // code that uses support |
| } |
| } |
| </pre> |
| |
| <p> In the new version of AspectJ, a better way of accomplishing many |
| of these state association is to use privately introduced fields. |
| Instead of creating an aspect instance for every <code>Point</code> |
| object, store the <code>PropertyChagneSupport</code> object in the |
| <code>Point</code> objects themselves. |
| </p> |
| |
| <pre class="codeindent"> |
| aspect BoundPoint { |
| private PropertyChangeSupport Point.support = new PropertyChangeSupport(this); |
| |
| void around(Point p): setters(p) { |
| // code that uses p.support |
| } |
| } |
| </pre> |
| |
| <p> Just as in the past, the PropertyChangeSupport object is not |
| accessable to anyone but the aspect, but now less mechanism is needed. |
| </p> |
| |
| <p> There are times when changing aspects that are defined <code>of |
| eachobject(instanceof(...))</code> may not be reasonable. If the |
| aspect instance is stored or passed to other methods, then having a |
| real <code>of eachobject(instanceof(...))</code>, now written |
| <code>perthis(this(...))</code>, association may capture the |
| crosscutting concern best. </p> |
| |
| <!-- ============================== --> |
| |
| <hr /> |
| <h2><a name="pre07b11">Porting pre-0.7beta11 code</a></h2> |
| |
| <ul> |
| <li><a href="#twoArgumentCalls">Removing two-argument calls</a></li> |
| <li><a href="#adviceInClasses">Removing advice from Class declarations</a></li> |
| </ul> |
| |
| <p>The following changes are only required when porting code written |
| prior to the 0.7beta11 release of AspectJ.</p> |
| |
| <h3><a name="twoArgumentCalls">Removing two-argument calls</a></h3> |
| |
| <p> In AspectJ 0.7beta11, the two-argument <code>calls</code> |
| primitive pointcut designator was deprecated. Removing these |
| designators will require different cases depending on what the |
| original pointcut did. </p> |
| |
| <h4>Calls to static methods</h4> |
| |
| <p> For pointcuts denoting calls to particular static methods, such as |
| </p> |
| |
| <blockquote><pre> |
| calls(String, static String valueOf(int)) // deprecated |
| </pre></blockquote> |
| |
| <p> the transformation is easy. Simply make the desired signature |
| explicit. Instead of catching all calls to any static method that |
| happens to have the signature <code>String valueOf(int)</code>, catch |
| calls to that exact method defined in the String class. </p> |
| |
| <blockquote><pre> |
| call(static String String.valueOf(int)) |
| </pre></blockquote> |
| |
| <p> Pointcuts denoting calls to classes of static methods can also be |
| rewritten with these rules. For example, </p> |
| |
| <blockquote><pre> |
| calls(my.package.*, static * get*(..)) // deprecated |
| </pre></blockquote> |
| |
| <p> should now be written </p> |
| |
| <blockquote><pre> |
| call(static * my.package.*.get*(..)) |
| </pre></blockquote> |
| |
| <h4>Calls to non-static methods</h4> |
| |
| <p> Many pointcuts denoting calls to non-static methods can be |
| fixed the same way that those pointcuts denoting calls to static |
| methods are fixed. So, |
| </p> |
| |
| <blockquote><pre> |
| calls(Thread, int getPriority()) // deprecated |
| </pre></blockquote> |
| |
| <p> which denotes all calls to nullary int methods named <code>getPriority</code> |
| when the called object is an instance of the <code>Thread</code> type, |
| can almost always be rewritten </p> |
| |
| <blockquote><pre> |
| call(int Thread.getPriority()) |
| </pre></blockquote> |
| |
| <p> which denotes all calls to the nullary int <code>Thread.getPriority()</code> |
| method. |
| </p> |
| |
| <p> Expanding the signature picks out slightly different join points |
| than the original two-argument form. This won't matter for most |
| programs, but in some cases the differences may be noticable. In |
| particular, the expanded-signature form only picks out those calls |
| where the called object is statically typed to <code>Thread</code> |
| when its <code>int getPriority()</code> method is called. If you want |
| to capture calls to the <code>int Thread.getPriority()</code> method, |
| regardless of how the called object is statically typed, you shoud use |
| the different translation: </p> |
| |
| <blockquote><PRE> |
| call(int getPriority()) && target(Thread) |
| </PRE></blockquote> |
| |
| <p> This will capture all call join points of methods with signature |
| <code>int Thread.getPriority()</code>. </p> |
| |
| <p> It will also denote any join points if the Thread type does not |
| define (possibly abstractly) some <code>int getPriority()</code> |
| method, though. </p> |
| |
| |
| <h3><a name="adviceInClasses">Removing advice from Class declarations</a></h3> |
| |
| <p> The simplest way to remove an advice declaration from a class is |
| to simply define the advice declaration in an inner aspect. So, |
| instead of </p> |
| |
| <blockquote><pre> |
| class C { |
| static before(): executions(C.new()) { ... } // deprecated |
| } |
| </pre></blockquote> |
| |
| <p> write </p> |
| |
| <blockquote><pre> |
| class C { |
| static aspect ConstructionProtocol { |
| static before(): executions(C.new()) { ... } |
| } |
| } |
| </pre></blockquote> |
| |
| <p> If your advice doesn't refer to any inner classes or interfaces of |
| C, you can move the inner aspect out of the class entirely. </p> |
| |
| <blockquote><pre> |
| class C { ... } |
| |
| aspect ConstructionProtocol { |
| static before(): execution(C.new()) { ... } |
| } |
| </pre></blockquote> |
| |
| <p> Your code will be clearer if you consider the purpose of each |
| piece of advice when you make this change. It may be that some of the |
| advice naturally belongs to another aspect, perhaps already existing. |
| Or it may be that some pieces of advice in a class are associated to |
| one concern and some to another; in which case more than aspect would |
| be appropriate. </p> |
| |
| <!-- ============================== --> |
| <hr /> |
| <h2><a name="pre07b10">Porting pre-0.7beta10 code</a></h2> |
| |
| <ul> |
| <li><a href="#joinPoints">Changing access to thisJoinPoint</a></li> |
| </ul> |
| |
| <p>The following changes are only required when porting code written |
| prior to the 0.7beta10 release of AspectJ.</p> |
| |
| |
| <h3><a name="joinPoints">Changing access to thisJoinPoint</a></h3> |
| |
| <p> In AspectJ 0.7beta10, access to the reflective object |
| <code>thisJoinPoint</code> substantially changed. The two parts of |
| this change were the elimination of the <code>runNext()</code> static |
| method, and the use of an interface hierarchy represent the join point |
| object. </p> |
| |
| <h4><a name="proceed"><code>thisJoinPoint.runNext()</code> to |
| <code>proceed()</code></a></h4> |
| |
| <p> The elimination of the <code>runNext()</code> static method |
| requires almost no porting work. An automatic replacement of the |
| string |
| </p> |
| |
| <blockquote><code>thisJoinPoint.runNext</code></blockquote> |
| |
| <p> with the string |
| </p> |
| |
| <blockquote><code>proceed</code></blockquote> |
| |
| <p> will do the job. However, if any around advice used the |
| identifier "<code>proceed</code>" as a formal parameter or local |
| variable, it must be renamed, and if any aspect used it as a field, |
| then references to the field in around advice should be made explicit |
| (prefixing the reference with the aspect name or "<code>this</code>", |
| depending on whether the field is static or not). </p> |
| |
| <h4><a name="thisJoinPoint">Using <code>thisJoinPoint</code></a></h4> |
| |
| <p> While access to reflective information through |
| <code>thisJoinPoint</code> is more powerful and regular through its |
| interface hierarchy, the previous uses must be rewritten. Changing |
| your code will likely require manual editing, but in doing so your |
| code should get simpler and cleaner. </p> |
| |
| <!-- --> |
| |
| <p> Many existing uses of the fields on join points can be re-written |
| to use one of: |
| </p> |
| |
| <ul> |
| <li><code>thisJoinPoint.toString()</code></li> |
| <li><code>thisJoinPoint.toShortString()</code></li> |
| <li><code>thisJoinPoint.toLongString()</code></li> |
| <li><code>thisJoinPoint.getSignature().toString()</code></li> |
| <li><code>thisJoinPoint.getSignature().toShortString()</code></li> |
| <li><code>thisJoinPoint.getSignature().toLongString()</code></li> |
| </ul> |
| |
| <p>For example: |
| </p> |
| |
| <blockquote><pre> |
| System.out.println(thisJoinPoint.className + "." + |
| thisJoinPoint.methodName) |
| </pre></blockquote> |
| |
| <p> can be replaced with |
| </p> |
| |
| <blockquote><code>System.out.println(thisJoinPoint)</code></blockquote> |
| |
| <p> or |
| </p> |
| |
| <blockquote><code>System.out.println(thisJoinPoint.getSignature().toShortString())</code></blockquote> |
| |
| <p> with comparable behavior. |
| </p> |
| |
| <!-- --> |
| |
| <p> Accesses to the parameters field of join points should be changed |
| as follows. A field access like: |
| </p> |
| |
| |
| <blockquote><code>thisJoinPoint.parameters</code></blockquote> |
| |
| <p> must be changed to: |
| </p> |
| <ul> |
| <li><code>thisJoinPoint.getArgs()</code></li> |
| </ul> |
| |
| <!-- --> |
| |
| <p> Accesses to the methodName and className fields of join points |
| that are not suitable for replacement with a toString method, |
| should be changed as follows. Field accesses like: |
| </p> |
| |
| <ul> |
| <li><code>thisJoinPoint.className</code></li> |
| <li><code>thisJoinPoint.methodName</code></li> |
| </ul> |
| |
| <p> must be changed to: |
| </p> |
| |
| <ul> |
| <li><code>thisJoinPoint.getSignature().getDeclaringType().getName()</code></li> |
| <li><code>thisJoinPoint.getSignature().getName()</code></li> |
| </ul> |
| |
| <!-- --> |
| |
| <p> Accessses to the parameterNames and parameterTypes fields of |
| join points, that are not suitable for conversion to one of the |
| toString() methods should be changed as follows. Field access |
| like: |
| </p> |
| |
| <ul> |
| <li><code>thisJoinPoint.parameterNames</code></li> |
| <li><code>thisJoinPoint.parameterTypes</code></li> |
| </ul> |
| |
| <p> must be changed to: |
| </p> |
| |
| <ul> |
| <li><code>((CodeSignature)thisJoinPoint.getSignature()).getParameterNames()</code></li> |
| <li><code>((CodeSignature)thisJoinPoint.getSignature()).getParameterTypes()</code></li> |
| </ul> |
| |
| </body> |
| </html> |