]> source.dussan.org Git - aspectj.git/commitdiff
added porting to 1.2 documentation
authoracolyer <acolyer>
Fri, 19 Mar 2004 20:48:44 +0000 (20:48 +0000)
committeracolyer <acolyer>
Fri, 19 Mar 2004 20:48:44 +0000 (20:48 +0000)
docs/dist/doc/porting.html

index d65a447d6924593a28d6425f4b950d92f77aff16..285a2e8bb3bdb92323ce9406a88dee21c4ea63ad 100644 (file)
@@ -7,13 +7,14 @@
 
 <div align=right><small>
 &copy; Copyright 1998-2002 Palo Alto Research Center Incorporated,
-                      2003 Contributors.
+                 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>
@@ -29,6 +30,112 @@ All rights reserved.
   <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: 
+<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> <code>call</code> pointcuts may match more join points than in the same
+program compiled at compliance level 1.3.
+</ul>
+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. 
+
+<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>
+
+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><code>About to call B.doIt(...)</code>
+<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. 
+
+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>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><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:
+
+<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>
+
 <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: