+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html> <head>
-<title>AspectJ 1.1 release candidate 2 -- 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 Readme</h1>
-
-<p align="right"><i>Version 1.1 release candidate 2</i></p>
-
-<p> This is an early-access 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 is intended to completely describe the 1.1 language
-and tools in relation to AspectJ 1.0.6.
-For the most up-to-date information about known issues in AspectJ 1.1,
-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>.
-
-</p>
-
-<p>The information in this document has been folded into the semantics
-appendix of the AspectJ programming guide, but has not yet been folded
-into the rest of the main line of AspectJ documentation. All
-descriptions here should be read as changes to the AspectJ
-documentation. </p>
-
-<p> The main body of this document describes the differences between
-this 1.1 release candidate and the 1.0.6 release. For those following our
-release schedule closely, however, these are the changes (other than
-bugfixes) since the 1.1beta2 release: </p>
-
-<ul>
- <li>The interaction between aspect instantiation and advice has been
- <a href="#ASPECT_INSTANTIATION_AND_ADVICE">clarified</a>. </li>
- <li>The new <code>declare dominates</code> is now written
- <code>declare precedence</code>. This is incompatible with
- previous 1.1betaX releases, but is completely compatible with
- 1.0 where this feature wasn't available at all.</li>
-</ul>
-
-<p> This document begins with short descriptions of changes from the
-1.0 release.
-</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>, and</li>
- <li><a href="#sources">the sources</a>,</li>
-</ul>
-
-<p> followed by <a href="#details">details</a> of many of the changes.
-</p>
-
-<p> Apart from these changes, the major change from the 1.0 series of
-releases is distribution. The documentation, core tools and ant tasks
-are now part of a single downloadable distribution from
-<a href="http://eclipse.org/aspectj">eclipse.org</a>. 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
-individual SourceForge projects, and their 1.1 releases may trail
-the main AspectJ release. </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 in this release.
- </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 is intended to replace the "dominates"
- clause on aspects. </li>
-
- <li>The order of <a href="#SUPER_IFACE_INITS">initialization join
- points for super-interfaces</a> has been clarified. </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. </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. </li>
-
- <li><a href="#SINGLE_INTERCLASS_TARGET">One target for intertype
- declarations</a></li>
-
- <li><a href="#UNAVAILABLE_JOIN_POINTS">No initializer execution join
- points</a></li>
-
- <li><a href="#CONSTRUCTOR_EXECUTION_IS_BIGGER">Initializers run
- inside constructor execution join points</a></li>
-
- <li><a href="#INTER_TYPE_FIELD_INITIALIZERS">inter-type field
- initializers</a> run before class-local field initializers</li>
-
- <li><a href="#WITHIN_MEMBER_TYPES">Small limitations of the within
- pointcut</a></li>
-
- <li><a href="#WITHIN_CODE">Small limitations of the withincode
- pointcut</a></li>
-
- <li><a href="#INSTANCEOF_ON_WILD">Can't do instanceof matching on
- type patterns with wildcards</a></li>
-
- <li><a href="#NO_SOURCE_COLUMN">SourceLocation.getColumn() is
- deprecated and will always return 0</a></li>
-
- <li>The interaction between aspect instantiation and advice has been
- <a href="#ASPECT_INSTANTIATION_AND_ADVICE">clarified</a>. </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.<p></p></li>
-
- <li>'declare soft: TYPE: POINTCUT;' In 1.0 a TYPE_PATTERN was
- allowed rather than a TYPE. This limitation makes declare soft
- much easier to implement efficiently.<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;'<p></p></li>
-
- <li>We did not implement the handling of more than one
- <code>..</code> wildcard in args PCDs (rarely encountered in the
- wild) because we didn't have the time. This might be available
- in later releases if there is significant outcry.</li>
-
- </ul>
-
- <p>Finally,
- we did not implement the <a href="#PER_TYPE">new
- pertype aspect specifier</a>. It has been taken off the table for
- 1.1, though 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 deliniates 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>: This option
- 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>: This option
- 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">-aspectpath, working with aspects in
- .class/.jar form</a></li>
-
- <li><a href="#OUTJAR">The -outjar option</a>: This option 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 allows control over
- warnings.</a></li>
-
- <li><a href="#OTHER_X_OPTIONS">Various -X options</a> changed.</li>
-
- <li><a href="#INCREMENTAL">Incremental compilation</a>: The AspectJ
- 1.1 compiler supports incremental compilation. </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">Source-specific options</a>: The -preprocess,
- -usejavac, -nocomment and -workingdir options are no longer
- supported</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> And 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> A short description of the options ajc accepts is available with
- "<code>ajc -help</code>".
- Longer descriptions are available in the Development Environment Guide
- section on ajc. </p>
- <p> </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.
- </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, they 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 hasn't changed much, and apart from being
- distributed from Sourceforge, AJDE for JBuilder, AJDE for Netbeans,
- and AJDE for Emacs haven't changed much either. They use the
- batch-build mode of the new compiler. Incremental building and
- bytecode weaving are not available in the AJDE tools in this release,
- but might be in a future release.</p>
-
- <p> Of note is that NetBeans 3.4 is supported, and there is now
- better integration for the compiler messages output window.</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">http://eclipse.org</a>.
- For more information, see the FAQ entry on
- <a href="http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/doc/faq.html#q:buildingsource">
- building sources</a>.
- </p>
-
-<!-- ============================== -->
-<hr>
-<hr>
-<h2><a name="details">Details</a></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 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 PCDs 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="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> Becuase 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
- combinded 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 pcds 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 decare 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 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 knowlege 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>
-
- <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 noticably
- 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 Java1.1 or later VMs 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>
-
-
-</body> </html>