aboutsummaryrefslogtreecommitdiffstats
path: root/docs/dist/doc/README-1.1.adoc
diff options
context:
space:
mode:
Diffstat (limited to 'docs/dist/doc/README-1.1.adoc')
-rw-r--r--docs/dist/doc/README-1.1.adoc1381
1 files changed, 1381 insertions, 0 deletions
diff --git a/docs/dist/doc/README-1.1.adoc b/docs/dist/doc/README-1.1.adoc
new file mode 100644
index 000000000..d846cff81
--- /dev/null
+++ b/docs/dist/doc/README-1.1.adoc
@@ -0,0 +1,1381 @@
+[[readme-1_1]]
+== AspectJ 1.1
+
+_© Copyright 2002 Palo Alto Research Center, Incorporated, 2003
+Contributors. All rights reserved._
+
+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.
+
+This document describes the differences between AspectJ versions 1.1 and
+1.0.6. Users new to AspectJ need only read the
+link:progguide/index.html[AspectJ Programming Guide] 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.
+
+This document first summarizes changes from the 1.0 release in
+
+* xref:#language[the language],
+* xref:#compiler[the compiler],
+* xref:#tools[the support tools],
+* xref:#runtime[the runtime],
+* xref:#devenv[the development environment support],
+* xref:#sources[the sources], and
+* xref:#distribution[the distribution],
+
+then xref:#details[details] some of the language and compiler changes,
+and finally points readers to the bug database for any
+xref:#knownLimitations[known limitations].
+
+'''''
+
+[[language]]
+=== The Language
+
+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 (_CTI_ or _RTI_, 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 _CRTI_. Programs using run-time incompatible
+forms should be verified that they are behaving as expected in 1.1.
+
+Most changes to the language are additions to expressibility requested
+by our users:
+
+* xref:#THROWS_PATTERN[Matching based on throws]: You can now make finer
+discriminations between methods based on declared exceptions.
+* xref:#NEW_PCDS[New kinded pointcut designators]: Now every kind of
+join point has a corresponding kinded pointcut designator.
+
+Some are have different behavior in edge cases but offer improved power
+and clarity:
+
+* xref:#ASPECT_PRECEDENCE[New aspect precedence form]: AspectJ 1.1 has a
+new declare form, `declare precedence`, that replaces the
+"dominates" clause on aspects. (_CTI_)
+* The order of xref:#SUPER_IFACE_INITS[initialization join points for
+super-interfaces] has been clarified. (_RTI_)
+
+But in order to support weaving into bytecode effectively, several
+incompatible changes had to be made to the language:
+
+* A class's default constructor may
+xref:#DEFAULT_CONSTRUCTOR_CONFLICT[conflict] with an inter-type
+constructor. (_CTI_)
+* xref:#NO_CALLEE_SIDE_CALL[No callee-side call join points]: The
+AspectJ 1.1 compiler does not expose call join points unless it is given
+the calling code. (_CRTI_)
+* xref:#SINGLE_INTERCLASS_TARGET[One target for intertype declarations].
+(_CTI_)
+* xref:#UNAVAILABLE_JOIN_POINTS[No initializer execution join points].
+(_RTI_)
+* xref:#AFTER_HANDLER[No after or around advice on handler join points].
+(_CTI_)
+* xref:#CONSTRUCTOR_EXECUTION_IS_BIGGER[Initializers run inside
+constructor execution join points]. (_RTI_)
+* xref:#INTER_TYPE_FIELD_INITIALIZERS[inter-type field initializers] run
+before class-local field initializers. (_RTI_)
+* xref:#WITHIN_MEMBER_TYPES[Small limitations of the within pointcut.]
+(_CRTI_)
+* xref:#WITHIN_CODE[Small limitations of the withincode pointcut.]
+(_CRTI_)
+* xref:#INSTANCEOF_ON_WILD[Can't do instanceof matching on type patterns
+with wildcards]. (_CTI_)
+* xref:#NO_SOURCE_COLUMN[SourceLocation.getColumn() is deprecated and
+will always return 0]. (_RTI_)
+* The interaction between aspect instantiation and advice has been
+xref:#ASPECT_INSTANTIATION_AND_ADVICE[clarified]. (_RTI_)
+* xref:#STRINGBUFFER[The String + operator is now correctly advised].
+(_CRTI_)
+
+[#NEW_LIMITATIONS]#There# are a couple of language limitations for
+things that are rarely used that make the implementation simpler, so we
+have restricted the language accordingly.
+
+* xref:#VOID_FIELD_SET[Field set join points now have a `void` return
+type.] This will require porting of code that uses the `set` PCD in
+conjunction with after-returning or around advice. (_CTI_)
+* '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. (_CTI_)
+* 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;' (_CTI_)
+* We did not implement the handling of more than one `..` 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. (_CTI_)
+
+We did not implement the long-awaited xref:#PER_TYPE[new pertype aspect
+specifier] in this release, but it may well be in a future release.
+
+'''''
+
+[[compiler]]
+=== The Compiler
+
+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.
+
+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.
+
+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.
+
+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:
+
+* xref:#SOURCEROOT[The -sourceroots option] takes one or more
+directories, and indicates that all the source files in those
+directories should be passed to the compiler.
+* xref:#BYTECODE_WEAVING[The -injars option] takes one or more jar
+files, and indicates that all the classfiles in the jar files should be
+woven into.
+* xref:#BINARY_ASPECTS[The -aspectpath option] takes one or more jar
+files, and weaves any aspects in .class form into the sources.
+* xref:#OUTJAR[The -outjar option] indicates that the result classfiles
+of compiling and weaving should be placed in the specified jar file.
+* xref:#XLINT[The -Xlint option] allows control over warnings.
+* xref:#OTHER_X_OPTIONS[Various -X options] changed.
+* xref:#INCREMENTAL[The -incremental option] tells the AspectJ 1.1
+compiler to recompile only as necessary.
+
+Some other features we wanted to support for 1.1, but did not make it
+into this release:
+
+* xref:#ERROR_MESSAGES[Error messages will sometimes be scary]
+* xref:#MESSAGE_CONTEXT[Source code context is not shown for errors and
+warnings detected during bytecode weaving]
+
+But some features of the 1.0 compiler are not supported in the 1.1
+compiler:
+
+* xref:#NO_SOURCE[The source-related options] -preprocess, -usejavac,
+-nocomment and -workingdir
+* xref:#NO_STRICT_LENIENT[The -strict and -lenient options]
+* xref:#NO_PORTING[The -porting option]
+* xref:#_13_REQUIRED[J2SE 1.2 is not supported; J2SE 1.3 or later is
+required.]
+
+A short description of the options ajc accepts is available with
+"`ajc -help`". Longer descriptions are available in the
+link:devguide/ajc-ref.html[Development Environment Guide section on
+ajc].
+
+Some changes to the implementation are almost entirely internal:
+
+* The behavior of the compiler in xref:#TARGET_TYPES_MADE_PUBLIC[lifting
+the visibility] of the target types of some declares and pointcuts to
+public has been clarified.
+
+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
+xref:#ONE_FOUR_METHOD_SIGNATURES[the -1.4 flag].
+
+'''''
+
+[[tools]]
+=== Support Tools
+
+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 `ajc` with the Javac task by setting the `build.compiler`
+property. The new task can automatically copy input resources to output
+and work in incremental mode using a "tag" file.
+
+This release does not include `ajdoc`, 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.
+
+AspectJ 1.1 will not include ajdb, 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.
+
+'''''
+
+[[runtime]]
+=== The Runtime Library
+
+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.
+
+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, `thisJoinPoint.getSourceLocation().getColumn()` is deprecated
+and will always return 0.
+
+'''''
+
+[[devenv]]
+=== The AJDE Tools
+
+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.
+
+'''''
+
+[[sources]]
+=== The Sources and the Licenses
+
+The AspectJ tools sources are available under the
+https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt[Eclipse Public
+License v 2.0] in the Git repository at https://eclipse.org/aspectj. For
+more information, see the FAQ entry on building sources.
+
+'''''
+
+[[distribution]]
+=== The AspectJ distribution
+
+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 https://eclipse.org/aspectj.
+To retain their MPL 1.1 license, Ajde for
+http://aspectj4emacs.sourceforge.net/[Emacs],
+http://aspectj4netbean.sourceforge.net/[NetBeans] and
+http://aspectj4jbuildr.sourceforge.net/[JBuilder] are now independent
+SourceForge projects.
+
+'''''
+
+'''''
+
+[[details]]
+=== Details of some language and compiler changes
+
+[[ASPECT_INSTANTIATION_AND_ADVICE]]
+==== Aspect Instantiation and Advice
+
+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:
+
+[source, java]
+....
+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");
+ }
+}
+....
+
+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...
+
+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:
+
+[source, java]
+....
+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");
+ }
+}
+....
+
+This program would throw a NullPointerException when run, since
+Client.foo() was called before the Watchcall instance could be
+instantiated.
+
+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.
+
+[[THROWS_PATTERN]]
+==== Matching based on throws
+
+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:
+
+[source, java]
+....
+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*);
+....
+
+The longwinded rules are that a method or constructor pattern can have a
+"throws clause pattern". Throws clause patterns look like:
+
+[source, text]
+....
+ThrowsClausePattern:
+ ThrowsClausePatternItem ("," ThrowsClausePatternItem)*
+
+ThrowsClausePatternItem:
+ ["!"] TypeNamePattern
+....
+
+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.
+
+If a ThrowsClausePatternItem begins with "!", then it matches a
+particular throws clause if and only if _none_ of the types named in the
+throws clause is matched by the TypeNamePattern.
+
+If a ThrowsClausePatternItem does not begin with "!", then it matches a
+throws clause if and only if _any_ of the types named in the throws
+clause is matched by the TypeNamePattern.
+
+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.
+
+[source, java]
+....
+/*[1]*/ call(* *(..) throws !IOException)
+/*[2]*/ call(* *(..) throws (!IOException))
+
+void m() throws RuntimeException, IOException {}
+....
+
+[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.
+
+[[NEW_PCDS]]
+==== New kinded pointcut designators
+
+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.
+
+`adviceexectuion()` will pick out advice execution join points. You will
+usually want to use `adviceexecution() && within(Aspect)` to
+restrict it to only those pieces of advice defined in a particular
+aspect. +
+`preinitialization(ConstructorPattern)` will pick out pre-initialization
+join points where the initialization process is entered through
+`ConstructorPattern`.
+
+[[PER_TYPE]]
+==== New pertype aspect specifier (not in 1.1)
+
+We strongly considered adding a pertype aspect kind to 1.1. This is
+somewhat motivated by the new
+xref:#SINGLE_INTERCLASS_TARGET[restrictions on inter-type declarations]
+
+. This is also motivated by many previous request to support a common
+logging idiom. Here's what pertype would look like:
+
+[source, java]
+....
+/** 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;
+....
+
+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.
+
+In any case, this feature will not be in AspectJ 1.1.
+
+[[SINGLE_INTERCLASS_TARGET]]
+==== One target for intertype declarations
+
+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.
+
+[source, java]
+....
+aspect A {
+ public void Target+.doStuff() { ... }
+}
+....
+
+The functionality of "multi-intertype declarations" can be recovered by
+using a helper interface.
+
+[source, java]
+....
+aspect A {
+ private interface MyTarget {}
+ declare parents: Target+ implements MyTarget;
+ public void MyTarget.doStuff() { ... }
+}
+....
+
+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.
+
+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
+xref:#PER_TYPE[pertype proposal] provides this functionality in a much
+more usable form.
+
+[[UNAVAILABLE_JOIN_POINTS]]
+==== No initializer execution join points
+
+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.
+
+[[AFTER_HANDLER]]
+==== No after or around advice on handler join points
+
+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.
+
+[[CONSTRUCTOR_EXECUTION_IS_BIGGER]]
+==== Initializers run inside constructor execution join points
+
+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:
+
+[source, java]
+....
+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());
+ }
+}
+....
+
+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.
+
+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.
+
+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.
+
+[[INTER_TYPE_FIELD_INITIALIZERS]]
+==== Inter-type field initializers
+
+The initializer, if any, of an inter-type field definition runs before
+the class-local initializers of its target class.
+
+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
+xref:#UNAVAILABLE_JOIN_POINTS[initializer execution join points] and
+xref:#CONSTRUCTOR_EXECUTION_IS_BIGGER[constructor execution], 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:
+
+[source, java]
+....
+int C.methodCount = 0;
+before(C c): this(c) && execution(* *(..)) { c.methodCount++; }
+....
+
+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.
+
+[[WITHIN_MEMBER_TYPES]]
+==== Small limitations of the within pointcut
+
+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.
+
+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:
+
+[source, java]
+....
+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");
+ }
+ });
+ }
+ }
+}
+....
+
+We believe the non-guarantee is small, and we haven't verified that it
+is a problem in practice.
+
+[[WITHIN_CODE]]
+==== Small limitations of the withincode pointcut
+
+The withincode pointcut has similar issues to those described above for
+within.
+
+[[INSTANCEOF_ON_WILD]]
+==== Can't do instanceof matching on type patterns with wildcard
+
+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:
+
+[source, java]
+....
+pointcut oneOfMine(): this(com.bigboxco..*);
+....
+
+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.:
+
+[source, java]
+....
+private interface OneOfMine {}
+declare parents: com.bigboxco..* implements OneOfMine;
+pointcut oneOfMine(): this(OneOfMine);
+....
+
+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:
+
+[source, java]
+....
+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;
+ ...
+}
+....
+
+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.
+
+[[NO_SOURCE_COLUMN]]
+==== SourceLocation.getColumn()
+
+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.
+
+[[ASPECT_PRECEDENCE]]
+==== Aspect precedence
+
+AspectJ 1.1 has a new declare form:
+
+[source, java]
+....
+declare precedence ":" TypePatternList ";"
+....
+
+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:
+
+[source, java]
+....
+declare precedence: *..*Security*, Logging+, *;
+....
+
+In the TypePatternList, the wildcard * means "any type not matched by
+another type in the declare precedence".
+
+===== Various cycles
+
+It is an error for any aspect to be matched by more than one TypePattern
+in a single declare precedence, so:
+
+[source, java]
+....
+declare precedence: A, B, A ; // error
+....
+
+However, multiple declare precedence forms may legally have this kind of
+circularity. For example, each of these declare precedence is perfectly
+legal:
+
+[source, java]
+....
+declare precedence: B, A;
+declare precedence: A, B;
+....
+
+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.
+
+===== Applies to concrete aspects
+
+Consider the following library aspects:
+
+[source, java]
+....
+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);
+}
+....
+
+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:
+
+[source, java]
+....
+declare precedence: MyLogging, MyProfiling;
+....
+
+===== Changing order of advice for sub-aspects
+
+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:
+
+[source, java]
+....
+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
+ }
+}
+....
+
+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.
+
+[[SOURCEROOT]]
+==== The -sourceroots option
+
+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).
+
+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
+
+[source, text]
+....
+ajc -sourceroots /myProject/gui:/myProject/base
+ajc -sourceroots d:\myProject\gui;d:\myProject\base
+....
+
+This option may be used in conjunction with lst files, listing .java
+files on the command line, and the -injars option.
+
+[[BYTECODE_WEAVING]]
+==== The -injars option
+
+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).
+
+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:
+
+[source, text]
+....
+ajc -injars /bin/myBase.jar:/bin/myGui.jar MyTracing.java
+ajc -injars d:\bin\myBase.jar;d:\bin\myGui.jar MyTracing.java
+....
+
+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.
+
+This option may be used in conjunction with lst files, listing .java
+files on the command line, and the -sourceroots option.
+
+[[OUTJAR]]
+==== The -outjar option
+
+The -outjar option takes the name of a jar file into which the results
+of the compilation should be put. For example:
+
+[source, text]
+....
+ajc -injars myBase.jar MyTracing.java -outjar myTracedBase.jar
+....
+
+No meta information is placed in the output jar file.
+
+[[INCREMENTAL]]
+==== Incremental compilation
+
+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.
+
+===== Limitations
+
+This new functionality is still only lightly tested.
+
+[[XNOWEAVE]]
+==== -XnoWeave, a compiler option to suppress weaving
+
+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.
+
+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 `-noweave`. We feel that using
+the `-aspectpath` option is a much better option. There may still be use
+cases for unwoven classfiles, but we've moved the flag to experimental
+status.
+
+[[BINARY_ASPECTS]]
+==== -aspectpath, working with aspects in .class/.jar form
+
+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.
+
+[[NO_CALLEE_SIDE_CALL]]
+==== Callee-side call join points
+
+The 1.0 implementation of AspectJ, when given:
+
+[source, java]
+....
+class MyRunnable implements Runnable {
+ public void run() { /*...*/ }
+}
+
+aspect A {
+ call(): (void run()) && target(MyRunnable) {
+ // do something here
+ }
+}
+....
+
+would cause A's advice to execute even when, say, java.lang.Thread
+called run() on a MyRunnable instance.
+
+With the new compiler, two things have happened in regard to callee-side
+calls:
+
+. because the programmer has access to more code (i.e., bytecode, not
+just source code), callee-side calls are much less important to have.
+. because compilation is more modular, allowing and encouraging separate
+compilation, callee-side calls are much more difficult to implement
+
+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.
+
+. One reason (though not the only reason) we worked so hard in the
+_implementation_ 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.
+. 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. +
+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.
+
+This implementation decision is completely in the letter and the spirit
+of the AspectJ language. From the semantics guide describing code the
+implementation controls:
+
+____
+But AspectJ implementations are permitted to deviate from this in a
+well-defined way -- they are permitted to advise only accesses in _code
+the implementation controls_. Each implementation is free within certain
+bounds to provide its own definition of what it means to control code.
+____
+
+And about a particular decision about the 1.0.6 implementation:
+
+____
+Different join points have different requirements. Method call join
+points can be advised only if ajc controls _either_ 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.
+____
+
+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.
+
+What does 1.1 gain from this?
+
+* a clear (and implemented) separate compilation model (see point 2,
+above)
+* 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.
+
+What does 1.1 lose from this?
+
+* 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.
+* The ability to, without access to the caller, capture entry to a
+particular method, but not super calls.
+* A code-size-improvement performance optimization.
+
+What are the possibilities for the future?
+
+* AspectJ 1.1.1 could expand its capture of call join points, possibly
+at the expense of separate compilation clarity, possibly not.
+* 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.
+
+How will this affect developers?
+
+* When using the call PCD but only supplying the callee code, supply the
+calling code or use the execution PCD instead.
+
+[[OTHER_X_OPTIONS]]
+==== Various -X options
+
+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:
+
+* -XOcodeSize: This is no longer necessary because inlining of around
+advice is on by default. We support its inverse,
+xref:#XNOINLINE[`-XnoInline`].
+* xref:#XNOWEAVE[-XnoWeave, a compiler option to suppress weaving]
+* -XtargetNearSource: Not supported in this release.
+* -XserializableAspects: Supported.
+* -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.
+* -Xlint: Still supported, with xref:#XLINT[various options].
+
+[[ERROR_MESSAGES]]
+==== Some confusing error messages
+
+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.
+
+[[MESSAGE_CONTEXT]]
+==== Source code context is not shown for errors and warnings detected during bytecode weaving
+
+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.
+
+[[XLINT]]
+==== The -Xlint option
+
+`-Xlint:ignore,error,warning` will set the level for all Xlint warnings.
+`-Xlint`, alone, is an abbreviation for `-Xlint:warning`.
+
+The `-Xlintfile:lint.properties` allows fine-grained control. In
+tools.jar, see `org/aspectj/weaver/XlintDefault.properties` for the
+default behavior and a template to copy.
+
+More `-Xlint` 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.
+
+[[NO_SOURCE]]
+==== Source-specific options
+
+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.
+
+[[NO_STRICT_LENIENT]]
+==== The -strict and -lenient options
+
+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.
+
+[[NO_PORTING]]
+==== The -porting option
+
+AspectJ 1.1 does not have a -porting option.
+
+[[_13_REQUIRED]]
+==== J2SE 1.3 required
+
+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.
+
+[[DEFAULT_CONSTRUCTOR_CONFLICT]]
+==== Default constructors
+
+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:
+
+[source, java]
+....
+class C {}
+
+aspect A {
+ C.new() {} // was allowed in 1.0.6
+ // is a "multiple definitions" conflict in 1.1
+}
+....
+
+In the Java Programming Language, a class defined without a constructor
+actually has a "default" constructor that takes no arguments and just
+calls `super()`.
+
+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.
+
+[[SUPER_IFACE_INITS]]
+==== Initialization join points for super-interfaces
+
+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.
+
+In the semantics document for AspectJ 1.0.6, the following promises were
+made about the order of this initialization:
+
+. a supertype is initialized before a subtype
+. initialized code runs only once
+. initializers for supertypes run in left-to-right order
+
+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:
+
+[source, java]
+....
+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;
+ }
+}
+....
+
+This was simply a bug in the AspectJ specification. The correct third
+rule is:
+
+____
+the initializers for a type's superclass are run before the initializers
+for its superinterfaces.
+____
+
+[[VOID_FIELD_SET]]
+==== Field Set Join Points
+
+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.
+
+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.
+
+Thus, programmers typically wanted to write something like:
+
+[source, java]
+....
+void around(): set(int Foo.i) {
+ if (theSetIsAllowed()) {
+ proceed();
+ }
+}
+....
+
+And were confused by it being a compile-time error. They weren't
+confused for long, and soon adapted to writing:
+
+[source, java]
+....
+int around(): set(int Foo.i) {
+ if (theSetIsAllowed()) {
+ return proceed();
+ } else {
+ return Foo.i;
+ }
+}
+....
+
+But there was definitely a short disconnect.
+
+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.
+
+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.
+
+[[XNOINLINE]]
+==== The -XnoInline Option
+
+The `-XnoInline` 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.
+
+[[TARGET_TYPES_MADE_PUBLIC]]
+==== Target types made public
+
+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.
+
+In particular, the types used in the `this`, `target`, and `args`
+pointcuts are made public, as are the super-types from `declare parents`
+and the exception type from `declare soft`.
+
+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.
+
+[[STRINGBUFFER]]
+==== String + now advised
+
+In Java, the + operator sometimes results in StringBuffer objects being
+created, appended to, and used to generate a new String. Thus,
+
+[source, java]
+....
+class Foo {
+ String makeEmphatic(String s) {
+ return s + "!";
+ }
+}
+....
+
+is approximately the same at runtime as
+
+[source, java]
+....
+class Foo {
+ String makeEmphatic(String s) {
+ return new StringBuffer(s).append("!").toString();
+ }
+}
+....
+
+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.
+
+This change is likely to affect highly wildcarded aspects, and can do so
+in surprising ways. In particular:
+
+[source, java]
+....
+class A {
+ before(int i): call(* *(int)) && args(i) {
+ System.err.println("entering with " + i);
+ }
+}
+....
+
+may result in a stack overflow error, since the argument to println is
+really
+
+[source, java]
+....
+new StringBuffer("entering with ").append(i).toString()
+....
+
+which has a call to StringBuffer.append(int). In such cases, it's worth
+restricting your pointcut, with something like one of:
+
+[source, java]
+....
+call(* *(int)) && args(i) && !within(A)
+call(* *(int)) && args(i) && !target(StringBuffer)
+....
+
+[[ONE_FOUR_METHOD_SIGNATURES]]
+==== The -1.4 flag and method signatures
+
+Consider the following aspect
+
+[source, java]
+....
+public aspect SwingCalls {
+
+ pointcut callingAnySwing(): call(* javax.swing..*+.*(..));
+
+ before(): callingAnySwing() {
+ System.out.println("Calling any Swing");
+ }
+}
+....
+
+And then consider the two statements
+
+[source, java]
+....
+JFrame frame = new JFrame();
+frame.setTitle("Title");
+....
+
+According to the Java Language Specification version 2, the call to
+`frame.setTitle("Title")` should always produce the bytecode for a call
+to `javax.swing.JFrame.setTitle`. However, older compilers (and eclipse
+when run without the `-1.4` flag) will generate the bytecode for a call
+to `java.awt.Frame.setTitle` 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.
+
+This is a good example of why the pattern
+`call(* *(..)) && target(JFrame)` 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.
+
+[[knownLimitations]]
+=== Known limitations
+
+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 https://bugs.eclipse.org/bugs, especially the open bugs
+for the
+https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Compiler&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED[compiler],
+https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=IDE&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED[IDE
+support],
+https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Doc&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED[documentation],
+and
+https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Ant&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED[Ant
+tasks]. 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
+https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&keywords=info
+For ajc's 1.1 implementation limitations, see
+link:progguide/implementation.html[Programming Guide Appendix:
+"Implementation Notes"].