aboutsummaryrefslogtreecommitdiffstats
path: root/docs/dist/doc
diff options
context:
space:
mode:
Diffstat (limited to 'docs/dist/doc')
-rw-r--r--docs/dist/doc/README-11.adoc446
-rw-r--r--docs/dist/doc/README-12.adoc201
-rw-r--r--docs/dist/doc/README-121.adoc23
-rw-r--r--docs/dist/doc/README-153.adoc11
-rw-r--r--docs/dist/doc/README-160.adoc19
-rw-r--r--docs/dist/doc/README-161.adoc9
-rw-r--r--docs/dist/doc/README-1610.adoc1
-rw-r--r--docs/dist/doc/README-1611.adoc2
-rw-r--r--docs/dist/doc/README-1612.adoc20
-rw-r--r--docs/dist/doc/README-164.adoc39
-rw-r--r--docs/dist/doc/README-167.adoc50
-rw-r--r--docs/dist/doc/README-168.adoc38
-rw-r--r--docs/dist/doc/README-169.adoc35
-rw-r--r--docs/dist/doc/README-170.adoc69
-rw-r--r--docs/dist/doc/README-174.adoc2
-rw-r--r--docs/dist/doc/README-180.adoc5
-rw-r--r--docs/dist/doc/README-182.adoc31
-rw-r--r--docs/dist/doc/README-183.adoc4
-rw-r--r--docs/dist/doc/README-187.adoc15
-rw-r--r--docs/dist/doc/README-190.adoc38
-rw-r--r--docs/dist/doc/README-191.adoc1
-rw-r--r--docs/dist/doc/README-193.adoc9
-rw-r--r--docs/dist/doc/README-195.adoc7
-rw-r--r--docs/dist/doc/README-196.adoc15
-rw-r--r--docs/dist/doc/changes.adoc6
-rw-r--r--docs/dist/doc/porting.adoc279
26 files changed, 729 insertions, 646 deletions
diff --git a/docs/dist/doc/README-11.adoc b/docs/dist/doc/README-11.adoc
index 377d18588..1843f38be 100644
--- a/docs/dist/doc/README-11.adoc
+++ b/docs/dist/doc/README-11.adoc
@@ -288,22 +288,21 @@ 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(..));
+public class Client {
+ public static void main(String[] args) {
+ Client c = new Client();
+ }
+}
- before(): myConstructor() {
- System.err.println("Entering Constructor");
- }
- }
+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
@@ -317,25 +316,24 @@ 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());
+public class Client {
+ public static int foo() { return 3; }
+ public static void main(String[] args) {
+ Client c = new Client();
+ }
+}
- before(): myConstructor() {
- System.err.println("Entering Constructor");
- }
- }
+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
@@ -356,29 +354,29 @@ 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*);
+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
+ThrowsClausePattern:
+ ThrowsClausePatternItem ("," ThrowsClausePatternItem)*
+ThrowsClausePatternItem:
+ ["!"] TypeNamePattern
....
A ThrowsClausePattern matches the ThrowsClause of any code member
@@ -398,12 +396,12 @@ 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]*/ 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
@@ -439,31 +437,31 @@ 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());
- }
+/** 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;
- /* We can use a special constructor to initialize the log field */
- public Logger(Class myType) {
- this.log = new Log(myType);
- }
+ /* 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());
}
- /** External code could use aspectOf to get at the log, i.e. */
- Log l = Logger.aspectOf(com.bigboxco.Foo.class).log;
+ /* 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
@@ -481,23 +479,23 @@ 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() { ... }
- }
-
+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() { ... }
- }
-
+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
@@ -531,18 +529,19 @@ 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());
- }
- }
+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
@@ -579,10 +578,10 @@ 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++; }
-
+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
@@ -604,25 +603,25 @@ 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:
-....
- 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");
- }
- });
- }
+[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
@@ -642,9 +641,9 @@ 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..*);
-
+pointcut oneOfMine(): this(com.bigboxco..*);
....
The only way to implement this kind of matching in a modular way would
@@ -653,27 +652,27 @@ 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);
-
+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;
- ...
- }
+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
@@ -696,9 +695,9 @@ deprecated by the compiler, and will always return 0.
AspectJ 1.1 has a new declare form:
+[source, java]
....
- declare precedence ":" TypePatternList ";"
-
+declare precedence ":" TypePatternList ";"
....
This is used to declare advice ordering constraints on join points. For
@@ -707,9 +706,9 @@ 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+, *;
-
+declare precedence: *..*Security*, Logging+, *;
....
In the TypePatternList, the wildcard * means "any type not matched by
@@ -720,19 +719,19 @@ another type in the declare precedence".
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
-
+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;
-
+declare precedence: B, A;
+declare precedence: A, B;
....
And a system in which both constraints are active may also be legal, so
@@ -743,33 +742,33 @@ idiom that can be used to enforce that A and B are strongly independent.
Consider the following library aspects:
+[source, java]
....
- abstract aspect Logging {
- abstract pointcut logged();
+abstract aspect Logging {
+ abstract pointcut logged();
- before(): logged() {
- System.err.println("thisJoinPoint: " + thisJoinPoint);
- }
- }
-
- aspect MyProfiling {
- abstract pointcut profiled();
+ before(): logged() {
+ System.err.println("thisJoinPoint: " + thisJoinPoint);
+ }
+}
- 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);
- }
+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
@@ -780,9 +779,9 @@ 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;
-
+declare precedence: MyLogging, MyProfiling;
....
===== Changing order of advice for sub-aspects
@@ -791,23 +790,23 @@ 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(): ... ;
+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
- }
- }
+ 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
@@ -827,10 +826,10 @@ 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
-
+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
@@ -848,10 +847,10 @@ 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
-
+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
@@ -869,9 +868,9 @@ files on the command line, and the -sourceroots 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
-
+ajc -injars myBase.jar MyTracing.java -outjar myTracedBase.jar
....
No meta information is placed in the output jar file.
@@ -920,17 +919,17 @@ The binary forms of this aspects will be untouched.
The 1.0 implementation of AspectJ, when given:
+[source, java]
....
- class MyRunnable implements Runnable {
- public void run() { ... }
- }
+class MyRunnable implements Runnable {
+ public void run() { /*...*/ }
+}
- aspect A {
- call(): (void run()) && target(MyRunnable) {
- // do something here
- }
+aspect A {
+ call(): (void run()) && target(MyRunnable) {
+ // do something here
}
-
+}
....
would cause A's advice to execute even when, say, java.lang.Thread
@@ -1117,14 +1116,14 @@ 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
- }
+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
@@ -1154,25 +1153,25 @@ 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 {}
+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
+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;
- }
+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
@@ -1198,27 +1197,27 @@ 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();
- }
+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;
- }
+int around(): set(int Foo.i) {
+ if (theSetIsAllowed()) {
+ return proceed();
+ } else {
+ return Foo.i;
}
-
+}
....
But there was definitely a short disconnect.
@@ -1267,6 +1266,7 @@ implementation.
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) {
@@ -1277,6 +1277,7 @@ class Foo {
is approximately the same at runtime as
+[source, java]
....
class Foo {
String makeEmphatic(String s) {
@@ -1292,6 +1293,7 @@ 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) {
@@ -1303,6 +1305,7 @@ class A {
may result in a stack overflow error, since the argument to println is
really
+[source, java]
....
new StringBuffer("entering with ").append(i).toString()
....
@@ -1310,6 +1313,7 @@ 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)
@@ -1320,6 +1324,7 @@ call(* *(int)) && args(i) && !target(StringBuffer)
Consider the following aspect
+[source, java]
....
public aspect SwingCalls {
@@ -1333,9 +1338,10 @@ public aspect SwingCalls {
And then consider the two statements
+[source, java]
....
- JFrame frame = new JFrame();
- frame.setTitle("Title");
+JFrame frame = new JFrame();
+frame.setTitle("Title");
....
According to the Java Language Specification version 2, the call to
diff --git a/docs/dist/doc/README-12.adoc b/docs/dist/doc/README-12.adoc
index 95775b45a..0b66b6556 100644
--- a/docs/dist/doc/README-12.adoc
+++ b/docs/dist/doc/README-12.adoc
@@ -139,21 +139,19 @@ returns false.
Consider a simple tracing aspect as follows:
+[source, java]
....
+public aspect Tracing {
- public aspect Tracing {
+ public static boolean enabled = false;
- public static boolean enabled = false;
+ pointcut toBeTraced() : execution(* *(..)) || execution(new(..));
- pointcut toBeTraced() : execution(* *(..)) || execution(new(..));
-
- before() : toBeTraced() && if(enabled) {
- Object[] args = thisJoinPoint.getArgs();
- // format args and print out entry trace record etc....
- }
+ before() : toBeTraced() && if(enabled) {
+ Object[] args = thisJoinPoint.getArgs();
+ // format args and print out entry trace record etc....
}
-
-
+}
....
The most important consideration is the system overhead when tracing is
@@ -189,20 +187,20 @@ were passed to the compiler. For example, an error message arising as a
result of a `declare error` statement might look as follows under
AspectJ 1.1.1:
+[source, text]
....
- BadClass.java:6 should not be calling bad methods
-
+BadClass.java:6 should not be calling bad methods
....
whereas in AspectJ 1.2 you will see:
+[source, text]
....
- BadClass.java:6 error should not be calling bad methods
- new C().bad();
- ^^^^^^^^^^^^^^
- method-call(void C.bad())
- see also: DeclareError.java:5
-
+BadClass.java:6 error should not be calling bad methods
+new C().bad();
+^^^^^^^^^^^^^^
+ method-call(void C.bad())
+ see also: DeclareError.java:5
....
There are four new things to note about this error message. Firstly,
@@ -220,13 +218,13 @@ When source code is not available, the messages show the binary input
source (class file or jar file) in which the error or warning was
detected:
+[source, text]
....
- BadClass.java:6 error should not be calling bad methods
- (no source information available)
- method-call(void C.bad())
- see also: C:\...\DeclareError.java:5
- see also: C:\...\bin-input.jar
-
+BadClass.java:6 error should not be calling bad methods
+(no source information available)
+ method-call(void C.bad())
+ see also: C:\...\DeclareError.java:5
+ see also: C:\...\bin-input.jar
....
This error message tells us that `BadClass.class` contained in a jar on
@@ -240,38 +238,36 @@ line 5 of the file `DeclareError.java`.
Consider the program:
+[source, java]
....
-
- 01 class A {
- 02 public void doIt() {...};
- 03 }
- 04
- 05 class B extends A {
- 06 public void doThisToo() {...};
- 07 }
- 08
- 09
- 10 public class CallsAandB {
- 11
- 12 public static void main(String[] args) {
- 13 B b = new B();
- 14 A bInDisguise = new B();
- 15
- 16 b.doIt(); // AspectJ 1.2 matches here
- 17 bInDisguise.doIt(); // this is never matched
- 18 }
- 19
- 20 }
- 21
- 22 aspect CallPCDMatchingExample {
- 23
- 24 before() : call(* B.doIt(..)) {
- 25 System.out.println("About to call B.doIt(...)");
- 26 }
- 27
- 28 }
-
-
+/*01*/ class A {
+/*02*/ public void doIt() {...};
+/*03*/ }
+/*04*/
+/*05*/ class B extends A {
+/*06*/ public void doThisToo() {...};
+/*07*/ }
+/*08*/
+/*09*/
+/*10*/ public class CallsAandB {
+/*11*/
+/*12*/ public static void main(String[] args) {
+/*13*/ B b = new B();
+/*14*/ A bInDisguise = new B();
+/*15*/
+/*16*/ b.doIt(); // AspectJ 1.2 matches here
+/*17*/ bInDisguise.doIt(); // this is never matched
+/*18*/ }
+/*19*/
+/*20*/ }
+/*21*/
+/*22*/ aspect CallPCDMatchingExample {
+/*23*/
+/*24*/ before() : call(* B.doIt(..)) {
+/*25*/ System.out.println("About to call B.doIt(...)");
+/*26*/ }
+/*27*/
+/*28*/ }
....
Because the static type of `bInDisguise` is `A` (line 14), the call on
@@ -287,19 +283,14 @@ designator does not match at a join point, and a user may have expected
it to. Compiling the above program using AspectJ 1.2 produces the
following compiler output:
+[source, text]
....
+CallsAandB.java:24 warning does not match because declaring type is A, if match desired use target(B) [Xlint:unmatchedSuperTypeInCall]
+before() : call(* B.doIt(..)) {
+ ^^^^^^^^^^^^^^^
+ see also: CallsAandB.java:17
-
- CallsAandB.java:24 warning does not match because declaring type is A, if match desired use target(B) [Xlint:unmatchedSuperTypeInCall]
- before() : call(* B.doIt(..)) {
- ^^^^^^^^^^^^^^^
- see also: CallsAandB.java:17
-
-
- 1 warning
-
-
-
+1 warning
....
The warning is telling us that the call pointcut associated with the
@@ -385,38 +376,36 @@ Consider again the following example program which illustrates the
differences in join point matching with the `call` pointcut designator
between 1.4 and 1.3 compliance levels.
+[source, java]
....
-
- 01 class A {
- 02 public void doIt() {...};
- 03 }
- 04
- 05 class B extends A {
- 06 public void doThisToo() {...};
- 07 }
- 08
- 09
- 10 public class CallsAandB {
- 11
- 12 public static void main(String[] args) {
- 13 B b = new B();
- 14 A bInDisguise = new B();
- 15
- 16 b.doIt(); // AspectJ 1.2 matches here
- 17 bInDisguise.doIt(); // this is never matched
- 18 }
- 19
- 20 }
- 21
- 22 aspect CallPCDMatchingExample {
- 23
- 24 before() : call(* B.doIt(..)) {
- 25 System.out.println("About to call B.doIt(...)");
- 26 }
- 27
- 28 }
-
-
+/*01*/ class A {
+/*02*/ public void doIt() {...};
+/*03*/ }
+/*04*/
+/*05*/ class B extends A {
+/*06*/ public void doThisToo() {...};
+/*07*/ }
+/*08*/
+/*09*/
+/*10*/ public class CallsAandB {
+/*11*/
+/*12*/ public static void main(String[] args) {
+/*13*/ B b = new B();
+/*14*/ A bInDisguise = new B();
+/*15*/
+/*16*/ b.doIt(); // AspectJ 1.2 matches here
+/*17*/ bInDisguise.doIt(); // this is never matched
+/*18*/ }
+/*19*/
+/*20*/ }
+/*21*/
+/*22*/ aspect CallPCDMatchingExample {
+/*23*/
+/*24*/ before() : call(* B.doIt(..)) {
+/*25*/ System.out.println("About to call B.doIt(...)");
+/*26*/ }
+/*27*/
+/*28*/ }
....
When this program is compiled with AspectJ 1.2 using the default
@@ -492,20 +481,21 @@ sample application that demonstrates these capabilities. Following the
instructions in the `README` file in that directory, running
"`aj tracing.ExampleMain`" with `ASPECTPATH` unset produces the output:
+[source, text]
....
- c1.perimeter() = 12.566370614359172
- c1.area() = 12.566370614359172
- s1.perimeter() = 4.0
- s1.area() = 1.0
- c2.distance(c1) = 4.242640687119285
- s1.distance(c1) = 2.23606797749979
- s1.toString(): Square side = 1.0 @ (1.0, 2.0)
-
+c1.perimeter() = 12.566370614359172
+c1.area() = 12.566370614359172
+s1.perimeter() = 4.0
+s1.area() = 1.0
+c2.distance(c1) = 4.242640687119285
+s1.distance(c1) = 2.23606797749979
+s1.toString(): Square side = 1.0 @ (1.0, 2.0)
....
If you set `ASPECTPATH` to include `../jars/tracingLib.jar`, and run
"`aj tracing.ExampleMain`" again, the output will be:
+[source, text]
....
--> tracing.TwoDShape(double, double)
<-- tracing.TwoDShape(double, double)
@@ -542,7 +532,6 @@ s1.area() = 1.0
<-- double tracing.TwoDShape.getY()
<-- double tracing.TwoDShape.distance(TwoDShape)
etc...
-
....
The scripts only support JDK 1.4 and above - attempting to use them with
diff --git a/docs/dist/doc/README-121.adoc b/docs/dist/doc/README-121.adoc
index 74d4b3030..fd082ebcb 100644
--- a/docs/dist/doc/README-121.adoc
+++ b/docs/dist/doc/README-121.adoc
@@ -34,17 +34,18 @@ option, or set showweaveinfo=true in the iajc ant task.
The following is an example of the messages produced when this option is
enabled:
+[source, text]
....
- C:\aspectj1.2.1\doc\examples\tjp>ajc -showWeaveInfo *.java
+C:\aspectj1.2.1\doc\examples\tjp>ajc -showWeaveInfo *.java
- Type 'tjp.Demo' (Demo.java:20) advised by around advice from 'tjp.GetInfo'
- (GetInfo.java:26) [RuntimeTest=true]
+Type 'tjp.Demo' (Demo.java:20) advised by around advice from 'tjp.GetInfo'
+(GetInfo.java:26) [RuntimeTest=true]
- Type 'tjp.Demo' (Demo.java:30) advised by around advice from 'tjp.GetInfo'
- (GetInfo.java:26) [RuntimeTest=true]
+Type 'tjp.Demo' (Demo.java:30) advised by around advice from 'tjp.GetInfo'
+(GetInfo.java:26) [RuntimeTest=true]
- Type 'tjp.Demo' (Demo.java:34) advised by around advice from 'tjp.GetInfo'
- (GetInfo.java:26) [RuntimeTest=true]
+Type 'tjp.Demo' (Demo.java:34) advised by around advice from 'tjp.GetInfo'
+(GetInfo.java:26) [RuntimeTest=true]
....
=== Dump Support
@@ -91,11 +92,11 @@ detecting this performance related bug and for piloting the fix.
String concatentation in declare error and warning statements is now
supported. For example, you can write:
+[source, java]
....
- declare warning : jdbcCall() && !inDataLayer()
- : "Please don't make calls to JDBC " +
- "outside of the data layer.";
-
+declare warning : jdbcCall() && !inDataLayer()
+ : "Please don't make calls to JDBC " +
+ "outside of the data layer.";
....
=== Load-time Weaving Support
diff --git a/docs/dist/doc/README-153.adoc b/docs/dist/doc/README-153.adoc
index 8b1c065f1..422b34447 100644
--- a/docs/dist/doc/README-153.adoc
+++ b/docs/dist/doc/README-153.adoc
@@ -14,8 +14,7 @@ Notable changes since the 1.5.2 release include: +
Until this release, the memory profile for AspectJ looked like this
(time is along the X axis, memory usage is the Y axis)
-``
-
+[source, text]
....
/\_
/ \_
@@ -31,8 +30,7 @@ discarding them once woven and dumped to disk. In 1.5.3 we don't compile
everything up front - we compile and weave files one at a time. Giving
us this profile:
-``
-
+[source, text]
....
/\ /\ /\
/ \/ \/ \
@@ -46,6 +44,7 @@ to compile a project. For example, I have a 1000file project, affected
by aspects at >750 join points. For given values of Xmx, here are the
times taken to compile it (on the command line) with AspectJ1.5.2:
+[source, text]
....
Xmx Time
512M 33seconds
@@ -58,6 +57,7 @@ The times gradually increase as the memory is reduced because the VM
starts to thrash in garbage collection. Here are the results for
AspectJ1.5.3:
+[source, text]
....
Xmx Time
512M 33s
@@ -106,8 +106,7 @@ Concrete aspects defined using aop.xml are now exposed for weaving.
It is now possible to ask an instance of a ptw aspect which type it is
'attached' to. The method:
-``
-
+[source, java]
....
String getWithinTypeName()
....
diff --git a/docs/dist/doc/README-160.adoc b/docs/dist/doc/README-160.adoc
index cba5ce076..d62985634 100644
--- a/docs/dist/doc/README-160.adoc
+++ b/docs/dist/doc/README-160.adoc
@@ -35,6 +35,7 @@ parentheses around the parameter types in a method signature determine
whether the annotations relate to the type of the parameter or the
parameter itself.
+[source, java]
....
execution(* *(@A *));
....
@@ -42,12 +43,14 @@ execution(* *(@A *));
- Execution of a method/ctor whose first parameter is of a type
annotated with @A.
+[source, java]
....
execution(* *(@A (*)));
....
- Execution of a method/ctor whose first parameter is annotated with @A
+[source, java]
....
execution(* *(@A (@B *)))
....
@@ -55,8 +58,9 @@ execution(* *(@A (@B *)))
- Execution of a method/ctor whose first parameter is annotated with @A
and is of a type annotated with @B. Example:
+[source, java]
....
------- Start of Test.java -----
+// ------ Start of Test.java -----
@interface A {}
@interface B {}
@@ -69,7 +73,11 @@ aspect X {
before(): execution(* *(@A (*))) {}
before(): execution(* *(@B (*))) {}
}
------- End of Test.java -----
+// ------ End of Test.java -----
+....
+
+[source, text]
+....
$ ajc -showWeaveInfo -1.6 Test.java
Join point 'method-execution(void C.foo(java.lang.String))' in Type 'C' (A.java:5) advised by before advice from 'X' (A.java:10)
@@ -78,9 +86,7 @@ Join point 'method-execution(void C.goo(java.lang.String))' in Type 'C' (A.java:
Join point 'method-execution(void C.goo(java.lang.String))' in Type 'C' (A.java:6) advised by before advice from 'X' (A.java:10)
....
-The first piece of advice matched both methods. The second only matched
-goo(). +
- +
+The first piece of advice matched both methods. The second only matched `goo()`.
==== Annotation Value Matching
@@ -93,13 +99,14 @@ has a particular value. Perhaps tracing has been turned on at the type
level and a few critical methods should not get traced. Here is some
code showing the use case:
+[source, java]
....
enum TraceLevel { NONE, LEVEL1, LEVEL2, LEVEL3 }
@interface Trace {
TraceLevel value() default TraceLevel.LEVEL1;
}
-
+
aspect X {
// Advise all methods marked @Trace except those with a tracelevel of none
before(): execution(@Trace !@Trace(TraceLevel.NONE) * *(..)) {
diff --git a/docs/dist/doc/README-161.adoc b/docs/dist/doc/README-161.adoc
index 2cea859bb..d4ef20cf4 100644
--- a/docs/dist/doc/README-161.adoc
+++ b/docs/dist/doc/README-161.adoc
@@ -146,8 +146,7 @@ If only binding an annotation at a method-execution join point in order
to access an *enum value* within it, there is a more optimal syntax that
can be used to produce faster code. Given this setup:
-``
-
+[source, java]
....
enum Colour { RED,GREEN,BLUE;}
@@ -159,6 +158,7 @@ public void colouredMethod() { }
Current syntax:
+[source, java]
....
before(ColouredAnnotation anno): execution(* *(..)) && @annotation(anno) {
printTheColour(anno.value());
@@ -167,12 +167,9 @@ before(ColouredAnnotation anno): execution(* *(..)) && @annotation(anno) {
New optional syntax:
-``
-
+[source, java]
....
before(Colour col): execution(* *(..)) && @annotation(ColouredAnnotation(col)) {
printTheColour(col);
}
....
-
-'''''
diff --git a/docs/dist/doc/README-1610.adoc b/docs/dist/doc/README-1610.adoc
index faf6b85d6..73d3dab90 100644
--- a/docs/dist/doc/README-1610.adoc
+++ b/docs/dist/doc/README-1610.adoc
@@ -23,6 +23,7 @@ project properties in eclipse and in the AspectJ Compiler section,
scroll down to 'Other' and in the non-standard compiler options setting,
specify:
+[source, text]
....
-Xset:minimalModel=true,typeDemotion=true
....
diff --git a/docs/dist/doc/README-1611.adoc b/docs/dist/doc/README-1611.adoc
index e240e36f4..d88609580 100644
--- a/docs/dist/doc/README-1611.adoc
+++ b/docs/dist/doc/README-1611.adoc
@@ -74,6 +74,7 @@ annotations, or modify existing annotations by changing their values.
1.6.11 includes a new piece of syntax that we are thinking might be
appropriate for one of these scenarios. 1.6.11 supports this:
+[source, java]
....
declare @field: int Foo.i: -@Anno;
....
@@ -89,6 +90,7 @@ but the inability to use it with binary weaving greatly reduced the
usefulness. Fixes have gone into 1.6.11 to support binary weaving. What
do we mean by intertype innertypes? Here is an example:
+[source, java]
....
class Foo {
public void m() {
diff --git a/docs/dist/doc/README-1612.adoc b/docs/dist/doc/README-1612.adoc
index d69061257..78a90829a 100644
--- a/docs/dist/doc/README-1612.adoc
+++ b/docs/dist/doc/README-1612.adoc
@@ -43,13 +43,14 @@ added and for some cases there can be no need for that abstract aspect.
This is a work in progress but now you can write this in the aop.xml:
+[source, xml]
....
<concrete-aspect name="MyAspect">
<before pointcut="execution(* Hello.say2(..)) AND args(message)"
- invokeClass="SomeRegularJavaClass"
+ invokeClass="SomeRegularJavaClass"
invokeMethod="someMethod(JoinPoint tjp, java.lang.String message)"/>
<after pointcut="execution(* Hello.say2(..)) AND args(message)"
- invokeClass="SomeRegularJavaClass"
+ invokeClass="SomeRegularJavaClass"
invokeMethod="someOtherMethod(JoinPoint tjp, java.lang.String message)"/>
</concrete-aspect>
@@ -58,7 +59,7 @@ public class SomeRegularJavaClass {
public static void someMethod(org.aspectj.lang.JoinPoint tjp, String s) {
System.out.println("in advice4: s="+s+" at "+tjp);
}
-
+
public static void someOtherMethod(org.aspectj.lang.JoinPoint tjp, String s) {
System.out.println("in advice5: s="+s+" at "+tjp);
}
@@ -101,8 +102,9 @@ get started!
There is now a new well known name that you can use in the if clauses in
your aspects. thisAspectInstance provides access to the aspect instance.
-Here is an example: ``
+Here is an example:
+[source, java]
....
aspect X {
boolean doit() {
@@ -116,10 +118,11 @@ aspect X {
}
....
-Now why not just use X.aspectOf() instead of thisAspectInstance? Well
-thisAspectInstance is quite useful when working with abstract/concrete
-aspects: ``
+Now why not just use `X.aspectOf()` instead of `thisAspectInstance`? Well,
+`thisAspectInstance` is quite useful when working with abstract/concrete
+aspects:
+[source, java]
....
abstract aspect X {
abstract pointcut p();
@@ -185,6 +188,7 @@ supports Java7 language constructs - that will happen after Eclipse
It is now possible to specify synthetic in pointcuts:
+[source, java]
....
pointcut p(): execution(!synthetic * *(..));
....
@@ -210,6 +214,7 @@ use when you want to match upon the existence of an annotation but you
don't need the annotation, you just need a value from it. This code
snippet shows an example:
+[source, java]
....
@interface SomeAnnotation {
int i();
@@ -227,6 +232,7 @@ binding too. Suppose the annotation had multiple int values, how would
we select which int to bind? AspectJ will now use the name (if it can)
to select the right value:
+[source, java]
....
@interface SomeAnnotation {
int mods();
diff --git a/docs/dist/doc/README-164.adoc b/docs/dist/doc/README-164.adoc
index b1de0e9b0..548cb086e 100644
--- a/docs/dist/doc/README-164.adoc
+++ b/docs/dist/doc/README-164.adoc
@@ -27,8 +27,7 @@ the full build times in AJDT:
AJDT 1.6.3 (uses AspectJ 1.6.3)
-``
-
+[source, text]
....
21352ms
21597ms
@@ -37,8 +36,7 @@ AJDT 1.6.3 (uses AspectJ 1.6.3)
AJDT 1.6.5dev builds (use AspectJ 1.6.4)
-``
-
+[source, text]
....
19811ms
19802ms
@@ -70,8 +68,7 @@ building code, weaving code.
Initially this is using AJDT 1.6.2 (which embeds AspectJ 1.6.3):
-``
-
+[source, text]
....
Type of change: adding a new method to a type
Project build times (first one is the compile of our change, the rest are for downstream projects):
@@ -88,8 +85,7 @@ Summary: Total time spent in the compiler for that change: 1597ms
Now with AspectJ 1.6.5 dev builds (which embed AspectJ 1.6.4):
-``
-
+[source, text]
....
Type of change: adding a new method to a type
Project build times (first one is the compile of our change, the rest are for downstream projects):
@@ -127,8 +123,9 @@ http://andrewclement.blogspot.com/2009/02/aspectj-fixing-reverse-cascade-errors.
*Optimizing support for maintaining per join point state*
The traditional way to maintain state on a per join point basis involves
-using the JoinPoint.StaticPart as a key into a map: ``
+using the JoinPoint.StaticPart as a key into a map:
+[source, java]
....
aspect X pertypewithin(*) {
Map<JoinPoint.StaticPart,Timer> timerMap = ...
@@ -149,8 +146,7 @@ points within a target type are unique (and start from 0) - they are
ideal for array lookups. So using this the above aspect can be
rewritten:
-``
-
+[source, java]
....
aspect X pertypewithin(*) {
Timer[] timerArray = ...
@@ -189,17 +185,16 @@ target instance.
The @DeclareMixin annotation is attached to a factory method which
returns instances of the delegate. Here is a basic example:
-``
-
+[source, java]
....
- // The factory method that can build the delegate instance is annotated with @DeclareMixin.
- // The annotation value defines the type pattern for targets of the mixin.
- // The parameter is the object for which a delegate is being constructed.
- // The interface that will be mixed in is the return value of the factory method.
- @DeclareMixin("org.xyz..*")
- public static SomeInterface createDelegate(Object instance) {
- return new SomeImplementation(instance);
- }
+// The factory method that can build the delegate instance is annotated with @DeclareMixin.
+// The annotation value defines the type pattern for targets of the mixin.
+// The parameter is the object for which a delegate is being constructed.
+// The interface that will be mixed in is the return value of the factory method.
+@DeclareMixin("org.xyz..*")
+public static SomeInterface createDelegate(Object instance) {
+ return new SomeImplementation(instance);
+}
....
More examples are
@@ -248,5 +243,3 @@ weaver. Although the type map uses Weak/Soft references to try and
better control how it uses memory, the JVM policies for managing these
references vary wildly and so some work needs to be done to allow for
these differences.
-
-'''''
diff --git a/docs/dist/doc/README-167.adoc b/docs/dist/doc/README-167.adoc
index 66476f8cc..5a2a9ffcf 100644
--- a/docs/dist/doc/README-167.adoc
+++ b/docs/dist/doc/README-167.adoc
@@ -18,6 +18,7 @@ pointcut matching]. Basically by turning on the options '-timers
-verbose' on the command line (or via Ant), output will be produced that
looks a little like this:
+[source, text]
....
Pointcut matching cost (total=6532ms for 675000 joinpoint match calls):
Time:482ms (jps:#168585) matching against
@@ -102,8 +103,7 @@ that actually runs? One user, Oliver Hoff, raised a query on the
performance of annotation binding. His case uncovered an old TODO left
in the code a few years ago:
-``
-
+[source, text]
....
// OPTIMIZE cache result of getDeclaredMethod and getAnnotation?
....
@@ -121,29 +121,28 @@ value at an execution join point in different ways. The three scenarios
look like this (where the annotation type is 'Marker' and it has a
String value field called 'message'):
-``
-
+[source, java]
....
- // CaseOne: annotation value fetching is done in the advice:
- pointcut adviceRetrievesAnnotation(): execution(@Marker * runOne(..));
- before(): adviceRetrievesAnnotation() {
- Marker marker = (Marker) ((MethodSignature)
- thisJoinPointStaticPart.getSignature()).getMethod().getAnnotation(Marker.class);
- String s = marker.message();
- }
-
- // CaseTwo: annotation binding is done in the pointcut, advice retrieves message
- pointcut pointcutBindsAnnotation(Marker l): execution(@Marker * runTwo(..)) && @annotation(l);
- before(Marker l): pointcutBindsAnnotation(l) {
- String s = l.message();
- }
-
- // CaseThree: annotation binding directly targets the message value in the annotation
- pointcut pointcutBindsAnnotationValue(String msg):
- execution(@Marker * runThree(..)) && @annotation(Marker(msg));
- before(String s): pointcutBindsAnnotationValue(s) {
- // already got the string
- }
+// CaseOne: annotation value fetching is done in the advice:
+pointcut adviceRetrievesAnnotation(): execution(@Marker * runOne(..));
+before(): adviceRetrievesAnnotation() {
+ Marker marker = (Marker) ((MethodSignature)
+ thisJoinPointStaticPart.getSignature()).getMethod().getAnnotation(Marker.class);
+ String s = marker.message();
+}
+
+// CaseTwo: annotation binding is done in the pointcut, advice retrieves message
+pointcut pointcutBindsAnnotation(Marker l): execution(@Marker * runTwo(..)) && @annotation(l);
+before(Marker l): pointcutBindsAnnotation(l) {
+ String s = l.message();
+}
+
+// CaseThree: annotation binding directly targets the message value in the annotation
+pointcut pointcutBindsAnnotationValue(String msg):
+ execution(@Marker * runThree(..)) && @annotation(Marker(msg));
+before(String s): pointcutBindsAnnotationValue(s) {
+ // already got the string
+}
....
Before 1.6.7, case 2 was slower than case 1 and case 3 wasn't supported
@@ -157,8 +156,7 @@ stress the AspectJ binding code. For the benchmark numbers the join
points advised by those advice were invoked 1,000,000 times. AspectJ
1.6.7:
-``
-
+[source, text]
....
Manually fetching annotation with getAnnotation(): 645ms
Binding annotation with @annotation(Marker): 445ms (was >20 *seconds* for 1.6.6, due to an extra reflection call)
diff --git a/docs/dist/doc/README-168.adoc b/docs/dist/doc/README-168.adoc
index eee958509..0a8e3cbb8 100644
--- a/docs/dist/doc/README-168.adoc
+++ b/docs/dist/doc/README-168.adoc
@@ -25,12 +25,11 @@ that is not
These three meet that spec:
-``
-
+[source, xml]
....
- <include within="*"/>
- <include within="@Foo *"/>
- <exclude within="*Funk*y*"/>
+<include within="*"/>
+<include within="@Foo *"/>
+<exclude within="*Funk*y*"/>
....
The include="*" can be optimized. The include="@Foo *" is not optimized.
@@ -51,22 +50,21 @@ more frequently.
The stack trace when this is hit looks like:
-``
-
+[source, text]
....
- ...
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:427)
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:427)
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:427)
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:427)
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:427)
- at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
- ...
+...
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:427)
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:427)
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:427)
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:427)
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:427)
+at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:393)
+...
....
The weaver has changed over the 1.5 and 1.6 releases and is now reaching
diff --git a/docs/dist/doc/README-169.adoc b/docs/dist/doc/README-169.adoc
index 1df44489f..4921f23d4 100644
--- a/docs/dist/doc/README-169.adoc
+++ b/docs/dist/doc/README-169.adoc
@@ -14,6 +14,7 @@ declare annotation constructs that take a member signature. For example,
if you wanted to attach an annotation to all your getter like methods,
you needed two constructs
+[source, java]
....
declare @method: * is*(): @FooBar;
declare @method: * get*(): @FooBar;
@@ -22,6 +23,7 @@ declare @method: * get*(): @FooBar;
Now AspectJ allows compound patterns for declare
@method/@constructor/@field.
+[source, java]
....
declare @method: (* is*()) || (* get*()): @FooBar;
....
@@ -32,6 +34,7 @@ It is now possible to ITD member types. The syntax is as would be
expected. This example introduces a new member type called Inner into
type Foo:
+[source, java]
....
public class Foo {
public static void main(String[] args) {
@@ -71,10 +74,9 @@ within it to switch-off if there is nothing for them to do.
Here is an example, 'AspectA' will switch itself off if the type
'a.b.c.Anno' cannot be found:
-``
-
+[source, xml]
....
- <aspect name="AspectA" requires="a.b.c.Anno"/>
+<aspect name="AspectA" requires="a.b.c.Anno"/>
....
==== Reduction in class file sizes: https://bugs.eclipse.org/bugs/show_bug.cgi?id=312839[312839]
@@ -130,8 +132,7 @@ the pointcuts defined in the original aspect.
Here is an example:
-``
-
+[source, xml]
....
<aspectj>
<aspects>
@@ -154,8 +155,7 @@ specifies that Y should in fact only be applied to com.foo..* types.
It is now possible to use joinpoint context in the messages attached to
declare warning and declare error constructs. Some examples:
-``
-
+[source, java]
....
declare warning: execution(* A.m(..)): "joinpoint is {joinpoint}";
declare warning: execution(* A.m(..)): "joinpoint kind is '{joinpoint.kind}'";
@@ -178,8 +178,7 @@ the message. Please raise an enhancement request if you need other keys
It is now possible to use a type pattern with declare warning and
declare error. For example:
-``
-
+[source, java]
....
declare warning: I+ && !hasfield(int i): "Implementations of I are expected to have a int field called i";
....
@@ -190,8 +189,7 @@ This is the ability to narrow the types of interest so that interfaces
can be ignored, or inner types, or classes or aspects. There is now a
new is() construct that enables this:
-``
-
+[source, java]
....
execution(* (!is(InnerType)).m(..)) {}
!within(* && is(InnerType)) {}
@@ -202,8 +200,9 @@ InnerType, AnonymousType, EnumType, AnonymousType.
Note: It is important to understand that "!within(is(InnerType))" and
"within(!is(InnerType))" are not the same. The latter one is unlikely to
-be what you want to use. For example here: ``
+be what you want to use. For example here:
+[source, java]
....
class Boo {
void foo() {}
@@ -223,8 +222,7 @@ result of that match will be negated.
Some users always expect this:
-``
-
+[source, java]
....
class C {
}
@@ -248,8 +246,7 @@ produce slightly different output.
Here is the output of javap when that is built with 1.6.8:
-``
-
+[source, java]
....
class C extends java.lang.Object{
public int ajc$interField$X$someField;
@@ -259,8 +256,7 @@ class C extends java.lang.Object{
Here is the output of javap when that is built with 1.6.9:
-``
-
+[source, java]
....
class C extends java.lang.Object{
private int someField;
@@ -284,8 +280,7 @@ and if you browse to it you will see it currently contains 1.6.9 dev
builds under the name 1.6.9.BUILD-SNAPSHOT. The repo is added with this
magic:
-``
-
+[source, xml]
....
<repository>
<id>maven.springframework.org</id>
diff --git a/docs/dist/doc/README-170.adoc b/docs/dist/doc/README-170.adoc
index de0248de7..b76f56139 100644
--- a/docs/dist/doc/README-170.adoc
+++ b/docs/dist/doc/README-170.adoc
@@ -36,6 +36,7 @@ start of a system using LTW and then reuses that woven bytecode on
subsequent starts - this saves weaving time and also memory consumption.
To activate it, use the following system properties:
+[source, text]
....
-Daj.weaving.cache.enabled=true
-Daj.weaving.cache.dir=/tmp/aspectj-cache/
@@ -51,8 +52,9 @@ Eclipse compiler.
It means that you can now use the new Java 7 language constructs in your
programs:
-- Diamond operator in advice: ``
+- Diamond operator in advice:
+[source, java]
....
aspect Foo {
before(): execution(* *(..)) {
@@ -61,58 +63,63 @@ aspect Foo {
}
....
-- Diamond operator in ITD: ``
+- Diamond operator in ITD:
+[source, java]
....
public List DiamondITD.ls = new ArrayList<>();
....
-- Underscore literals and binary literals in advice: ``
+- Underscore literals and binary literals in advice:
+[source, java]
....
- before(): execution(* *(..)) {
- int onemill = 1_000_000;
- int four =0b100;
- }
+before(): execution(* *(..)) {
+ int onemill = 1_000_000;
+ int four =0b100;
+}
....
- Multi-catch:``
+[source, java]
....
before(): execution(* main(..)) {
- try {
- foo("abc");
- } catch (ExceptionA | ExceptionB ex) {
- bar(ex);
- }
+ try {
+ foo("abc");
+ } catch (ExceptionA | ExceptionB ex) {
+ bar(ex);
+ }
}
....
- String switch:``
+[source, java]
....
- before(String s): execution(* *(..)) && args(s) {
- switch(s) {
- case "quux":
- foo();
- break;
- case "bar":
- foo();
- break;
- default:
- foo();
- break;
- }
- }
+before(String s): execution(* *(..)) && args(s) {
+ switch(s) {
+ case "quux":
+ foo();
+ break;
+ case "bar":
+ foo();
+ break;
+ default:
+ foo();
+ break;
+ }
+}
....
- Try with resources:``
+[source, java]
....
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest))
- {
- // code
- }
+try (
+ InputStream in = new FileInputStream(src);
+ OutputStream out = new FileOutputStream(dest))
+{
+ // code
+}
....
diff --git a/docs/dist/doc/README-174.adoc b/docs/dist/doc/README-174.adoc
index 7b4cbb54c..3b55b4a43 100644
--- a/docs/dist/doc/README-174.adoc
+++ b/docs/dist/doc/README-174.adoc
@@ -18,6 +18,7 @@ JVM where JMX is turned on
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=420210[420210]) The new
keys are:
+
+[source, java]
....
joinpoint.enclosingclass // Bar
joinpoint.enclosingmember // void Bar.foo(String)
@@ -29,6 +30,7 @@ All keys are case insensitive.
needing to supply a file
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=419279[419279])
+
+[source, text]
....
ajc -Xlint:adviceDidNotMatch=error,noGuardForLazyTjp=ignore Foo.java
....
diff --git a/docs/dist/doc/README-180.adoc b/docs/dist/doc/README-180.adoc
index fe988aa5a..115de3d6d 100644
--- a/docs/dist/doc/README-180.adoc
+++ b/docs/dist/doc/README-180.adoc
@@ -21,8 +21,9 @@ patch on top of Eclipse 4.3.2).
Here is a sample AspectJ8 program:
+[source, java]
....
-=== 8< ==== C.java ==== 8< ===
+// === 8< ==== C.java ==== 8< ===
import java.util.Arrays;
interface I {
@@ -67,5 +68,5 @@ class MyClass {
return args;
}
}
-=== 8< ==== C.java ==== 8< ===
+// === 8< ==== C.java ==== 8< ===
....
diff --git a/docs/dist/doc/README-182.adoc b/docs/dist/doc/README-182.adoc
index 45215367d..28fa7b2da 100644
--- a/docs/dist/doc/README-182.adoc
+++ b/docs/dist/doc/README-182.adoc
@@ -35,8 +35,7 @@ Here is a short example, a very basic annotation and application:
===== Marker.java
-``
-
+[source, java]
....
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -47,8 +46,7 @@ public @interface Marker { }
===== Code.java
-``
-
+[source, java]
....
public class Code {
@@ -60,13 +58,13 @@ public class Code {
}
public void moo() {}
-
+
@Marker
public void boo() {}
-
+
@Marker
public void too() {}
-
+
public void woo() {}
}
....
@@ -78,8 +76,7 @@ contrived demo!)
===== DemoProcessor.java
-``
-
+[source, java]
....
import java.io.*;
import javax.tools.*;
@@ -90,7 +87,7 @@ import javax.lang.model.element.*;
@SupportedAnnotationTypes(value= {"*"})
@SupportedSourceVersion(SourceVersion.RELEASE_6)
-public class DemoProcessor extends AbstractProcessor {
+public class DemoProcessor extends AbstractProcessor {
private Filer filer;
@@ -106,7 +103,7 @@ public class DemoProcessor extends AbstractProcessor {
if (element.getKind() == ElementKind.METHOD) {
// For any methods we find, create an aspect:
String methodName = element.getSimpleName().toString();
- String aspectText =
+ String aspectText =
"public aspect Advise_"+methodName+" {\n"+
" before(): execution(* "+methodName+"(..)) {\n"+
" System.out.println(\""+methodName+" running\");\n"+
@@ -131,22 +128,19 @@ public class DemoProcessor extends AbstractProcessor {
With those sources, we compile the processor:
-``
-
+[source, text]
....
ajc -1.6 DemoProcessor.java Marker.java
....
Now compile the code with the processor specified:
-``
-
+[source, text]
....
ajc -1.6 -processor DemoProcessor -showWeaveInfo Code.java Marker.java
....
-``
-
+[source, text]
....
Generated aspect to advise too
Generated aspect to advise boo
@@ -159,8 +153,7 @@ the code being compiled immediately.
Finally we can run it:
-``
-
+[source, text]
....
java Code
boo running
diff --git a/docs/dist/doc/README-183.adoc b/docs/dist/doc/README-183.adoc
index 95425e392..8c615ef84 100644
--- a/docs/dist/doc/README-183.adoc
+++ b/docs/dist/doc/README-183.adoc
@@ -35,6 +35,7 @@ extraneous dependencies to an applications build classpath.
Example:
+[source, java]
....
import org.aspectj.lang.annotation.*;
@@ -63,6 +64,7 @@ appears to come up when the aspect is non-optimal anyway and hitting
preinitialization was never really intended by the pointcut writer. For
example:
+[source, java]
....
execution(* foo(..)) && cflow(within(Bar))
....
@@ -72,12 +74,14 @@ joinpoints, many of which the user probably didn't mean to. It feels
like we actually need a warning to indicate the pointcut is probably
suboptimal. What the user probably meant was something more like this:
+[source, java]
....
execution(* foo(..)) && cflow(execution(* Bar.*(..))
....
or
+[source, java]
....
execution(* foo(..)) && cflow(within(Bar) && execution(* *(..)))
....
diff --git a/docs/dist/doc/README-187.adoc b/docs/dist/doc/README-187.adoc
index de61a362b..bcc5f75cc 100644
--- a/docs/dist/doc/README-187.adoc
+++ b/docs/dist/doc/README-187.adoc
@@ -25,8 +25,7 @@ will not be woven.
Here is a simple aspect:
-``
-
+[source, java]
....
public aspect Azpect {
before(): execution(* *(..)) {
@@ -37,8 +36,7 @@ public aspect Azpect {
Compiled via:
-``
-
+[source, text]
....
ajc -1.8 Azpect.java -outxml
....
@@ -48,8 +46,7 @@ META-INF/aop-ajc.xml.
I then have this sample application (same directory):
-``
-
+[source, java]
....
import java.lang.management.ManagementFactory;
import org.aspectj.weaver.loadtime.Agent;
@@ -96,8 +93,7 @@ public class Application {
And this Sample class:
-``
-
+[source, java]
....
public class Sample {
public void doSomething() {
@@ -116,8 +112,7 @@ JDK tools.jar on your classpath*.
Once compiled we can run it:
-``
-
+[source, text]
....
java -DAGENT_PATH=<path-to>/aspectjweaver.jar Application
....
diff --git a/docs/dist/doc/README-190.adoc b/docs/dist/doc/README-190.adoc
index 3b1f27784..323573146 100644
--- a/docs/dist/doc/README-190.adoc
+++ b/docs/dist/doc/README-190.adoc
@@ -41,6 +41,7 @@ In anticipation of not all build plugins supporting that
-Xajruntimetarget option, you can now specify these kinds of option in
the ASPECTJ_OPTS environment variable. Set that in your environment:
+[source, text]
....
export ASPECTJ_OPTS="-Xajruntimetarget:1.9"
....
@@ -58,17 +59,18 @@ useful with Java9 which includes a number of module related commands.
For example, here is an iajc usage with compilerArg that is passing
--add-modules java.xml.bind:
+[source, xml]
....
- <iajc destdir="bin" failonerror="true"
- showWeaveInfo="true" source="1.9" target="1.9"
- debug="true" fork="true" maxmem="256m">
- <compilerArg value="--add-modules"/>
- <compilerArg value="java.xml.bind"/>
- <src path="src" />
- <classpath>
- <pathelement location="${aspectj.home}/lib/aspectjrt.jar"/>
- </classpath>
- </iajc>
+<iajc destdir="bin" failonerror="true"
+ showWeaveInfo="true" source="1.9" target="1.9"
+ debug="true" fork="true" maxmem="256m">
+ <compilerArg value="--add-modules"/>
+ <compilerArg value="java.xml.bind"/>
+ <src path="src" />
+ <classpath>
+ <pathelement location="${aspectj.home}/lib/aspectjrt.jar"/>
+ </classpath>
+</iajc>
....
1.9.0.RC4 available 21-Feb-2018
@@ -103,6 +105,7 @@ AspectJ can now be used with the new module system available in Java9.
The key jars in AspectJ have been given automatic module names. The
automatic module name is org.aspectj.runtime for the aspectjrt module:
+[source, text]
....
$ java --module-path <pathto>/lib/aspectjrt.jar --list-modules | grep aspectj
@@ -112,6 +115,7 @@ org.aspectj.runtime file:///<pathto>/lib/aspectjrt.jar automatic
And similarly org.aspectj.weaver and org.aspectj.tools for aspectjweaver
and aspectjtools respectively:
+[source, text]
....
$ java --module-path <pathto>/lib/aspectjweaver.jar --describe-module org.aspectj.weaver
@@ -137,6 +141,7 @@ contains org.aspectj.asm.internal
AspectJ understands module-info.java source files and building modules
that include aspects. Here is an example:
+[source, java]
....
module-info.java
@@ -170,6 +175,7 @@ public aspect Azpect {
We can now build those into a module:
+[source, text]
....
$ ajc -1.9 module-info.java otherpkg/Azpect.java pkg/Demo.java -outjar demo.jar
@@ -182,12 +188,14 @@ Wait, that failed! Yes, aspectjrt.jar (which includes the required
org.aspectj.weaver module) wasn't supplied. We need to pass it on the
module-path:
+[source, text]
....
$ ajc -1.9 --module-path <pathto>/aspectjrt.jar module-info.java otherpkg/Azpect.java pkg/Demo.java -outjar demo.jar
....
Now we have a demo module we can run:
+[source, text]
....
$ java --module-path <pathto>/aspectjrt.jar:demo.jar --module demo/pkg.Demo
@@ -206,8 +214,9 @@ A module is really just a jar with a module-info descriptor. As such you
can simply pass a module on the inpath and binary weave it with other
aspects. Take the module we built above, let's weave into it again:
+[source, java]
....
-extra/AnotherAzpect.java
+// extra/AnotherAzpect.java
package extra;
@@ -218,6 +227,7 @@ public aspect AnotherAzpect {
}
....
+[source, text]
....
$ ajc -inpath demo.jar AnotherAzpect.java -outjar newdemo.jar
....
@@ -231,6 +241,7 @@ Because the new jar produced includes the compiled aspect, the
module-info specification inside is still correct, so we can run it
exactly as before:
+[source, text]
....
$ java --module-path ~/installs/aspectj190rc1/lib/aspectjrt.jar:newdemo.jar --module demo/pkg.Demo
@@ -239,9 +250,6 @@ AnotherAzpect running
Demo running
....
- +
- +
-
=== Faster Spring AOP
Dave Syer recently created a series of benchmarks for checking the speed
@@ -250,6 +258,7 @@ of Spring-AspectJ: https://github.com/dsyer/spring-boot-aspectj
Here we can see the numbers for AspectJ 1.8.11 (on an older Macbook
Pro):
+[source, text]
....
Benchmark (scale) Mode Cnt Score Error Units
StartupBenchmark.ltw N/A avgt 10 2.553 ~ 0.030 s/op
@@ -295,6 +304,7 @@ primary change is factoring in the annotation type.
What difference does that make? AspectJ 1.9.0.RC1:
+[source, text]
....
Benchmark (scale) Mode Cnt Score Error Units
StartupBenchmark.ltw N/A avgt 10 2.568 ~ 0.035 s/op
diff --git a/docs/dist/doc/README-191.adoc b/docs/dist/doc/README-191.adoc
index acab550c3..bba435893 100644
--- a/docs/dist/doc/README-191.adoc
+++ b/docs/dist/doc/README-191.adoc
@@ -14,6 +14,7 @@ AspectJ has updated to a recent JDT compiler version (commit
This means you can use the 'var' support. A simple example of combining
var with an aspect:
+[source, java]
....
public class Code3 {
public static void main(String []argv) {
diff --git a/docs/dist/doc/README-193.adoc b/docs/dist/doc/README-193.adoc
index a75724c2c..22824b66b 100644
--- a/docs/dist/doc/README-193.adoc
+++ b/docs/dist/doc/README-193.adoc
@@ -10,8 +10,9 @@ expression syntax, but you must activate support for that via an
--enable-preview flag when using the compiler and attempting to run the
resultant classes: Here is Switch3.java:
+[source, java]
....
-=========8<=========
+// =========8<=========
public class Switch3 {
public static void main(String[] argv) {
System.out.println(one(Color.R));
@@ -29,7 +30,7 @@ public class Switch3 {
};
return result;
}
-
+
public static final int foo(int i) {
return i+1;
}
@@ -44,11 +45,12 @@ aspect X {
return proceed()*3;
}
}
-=========8<=========
+// =========8<=========
....
Compile it with:
+[source, text]
....
$ ajc --enable-preview -showWeaveInfo -12 Switch3.java
@@ -63,6 +65,7 @@ Join point 'method-call(int Switch3.foo(int))' in Type 'Switch3' (Switch3.java:1
Now run it:
+[source, text]
....
$ java --enable-preview Switch3
3
diff --git a/docs/dist/doc/README-195.adoc b/docs/dist/doc/README-195.adoc
index 2af7e42a7..36a157c53 100644
--- a/docs/dist/doc/README-195.adoc
+++ b/docs/dist/doc/README-195.adoc
@@ -12,8 +12,9 @@ must activate support for that via an --enable-preview flag when using
the compiler and attempting to run the resultant classes: Here is
Code.java:
+[source, java]
....
-=======8<=========
+// =======8<=========
public class Code {
public static void main(String[] argv) {
}
@@ -33,17 +34,19 @@ lines
}
}
-=========8<=========
+// =========8<=========
....
Compile it with:
+[source, text]
....
$ ajc --enable-preview -13 Code.java
....
Now run it:
+[source, text]
....
$ java --enable-preview Code
This
diff --git a/docs/dist/doc/README-196.adoc b/docs/dist/doc/README-196.adoc
index 536cd4ec9..35e7ab2d3 100644
--- a/docs/dist/doc/README-196.adoc
+++ b/docs/dist/doc/README-196.adoc
@@ -11,12 +11,13 @@ AspectJ 1.9.6 supports Java14. Java14 introduces records, but you must
activate support for that via an --enable-preview flag when using the
compiler and attempting to run the resultant classes: Here is Code.java:
+[source, java]
....
-=======8<=========
+// =======8<=========
public record Person(String firstName, String lastName, int age) {}
-=======8<=========
+// =======8<=========
-=======8<=========
+// =======8<=========
public class UsingPersonRecord {
public static void main(String[] argv) {
Person p = new Person("A","B",99);
@@ -24,25 +25,27 @@ public class UsingPersonRecord {
System.out.println(p.firstName());
}
}
-=======8<=========
+// =======8<=========
-=======8<=========
+// =======8<=========
public aspect TraceRecordComponents {
before(): execution(public * *()) {
System.out.println(thisJoinPointStaticPart);
}
}
-=======8<=========
+// =======8<=========
....
Compile it with:
+[source, text]
....
$ ajc --enable-preview -14 Person.java UsingPersonRecord.java TraceRecordComponents.java
....
Now run it:
+[source, text]
....
$ java --enable-preview UsingPersonRecord
execution(String Person.toString())
diff --git a/docs/dist/doc/changes.adoc b/docs/dist/doc/changes.adoc
index c7b2d6975..25ef37f09 100644
--- a/docs/dist/doc/changes.adoc
+++ b/docs/dist/doc/changes.adoc
@@ -178,10 +178,10 @@ compiler supports an additional option, -showWeaveInfo, which will
produce informational messages concerning the activity of the weaver.
For example:
+
+[source, text]
....
- Type 'tjp.Demo' (Demo.java:30) advised by around advice from 'tjp.GetInfo'
- (GetInfo.java:26) [RuntimeTest=true]
-
+Type 'tjp.Demo' (Demo.java:30) advised by around advice from 'tjp.GetInfo'
+(GetInfo.java:26) [RuntimeTest=true]
....
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=44191[44191] AspectJ
1.2.1 improves the error messages issued in many of the infamous "can't
diff --git a/docs/dist/doc/porting.adoc b/docs/dist/doc/porting.adoc
index bc95dc5c7..cbf8ede6d 100644
--- a/docs/dist/doc/porting.adoc
+++ b/docs/dist/doc/porting.adoc
@@ -37,35 +37,36 @@ The following example program illustrates the differences in join point
matching with the `call` pointcut designator between 1.4 and 1.3
compliance levels.
-....
-01 class A {
-02 public void doIt() {...};
-03 }
-04
-05 class B extends A {
-06 public void doThisToo() {...};
-07 }
-08
-09
-10 public class CallsAandB {
-11
-12 public static void main(String[] args) {
-13 B b = new B();
-14 A bInDisguise = new B();
-15
-16 b.doIt(); // AspectJ 1.2 matches here
-17 bInDisguise.doIt(); // this is never matched
-18 }
-19
-20 }
-21
-22 aspect CallPCDMatchingExample {
-23
-24 before() : call(* B.doIt(..)) {
-25 System.out.println("About to call B.doIt(...)");
-26 }
-27
-28 }
+[source, java]
+....
+/*01*/ class A {
+/*02*/ public void doIt() {...};
+/*03*/ }
+/*04*/
+/*05*/ class B extends A {
+/*06*/ public void doThisToo() {...};
+/*07*/ }
+/*08*/
+/*09*/
+/*10*/ public class CallsAandB {
+/*11*/
+/*12*/ public static void main(String[] args) {
+/*13*/ B b = new B();
+/*14*/ A bInDisguise = new B();
+/*15*/
+/*16*/ b.doIt(); // AspectJ 1.2 matches here
+/*17*/ bInDisguise.doIt(); // this is never matched
+/*18*/ }
+/*19*/
+/*20*/ }
+/*21*/
+/*22*/ aspect CallPCDMatchingExample {
+/*23*/
+/*24*/ before() : call(* B.doIt(..)) {
+/*25*/ System.out.println("About to call B.doIt(...)");
+/*26*/ }
+/*27*/
+/*28*/ }
....
When this program is compiled with AspectJ 1.2 using the default
@@ -99,8 +100,8 @@ does not match at a join point, and a user may have expected it to.
Compiling the above program using AspectJ 1.2 produces the following
compiler output:
+[source, text]
....
-
CallsAandB.java:24 warning does not match because declaring type is A, if match desired use target(B) [Xlint:unmatchedSuperTypeInCall]
before() : call(* B.doIt(..)) {
^^^^^^^^^^^^^^^
@@ -109,7 +110,6 @@ before() : call(* B.doIt(..)) {
1 warning
-
....
The warning is telling us that the call pointcut associated with the
@@ -147,6 +147,7 @@ an interface is now (correctly) prohibited, and there will no longer be
a constructor-execution join point for the interface. To initialize a
field declared on an interface, use initialization, e.g.,
+[source, java]
....
int I.i;
after(I i) returning: initialization(I) && this(i) { i.i = 2; }
@@ -154,6 +155,7 @@ after(I i) returning: initialization(I) && this(i) { i.i = 2; }
To pick out the constructor-execution for any implementation of I, try
+[source, java]
....
execution(I+.new(..))
....
@@ -172,6 +174,7 @@ older version of BCEL available earlier on your classpath than the
version included in the 1.2 aspectjtools.jar then you will see errors
like:
+[source, text]
....
C:\work\test\TestAspect.aj error Internal compiler error
java.lang.NoSuchMethodError: org.apache.bcel.generic.InstructionFactory.
@@ -219,6 +222,7 @@ Conflicts will be reported for no-argument constructors generated by
compilers when no constructor is defined for a class. That means the
following code will compile in 1.0 but not in 1.1:
+[source, java]
....
class C {}
aspect A {
@@ -243,6 +247,7 @@ The compiler will report an error that the form
`aspect {name} dominates {list}...` is no longer supported. It has been
replaced by a new declare statement:
+[source, java]
....
declare precedence : {name} {list}...
....
@@ -269,6 +274,7 @@ returning advice.
The main change that was made was of after returning advice for
constructor execution join points. Previously, this advice was legal:
+[source, java]
....
after() returning (Foo f): execution(Foo.new(..)) { ... }
....
@@ -280,6 +286,7 @@ constructor calls) do not return the value of the new object. Rather,
void method. With that in mind, any code like the above should be
conveted to the form.
+[source, java]
....
after(Foo f) returning: this(f) && execution(Foo.new(..)) { ... }
....
@@ -287,6 +294,7 @@ after(Foo f) returning: this(f) && execution(Foo.new(..)) { ... }
In compilers prior to 1.0.4, the following advice could pick out join
points
+[source, java]
....
after() returning (String s): call(void foo()) { ... }
....
@@ -294,6 +302,7 @@ after() returning (String s): call(void foo()) { ... }
This is no longer picked out. This pattern was most commonly used in
highly polymorphic contexts, such as
+[source, java]
....
after() returning (String s): call(* foo()) { ... }
....
@@ -301,6 +310,7 @@ after() returning (String s): call(* foo()) { ... }
If you want to capture all calls, binding null objects for those that
would otherwise have no value, you must use the `Object` type.
+[source, java]
....
after() returning (Object o): call(* foo()) { ... }
....
@@ -378,18 +388,20 @@ for example, you named a parameter of a pointcut "set", you should (for
your own sanity -- the compiler doesn't require it) rename it in the
rewritten pointcut.
+[source, java]
....
pointcut sort(Collection set): calls(void addAll(set));
-==>
+// ==>
pointcut sort(Collection mySet): call(void addAll(mySet));
....
While converting to use singular nouns for the primitive pointcuts, you
may also want to remove the "s" from your user-defined pointcuts.
+[source, java]
....
pointcut publicCalls(): calls(public * *(..));
-==>
+// ==>
pointcut publicCall(): call(public * *(..));
....
@@ -412,9 +424,10 @@ straightforward, depending on whether the pointcut exposed state or not.
Receptions pointcuts that did not expose state can simply be replaced by
the new `call` and `target` pointcuts:
+[source, java]
....
receptions(void Foo.m())
-==>
+// ==>
target(Foo) && call(void m())
....
@@ -424,9 +437,10 @@ Some receptions pointcuts exposed the receiving object by replacing the
receiving type with a pointcut formal. These PCDs should be rewritten to
use the new `target` pointcut to expose the receiving object.
+[source, java]
....
pointcut fooCallees(Foo f): receptions(void f.m());
-==>
+// ==>
pointcut fooCallee(Foo f): target(f) && call(void m());
....
@@ -434,9 +448,10 @@ Like xref:#_1_0a1-fixing-state-access[other pointcuts], receptions
pointcuts that exposed one or more arguments should be rewritten to use
the `args` pointcut:
+[source, java]
....
pointcut intPassers(int i, int j): receptions(void Foo.m(i, j));
-==>
+// ==>
pointcut intPasser(int i, int j):
args(i, j) && target(Foo) && call(void m(int, int));
....
@@ -453,9 +468,10 @@ but also of classes that extended C.
If you want this behaviour, then you need to use the new subtypes
operator, +, on the type name in question. So,
+[source, java]
....
receptions(C.new())
-==>
+// ==>
call(C+.new())
....
@@ -468,6 +484,7 @@ allow all kinds of advice it may be that the object isn't constructed
yet (say, in before or around advice). This is a benefit, in that it
allows caching constructed objects
+[source, java]
....
aspect Singleton {
private C theC = null;
@@ -482,9 +499,10 @@ aspect Singleton {
but it does require some rewriting. The new object can be accessed as
the return value in after returning advice. So,
+[source, java]
....
after(Point p) returning (): receptions(p.new(int, int)) { ... }
-==>
+// ==>
after() returning (Point p): call(Point+.new(int, int)) { ... }
....
@@ -509,15 +527,17 @@ Any time you have a pointcut that has a signature where one of the
arguments was a pointcut or advice formal, just replace that formal with
its type and add an `args` pointcut.
+[source, java]
....
pointcut intPassers(int i, int j): calls(void Foo.m(i, j));
-==>
+// ==>
pointcut intPasser(int i, int j): args(i, j) && call(void Foo.m(int, int));
....
+[source, java]
....
pointcut stringPassers(String s): receptions(void Foo.m(s, ..));
-==>
+// ==>
pointcut stringPasser(String s): args(s, ..) && call(void Foo.m(String, ..));
....
@@ -525,6 +545,7 @@ pointcut stringPasser(String s): args(s, ..) && call(void Foo.m(String, ..));
If a calls pointcut exposed the the receiving object, such as
+[source, java]
....
pointcut fooCallees(Foo f): calls(void f.m());
....
@@ -532,6 +553,7 @@ pointcut fooCallees(Foo f): calls(void f.m());
then the new version should use the `target` pointcut to get at that
object
+[source, java]
....
pointcut fooCallee(Foo f): target(f) && call(void Foo.m());
....
@@ -543,9 +565,10 @@ returning advice, when it is guaranteed that the object was successfully
constructed. So instead of using the `target` pointcut to expose the
value, you should use the normal `after returning` mechanism:
+[source, java]
....
after(Point p) returning (): calls(p.new(int, int)) { ... }
-==>
+// ==>
after() returning (Point p): call(Point+.new(int, int)) { ... }
....
@@ -555,15 +578,17 @@ Exposing the target object of a `gets` or `sets` pointcut should be done
the same way it was for `calls` pointcuts, with the new `target`
pointcut.
+[source, java]
....
before(Frame f): gets(Color f.color) { ... }
-==>
+// ==>
before(Frame f): target(f) && get(Color Frame.color) { ... }
....
+[source, java]
....
before(Frame f): sets(Color f.color) { ... }
-==>
+// ==>
before(Frame f): target(f) && set(Color Frame.color) { ... }
....
@@ -573,11 +598,14 @@ the field yourself in the body. Depending on the rest of your system,
you may need to restrict the advice from the aspect body to eliminiate
the circularity.
+[source, java]
....
aspect A {
before(Frame f, Color c): gets(Color f.color)[c] { ... }
}
-==>
+
+// ==>
+
aspect A {
before(Frame f):
target(f) && get(Color Frame.color) && !within(A) {
@@ -590,11 +618,14 @@ aspect A {
The same can be done for `around` advice. However, the only way to port
after advice that needs the old value is to convert it to around advice.
+[source, java]
....
aspect A {
after(Frame f, Color c) returning (): gets(Color f.color)[c] { ... }
}
-==>
+
+// ==>
+
aspect A {
void around(Frame f):
target(f) && get(Color Frame.color) && !within(A) {
@@ -610,9 +641,10 @@ available, but not the way it was previously. Instead of using the
square bracket syntax, we use an `args` pointcut. All set join points
are assumed to have exactly one argument, which holds the new value. So,
+[source, java]
....
after(Color newColor): sets(Color Frame.color)[][newColor] { ... }
-==>
+// ==>
after(Color newColor): args(newColor) && set(Color Frame.color) { ... }
....
@@ -625,9 +657,10 @@ The value of the exception at an exception handler join point is now
accessed through the `args` pointcut; all exception handler join points
are treated as having exactly one argument, the exception value. So,
+[source, java]
....
before(NotFoundException e): handlers(e) { ... }
-==>
+// ==>
before(NotFoundException e): args(e) && handler(NotFoundException) { ... }
....
@@ -640,9 +673,10 @@ closed, and within can only take type patterns, not pointcut or advice
formals. A use of the `this` pointcut will capture what previous
implementations did:
+[source, java]
....
pointcut usesFoo(Foo f): within(f);
-==>
+// ==>
pointcut usesFoo(Foo f): this(f) && within(Foo);
....
@@ -667,6 +701,7 @@ to match.
For example, the pointcut
+[source, java]
....
calls(void m(Object))
....
@@ -677,6 +712,7 @@ out method calls to methods that are defined to take exactly the type
Object, which may be a lot fewer join points. If you want the old
behaviour, simply convert to
+[source, java]
....
call(void m(Object+))
....
@@ -692,10 +728,11 @@ pointcut, composed (with `&&`) with another pointcut. If the other
pointcut was a `receptions` pointcut, then `instanceof` should be
converted to `target` (and `receptions` converted to `call`). So,
+[source, java]
....
pointcut stateChanges(Subject s):
instanceof(s) && receptions(void Button.click());
-==>
+// ==>
pointcut stateChange(Subject s):
target(s) && call(void Button.click());
....
@@ -703,15 +740,17 @@ pointcut stateChange(Subject s):
In all other cases, `instanceof` referred to the currently executing
object, and so should be converted into `this`
+[source, java]
....
before(Point p): instanceof(p) && executions(* makePolar(..)) { ... }
-==>
+// ==>
before(Point p): this(p) && execution(* makePolar(..)) { ... }
....
+[source, java]
....
pointcut setup(Client c): instanceof(c) && calls(Remote Naming.lookup(String));
-==>
+// ==>
pointcut setup(Client c): this(c) && calls(Remote Naming.lookup(String));
....
@@ -728,9 +767,10 @@ fields.
The old behaviour can be recovered with a simple rewrite.
+[source, java]
....
initializations(A)
-==>
+// ==>
initialization(A.new(..)) && !execution(A.new(..))
....
@@ -760,20 +800,22 @@ If the aspect whose presense you are checking for was defined
`of eachcflow`, `of eachcflowbelow`, or, more unlikely, `of eachJVM()`,
then the conversion is simple:
+[source, java]
....
hasaspect(A)
-==>
+// ==>
if(A.hasAspect())
....
If the aspect was defined `of eachobject`, then you will have to expose
the current object in your pointcut or advice parameters:
+[source, java]
....
pointcut cut(): hasaspect(A) ... ;
-==>
+// ==>
pointcut cut(Object o): this(o) && if(A.hasAspect(o)) ... ;
-or
+// or
pointcut cut(Object o): target(o) && if(A.hasAspect(o)) ... ;
....
@@ -782,11 +824,12 @@ aspect, then you can get the same state by using `A.aspectOf()` in the
body of the advice. For example, if the aspect A were defined
`of eachcflow`, then
+[source, java]
....
before(A myA): hasaspect(myA) {
myA.checkStatus();
}
-==>
+// ==>
before(): if(A.hasAspect()) {
A myA = A.aspectOf();
myA.checkStatus();
@@ -801,9 +844,10 @@ of within and the xref:#_1_0a1-subtypes-to-plus[new subtypes operator],
+, instead. You'll save two characters and be using a simpler and more
orthogonal language.
+[source, java]
....
withinall(Foo)
-==>
+// ==>
within(Foo+)
....
@@ -813,9 +857,10 @@ within(Foo+)
The returns keyword is no longer necessary for user-defined pointcuts.
Simply remove it when you find it.
+[source, java]
....
pointcut publicIntCalls() returns int: calls(public int *(..));
-==>
+// ==>
pointcut publicIntCall(): call(public int *(..));
....
@@ -864,9 +909,10 @@ programs easier. There is one ugly idiom, however, that this change
disposes of. If your program includes the type pattern `*..*`, which
used to match all types, you can replace it with the much simpler *.
+[source, java]
....
pointcut unaryVoidMethods(): call(void *(*..*));
-==>
+// ==>
pointcut unaryVoidMethod(): call(void *(*));
....
@@ -882,11 +928,12 @@ wrote `subtypes(Foo)`, i.e., the subtypes of a single type, simply
replace this with `Foo+`. Otherwise, use the + operator as appropriate
in `TypePattern`.
+[source, java]
....
public void (subtypes(Target0 || Target1)).accept(Visitor v) {
v.visit(this);
}
-==>
+// ==>
public void (Target0+ || Target1+).accept(Visitor v) {
v.visit(this);
}
@@ -901,9 +948,10 @@ public void (Target0+ || Target1+).accept(Visitor v) {
The returns keyword is no longer used for around advice. Instead, the
return type is declared as it is for methods. So,
+[source, java]
....
around(Point p) returns void: setters(p) { ... }
-==>
+// ==>
void around(Point p): setter(p) { ... }
....
@@ -913,6 +961,7 @@ void around(Point p): setter(p) { ... }
Around advice must now declare the checked exceptions it throws with a
`throws` clause, much like a method.
+[source, java]
....
char around(char c) throws java.io.CharConversionException: converter(c) {
char result;
@@ -951,6 +1000,7 @@ This allows interesting advice interaction. In the following advice, for
example, the `after throwing` advice will catch the exception thrown by
the `before` advice
+[source, java]
....
aspect A {
before(): call(void main(..)) {
@@ -965,6 +1015,7 @@ aspect A {
But reversing the order will give the `before` advice more precedence,
making its exception uncatchable by the `after throwing` advice
+[source, java]
....
aspect A {
after() throwing(RuntimeException e): call(void main(..)) {
@@ -986,15 +1037,17 @@ If you use after returning advice and do not need to expose the return
value, you no longer need to write an empty set of parentheses to
indicate that fact. So,
+[source, java]
....
after(Formals) returning (): Pointcut { ... }
-==>
+// ==>
after(Formals) returning: Pointcut { ... }
....
The same syntax is now available for after throwing advice, in case you
do not care what `Throwable` is thrown.
+[source, java]
....
after(Formals) throwing: Pointcut { ... }
....
@@ -1013,6 +1066,7 @@ The `JoinPoint` object hierarchy has been folded into a single class,
`org.aspectj.lang.JoinPoint`. A common pattern in logging, for example,
was
+[source, java]
....
before() executions(* myMethod()) {
ExecutionJoinPoint jp = (ExecutionJoinPoint)thisJoinPoint;
@@ -1025,6 +1079,7 @@ before() executions(* myMethod()) {
While there is still a rich hierarchy for signatures, there is only one
`JoinPoint` type, so this can be rewritten as:
+[source, java]
....
before() executions(* myMethod()) {
JoinPoint jp = thisJoinPoint;
@@ -1045,12 +1100,14 @@ Some of the method names of `JoinPoint` have been reorganized, as well.
The keywords `+implements` and `+extends` no longer exist. Instead,
AspectJ uses the `declare` form for exactly the same functionality.
+[source, java]
....
Point +implements Serializable;
=>
declare parents: Point implements Serializable;
....
+[source, java]
....
MyButton +extends ButtonAdaptor;
=>
@@ -1063,6 +1120,7 @@ declare parents: MyButton extends ButtonAdaptor;
Around advice advice no longer effects the static exception checking of
Java. This means that the following code previously compiled:
+[source, java]
....
class C {
void noExceptionDeclared() {
@@ -1088,6 +1146,7 @@ exceptionDeclared() will not, actually, throw an exception, we now
"soften" that exception, that is, take it out of the space of declared
exceptions.
+[source, java]
....
declare soft: ExceptionType: Pointcut;
....
@@ -1097,6 +1156,7 @@ would require runtime information. But picking out method calls is just
fine. So in order to make the above example work, one new declaration is
needed:
+[source, java]
....
declare soft: IOException:
call(void C.exceptionDeclared()) &&
@@ -1109,9 +1169,10 @@ declare soft: IOException:
The syntax of "of each" modifiers has changed. For `of eachcflow` and
`of eachcflowbelow`, you can simply replace "of each" with "per". So,
+[source, java]
....
aspect A of eachcflow(...) { ... }
-==>
+// ==>
aspect A percflow(...) { ... }
....
@@ -1120,11 +1181,12 @@ remove that declaration entirely (because this is the default
behaviour), or replace the `of eachJVM()` declaration with an
`issingleton` declaration.
+[source, java]
....
aspect of eachJVM() { ... }
-==>
+// ==>
aspect A { ... }
-or
+// or
aspect A issingleton { ... }
....
@@ -1135,13 +1197,16 @@ you replace with depends on the `Pointcut` you use.
If you use a pointcut that picked out reception join points, then use
`pertarget`, and rewrite the pointcut to pick out call join points. So
+[source, java]
....
aspect Shadow
of eachobject(receptions(void Point.setX(int)) ||
receptions(void Point.setY(int))) {
...
}
-==>
+
+// ==>
+
aspect Shadow pertarget(call(void Point.setX(int)) ||
call(void Point.setY(int))) {
...
@@ -1193,7 +1258,7 @@ In many cases, you may not care whether the points of `Pointcut` are
included or not, and so can safely leave `cflow(Pointcut)` pointcut
designators alone. However, if you use the idiom
-[source,codeindent]
+[source, java]
----
Pointcut && ! cflow(Pointcut)
----
@@ -1201,7 +1266,7 @@ Pointcut && ! cflow(Pointcut)
to capture the non-recursive entries to a particular pointcut, you will
definitely want to rewrite that as
-[source,codeindent]
+[source, java]
----
Pointcut && ! cflowbelow(Pointcut)
----
@@ -1212,14 +1277,14 @@ The primitive pointcut designator `cflowtop(Pointcut)` has been removed
from the language, as it is expressible with `cflow` or `cflowbelow`.
All uses of `cflowtop(Pointcut)` can be rewritten as:
-[source,codeindent]
+[source, java]
----
cflowbelow(Pointcut && ! cflowbelow(Pointcut))
----
Though in most cases the following is sufficient
-[source,codeindent]
+[source, java]
----
cflow(Pointcut && ! cflowbelow(Pointcut))
----
@@ -1232,7 +1297,7 @@ override all of its abstract pointcuts with an empty pointcut. AspectJ
0.8beta3 enforces the restriction that a concrete aspect may not have
any abstract pointcuts. Thus the following extension:
-[source,codeindent]
+[source, java]
----
abstract aspect A {
abstract pointcut pc();
@@ -1245,14 +1310,14 @@ will no longer compile.
Adding the new empty pointcut designator
-[source,codeindent]
+[source, java]
----
pointcut Id();
----
in the declaration of the concrete aspect fixes this problem.
-[source,codeindent]
+[source, java]
----
abstract aspect A {
abstract pointcut pc();
@@ -1269,7 +1334,7 @@ aspect B {
Previously, the compiler silently refrained from applying a piece of
advice to join points within its own advice body. So, for example, in
-[source,codeindent]
+[source, java]
----
class C {
static int i;
@@ -1292,7 +1357,7 @@ Most cases of this error can be fixed by correctly specifying the
desired pointcut: In the above example, the intention is clearly not to
trace _all_ references of `C.i`, just those outside the aspect.
-[source,codeindent]
+[source, java]
----
class C {
static int i;
@@ -1310,7 +1375,7 @@ code in the aspect, but not in the particular piece of advice. In such
cases, you can pull the body of the advice into a method and restrict
away from that method (and away from calls to that method):
-[source,codeindent]
+[source, java]
----
class C {
static int i;
@@ -1353,10 +1418,10 @@ to the 0.8beta1 release of AspectJ.
The syntax of introduction has changed. Porting most programs should
require some simple editing. Anywhere you have an introduction block
-[source,codeindent]
+[source, java]
----
introduction GTN {
- ...
+ // ...
}
----
@@ -1368,7 +1433,7 @@ For field introduction, place the `GTN` in front of the field name, and
for constructor introduction, place the `GTN` in front of the `new`
identifier.
-[source,codeindent]
+[source, java]
----
introduction Foo {
public void doStuff() { this.doStuffLater(); }
@@ -1376,7 +1441,7 @@ introduction Foo {
public new(int x) { super(); calorieCount = x; }
}
-==>
+// ==>
public void Foo.doStuff() { this.doStuffLater(); }
public int Foo.calorieCount= 3;
@@ -1387,14 +1452,14 @@ For implements and extends introduction, move the `GTN` in front of the
new identifiers `implements` or `extends`, and place that in a
`declare parents` form.
-[source,codeindent]
+[source, java]
----
introduction Foo {
implements Comparable;
extends Goo;
}
-==>
+// ==>
declare parents: Foo implements Comparable;
declare parents: Foo extends Goo;
@@ -1404,13 +1469,13 @@ In all cases, if the `GTN` is just a type name, it can be moved down on
its own. However, if the `GTN` uses any of `&&`, `||`, and `!`, it must
be parenthesized.
-[source,codeindent]
+[source, java]
----
introduction subtypes(Foo) && !Goo {
int x;
}
-==>
+// ==>
int (Foo+ && !Goo).x;
----
@@ -1423,7 +1488,7 @@ need to modify your code to avoid this accessibility issue, or you will
need to use the `privileged` modifier on the aspect that contains the
introduction.
-[source,codeindent]
+[source, java]
----
class Counter {
private int count = 2;
@@ -1435,7 +1500,8 @@ aspect ExposeCountersPrivates {
}
}
-==>
+// ==>
+
// in 0.8, only privileged aspects can expose a class's privates
privileged aspect ExposeCountersPrivates {
public int Counter.getCount() { return count; }
@@ -1446,7 +1512,7 @@ If you have introduced private or package-protected members, you will
probably have to re-write some code. Most previous uses of introducing
privates can be improved by using private introduction instead.
-[source,codeindent]
+[source, java]
----
class C {
}
@@ -1458,7 +1524,8 @@ aspect AddCounter {
}
}
-==>
+// ==>
+
aspect AddCounter {
private int Counter.count;
public int Counter.getCount() { return count; }
@@ -1491,7 +1558,7 @@ clause or is declared "of eachJVM()", and is not extended by another
aspect, simply remove the keyword "static" from all pieces of advice,
and make sure the aspect is not defined with the "abstract" modifier.
-[source,codeindent]
+[source, java]
----
aspect Tracing {
static before(): executions(* *(..)) {
@@ -1499,7 +1566,7 @@ aspect Tracing {
}
}
-==>
+// ==>
aspect Tracing {
before(): execution(* *(..)) {
@@ -1513,7 +1580,7 @@ advice, is extended, or is "of eachObject(...)" or "of
eachcflowroot(...)", you should group your static advice together and
put it in a new aspect, possibly even an inner aspect.
-[source,codeindent]
+[source, java]
----
aspect ComplexTracing of eachobject(cflow(executions(void Main.main(..)))) {
static before(): executions(* *(..)) {
@@ -1526,7 +1593,7 @@ aspect ComplexTracing of eachobject(cflow(executions(void Main.main(..)))) {
// some other dynamic advice, fields, etc
}
-==>
+// ==>
aspect ComplexTracing of eachobject(cflow(executions(void Main.main(..)))) {
static aspect AlwaysTracing {
@@ -1551,7 +1618,7 @@ majority of your code the most serious change this requires is to add an
explicit `abstract` modifier to a super-aspect that was already
implicitly abstract.
-[source,codeindent]
+[source, java]
----
aspect BaseTracing {
abstract pointcut traced();
@@ -1560,11 +1627,11 @@ aspect BaseTracing {
}
}
-==>
+// ==>
// make this abstract aspect explicitly abstract
abstract aspect BaseTracing {
- ...
+ // ...
}
----
@@ -1576,20 +1643,22 @@ instance of a subaspect back.
This pattern was used in the Spacewar example in the AspectJ
distribution. We had the class hierarchy
+[source, text]
....
- SpaceObject (abstract)
- |- Ship
- |- Bullet
- |- EnergyPellet
+SpaceObject (abstract)
+ |- Ship
+ |- Bullet
+ |- EnergyPellet
....
And the aspect hierarchy
+[source, text]
....
- SpaceObjectDA (abstract)
- |- ShipDA of eachobject(instanceof(Ship))
- |- BulletDA of eachobject(instanceof(Ship))
- |- EnergyPacketDA of eachobject(instanceof(Ship))
+SpaceObjectDA (abstract)
+ |- ShipDA of eachobject(instanceof(Ship))
+ |- BulletDA of eachobject(instanceof(Ship))
+ |- EnergyPacketDA of eachobject(instanceof(Ship))
....
And we would call `SpaceObjectDA.getAspect(SpaceObject)` to access the
@@ -1609,7 +1678,7 @@ defined `of eachobject(instanceof(...))`. A prime example of this was
the `BoundPoint` aspect of the bean example: which needed to associate
each point with a `PropertyChangeSupport` object.
-[source,codeindent]
+[source, java]
----
aspect BoundPoint of eachobject(instanceof(Point)) {
@@ -1630,7 +1699,7 @@ these state association is to use privately introduced fields. Instead
of creating an aspect instance for every `Point` object, store the
`PropertyChagneSupport` object in the `Point` objects themselves.
-[source,codeindent]
+[source, java]
----
aspect BoundPoint {
private PropertyChangeSupport Point.support = new PropertyChangeSupport(this);