From: acolyer The default AspectJ compiler compliance level is now 1.4 (whereas in
+previous releases the default compliance level was 1.3). This has a number
+of implications:
+AspectJ Porting Notes
+
+Porting pre-1.2 code to AspectJ 1.2
+README-12.html contains a discussion
+of the changes between 1.1 and 1.2. The key points are:
+
+
+
+The AspectJ compiler can be restored to 1.3 compliance settings by specifying the
+"-1.3" option on the command-line.
+call
pointcuts may match more join points than in the same
+program compiled at compliance level 1.3.
+
The following example program illustrates the differences in join point matching
+with the call
pointcut designator between 1.4 and 1.3 compliance levels.
+
+
+
+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 }
+
+
+
+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:
+About to call B.doIt(...)
+
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. + +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 is matched by the call pcd. + +
This is a good example of why the recommended style is to use call(* doIt(..)) && target(B)
,
+which always matches based on the actual type of the receiver.
+
+
New warnings emitted by the compiler for unmatched call pcds. Because users have found
+the static type matching used for a type pattern specified in a call
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:
+
+
+
+
+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
+
+
+1 warning
+
+
+
+
+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 bInDisguise.doIt()
. Since the static type of
+bInDisguise
is A
, 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
+call(* doIt(..) && target(B)
.
+
+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 target
designator in place of a type pattern in the call
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 target
expression. Note that target
cannot be used in declare
statements.
+