diff options
author | acolyer <acolyer> | 2004-03-19 20:49:58 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2004-03-19 20:49:58 +0000 |
commit | cce24d74634779801e999fb09f9031687eaa3d31 (patch) | |
tree | 0b2d8c0227d1b5f27e2d950680b06b07b94ebca5 /docs | |
parent | 5ca765d79fe9fd1445cf12841d3dacd96d508862 (diff) | |
download | aspectj-cce24d74634779801e999fb09f9031687eaa3d31.tar.gz aspectj-cce24d74634779801e999fb09f9031687eaa3d31.zip |
placeholder readme for 1.2
Diffstat (limited to 'docs')
-rw-r--r-- | docs/dist/doc/README-12.html | 1542 |
1 files changed, 1542 insertions, 0 deletions
diff --git a/docs/dist/doc/README-12.html b/docs/dist/doc/README-12.html new file mode 100644 index 000000000..7ca9e558c --- /dev/null +++ b/docs/dist/doc/README-12.html @@ -0,0 +1,1542 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> <head> +<title>AspectJ 1.1 Readme</title> +<style type="text/css"> +<!-- + P { margin-left: 20px; } + PRE { margin-left: 20px; } + LI { margin-left: 20px; } + H4 { margin-left: 20px; } + H3 { margin-left: 10px; } +--> +</style> +</head> + +<body> +<div align="right"><small> +© Copyright 2002 Palo Alto Research Center, Incorporated, +2003 Contributors. +All rights reserved. +</small></div> + + +<h1>AspectJ 1.2 Readme</h1> + +<i> content to be replaced </i> + + +<p> This is the initial release of AspectJ 1.1. It includes a small +number of new language features as well as major improvements to the +functionality of the tools. </p> + +<p> +This document describes the differences between +AspectJ versions 1.1 and 1.0.6. +Users new to AspectJ need only read +the <a href="progguide/index.html">AspectJ Programming Guide</a> +since it describes the 1.1 language. +Users familiar with AspectJ 1.0 may find this document +a quicker way to learn what changed in the language +and tools, and should use it as a guide for porting +programs from 1.0 to 1.1. +</p> + +<p>This document first summarizes changes from the 1.0 release in +</p> + +<ul> + <li><a href="#language">the language</a>,</li> + <li><a href="#compiler">the compiler</a>,</li> + <li><a href="#tools">the support tools</a>,</li> + <li><a href="#runtime">the runtime</a>,</li> + <li><a href="#devenv">the development environment support</a>,</li> + <li><a href="#sources">the sources</a>, and</li> + <li><a href="#distribution">the distribution</a>,</li> +</ul> + +<p> then <a href="#details">details</a> some of the language + and compiler changes, + and finally points readers to the bug database for any + <a href="#knownLimitations">known limitations</a>. +</p> + +<!-- ============================== --> +<hr> +<h2><a name="language">The Language</a></h2> + + <p> AspectJ 1.1 is a slightly different language than AspectJ 1.0. + In all but a few cases, programs written in AspectJ 1.0 should + compile correctly in AspectJ 1.1. In many cases, there are + new or preferred forms in AspectJ 1.1. However, some AspectJ 1.0 + features have changed in 1.1, so some 1.0 programs + will not compile or will run differently in 1.1. + The corresponding features are marked below as compile-time + or run-time incompatible (<em>CTI</em> or <em>RTI</em>, respectively). + When the language change involves a move in the static shadow effective + at run-time but also apparent at compile-time (e.g., in declare + error or warning statements), it is marked <em>CRTI</em>. + Programs using run-time incompatible forms should be verified that + they are behaving as expected in 1.1. + </p> + + <p> + Most changes to the language are additions to expressibility + requested by our users: + </p> + + <ul> + <li><a href="#THROWS_PATTERN">Matching based on throws</a>: You can + now make finer discriminations between methods based on declared + exceptions. </li> + + <li><a href="#NEW_PCDS">New kinded pointcut designators</a>: Now + every kind of join point has a corresponding kinded pointcut + designator. </li> + </ul> + + <p> Some are have different behavior in edge cases but offer + improved power and clarity: </p> + + <ul> + <li><a href="#ASPECT_PRECEDENCE">New aspect precedence form</a>: + AspectJ 1.1 has a new declare form, <code>declare + precedence</code>, that replaces the "dominates" + clause on aspects. (<em>CTI</em>) </li> + + <li>The order of <a href="#SUPER_IFACE_INITS">initialization join + points for super-interfaces</a> has been clarified. (<em>RTI</em>) </li> + </ul> + + <p> But in order to support weaving into bytecode effectively, + several incompatible changes had to be made to the language: </p> + + <ul> + <li>A class's default constructor may + <a href="#DEFAULT_CONSTRUCTOR_CONFLICT">conflict</a> with an + inter-type constructor. (<em>CTI</em>) </li> + + <li><a href="#NO_CALLEE_SIDE_CALL">No callee-side call join + points</a>: The AspectJ 1.1 compiler does not expose call join + points unless it is given the calling code. (<em>CRTI</em>) </li> + + <li><a href="#SINGLE_INTERCLASS_TARGET">One target for intertype + declarations</a>. (<em>CTI</em>) </li> + + <li><a href="#UNAVAILABLE_JOIN_POINTS">No initializer execution join + points</a>. (<em>RTI</em>)</li> + + <li><a href="#AFTER_HANDLER">No after or around advice on handler + join points</a>. (<em>CTI</em>) </li> + + <li><a href="#CONSTRUCTOR_EXECUTION_IS_BIGGER">Initializers run + inside constructor execution join points</a>. (<em>RTI</em>)</li> + + <li><a href="#INTER_TYPE_FIELD_INITIALIZERS">inter-type field + initializers</a> run before class-local field initializers. (<em>RTI</em>) </li> + + <li><a href="#WITHIN_MEMBER_TYPES">Small limitations of the within + pointcut.</a> (<em>CRTI</em>)</li> + + <li><a href="#WITHIN_CODE">Small limitations of the withincode + pointcut.</a> (<em>CRTI</em>)</li> + + <li><a href="#INSTANCEOF_ON_WILD">Can't do instanceof matching on + type patterns with wildcards</a>. (<em>CTI</em>) </li> + + <li><a href="#NO_SOURCE_COLUMN">SourceLocation.getColumn() is + deprecated and will always return 0</a>. (<em>RTI</em>) </li> + + <li>The interaction between aspect instantiation and advice has been + <a href="#ASPECT_INSTANTIATION_AND_ADVICE">clarified</a>. (<em>RTI</em>) </li> + + <li><a href="#STRINGBUFFER">The String + operator is now correctly advised</a>. + (<em>CRTI</em>) </li> + </ul> + + <p><a name="NEW_LIMITATIONS">There</a> are a couple of language + limitations for things that are rarely used that make the + implementation simpler, so we have restricted the language accordingly. + </p> + + <ul> + <li><a href="#VOID_FIELD_SET">Field set join points now have a + <code>void</code> return type.</a> This will require + porting of code that uses the <code>set</code> PCD in conjunction + with after-returning or around advice. (<em>CTI</em>) <p></p></li> + + <li>'declare soft: TYPE: POINTCUT;' - AspectJ 1.1 only + accepts TYPE rather than a TYPE_PATTERN. + This limitation makes declare soft + much easier to implement efficiently. (<em>CTI</em>) <p></p></li> + + <li>Inter-type field declarations only allow a single field per + line, i.e. this is now illegal 'int C.field1, D.field2;' This must + instead be, 'int C.field1; int D.field2;' (<em>CTI</em>) <p></p></li> + + <li>We did not implement the handling of more than one + <code>..</code> wildcard in args PCD's (rarely encountered in the + wild) because we didn't have the time. This might be available + in later releases if there is significant outcry. (<em>CTI</em>) </li> + + </ul> + + <p>We did not implement the long-awaited <a href="#PER_TYPE">new + pertype aspect specifier</a> in this release, but it may well + be in a future release.</p> + + +<!-- ============================== --> +<hr> +<h2><a name="compiler">The Compiler</a></h2> + + <p> The compiler for AspectJ 1.1 is different than the compiler for + AspectJ 1.0. While this document describes the differences in the + compiler, it's worthwhile noting that much effort has been made to + make sure that the interface to ajc 1.1 is, as much as possible, the + same as the interface to ajc 1.0. There are two important changes + under the hood, however. </p> + + <p> First, the 1.1 compiler is implemented on top of the + open-source Eclipse compiler. This has two benefits: It allows us + to concentrate on the AspectJ extensions to Java and let the Eclipse + team worry about making sure the Java edge cases work, and it allows + us to piggyback on Eclipse's already mature incremental compilation + facilities. </p> + + <p> Second, ajc now cleanly delineates compilation of source code + from assembly (or "weaving") of bytecode. The compiler still + accepts source code, but internally it transforms it into bytecode + format before weaving. </p> + + <p> This new architecture, and other changes to the compiler, allows + us to implement some features that were defined in the AspectJ 1.0 + language but not implementable in the 1.1 compiler. It also makes + some new features available: </p> + + <ul> + <li><a href="#SOURCEROOT">The -sourceroots option</a> + takes one or more directories, and indicates that all the source + files in those directories should be passed to the compiler. </li> + + <li><a href="#BYTECODE_WEAVING">The -injars option</a> + takes one or more jar files, and indicates that all the classfiles + in the jar files should be woven into. </li> + + <li><a href="#BINARY_ASPECTS">The -aspectpath option</a> + takes one or more jar files, and weaves any aspects in .class form + into the sources.</li> + + <li><a href="#OUTJAR">The -outjar option</a> indicates + that the result classfiles of compiling and weaving should be placed + in the specified jar file. </li> + + <li><a href="#XLINT">The -Xlint option</a> allows control over + warnings.</li> + + <li><a href="#OTHER_X_OPTIONS">Various -X options</a> changed.</li> + + <li><a href="#INCREMENTAL">The -incremental option</a> tells the + AspectJ 1.1 compiler to recompile only as necessary. </li> + </ul> + + <p> Some other features we wanted to support for 1.1, but did not make + it into this release: </p> + + <ul> + <li><a href="#ERROR_MESSAGES">Error messages will sometimes be scary</a></li> + <li><a href="#MESSAGE_CONTEXT">Source code context is not shown + for errors and warnings detected during bytecode weaving</a></li> + </ul> + + <p> But some features of the 1.0 compiler are not supported in the + 1.1 compiler: </p> + + <ul> + <li><a href="#NO_SOURCE">The source-related options</a> -preprocess, + -usejavac, -nocomment and -workingdir</li> + + <li><a href="#NO_STRICT_LENIENT">The -strict and -lenient options</a> + </li> + + <li><a href="#NO_PORTING">The -porting option</a></li> + + <li><a href="#13_REQUIRED">J2SE 1.2 is not supported; + J2SE 1.3 or later is required.</a></li> + </ul> + + <p> A short description of the options ajc accepts is available with + "<code>ajc -help</code>". + Longer descriptions are available in the + <a href="devguide/ajc-ref.html">Development Environment Guide + section on ajc</a>. </p> + <p> </p> + + + <p> Some changes to the implementation are almost entirely + internal: + </p> + + <ul> + <li>The behavior of the compiler in + <a href="#TARGET_TYPES_MADE_PUBLIC">lifting the visibility</a> of + the target types of some declares and pointcuts to public has been + clarified. </li> + </ul> + + <p> Also, it is worth noting that because AspectJ now works on bytecode, + it is somewhat sensitive to how different compilers generate + bytecode, especially when compiling with and without <a + href="#ONE_FOUR_METHOD_SIGNATURES">the -1.4 flag</a>. </p> + + + +<!-- ============================== --> +<hr> +<h2><a name="tools">Support Tools</a></h2> + + <p>This release includes an Ant task for old-style 1.0 build + scripts, a new task for all the new compiler options, and a + CompilerAdapter to support running <code>ajc</code> with the Javac + task by setting the <code>build.compiler</code> property. + The new task can automatically copy input resources to output + and work in incremental mode using a "tag" file. + </p> + + <p>This release does not include <code>ajdoc</code>, the + documentation tool for AspectJ sources. + Ajdoc is deeply dependent on the + abstract syntax tree classes from the old compiler, so it needs a + bottom-up rewrite. We think it best to use this opportunity to + implement more general API's for publishing and rendering static + structure. Because those API's are last to settle in the new + architecture, and because the compiler itself is a higher priority, + we are delaying work on ajdoc until after the 1.1 release.</p> + + <p>AspectJ 1.1 will not include <tt>ajdb</tt>, the AspectJ + stand-alone debugger. It is no longer necessary for two reasons. + First, the -XnoInline flag will tell the compiler to generate + code without inlining that should work correctly with any Java + debugger. For code generated with inlining enabled, more + third-party debuggers are starting to work according to JSR 45, + "Debugging support for other languages," which is supported by + AspectJ 1.0. We aim to support JSR-45 in AspectJ 1.1, but + support will not be in the initial release. Consider using + the -XnoInline flag until support is available.</p> + +<!-- ============================== --> +<hr> +<h2><a name="runtime">The Runtime Library</a></h2> + + <p>This release has minor additions to the runtime library classes. + As with any release, you should compile and run with the runtime + library that came with your compiler, and you may run with + a later version of the library without recompiling your code.</p> + + <p> In one instance, however, runtime classes behave differently this release. + Because the AspectJ 1.1 compiler does its weaving through + bytecode, column numbers of source locations are not available. + Therefore, <code>thisJoinPoint.getSourceLocation().getColumn()</code> + is deprecated and will always return 0. </p> + +<!-- ============================== --> +<hr> +<h2><a name="devenv">The AJDE Tools</a></h2> + + <p> The AspectJ Browser supports incremental compilation and running + programs. AJDE for JBuilder, AJDE for NetBeans, and AJDE for Emacs +are now independent SourceForge projects (to keep their licenses). + They use the batch-build mode of the new compiler. + </p> + +<!-- ============================== --> +<hr> +<h2><a name="sources">The Sources and the Licenses</a></h2> + + <p> The AspectJ tools sources are available under the + <a href="http://eclipse.org/legal/cpl-v10.html">Common Public + License</a> in the CVS repository + at <a href="http://eclipse.org/aspectj">http://eclipse.org/aspectj</a>. + For more information, see the FAQ entry on + <a href="faq.html#q:buildingsource">building sources</a>. + </p> + + +<!-- ============================== --> +<hr> +<h2><a name="distribution">The AspectJ distribution</a></h2> + + <p> AspectJ 1.0 had many distributions - for the tools, + the documentation, each IDE support package, + their respective sources, and the Ant tasks - + because they came under different licenses. + All of AspectJ 1.1 is licensed under the CPL 1.0, + so the tools, Ant tasks, and documentation are all + in one distribution available from + <a href="http://eclipse.org/aspectj"> + http://eclipse.org/aspectj</a>. +To retain their MPL 1.1 license, +Ajde for +<a href="http://aspectj4emacs.sourceforge.net/">Emacs</a>, +<a href="http://aspectj4netbean.sourceforge.net/">NetBeans</a> and +<a href="http://aspectj4jbuildr.sourceforge.net/">JBuilder</a> +are now independent SourceForge projects. </p> + + </p> + + +<!-- ============================== --> +<hr> +<hr> +<h2><a name="details">Details</a> of some language and compiler changes</h2> + + <h3><a name="ASPECT_INSTANTIATION_AND_ADVICE">Aspect Instantiation + and Advice</a></h3> + + <p> In AspectJ 1.0.6, we made an effort to hide some complications + with Aspect instantiation from the user. In particular, the + following code compiled and ran: + </p> + + <PRE> + public class Client + { + public static void main(String[] args) { + Client c = new Client(); + } + } + + aspect Watchcall { + pointcut myConstructor(): execution(new(..)); + + before(): myConstructor() { + System.err.println("Entering Constructor"); + } + } + </PRE> + + <p> But there's a conceptual problem with this code: The before + advice should run before the execution of all constructors in the + system. It must run in the context of an instance of the + Watchcall aspect. The only way to get such an instance is to have + Watchcall's default constructor execute. But before that + executes, we need to run the before advice...</p> + + <p> AspectJ 1.0.6 hid this circularity through the ad-hoc + mechanism of preventing an aspect's advice from matching join + points that were within the aspect's definition, and occurred + before the aspect was initialized. But even in AspectJ 1.0.6, + this circularity could be exposed: + </p> + + <PRE> + public class Client + { + public static int foo() { return 3; } + public static void main(String[] args) { + Client c = new Client(); + } + } + + aspect Watchcall { + int i = Client.foo(); + pointcut myConstructor(): + execution(new(..)) || execution(int foo()); + + before(): myConstructor() { + System.err.println("Entering Constructor"); + } + } + </PRE> + + <p>This program would throw a NullPointerException when run, since + Client.foo() was called before the Watchcall instance could be + instantiated. </p> + + <p> In AspectJ 1.1, we have decided that half-hiding the problem + just leads to trouble, and so we are no longer silently hiding + some join points before aspect initialization. However, we have + provided a better exception than a NullPointerException for this + case. In AspectJ 1.1, both of the above programs will throw + org.aspectj.lang.NoAspectBoundException. + </p> + + <h3><a name="THROWS_PATTERN">Matching based on throws</a></h3> + + <p> Type patterns may now be used to pick out methods and + constructors based on their throws clauses. This allows the + following two kinds of extremely wildcarded pointcuts: </p> + + <pre> pointcut throwsMathlike(): + // each call to a method with a throws clause containing at least + // one exception with "Math" in its name. + call(* *(..) throws *..*Math*); + + pointcut doesNotThrowMathlike(): + // each call to a method with a throws clause containing no + // exceptions with "Math" in its name. + call(* *(..) throws !*..*Math*); + </pre> + + <p> The longwinded rules are that a method or constructor pattern + can have a "throws clause pattern". Throws clause patterns look + like: </p> + + <pre> ThrowsClausePattern: + ThrowsClausePatternItem ("," ThrowsClausePatternItem)* + + ThrowsClausePatternItem: + ["!"] TypeNamePattern + </pre> + + <p> A ThrowsClausePattern matches the ThrowsClause of any code + member signature. To match, each ThrowsClausePatternItem must + match the throws clause of the member in question. If any item + doesn't match, then the whole pattern doesn't match. This rule is + unchanged from AspectJ 1.0. </p> + + <p> If a ThrowsClausePatternItem begins with "!", then it matches + a particular throws clause if and only if <em>none</em> of the + types named in the throws clause is matched by the + TypeNamePattern. </p> + + <p> If a ThrowsClausePatternItem does not begin with "!", then it + matches a throws clause if and only if <em>any</em> of the types + named in the throws clause is matched by the TypeNamePattern.</p> + + <p> These rules are completely backwards compatible with + AspectJ 1.0. The rule for "!" matching has one potentially + surprising property, in that the two PCD's shown below will have + different matching rules. </p> + + <pre> [1] call(* *(..) throws !IOException) + [2] call(* *(..) throws (!IOException)) + + void m() throws RuntimeException, IOException {} + </pre> + + <p> [1] will NOT match the method m(), because method m's throws + clause declares that it throws IOException. [2] WILL match the + method m(), because method m's throws clause declares the it + throws some exception which does not match IOException, + i.e. RuntimeException. </p> + + <h3><a name="NEW_PCDS">New kinded pointcut designators</a></h3> + + <p> AspectJ 1.0 does not provide kinded pointcut designators for + two (rarely used) join points: preinitialization (the code that + runs before a super constructor call is made) and advice + execution. AspectJ 1.1 does not change the meaning of the join + points, but provides two new pointcut designators to pick out + these join points, thus making join points and pointcut + designators more parallel. </p> + + <p> <code>adviceexectuion()</code> will pick out advice execution + join points. You will usually want to use <code>adviceexecution() + && within(Aspect)</code> to restrict it to only those pieces of + advice defined in a particular aspect. <br> + <code>preinitialization(<var>ConstructorPattern</var>)</code> will + pick out pre-initialization join points where the initialization + process is entered through + <code><var>ConstructorPattern</var></code>. </p> + + <h3><a name="PER_TYPE">New pertype aspect specifier</a> (not in 1.1)</h3> + + <p>We strongly considered adding a pertype aspect kind to 1.1. + This is somewhat motivated by the new + <a href="#SINGLE_INTERCLASS_TARGET">restrictions on inter-type + declarations<a>. This is also motivated by many previous request + to support a common logging idiom. Here's what pertype would look + like:</p> + + <pre> /** One instance of this aspect will be created for each class, + * interface or aspect in the com.bigboxco packages. + */ + aspect Logger pertype(com.bigboxco..*) { + /* This field holds a logger for the class. */ + Log log; + + /* This advice will run for every public execution defined by + * a type for which a Logger aspect has been created, i.e. + * any type in com.bigboxco..* + */ + before(): execution(public * *(..)) { + log.enterMethod(thisJoinPoint.getSignature().getName()); + } + + /* We can use a special constructor to initialize the log field */ + public Logger(Class myType) { + this.log = new Log(myType); + } + } + + /** External code could use aspectOf to get at the log, i.e. */ + Log l = Logger.aspectOf(com.bigboxco.Foo.class).log; + </pre> + + <p>The one open question that we see is how this should interact + with inner types. If a pertype aspect is created for an outer + type should advice in that aspect run for join points in inner + types? That is the behavior of the most common uses of this + idiom. </p> + + <p> In any case, this feature will not be in AspectJ 1.1. + </p> + + <h3><a name="SINGLE_INTERCLASS_TARGET">One target for intertype + declarations</a></h3> + + <p> Intertype declarations (once called "introductions") in + AspectJ 1.1 can only have one target type. So the following code + intended to declare that there is a void doStuff() method on all + subtypes of Target is not legal AspectJ 1.1 code. + </p> + + <pre> aspect A { + public void Target+.doStuff() { ... } + } + </pre> + + <p> The functionality of "multi-intertype declarations" can be + recovered by using a helper interface. + </p> + + <pre> aspect A { + private interface MyTarget {} + declare parents: Target+ implements MyTarget; + public void MyTarget.doStuff() { ... } + } + </pre> + + <p> We believe this is better style in AspectJ 1.0 as well, as it + makes clear the static type of "this" inside the method body. + </p> + + <p> The one piece of functionality that can not be easily + recovered is the ability to add static fields to many classes. We + believe that the <a href="#PER_TYPE">pertype proposal</a> provides + this functionality in a much more usable form.</p> + + <h3><a name="UNAVAILABLE_JOIN_POINTS">No initializer execution join + points</a></h3> + + <p> AspectJ 1.1 does not consider initializer execution a + principled join point. The collection of initializer code (the + code that sets fields with initializers and the code in non-static + initializer blocks) is something that makes sense only in Java + source code, not in Java bytecode. </p> + + <h3><a name="AFTER_HANDLER"></a>No after or around advice on handler + join points</h3> + + <p> The end of an exception handler is underdetermined in bytecode, + so ajc will not implement after or around advice on handler join + points, instead signaling a compile-time error.</p> + + <h3><a name="CONSTRUCTOR_EXECUTION_IS_BIGGER">Initializers run + inside constructor execution join points</a></h3> + + <p> The code generated by the initializers in Java source code now + runs inside of constructor execution join points. This changes + how before advice runs on constructor execution join points. + Consider: </p> + + <pre> class C { + C() { } + String id = "identifier"; // this assignment + // has to happen sometime + } + aspect A { + before(C c) this(c) && execution(C.new()) { + System.out.println(c.id.length()); + } + } + </pre> + + <p> In AspectJ 1.0, this will print "10", since id is assigned its + initial value prior to the before advice's execution. However, in + AspectJ 1.1, this will throw a NullPointerExcception, since "id" + does not have a value prior to the before advice's execution. + </p> + + <p> Note that the various flavors of after returning advice are + unchanged in this respect in AspectJ 1.1. Also note that this + only matters for the execution of constructors that call a + super-constructor. Execution of constructors that call a + this-constructor are the same in AspectJ 1.1 as in AspectJ 1.0. + </p> + + <p> We believe this difference should be minimal to real programs, + since programmers using before advice on constructor execution + must always assume incomplete object initialization, since the + constructor has not yet run. </p> + + <h3><a name="INTER_TYPE_FIELD_INITIALIZERS">Inter-type field initializers</a></h3> + + <p> The initializer, if any, of an inter-type field definition runs + before the class-local initializers of its target class. </p> + + <p> In AspectJ 1.0.6, such an initializer would run after the + initializers of a class but before the execution of any of its + constructor bodies. As already discussed in the sections about + <a href="#UNAVAILABLE_JOIN_POINTS">initializer execution join + points</a> and <a href="#CONSTRUCTOR_EXECUTION_IS_BIGGER">constructor + execution</a>, the point in code between the initializers of a class + and its constructor body is not principled in bytecode. So we had a + choice of running the initializer of an inter-type field definition at + the beginning of initialization (i.e., before initializers from + the target class) or at the end (i.e., just before its called + constructor exits). We chose the former, having this pattern in mind: + </p> + + <PRE> + int C.methodCount = 0; + before(C c): this(c) && execution(* *(..)) { c.methodCount++; } + </PRE> + + <p> We felt there would be too much surprise if a constructor called a + method (thus incrementing the method count) and then the field was + reset to zero after the constructor was done. + </p> + + <h3><a name="WITHIN_MEMBER_TYPES">Small limitations of the within + pointcut</a></h3> + + <p>Because of the guarantees made (and not made) by the Java + classfile format, there are cases where AspectJ 1.1 cannot + guarantee that the within pointcut designator will pick out all + code that was originally within the source code of a certain + type. + </p> + + <p> The non-guarantee applies to code inside of anonymous and + local types inside member types. While the within pointcut + designator behaves exactly as it did in AspectJ 1.0 when given a + package-level type (like C, below), if given a member-type (like + C.InsideC, below), it is not guaranteed to capture code in + contained local and anonymous types. For example: </p> + + <pre> class C { + Thread t; + class InsideC { + void setupOuterThread() { + t = new Thread( + new Runnable() { + public void run() { + // join points with code here + // might not be captured by + // within(C.InsideC), but are + // captured by within(C) + System.out.println("hi"); + } + }); + } + } + } + </pre> + + <p> We believe the non-guarantee is small, and we haven't verified + that it is a problem in practice. </p> + + <h3><a name="WITHIN_CODE">Small limitations of the withincode + pointcut</a></h3> + + <p>The withincode pointcut has similar issues to those described + above for within. + </p> + + <h3><a name="INSTANCEOF_ON_WILD">Can't do instanceof matching on + type patterns with wildcard</a></h3> + + <p>The pointcut designators this, target and args specify a + dynamic test on their argument. These tests can not be performed + on type patterns with wildcards in them. The following code that + compiled under 1.0 will be an error in AspectJ-1.1:</p> + + <pre> pointcut oneOfMine(): this(com.bigboxco..*); + </pre> + + <p>The only way to implement this kind of matching in a modular + way would be to use the reflection API at runtime on the Class of + the object. This would have a very high performance cost and + possible security issues. There are two good work-arounds. If + you control the source or bytecode to the type you want to match + then you can use declare parents, i.e.:</p> + + <pre> private interface OneOfMine {} + declare parents: com.bigboxco..* implements OneOfMine; + pointcut oneOfMine(): this(OneOfMine); + </pre> + + <p>If you want the more dynamic matching and are willing to pay + for the performance, then you should use the Java reflection API + combined with if. That would look something like:</p> + + <pre> pointcut oneOfMine(): this(Object) && + if(classMatches("com.bigboxco..*", + thisJoinPoint.getTarget().getClass())); + + static boolean classMatches(String pattern, Class _class) { + if (patternMatches(pattern, _class.getName())) return true; + ... + } + </pre> + + <p>Note: wildcard type matching still works in all other PCD's that + match based on static types. So, you can use + 'within(com.bigboxco..*+)' to match any code lexically within one + of your classes or a subtype thereof. This is often a good + choice.</p> + </p> + + + <h3><a name="NO_SOURCE_COLUMN">SourceLocation.getColumn()</a></h3> + + <p>The Java .class file format contains information about the + source file and line numbers of its contents; however, it has no + information about source columns. As a result, we can not + effectively support the access of column information in the + reflection API. So, any calls to + thisJoinPoint.getSourceLocation().getColumn() will be marked as + deprecated by the compiler, and will always return 0.</p> + + <h3><a name="ASPECT_PRECEDENCE">Aspect precedence</a></h3> + + <p> AspectJ 1.1 has a new declare form: + </p> + + <pre> declare precedence ":" TypePatternList ";" + </pre> + + <p> This is used to declare advice ordering constraints on join + points. For example, the constraints that (1) aspects that have + Security as part of their name should dominate all other aspects, and + (2) the Logging aspect (and any aspect that extends it) should + dominate all non-security aspects, can be expressed by: </p> + + <pre> declare precedence: *..*Security*, Logging+, *; + </pre> + + <p> In the TypePatternList, the wildcard * means "any type not matched + by another type in the declare precedence". </p> + + <h4>Various cycles</h4> + + <p> It is an error for any aspect to be matched by more than one + TypePattern in a single declare precedence, so: </p> + + <pre> declare precedence: A, B, A ; // error + </pre> + + <p> However, multiple declare precedence forms may legally have this + kind of circularity. For example, each of these declare precedence is + perfectly legal: + </p> + + <pre> declare precedence: B, A; + declare precedence: A, B; + </pre> + + <p> And a system in which both constraints are active may also be + legal, so long as advice from A and B don't share a join point. So + this is an idiom that can be used to enforce that A and B are strongly + independent. </p> + + <h4>Applies to concrete aspects</h4> + + <p> Consider the following library aspects: + </p> + + <pre> abstract aspect Logging { + abstract pointcut logged(); + + before(): logged() { + System.err.println("thisJoinPoint: " + thisJoinPoint); + } + } + + aspect MyProfiling { + abstract pointcut profiled(); + + Object around(): profiled() { + long beforeTime = System.currentTimeMillis(); + try { + return proceed(); + } finally { + long afterTime = System.currentTimeMillis(); + addToProfile(thisJoinPointStaticPart, + afterTime - beforeTime); + } + } + abstract void addToProfile( + org.aspectj.JoinPoint.StaticPart jp, + long elapsed); + } + </pre> + + <p> In order to use either aspect, they must be extended with + concrete aspects, say, MyLogging and MyProfiling. In AspectJ + 1.0, it was not possible to express that Logging's advice (when + concerned with the concrete aspect MyLogging) dominated + Profiling's advice (when concerned with the concrete aspect + MyProfiling) without adding a dominates clause to Logging + itself. In AspectJ 1.1, we can express that constraint with a + simple: </p> + + <pre> declare precedence: MyLogging, MyProfiling; + </pre> + + <h4>Changing order of advice for sub-aspects</h4> + + <p> By default, advice in a sub-aspect has more precedence than + advice in a super-aspect. One use of the AspectJ 1.0 dominates + form was to change this precedence: + </p> + + <pre> abstract aspect SuperA dominates SubA { + pointcut foo(): ... ; + + before(): foo() { + // in AspectJ 1.0, runs before the advice in SubA + // because of the dominates clause + } + } + + aspect SubA extends SuperA { + before(): foo() { + // in AspectJ 1.0, runs after the advice in SuperA + // because of the dominates clause + } + } + </pre> + + <p> This no longer works in AspectJ 1.1, since declare precedence only + matters for concrete aspects. Thus, if you want to regain this kind + of precedence change, you will need to refactor your aspects. + </p> + + <h3><a name="SOURCEROOT">The -sourceroots option</a></h3> + + <p> The AspectJ 1.1 compiler now accepts a -sourceroots option used to + pass all .java files in particular directories to the compiler. It + takes either a single directory name, or a list of directory names + separated with the CLASSPATH separator character (":" for various + Unices, ";" for various Windows). </p> + + <p> So, if you have your project separated into a gui module and a + base module, each of which is stored in a directory tree, you might + use one of + </p> + + <pre> ajc -sourceroots /myProject/gui:/myProject/base + ajc -sourceroots d:\myProject\gui;d:\myProject\base + </pre> + + <p> This option may be used in conjunction with lst files, listing + .java files on the command line, and the -injars option. + </p> + + <h3><a name="BYTECODE_WEAVING">The -injars option</a></h3> + + <p> The AspectJ 1.1 compiler now accepts an -injars option used to + pass all .class files in a particular jar file to the compiler. It + takes either a single directory name, or a list of directory names + separated with the CLASSPATH separator character (":" for various + Unices, ";" for various Windows). </p> + + <p> So, if MyTracing.java defines a trace aspect that you want to + apply to all the classes in myBase.jar and myGui.jar, you would use + one of: </p> + + <pre> ajc -injars /bin/myBase.jar:/bin/myGui.jar MyTracing.java + ajc -injars d:\bin\myBase.jar;d:\bin\myGui.jar MyTracing.java + </pre> + + <p> The class files in the input jars must not have had advice woven + into them, since AspectJ enforces the requirement that advice is woven + into a particular classfile only once. So if the classfiles in the + jar file are to be created with the ajc compiler (as opposed to a pure + Java compiler), they should not be compiled with any non-abstract + aspects. </p> + + <p> This option may be used in conjunction with lst files, listing + .java files on the command line, and the -sourceroots option. + </p> + + <h3><a name="OUTJAR">The -outjar option</a></h3> + + <p> The -outjar option takes the name of a jar file into which the + results of the compilation should be put. For example: + + <pre> ajc -injars myBase.jar MyTracing.java -outjar myTracedBase.jar + </pre> + + <p> No meta information is placed in the output jar file. </p> + + <h3><a name="INCREMENTAL">Incremental compilation</a></h3> + + <p> The AspectJ 1.1 compiler now supports incremental compilation. + When ajc is called with the -incremental option, it must also be + passed a -sourceroots option specifying a directory to incrementally + compile. Once the initial compile is done, ajc waits for console + input. Every time it reads a new line (i.e., every time the user + hits return) ajc recompiles those input files that need recompiling. + </p> + + <h4>Limitations</h4> + + <p> This new functionality is still only lightly tested. </p> + + <h3><a name="XNOWEAVE">-XnoWeave, a compiler option to suppress + weaving</a></h3> + + <p> The -XnoWeave option suppresses weaving, and generates + classfiles and that can be passed to ajc again (through the + -injars option) to generate final, woven classfiles. </p> + + <p> This option was originally envisioned to be the primary way to + generate binary aspects that could be linked with other code, and + so it was previously (in AspectJ 1.1beta1) named + <code>-noweave</code>. We feel that using the + <code><a href="#BINARY_ASPECTS">-aspectpath</a></code> option is a + much better option. There may still be use cases for unwoven + classfiles, but we've moved the flag to experimental status. + </p> + + <h3><a name="BINARY_ASPECTS">-aspectpath, working with aspects in .class/.jar + form</a> </h3> + + <p> When aspects are compiled into classfiles, they include all + information necessary for the ajc compiler to weave their advice + and deal with their inter-type declarations. In order for these + aspects to have an effect on a compilation process, they must be + passed to the compiler on the -aspectpath. Every .jar file on + this path will be searched for aspects and any aspects that are + found will be enabled during the compilation. The binary forms of + this aspects will be untouched. </p> + + <h3><a name="NO_CALLEE_SIDE_CALL">Callee-side call join + points</a></h3> + + <p> The 1.0 implementation of AspectJ, when given: + </p> + + <pre> class MyRunnable implements Runnable { + public void run() { ... } + } + + aspect A { + call(): (void run()) && target(MyRunnable) { + // do something here + } + } + </pre> + + <p> would cause A's advice to execute even when, say, java.lang.Thread + called run() on a MyRunnable instance. + </p> + + <p> With the new compiler, two things have happened in regard to + callee-side calls: + </p> + + <ol> + <li>because the programmer has access to more code (i.e., + bytecode, not just source code), callee-side calls are much + less important to have.</li> + + <li>because compilation is more modular, allowing and + encouraging separate compilation, callee-side calls are much + more difficult to implement</li> + </ol> + + <p> With these two points in mind, advice in an aspect will not be + applied to call join points whose call site is completely + unavailable to the aspect. </p> + + <ol> + <li>One reason (though not the only reason) we worked so hard in + the <em>implementation</em> of 1.0.6 to expose call join + points, even if we only had access to the callee's code, was + that otherwise users couldn't get access to call join points + where the call was made from bytecode. This is no longer the + case. In short, the implementation controls much more code (or + has the capability to) than ever before.</li> + + <li>The implementation model for the AspectJ 1.1 compiler is to + separate the compilation of aspects/advice from their + weaving/linking. A property of the model is that the + compilation requires no access to "target" code, only the + weaving/linking does, and weaving/linking is inherently + per-class local: No action at weaving/linking time depends on + the coordinated mangling of multiple classfiles. Rather, all + weaving is done on a per classfile basis. This is an essential + property for the current separate compilation model. <br> + + However, allowing implementation of call advice on either + side requires simultaneous knowledge of both sides. If we first + have access to a call, we can't decide to simply put the advice + on the call site, since later we may decide to implement on the + callee.</li> + </ol> + + <p>This implementation decision is completely in the letter and + the spirit of the AspectJ language. From the semantics guide + describing code the implementation controls:</p> + + <blockquote> + But AspectJ implementations are permitted to deviate from this + in a well-defined way -- they are permitted to advise only + accesses in <em>code the implementation + controls</em>. Each implementation is free within certain + bounds to provide its own definition of what it means to control + code. + </blockquote> + + <p>And about a particular decision about the 1.0.6 + implementation:</p> + + <blockquote> + Different join points have different requirements. Method call + join points can be advised only if ajc controls + <em>either</em> the code for the caller or the code + for the receiver, and some call pointcut designators may + require caller context (what the static type of the receiver + is, for example) to pick out join points. + </blockquote> + + <p> The 1.1 implementation makes a different design decision: + Method call join points can be advised only if ajc (in compiler or + linker form) controls the code for the caller. </p> + + <p>What does 1.1 gain from this?</p> + + <ul> + <li>a clear (and implemented) separate compilation model (see + point 2, above)</li> + + <li>a less confusing interaction between call join points and + the thisJoinPoint reflective object: We still get bug reports + about source information sometimes existing and sometimes not + existing at call join points.</li> + </ul> + + <p> What does 1.1 lose from this?</p> + + <ul> + <li>The ability to capture all calls to Runnable.run() from + anywhere to code ajc has access too, even from Thread, even if + you don't compile java.lang with ajc.</li> + + <li>The ability to, without access to the caller, capture entry to + a particular method, but not super calls.</li> + + <li>A code-size-improvement performance optimization.</li> + </ul> + + <p> What are the possibilities for the future?</p> + + <ul> + <li>AspectJ 1.1.1 could expand its capture of call join points, + possibly at the expense of separate compilation clarity, + possibly not. </li> + + <li>AspectJ 1.1.1 could re-introduce reception join points from + AspectJ 0.7 (what callee-side call join points actually are): + though they would never ever be taught in a tutorial or + entry-level description of the model, they may have specialized + uses.</li> + </ul> + + <p> How will this affect developers?</p> + <ul> + <li>When using the call PCD but only supplying the callee + code, supply the calling code or use the execution PCD instead. + </li> + </ul> + + <h3><a name="OTHER_X_OPTIONS">Various -X options</a></h3> + + <p> The AspectJ 1.0 compiler supported a number of options that + started with X, for "experimental". Some of them will not be + supported in 1.1, either because the "experiment" succeeded (in + which case it's part of the normal functionality) or failed. + Others will be supported as is (or nearly so) in 1.1: + </p> + + <ul> + <li>-XOcodeSize: This is no longer necessary because inlining + of around advice is on by default. We support its inverse, + <a href="#XNOINLINE"><code>-XnoInline</code></a>. + </li> + + <li><a href="#XNOWEAVE">-XnoWeave, a compiler option to suppress + weaving</a></li> + + <li>-XtargetNearSource: Not supported in this release. </li> + + <li>-XserializableAspects: Supported. </li> + + <li>-XaddSafePrefix: This option will not be supported in 1.1 at + all because we're now always using (what we believe to be) safe + prefixes. </li> + + <li>-Xlint: Still supported, with <a href="#XLINT">various + options</a>. </li> + </ul> + + <h3><a name="ERROR_MESSAGES">Some confusing error messages</a></h3> + + <p>Building on the eclipse compiler has given us access to a very + sophisticated problem reporting system as well as highly optimized + error messages for pure Java code. Often this leads to noticeably + better error messages than from ajc-1.0.6. However, when we don't + handle errors correctly this can sometimes lead to cascading error + messages where a single small syntax error will produce dozens of + other messages. Please report any very confusing error messages as + bugs.</p> + + + <h3><a name="MESSAGE_CONTEXT">Source code context is not shown + for errors and warnings detected during bytecode weaving</a></h3> + + <p>For compiler errors and warnings detected during bytecode weaving, + source code context will not be displayed. In particular, for declare + error and declare warning statements, the compiler now only emits the + file and line. We are investigating ways to overcome this in cases + where the source code is available; in cases where source code is + not available, we might specify the signature of the offending code. + For more information, see bug 31724.</p> + + + <h3><a name="XLINT">The -Xlint option</a></h3> + + <p><code>-Xlint:ignore,error,warning</code> will set the level for + all Xlint warnings. <code>-Xlint</code>, alone, is an + abbreviation for <code>-Xlint:warning</code>.</p> + + <p>The <code>-Xlintfile:lint.properties</code> allows fine-grained + control. In tools.jar, see + <code>org/aspectj/weaver/XlintDefault.properties</code> for the + default behavior and a template to copy. </p> + + <p> More <code>-Xlint</code> warnings are supported now, and + we may add disabled warnings in subsequent bug-fix releases of 1.1. + Because the configurability allows users to turn off + warnings, we will be able to warn about more potentially + dangerous situations, such as the potentially unsafe casts used by + very polymorphic uses of proceed in around advice. </p> + + <h3><a name="NO_SOURCE">Source-specific options</a></h3> + + <p> Because AspectJ 1.1 does not generate source code after + weaving, the source-code-specific options -preprocess, -usejavac, + -nocomment and -workingdir options are meaningless and so not + supported. </p> + + <h3><a name="NO_STRICT_LENIENT">The -strict and -lenient + options</a></h3> + + <p> Because AspectJ 1.1 uses the Eclipse compiler, which has its + own mechanism for changing strictness, we no longer support the + -strict and -lenient options. </p> + + <h3><a name="NO_PORTING">The -porting option</a></h3> + + <p> AspectJ 1.1 does not have a -porting option.</p> + + <h3><a name="13_REQUIRED">J2SE 1.3 required</a></h3> + + <p>Because we build on Eclipse, the compiler will no longer run + under J2SE 1.2. You must run the compiler (and all tools based on + the compiler) using J2SE 1.3 or later. The code generated by the + compiler can still run on Java 1.1 or later VM's if compiled against + the correct runtime libraries.</p> + + <h3><a name="DEFAULT_CONSTRUCTOR_CONFLICT">Default + constructors</a></h3> + + <p> AspectJ 1.1 does not allow the inter-type definition of a + zero-argument constructor on a class with a visible default + constructor. So this is no longer allowed: </p> + + <PRE> + class C {} + + aspect A { + C.new() {} // was allowed in 1.0.6 + // is a "multiple definitions" conflict in 1.1 + } + </PRE> + + <p> In the Java Programming Language, a class defined without a + constructor actually has a "default" constructor that takes no + arguments and just calls <code>super()</code>. </p> + + <p> This default constructor is a member of the class like any other + member, and can be referenced by other classes, and has code generated + for it in classfiles. Therefore, it was an oversight that AspectJ + 1.0.6 allowed such an "overriding" inter-type constructor definition. + </p> + + <h3><a name="SUPER_IFACE_INITS">Initialization join points for + super-interfaces</a></h3> + + <p> In AspectJ, interfaces may have non-static members due to + inter-type declarations. Because of this, the semantics of AspectJ + defines the order that initializer code for interfaces is run. + </p> + + <p> In the semantics document for AspectJ 1.0.6, the following + promises were made about the order of this initialization: + </p> + + <ol> + <li>a supertype is initialized before a subtype</li> + <li>initialized code runs only once</li> + <li>initializers for supertypes run in left-to-right order</li> + </ol> + + <p> The first two properties are important and are preserved in + AspectJ 1.1, but the third property is and was ludicrous, and was + never properly implemented (and never could be) in AspectJ 1.0.6. + Consider: </p> + + <PRE> + interface Top0 {} + interface Top1 {} + interface I extends Top0, Top1 {} + interface J extends Top1, Top0 {} + + class C implements I, J {} + // I says Top0's inits must run before Top1's + // J says Top1's inits must run before Top0's + + aspect A { + int Top0.i = foo("I'm in Top0"); + int Top1.i = foo("I'm in Top1"); + static int foo(String s) { + System.out.println(s); + return 37; + } + } + </PRE> + + <p> This was simply a bug in the AspectJ specification. The correct + third rule is: + </p> + + <blockquote>the initializers for a type's superclass are run before the + initializers for its superinterfaces. + </blockquote> + + + <h3><a name="VOID_FIELD_SET">Field Set Join Points</a></h3> + + <p> In AspectJ 1.0.6, the join point for setting a field F had, as a + return type, F's type. This was "java compatible" because + field assignment in java, such as "Foo.i = 37", is in fact an + expression, and does in fact return a value, the value that the + field is assigned to. + </p> + + <p> This was never "java programmer compatible", however, largely + because programmers have absorbed the good style of rarely using an + assignment statement in a value context. Programmers typically expect + "Foo.i = 37" not to return a value, but to simply assign a value. </p> + + <p> Thus, programmers typically wanted to write something like: + </p> + + <PRE> + void around(): set(int Foo.i) { + if (theSetIsAllowed()) { + proceed(); + } + } + </PRE> + + <p> And were confused by it being a compile-time error. They weren't + confused for long, and soon adapted to writing: + </p> + + <PRE> + int around(): set(int Foo.i) { + if (theSetIsAllowed()) { + return proceed(); + } else { + return Foo.i; + } + } + </PRE> + + <p> But there was definitely a short disconnect. </p> + + <p> On top of that, we were never shown a convincing use-case for + returning an interesting value from a set join point. When we + revisited this issue, in fact, we realized we had a long-standing bug + in 1.0.6 dealing with the return value of pre-increment expressions + (such as ++Foo.i) that nobody had found because nobody cares about the + return value of such join points. + </p> + + <p> So, because it's easier to implement, and because we believe that + this is the last possibility to make the semantics more useful, we + have made set join points have a void return type in 1.1. </p> + + <h3><a name="XNOINLINE">The -XnoInline Option</a></h3> + + <p> The <code>-XnoInline</code> + option to indicate that no inlining of any kind should be done. This + is purely a compiler pragma: No program semantics (apart from stack + traces) will be changed by the presence or absence of this option. + </p> + + <h3><a name="TARGET_TYPES_MADE_PUBLIC">Target types made + public</a></h3> + + <p> Even in 1.0.6, the AspectJ compiler has occasionally needed to + convert the visibility of a package-level class to a public one. This + was previously done in an ad-hoc basis that took whole-program + analysis into account. With the incremental compilation model of + AspectJ 1.1, we can now specify the occasions when the compiler makes + these visibility changes. + </p> + + <p> In particular, the types used in the <code>this</code>, + <code>target</code>, and <code>args</code> pointcuts are made public, + as are the super-types from <code>declare parents</code> and the + exception type from <code>declare soft</code>. + </p> + + <p> We believe the visibility changes could be avoided in the future + with various implementation tricks if they become a serious + concern, but did not encounter them as such a concern when they were + done in the 1.0.6 implementation. </p> + +<h3><a name="STRINGBUFFER">String + now advised</a></h3> + +<p> In Java, the + operator sometimes results in StringBuffer objects +being created, appended to, and used to generate a new String. Thus, +</p> + +<PRE> +class Foo { + String makeEmphatic(String s) { + return s + "!"; + } +} +</PRE> + +<p> is approximately the same at runtime as +</p> + +<PRE> +class Foo { + String makeEmphatic(String s) { + return new StringBuffer(s).append("!").toString(); + } +} +</PRE> + + +<p> In the design process of AspectJ 1.0.6 we didn't expose those +StringBuffer methods and constructors as join points (though we did +discuss it), but in 1.1 we do. </p> + +<p> This change is likely to affect highly wildcarded aspects, and can +do so in surprising ways. In particular: +</p> + +<PRE> +class A { + before(int i): call(* *(int)) && args(i) { + System.err.println("entering with " + i); + } +} +</PRE> + +<p> may result in a stack overflow error, since the argument to +println is really </p> + +<PRE> +new StringBuffer("entering with ").append(i).toString() +</PRE> + +<p> which has a call to StringBuffer.append(int). In such cases, it's +worth restricting your pointcut, with something like one of: +</p> + +<PRE> +call(* *(int)) && args(i) && !within(A) +call(* *(int)) && args(i) && !target(StringBuffer) +</PRE> + +<h3><a name="ONE_FOUR_METHOD_SIGNATURES">The -1.4 flag and method signatures</a></h3> + +<p> Consider the following aspect +</p> + +<PRE> +public aspect SwingCalls { + + pointcut callingAnySwing(): call(* javax.swing..*+.*(..)); + + before(): callingAnySwing() { + System.out.println("Calling any Swing"); + } +} +</PRE> + +<p> And then consider the two statements +</p> + +<PRE> + JFrame frame = new JFrame(); + frame.setTitle("Title"); +</PRE> + +<p> According to the Java Language Specification version 2, the call +to <code>frame.setTitle("Title")</code> should always produce the +bytecode for a call to <code>javax.swing.JFrame.setTitle</code>. +However, older compilers (and eclipse when run without the +<code>-1.4</code> flag) will generate the bytecode for a call to +<code>java.awt.Frame.setTitle</code> instead since this method is not +overriden by JFrame. The AspectJ weaver depends on the correctly +generated bytecode in order to match patterns like the one you show +correctly. </p> + +<p> This is a good example of why the pattern <code>call(* *(..)) && +target(JFrame)</code> is the recommended style. In general, OO +programmers don't want to care about the static type of an object at a +call site, but only want to know the dynamic instanceof behavior which +is what the target matching will handle. </p> + + +<h2><a name="knownLimitations">Known limitations</a></h2> + +<p>The AspectJ 1.1.0 release contains a small number of known limitations +relative to the AspectJ 1.1 language. +For the most up-to-date information about known limitations in an +AspectJ 1.1 release, see the bug database at + <a href="http://bugs.eclipse.org/bugs">http://bugs.eclipse.org/bugs</a>, +especially the open bugs for the +<a href="http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Compiler&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED"> + compiler</a>, +<a href="http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=IDE&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED"> + IDE support</a>, +<a href="http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Doc&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED"> + documentation</a>, and +<a href="http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Ant&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED"> + Ant tasks</a>. +Developers should know about bugs marked with the "info" keyword +because those bugs reflect failures to implement the 1.1 language perfectly. +These might be fixed during the 1.1 release cycle; find them using the query + <a href="http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&keywords=info"> + http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&keywords=info</a> + +For ajc's 1.1 implementation limitations, see + <a href="progguide/implementation.html"> + Programming Guide Appendix: "Implementation Notes"</a>. + +</p> +</body> </html> |