Browse Source

Fix more AsciiDoc links and code blocks (WIP)

- Add Java syntax highlighting to AspectJ and Java files
- Add XML syntax highlighting to XML files (Ant, LTW etc.)
- Dedent and remove empty lines, where necessary
- Enclose in-line line numbers for Java code in /*23*/ comments in order
  to enable Java formatting

Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
tags/V1_9_21_1
Alexander Kriegisch 2 years ago
parent
commit
a6a1dbea46
64 changed files with 1479 additions and 1260 deletions
  1. 31
    6
      docs/adk15ProgGuideDB/annotations.adoc
  2. 45
    0
      docs/adk15ProgGuideDB/ataspectj.adoc
  3. 3
    0
      docs/adk15ProgGuideDB/autoboxing.adoc
  4. 4
    0
      docs/adk15ProgGuideDB/covariance.adoc
  5. 1
    0
      docs/adk15ProgGuideDB/enumeratedtypes.adoc
  6. 30
    0
      docs/adk15ProgGuideDB/generics.adoc
  7. 1
    0
      docs/adk15ProgGuideDB/grammar.adoc
  8. 11
    0
      docs/adk15ProgGuideDB/joinpointsignatures.adoc
  9. 3
    0
      docs/adk15ProgGuideDB/miscellaneous.adoc
  10. 4
    0
      docs/adk15ProgGuideDB/pertypewithin.adoc
  11. 8
    0
      docs/adk15ProgGuideDB/varargs.adoc
  12. 1
    0
      docs/devGuideDB/aj.adoc
  13. 1
    1
      docs/devGuideDB/ajbrowser.adoc
  14. 18
    0
      docs/devGuideDB/ajc.adoc
  15. 33
    36
      docs/devGuideDB/ajdb.adoc
  16. 5
    3
      docs/devGuideDB/ajdee.adoc
  17. 1
    0
      docs/devGuideDB/ajdoc.adoc
  18. 15
    1
      docs/devGuideDB/antsupport.adoc
  19. 3
    1
      docs/devGuideDB/aspectj-mode.adoc
  20. 9
    2
      docs/devGuideDB/ltw.adoc
  21. 3
    0
      docs/developer/amcDesignNotes.adoc
  22. 51
    0
      docs/developer/compiler-weaver/index.adoc
  23. 1
    0
      docs/dist/LICENSE-AspectJ.adoc
  24. 226
    220
      docs/dist/doc/README-11.adoc
  25. 95
    106
      docs/dist/doc/README-12.adoc
  26. 12
    11
      docs/dist/doc/README-121.adoc
  27. 5
    6
      docs/dist/doc/README-153.adoc
  28. 13
    6
      docs/dist/doc/README-160.adoc
  29. 3
    6
      docs/dist/doc/README-161.adoc
  30. 1
    0
      docs/dist/doc/README-1610.adoc
  31. 2
    0
      docs/dist/doc/README-1611.adoc
  32. 13
    7
      docs/dist/doc/README-1612.adoc
  33. 16
    23
      docs/dist/doc/README-164.adoc
  34. 24
    26
      docs/dist/doc/README-167.adoc
  35. 18
    20
      docs/dist/doc/README-168.adoc
  36. 15
    20
      docs/dist/doc/README-169.adoc
  37. 38
    31
      docs/dist/doc/README-170.adoc
  38. 2
    0
      docs/dist/doc/README-174.adoc
  39. 3
    2
      docs/dist/doc/README-180.adoc
  40. 12
    19
      docs/dist/doc/README-182.adoc
  41. 4
    0
      docs/dist/doc/README-183.adoc
  42. 5
    10
      docs/dist/doc/README-187.adoc
  43. 24
    14
      docs/dist/doc/README-190.adoc
  44. 1
    0
      docs/dist/doc/README-191.adoc
  45. 6
    3
      docs/dist/doc/README-193.adoc
  46. 5
    2
      docs/dist/doc/README-195.adoc
  47. 9
    6
      docs/dist/doc/README-196.adoc
  48. 3
    3
      docs/dist/doc/changes.adoc
  49. 174
    105
      docs/dist/doc/porting.adoc
  50. 47
    37
      docs/faq/faq.adoc
  51. 1
    1
      docs/pdGuideDB/ajcore.adoc
  52. 3
    0
      docs/pdGuideDB/ltwdump.adoc
  53. 5
    0
      docs/pdGuideDB/messages.adoc
  54. 3
    0
      docs/pdGuideDB/trace.adoc
  55. 89
    42
      docs/progGuideDB/examples.adoc
  56. 35
    7
      docs/progGuideDB/gettingstarted.adoc
  57. 5
    0
      docs/progGuideDB/idioms.adoc
  58. 6
    0
      docs/progGuideDB/implementation.adoc
  59. 79
    36
      docs/progGuideDB/language.adoc
  60. 5
    0
      docs/progGuideDB/pitfalls.adoc
  61. 71
    243
      docs/progGuideDB/quickreference.adoc
  62. 112
    198
      docs/progGuideDB/semantics.adoc
  63. 6
    0
      docs/sandbox/readme-sandbox.adoc
  64. 1
    0
      docs/sandbox/trails/j2ee.adoc

+ 31
- 6
docs/adk15ProgGuideDB/annotations.adoc View File

@@ -19,10 +19,10 @@ program source by using the `@` symbol. For example, the following piece
of code uses the `@Deprecated` annotation to indicate that the
`obsoleteMethod()` has been deprecated:

[source, java]
....
@Deprecated
public void obsoleteMethod() { ... }
....

Annotations may be _marker annotations_, _single-valued annotations_, or
@@ -32,27 +32,27 @@ annotations, as in the deprecation example above. Single-value
annotation types have a single member, and the annotation may be written
in one of two equivalent forms:

[source, java]
....
@SuppressWarnings({"unchecked"})
public void someMethod() {...}
....

or

[source, java]
....
@SuppressWarnings(value={"unchecked"})
public void someMethod() {...}
....

Multi-value annotations must use the `member-name=value
` syntax to specify annotation values. For example:

[source, java]
....
@Authenticated(role="supervisor",clearanceLevel=5)
public void someMethod() {...}
....

==== Retention Policies
@@ -96,6 +96,7 @@ presence or absence of annotations.

By default annotations are _not_ inherited. Given the following program

[source, java]
....
@MyAnnotation
class Super {
@@ -105,7 +106,6 @@ class Super {
class Sub extends Super {
public void foo() {}
}
....

Then `Sub` _does not_ have the `MyAnnotation` annotation, and
@@ -133,6 +133,7 @@ permitted on pointcut declarations or on `declare` statements.

The following example illustrates the use of annotations in aspects:

[source, java]
....
@AspectAnnotation
public abstract aspect ObserverProtocol {
@@ -192,6 +193,7 @@ advice statement by using the
the same way as the Java 5 SuppressWarnings annotation (See JLS
9.6.1.5), but has class file retention.

[source, java]
....
import org.aspectj.lang.annotation.SuppressAjWarnings;

@@ -262,6 +264,7 @@ Some examples of annotation patterns follow:
AspectJ 1.5 extends type patterns to allow an optional
`AnnotationPattern` prefix.

[source, text]
....
TypePattern := SimpleTypePattern |
'!' TypePattern |
@@ -288,9 +291,9 @@ pattern, the parenthesis are required (as in `(@Foo Hello+)`). In some
cases (such as a type pattern used within a `within` or `handler`
pointcut expression), the parenthesis are optional:

[source, text]
....
OptionalParensTypePattern := AnnotationPattern? TypePattern
....

The following examples illustrate the use of annotations in type
@@ -330,6 +333,7 @@ patterns:
A `FieldPattern` can optionally specify an annotation-matching pattern
as the first element:

[source, text]
....
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
@@ -371,6 +375,7 @@ annotations that match the pattern. For example:
A `MethodPattern` can optionally specify an annotation-matching pattern
as the first element.

[source, text]
....
MethodPattern :=
AnnotationPattern? MethodModifiersPattern? TypePattern
@@ -397,6 +402,7 @@ TypePatternList := TypePattern (',' TypePattern)*

A `ConstructorPattern` has the form

[source, text]
....
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
@@ -470,6 +476,7 @@ Like their counterparts, these pointcut designators can be used both for
join point matching, and to expose context. The format of these new
designators is:

[source, text]
....
AtThis := '@this' '(' AnnotationOrIdentifer ')'

@@ -505,6 +512,7 @@ Annotations can be exposed as context in the body of advice by using the
forms of `@this(), @target()` and `@args()` that use bound variables in
the place of annotation names. For example:

[source, java]
....
pointcut callToClassifiedObject(Classified classificationInfo) :
call(* *(..)) && @target(classificationInfo);
@@ -521,6 +529,7 @@ at a given position in an `@args` expression indicates that the runtime
type of the argument in that position at a join point must have an
annotation of the indicated type. For example:

[source, java]
....
/**
* matches any join point with at least one argument, and where the
@@ -544,6 +553,7 @@ available reflectively with the body of advice through the
the arguments, or object bound to this or target at a join point you can
use the following code fragments:

[source, java]
....
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations();
Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations();
@@ -555,6 +565,7 @@ point where the executing code is defined within a type (`@within`), or
a method/constructor (`@withincode`) that has an annotation of the
specified type. The form of these designators is:

[source, text]
....
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
@@ -574,6 +585,7 @@ The `@annotation` pointcut designator matches any join point where the
_subject_ of the join point has an annotation of the given type. Like
the other @pcds, it can also be used for context exposure.

[source, text]
....
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
....
@@ -589,6 +601,7 @@ extended with additional operations that provide access to the
annnotations can be queried. The following fragment illustrates an
example use of this interface to access annotation information.

[source, java]
....
Signature sig = thisJoinPointStaticPart.getSignature();
AnnotatedElement declaringTypeAnnotationInfo = sig.getDeclaringType();
@@ -621,6 +634,7 @@ considered to be an annotation on the parameter type or an annotation on
the parameter itself is determined through the use of parentheses around
the parameter type. Consider the following:

[source, java]
....
@SomeAnnotation
class AnnotatedType {}
@@ -634,6 +648,7 @@ class C {
The method foo has a parameter of an annotated type, and can be matched
by this pointcut:

[source, java]
....
pointcut p(): execution(* *(@SomeAnnotation *));
....
@@ -645,6 +660,7 @@ parameter of any type that has the annotation @SomeAnnotation'.
To match the parameter annotation case, the method goo, this is the
pointcut:

[source, java]
....
pointcut p(): execution(* *(@SomeAnnotation (*)));
....
@@ -657,6 +673,7 @@ annotation of @SomeAnnotation'.
To match when there is a parameter annotation and an annotation on the
type as well:

[source, java]
....
pointcut p(): execution(* *(@SomeAnnotation (@SomeOtherAnnotation *)));
....
@@ -671,6 +688,7 @@ According to the Java 5 specification, non-type annotations are not
inherited, and annotations on types are only inherited if they have the
`@Inherited` meta-annotation. Given the following program:

[source, java]
....
class C1 {
@SomeAnnotation
@@ -714,6 +732,7 @@ actually being called).
The `if` pointcut designator can be used to write pointcuts that match
based on the values annotation members. For example:

[source, java]
....
pointcut txRequiredMethod(Tx transactionAnnotation) :
execution(* *(..)) && @this(transactionAnnotation)
@@ -729,12 +748,14 @@ Since pointcut expressions in AspectJ 5 support join point matching
based on annotations, this facility can be exploited when writing
`declare warning` and `declare error` statements. For example:

[source, java]
....
declare warning : withincode(@PerformanceCritical * *(..)) &&
call(@ExpensiveOperation * *(..))
: "Expensive operation called from within performance critical section";
....

[source, java]
....
declare error : call(* org.xyz.model.*.*(..)) &&
!@within(Trusted)
@@ -745,6 +766,7 @@ declare error : call(* org.xyz.model.*.*(..)) &&

The general form of a `declare parents` statement is:

[source, text]
....
declare parents : TypePattern extends Type;
declare parents : TypePattern implements TypeList;
@@ -774,6 +796,7 @@ issued).

The general form of a declare precedence statement is:

[source, java]
....
declare precedence : TypePatList;
....
@@ -798,6 +821,7 @@ a future release.

The general form is:

[source, text]
....
declare @<kind> : ElementPattern : Annotation ;
....
@@ -809,6 +833,7 @@ specified by the `@Target` annotation.

`ElementPattern` is defined as follows:

[source, text]
....
ElementPattern := TypePattern |
MethodPattern |

+ 45
- 0
docs/adk15ProgGuideDB/ataspectj.adoc View File

@@ -30,6 +30,7 @@ used to declare aspects and aspect members.
Aspect declarations are supported by the
`org.aspectj.lang.annotation.Aspect` annotation. The declaration:

[source, java]
....
@Aspect
public class Foo {}
@@ -37,6 +38,7 @@ public class Foo {}

Is equivalent to:

[source, java]
....
public aspect Foo {}
....
@@ -44,6 +46,7 @@ public aspect Foo {}
To specify an aspect an aspect instantiation model (the default is
singleton), provide the perclause as the `@Aspect` value. For example:

[source, java]
....
@Aspect("perthis(execution(* abc..*(..)))")
public class Foo {}
@@ -51,6 +54,7 @@ public class Foo {}

is equivalent to...

[source, java]
....
public aspect Foo perthis(execution(* abc..*(..))) {}
....
@@ -86,6 +90,7 @@ section.
Here is a simple example of a pointcut declaration in both code and
@AspectJ styles:

[source, java]
....
@Pointcut("call(* *.*(..))")
void anyCall() {}
@@ -93,6 +98,7 @@ void anyCall() {}

is equivalent to...

[source, java]
....
pointcut anyCall() : call(* *.*(..));
....
@@ -100,6 +106,7 @@ pointcut anyCall() : call(* *.*(..));
When binding arguments, simply declare the arguments as normal in the
annotated method:

[source, java]
....
@Pointcut("call(* *.*(int)) && args(i) && target(callee)")
void anyCall(int i, Foo callee) {}
@@ -107,6 +114,7 @@ void anyCall(int i, Foo callee) {}

is equivalent to...

[source, java]
....
pointcut anyCall(int i, Foo callee) : call(* *.*(int)) && args(i) && target(callee);
....
@@ -115,6 +123,7 @@ An example with modifiers (Remember that Java 5 annotations are not
inherited, so the `@Pointcut` annotation must be present on the
extending aspect's pointcut declaration too):

[source, java]
....
@Pointcut("")
protected abstract void anyCall();
@@ -122,6 +131,7 @@ protected abstract void anyCall();

is equivalent to...

[source, java]
....
protected abstract pointcut anyCall();
....
@@ -139,6 +149,7 @@ scope.

Consider the following compilation unit:

[source, java]
....
package org.aspectprogrammer.examples;

@@ -152,6 +163,7 @@ public aspect Foo {

Using the annotation style this would be written as:

[source, java]
....
package org.aspectprogrammer.examples;

@@ -186,6 +198,7 @@ have either an empty body (`if()`, or be one of the expression forms
and return a boolean. The body of the method contains the condition to
be evaluated. For example:

[source, java]
....
@Pointcut("call(* *.*(int)) && args(i) && if()")
public static boolean someCallWithIfTest(int i) {
@@ -195,12 +208,14 @@ public static boolean someCallWithIfTest(int i) {

is equivalent to...

[source, java]
....
pointcut someCallWithIfTest(int i) : call(* *.*(int)) && args(i) && if(i > 0);
....

and the following is also a valid form:

[source, java]
....
static int COUNT = 0;

@@ -260,6 +275,7 @@ method execution join point).
The following example shows a simple before advice declaration in both
styles:

[source, java]
....
@Before("call(* org.aspectprogrammer..*(..)) && this(Foo)")
public void callFromFoo() {
@@ -269,6 +285,7 @@ public void callFromFoo() {

is equivalent to...

[source, java]
....
before() : call(* org.aspectprogrammer..*(..)) && this(Foo) {
System.out.println("Call from Foo");
@@ -278,6 +295,7 @@ before() : call(* org.aspectprogrammer..*(..)) && this(Foo) {
If the advice body needs to know which particular `Foo` instance is
making the call, just add a parameter to the advice declaration.

[source, java]
....
before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) {
System.out.println("Call from Foo: " + foo);
@@ -286,6 +304,7 @@ before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) {

can be written as:

[source, java]
....
@Before("call(* org.aspectprogrammer..*(..)) && this(foo)")
public void callFromFoo(Foo foo) {
@@ -298,6 +317,7 @@ If the advice body needs access to `thisJoinPoint` ,
these need to be declared as additional method parameters when using the
annotation style.

[source, java]
....
@Before("call(* org.aspectprogrammer..*(..)) && this(foo)")
public void callFromFoo(JoinPoint thisJoinPoint, Foo foo) {
@@ -308,6 +328,7 @@ public void callFromFoo(JoinPoint thisJoinPoint, Foo foo) {

is equivalent to...

[source, java]
....
before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) {
System.out.println("Call from Foo: " + foo + " at "
@@ -317,6 +338,7 @@ before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) {

Advice that needs all three variables would be declared:

[source, java]
....
@Before("call(* org.aspectprogrammer..*(..)) && this(Foo)")
public void callFromFoo(JoinPoint thisJoinPoint,
@@ -340,6 +362,7 @@ To expose a return value with after returning advice simply declare the
returning parameter as a parameter in the method body and bind it with
the "returning" attribute:

[source, java]
....
@AfterReturning("criticalOperation()")
public void phew() {
@@ -354,6 +377,7 @@ public void itsAFoo(Foo f) {

is equivalent to...

[source, java]
....
after() returning : criticalOperation() {
System.out.println("phew");
@@ -375,6 +399,7 @@ the design goals for the annotation style is that a large class of
AspectJ applications should be compilable with a standard Java 5
compiler. A straight call to `proceed` inside a method body:

[source, java]
....
@Around("call(* org.aspectprogrammer..*(..))")
public Object doNothing() {
@@ -386,6 +411,7 @@ will result in a "No such method" compilation error. For this reason
AspectJ 5 defines a new sub-interface of `JoinPoint` ,
`ProceedingJoinPoint` .

[source, java]
....
public interface ProceedingJoinPoint extends JoinPoint {
public Object proceed(Object[] args);
@@ -394,6 +420,7 @@ public interface ProceedingJoinPoint extends JoinPoint {

The around advice given above can now be written as:

[source, java]
....
@Around("call(* org.aspectprogrammer..*(..))")
public Object doNothing(ProceedingJoinPoint thisJoinPoint) {
@@ -403,6 +430,7 @@ public Object doNothing(ProceedingJoinPoint thisJoinPoint) {

Here's an example that uses parameters for the proceed call:

[source, java]
....
@Aspect
public class ProceedAspect {
@@ -420,6 +448,7 @@ public class ProceedAspect {

is equivalent to:

[source, java]
....
public aspect ProceedAspect {
pointcut setAge(int i): call(* setAge(..)) && args(i);
@@ -505,6 +534,7 @@ introduce a marker interface.

Consider the following aspect:

[source, java]
....
public aspect MoodIndicator {

@@ -532,6 +562,7 @@ type of the inter-type declaration).

Using the annotation style this aspect can be written:

[source, java]
....
@Aspect
public class MoodIndicator {
@@ -575,6 +606,7 @@ aspect' field of a non-interface type. The interface type is the
inter-type declaration contract that dictates which methods are declared
on the target type.

[source, java]
....
// this type will be affected by the inter-type declaration as the type pattern matches
package org.xyz;
@@ -596,6 +628,7 @@ interface methods.

Consider the following aspect:

[source, java]
....
public aspect SerializableMarker {
declare parents : org.xyz..* implements Serializable;
@@ -604,6 +637,7 @@ public aspect SerializableMarker {

Using the annotation style this aspect can be written:

[source, java]
....
@Aspect
public class SerializableMarker {
@@ -620,6 +654,7 @@ implemented by the target type, an error will be issued during weaving.

Consider the following aspect:

[source, java]
....
public aspect MoodIndicator {

@@ -647,6 +682,7 @@ type of the inter-type declaration).

Using the annotation style this aspect can be written:

[source, java]
....
@Aspect
public class MoodIndicator {
@@ -690,6 +726,7 @@ Exploiting this syntax requires the user to obey the rules of pure Java.
So references to any targeted type as if it were affected by the Mixin
must be made through a cast, like this:

[source, java]
....
// this type will be affected by the inter-type declaration as the type pattern matches
package org.xyz;
@@ -710,6 +747,7 @@ parameter. If it does, then when the factory method is called the
parameter will be the object instance for which a delegate should be
created:

[source, java]
....
@Aspect
public class Foo {
@@ -725,6 +763,7 @@ It is also possible to make the factory method non-static - and in this
case it can then exploit the local state in the surrounding aspect
instance, but this is only supported for singleton aspects:

[source, java]
....
@Aspect
public class Foo {
@@ -743,6 +782,7 @@ necessary. In this example the return type of the method extends
multiple other interfaces and only a couple of them (I and J) should be
mixed into any matching targets:

[source, java]
....
// interfaces is an array of interface classes that should be mixed in
@DeclareMixin(value="org.xyz..*",interfaces={I.class,J.class})
@@ -777,6 +817,7 @@ Declare annotation is also not supported in the 1.5.0 release of AspectJ
Declare precedence _is_ supported. For declare precedence, use the
`@DeclarePrecedence` annotation as in the following example:

[source, java]
....
public aspect SystemArchitecture {
declare precedence : Security*, TransactionSupport, Persistence;
@@ -787,6 +828,7 @@ public aspect SystemArchitecture {

can be written as:

[source, java]
....
@Aspect
@DeclarePrecedence("Security*,org.xyz.TransactionSupport,org.xyz.Persistence")
@@ -806,6 +848,7 @@ issued.
Note that the String must be a literal and not the result of the
invocation of a static method for example.

[source, java]
....
declare warning : call(* javax.sql..*(..)) && !within(org.xyz.daos..*)
: "Only DAOs should be calling JDBC.";
@@ -816,6 +859,7 @@ declare error : execution(* IFoo+.*(..)) && !within(org.foo..*)

can be written as...

[source, java]
....
@DeclareWarning("call(* javax.sql..*(..)) && !within(org.xyz.daos..*)")
static final String aMessage = "Only DAOs should be calling JDBC.";
@@ -844,6 +888,7 @@ compilation error if another part of the program tries to call them.
To provide equivalent support for AspectJ applications compiled with a
standard Java 5 compiler, AspectJ 5 defines the `Aspects` utility class:

[source, java]
....
public class Aspects {


+ 3
- 0
docs/adk15ProgGuideDB/autoboxing.adoc View File

@@ -15,6 +15,7 @@ assignments or method or constructor invocations.

For example:

[source, java]
....
int i = 0;
i = new Integer(5); // auto-unboxing
@@ -28,6 +29,7 @@ Integer i2 = 5; // autoboxing
Most of the pointcut designators match based on signatures, and hence
are unaffected by autoboxing. For example, a call to a method

[source, java]
....
public void foo(Integer i);
....
@@ -52,6 +54,7 @@ single argument of type `Integer` or of type `int`.
Autoboxing and unboxing are also applied when binding pointcut or advice
parameters, for example:

[source, java]
....
pointcut foo(int i) : args(i);


+ 4
- 0
docs/adk15ProgGuideDB/covariance.adoc View File

@@ -6,6 +6,7 @@
Java 5 (and hence AspectJ 5) allows you to narrow the return type in an
overriding method. For example:

[source, java]
....
class A {
public A whoAreYou() {...}
@@ -26,6 +27,7 @@ designators are extended to match against covariant methods.
Given the classes `A` and `B` as defined in the previous section, and
the program fragment

[source, java]
....
A a = new A();
B b = new B();
@@ -35,12 +37,14 @@ b.whoAreYou();

The signatures for the call join point `a.whoAreYou()` are simply:

[source, java]
....
A A.whoAreYou()
....

The signatures for the call join point `b.whoAreYou()` are:

[source, java]
....
A A.whoAreYou()
B B.whoAreYou()

+ 1
- 0
docs/adk15ProgGuideDB/enumeratedtypes.adoc View File

@@ -8,6 +8,7 @@ Java 5 (and hence AspectJ 5) provides explicit support for enumerated
types. In the simplest case, you can declare an enumerated type as
follows:

[source, java]
....
public enum ProgrammingLanguages {
COBOL, C, JAVA, ASPECTJ

+ 30
- 0
docs/adk15ProgGuideDB/generics.adoc View File

@@ -15,6 +15,7 @@ the type name. By convention formal type parameters are named using a
single letter, though this is not required. A simple generic list type
(that can contain elements of any type `E`) could be declared:

[source, java]
....
interface List<E> {
Iterator<E> iterator();
@@ -63,6 +64,7 @@ parameterized type by specifying a concrete type specfication for each
type parameter in the generic type. The following example declares a
list of strings and a list of numbers:

[source, java]
....
List<String> strings;
List<Number> numbers;
@@ -78,6 +80,7 @@ written in the Java 5 language would not be expected to use raw types.
Parameterized types are instantiated by specifying type parameter values
in the constructor call expression as in the following examples:

[source, java]
....
List<String> strings = new MyListImpl<String>();
List<Number> numbers = new MyListImpl<Number>();
@@ -135,6 +138,7 @@ The supertype of a generic type `C` is the type given in the extends
clause of `C`, or `Object` if no extends clause is present. Given the
type declaration

[source, java]
....
public interface List<E> extends Collection<E> {... }
....
@@ -164,6 +168,7 @@ type `List<? extends Number>`.
A static method may be declared with one or more type parameters as in
the following declaration:

[source, java]
....
static <T> T first(List<T> ts) { ... }
....
@@ -174,6 +179,7 @@ not need to be declared as a type parameter of the enclosing type.
Non-static methods may also be declared with one or more type parameters
in a similar fashion:

[source, java]
....
<T extends Number> T max(T t1, T t2) { ... }
....
@@ -215,6 +221,7 @@ generic type.
Generic methods and constructors, and members defined in generic types,
may use type variables as part of their signature. For example:

[source, java]
....
public class Utils {

@@ -334,6 +341,7 @@ types (methods) and field types (fields). This is achieved by specifying
a parameterized type pattern at the appropriate point in the signature
pattern. For example, given the class `Foo`:

[source, java]
....
public class Foo {

@@ -376,6 +384,7 @@ expression `call(* addStrings(List))` and by the expression
Remember that any type variable reference in a generic member is
_always_ matched by its erasure. Thus given the following example:

[source, java]
....
class G<T> {
List<T> foo(List<String> ls) { return null; }
@@ -396,6 +405,7 @@ different type to `List<String>`, even though a variable of type
`List<String>` can be assigned to a variable of type `List<?>`. Given
the methods:

[source, java]
....
class C {
public void foo(List<? extends Number> listOfSomeNumberType) {}
@@ -423,6 +433,7 @@ Under certain circumstances a Java 5 compiler is required to create
_bridge methods_ that support the compilation of programs using raw
types. Consider the types

[source, java]
....
class Generic<T> {
public T foo(T someObject) {
@@ -445,6 +456,7 @@ in `Generic`. This is an example of a case where a Java 5 compiler will
create a _bridge method_ in `SubGeneric`. Although you never see it, the
bridge method will look something like this:

[source, java]
....
public Object foo(Object arg) {
Number n = (Number) arg; // "bridge" to the signature defined in this type
@@ -464,6 +476,7 @@ It _is_ possible to _call_ a bridge method as the following short code
snippet demonstrates. Such a call _does_ result in a call join point for
the call to the method.

[source, java]
....
SubGeneric rawType = new SubGeneric();
rawType.foo("hi"); // call to bridge method (will result in a runtime failure in this case)
@@ -483,6 +496,7 @@ types with the `this()` and `target()` pointcuts. Parameterized types
may however be used in conjunction with `args()`. Consider the following
class

[source, java]
....
public class C {
public void foo(List<String> listOfStrings) {}
@@ -513,6 +527,7 @@ args(List<Double>)::
instance of List at join point method-execution(void C.goo(List<?
extends Number>)) [Xlint:uncheckedArgument]";

[source, java]
....
public aspect A {
before(List<Double> listOfDoubles) : execution(* C.*(..)) && args(listOfDoubles) {
@@ -533,6 +548,7 @@ pointcut associated with the advice will be suppressed. To suppress just
an `uncheckedArgument` warning, use the annotation
`@SuppressWarnings("uncheckedArgument")` as in the following examples:

[source, java]
....
import org.aspectj.lang.annotation.SuppressAjWarnings
public aspect A {
@@ -560,6 +576,7 @@ following example the advice will match the execution of `bar` but not
of `goo` since the signature of `goo` is not matched by the execution
pointcut expression.

[source, java]
....
public aspect A {
before(List<Double> listOfDoubles) : execution(* C.*(List<Double>)) && args(listOfDoubles) {
@@ -580,6 +597,7 @@ an `uncheckedArgument` warning.

Consider the following program:

[source, java]
....
public class C {
public static void main(String[] args) {
@@ -622,6 +640,7 @@ to a method declared to take a `List<? extends Number>`,
matching to only those join points at which the argument is guaranteed
to be an instance of `List<? extends Number>`.

[source, java]
....
aspect A {
before(List<? extends Number> aListOfSomeNumberType)
@@ -641,6 +660,7 @@ described for args. For example, the following aspect matches the
execution of any method returning a `List`, and makes the returned list
available to the body of the advice.

[source, java]
....
public aspect A {
pointcut executionOfAnyMethodReturningAList() : execution(List *(..));
@@ -661,6 +681,7 @@ we only perform safe operations on the list.

Given the class

[source, java]
....
public class C {
public List<String> foo(List<String> listOfStrings) {...}
@@ -676,6 +697,7 @@ bind the return value. It will also run after the execution of `goo` and
bind the return value, but gives an `uncheckedArgument` warning during
compilation. It does _not_ run after the execution of `foo`.

[source, java]
....
public aspect Returning {
after() returning(List<Double> listOfDoubles) : execution(* C.*(..)) {
@@ -701,6 +723,7 @@ reference, and not a raw type reference.

Consider the generic type `Generic` with a pointcut `foo`:

[source, java]
....
public class Generic<T> {
/**
@@ -713,6 +736,7 @@ public class Generic<T> {
Such a pointcut must be refered to using a parameterized reference as
shown below.

[source, java]
....
public aspect A {
// runs before the execution of any implementation of a method defined for MyClass
@@ -813,6 +837,7 @@ permitted in this parameterization.

Given the aspect declaration:

[source, java]
....
public abstract aspect ParentChildRelationship<P,C> {
...
@@ -843,6 +868,7 @@ within inter-type declarations_. For example, we can declare a
`ParentChildRelationship` aspect to manage the bi-directional
relationship between parent and child nodes as follows:

[source, java]
....
/**
* a generic aspect, we've used descriptive role names for the type variables
@@ -939,6 +965,7 @@ parent and child. In a compiler implementation managing an abstract
syntax tree (AST) in which AST nodes may contain other AST nodes we
could declare the concrete aspect:

[source, java]
....
public aspect ASTNodeContainment extends ParentChildRelationship<ASTNode,ASTNode> {
before(ASTNode parent, ASTNode child) : addingChild(parent, child) {
@@ -965,6 +992,7 @@ void setParent(ASTNode parent)

In a system managing orders, we could declare the concrete aspect:

[source, java]
....
public aspect OrderItemsInOrders extends ParentChildRelationship<Order, OrderItem> {
}
@@ -991,6 +1019,7 @@ void setParent(Order parent)
A second example of an abstract aspect, this time for handling
exceptions in a uniform manner, is shown below:

[source, java]
....
abstract aspect ExceptionHandling<T extends Throwable> {

@@ -1024,6 +1053,7 @@ of the aspect to be designed to work together in a type-safe manner. The
following concrete sub-aspect shows how the abstract aspect might be
extended to handle `IOExceptions`.

[source, java]
....
public aspect IOExceptionHandling extends ExceptionHandling<IOException>{


+ 1
- 0
docs/adk15ProgGuideDB/grammar.adoc View File

@@ -1,6 +1,7 @@
[[grammar]]
== A Grammar for the AspectJ 5 Language

[source, text]
....
=== type patterns ===


+ 11
- 0
docs/adk15ProgGuideDB/joinpointsignatures.adoc View File

@@ -25,6 +25,7 @@ A kinded pointcut is written using patterns, some of which match based
on _signature_, and some of which match based on _modifiers_. For
example, in the `call` pointcut designator:

[source, text]
....
call(ModifierPattern TypePattern TypePattern.IdPattern(TypePatternList) ThrowsPattern)
....
@@ -96,6 +97,7 @@ For a call join point where a call is made to a method
`m(parameter_types)` on a target type `T` (where `T` is the static type
of the target):

[source, java]
....
T t = new T();
t.m("hello"); <= call join point occurs when this line is executed
@@ -108,6 +110,7 @@ declare a definition of `m(parameter_types)`, then `R(T)` is the return
type in the definition of `m` that `T` inherits. Given the call above,
and the definition of `T.m`:

[source, java]
....
interface Q {
R m(String s);
@@ -135,6 +138,7 @@ signature of the call join point, where `R(A)` is the return type of `

Continuing the example from above,we can deduce that

[source, java]
....
R' S.m(String)
R P.m(String)
@@ -151,6 +155,7 @@ different declaring type.
Join point signatures for execution join points are defined in a similar
manner to signatures for call join points. Given the hierarchy:

[source, java]
....
interface Q {
R m(String s);
@@ -174,6 +179,7 @@ class U extends T {
Then the execution join point signatures arising as a result of the call
to `u.m("hello")` are:

[source, java]
....
R' U.m(String)
R' S.m(String)
@@ -198,6 +204,7 @@ If `T` does not directly declare a member `f`, then for each super type
does declare the member `f`, `F S.f` is a signature of the join point.
For example, given the hierarchy:

[source, java]
....
class P {
F f;
@@ -213,6 +220,7 @@ class T extends S { }
Then the join point signatures for a field get join point of the field
`f` on an object with declared type `T` are:

[source, java]
....
F S.f
F T.f
@@ -263,6 +271,7 @@ chain.

For example, given the following types

[source, java]
....
public class X {
@Foo
@@ -293,6 +302,7 @@ point

Given the hierarchy

[source, java]
....
interface Q {
R m(String s);
@@ -313,6 +323,7 @@ class T extends S {}

and the program fragment:

[source, java]
....
P p = new P();
S s = new S();

+ 3
- 0
docs/adk15ProgGuideDB/miscellaneous.adoc View File

@@ -8,6 +8,7 @@ AspectJ 5 is more liberal than AspectJ 1.2.1 in accepting pointcut
expressions that bind context variables in more than one location. For
example, AspectJ 1.2.1 does not allow:

[source, java]
....
pointcut foo(Foo foo) : (execution(* *(..)) && this(foo) ) ||
(set(* *) && target(foo));
@@ -28,6 +29,7 @@ exceptions. If the exception type specified in a declare soft statement
is `RuntimeException` or a subtype of `RuntimeException` then a new
XLint warning will be issued:

[source, java]
....
declare soft : SomeRuntimeException : execution(* *(..));

@@ -43,6 +45,7 @@ _checked_ exception thrown at a matched join point, where the exception
is an instance of the softened exception, will be softened to an
`org.aspectj.lang.SoftException`.

[source, java]
....
public aspect SoftenExample {
declare soft : Exception : execution(* Foo.*(..));

+ 4
- 0
docs/adk15ProgGuideDB/pertypewithin.adoc View File

@@ -5,6 +5,7 @@ AspectJ 5 defines a new per-clause type for aspect instantiation:
`pertypewithin`. Unlike the other per-clauses, `pertypewithin` takes a
type pattern:

[source, text]
....
PerTypeWithin := 'pertypewithin' '(' OptionalParensTypePattern ')'
....
@@ -16,6 +17,7 @@ the associated type pattern.
Pertypewithin aspects have `aspectOf` and `hasAspect` methods with the
following signatures:

[source, java]
....
/**
* return true if this aspect has an instance associated with
@@ -37,6 +39,7 @@ In addition, `pertypewithin` aspects have a `getWithinTypeName` method
that can be called to return the package qualified name of the type for
which the aspect instance has been created.

[source, java]
....
/**
* return the package qualified name (eg. com.foo.MyClass) of the type
@@ -51,6 +54,7 @@ upon an implicit pointcut condition. In this case, that any join point
be `within` the type that the executing aspect is an `aspectOf`. For
example, given the aspect definition

[source, java]
....
import java.util.*;


+ 8
- 0
docs/adk15ProgGuideDB/varargs.adoc View File

@@ -7,6 +7,7 @@ Java 5 (and hence AspectJ 5) allows you to specify methods that take a
variable number of arguments of a specified type. This is achieved using
an ellipsis (...) in the method signature as shown:

[source, java]
....
public void foo(int i, String... strings) {
}
@@ -21,6 +22,7 @@ A _varargs_ method may be called with zero or more arguments in the
variable argument position. For example, given the definition of `foo`
above, the following calls are all legal:

[source, java]
....
foo(5);
foo(5,"One String");
@@ -31,6 +33,7 @@ foo(3,"One String","Two Strings","Three Strings");
A _varargs_ parameter is treated as an array within the defining member.
So in the body of `foo` we could write for example:

[source, java]
....
public void foo(int i, String... strings) {
String[] someStrings = strings;
@@ -41,6 +44,7 @@ public void foo(int i, String... strings) {
One consequence of this treatment of a varargs parameter as an array is
that you can also call a varargs method with an array:

[source, java]
....
foo(7,new String[] {"One String","Two Strings"});
....
@@ -63,6 +67,7 @@ annotations (xref:annotations.adoc#signaturePatterns[Signature Patterns]), that
`ConstructorPattern` are extended to allow a `varargs` pattern in the
last argument position of a method or constructor signature.

[source, text]
....
FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? |
OptionalParensTypePattern (',' FormalsPattern)* |
@@ -93,6 +98,7 @@ initialization(org.xyz.*.new((Foo || Goo)...))::
A variable argument parameter and an array parameter are treated as
distinct signature elements, so given the method definitions:

[source, java]
....
void foo(String...);
void bar(String[]);
@@ -110,6 +116,7 @@ array type, as discussed in the introduction to this section. We follow
the same convention when binding a varargs parameter via the `args`
pointcut designator. Given a method

[source, java]
....
public void foo(int i, String... strings) {
}
@@ -123,6 +130,7 @@ syntax within an args pointcut designator - so you _cannot_ write
Binding of a varargs parameter in an advice statement is
straightforward:

[source, java]
....
before(int i, String[] ss) : call(* foo(int,String...)) && args(i,ss) {
// varargs String... argument is accessible in advice body through ss

+ 1
- 0
docs/devGuideDB/aj.adoc View File

@@ -27,6 +27,7 @@ xref:ltw.adoc#ltw[Load-Time Weaving].

Use ajc to build a library, then weave at load time

[source, text]
....
REM compile library
${ASPECTJ_HOME}\bin\ajc.bat -outjar lib\aspects.jar @aspects.lst

+ 1
- 1
docs/devGuideDB/ajbrowser.adoc View File

@@ -17,9 +17,9 @@ invoke the script in `{aspectj}/bin` (if AspectJ is installed correctly)
or by using the `aspectjtools.jar` directly, and specifying no arguments
or some number of build configuration files (suffix `.lst`):

[source, text]
....
java -jar aspectj1.1/lib/aspectjtools.jar aspectj1.1/doc/examples/spacewar/debug.lst

....

[[ajbrowser-building]]

+ 18
- 0
docs/devGuideDB/ajc.adoc View File

@@ -146,6 +146,7 @@ destination directory on the inpath and rebuild.)
Emit warnings for any instances of the comma-delimited list of
questionable code (eg '-warn:unusedLocals,deprecation'):
+
[source, text]
....
constructorName method with constructor name
packageDefaultMethod attempt to override package-default method
@@ -168,6 +169,7 @@ none suppress all compiler warnings
-g<:[lines,vars,source]>::
debug attributes level, that may take three forms:
+
[source, text]
....
-g all debug info ('-g:lines,vars,source')
-g:none no debug info
@@ -261,6 +263,7 @@ previous releases of AspectJ, see xref:compatibility.adoc#versionCompatibility[V

Compile two files:

[source, text]
....
ajc HelloWorld.java Trace.java
....
@@ -271,6 +274,7 @@ relative to the argfile, and may include other argfiles by @-reference.
The following file `sources.lst` contains absolute and relative files
and @-references:

[source, text]
....
Gui.java
/home/user/src/Library.java
@@ -283,6 +287,7 @@ view/body/ArrayView.java

Compile the files using either the -argfile or @ form:

[source, text]
....
ajc -argfile sources.lst
ajc @sources.lst
@@ -317,6 +322,7 @@ sources with the aspect library.
The tracing example is in the AspectJ distribution
(\{aspectj}/doc/examples/tracing). This uses the following files:

[source, text]
....
aspectj1.1/
bin/
@@ -346,6 +352,7 @@ environment as needed.

Setup the path, classpath, and current directory:

[source, text]
....
cd examples
export ajrt=../lib/aspectjrt.jar
@@ -355,18 +362,21 @@ export PATH="../bin:$PATH"

Build a read-only tracing library:

[source, text]
....
ajc -argfile tracing/tracelib.lst -outjar tracelib.jar
....

Build the application with tracing in one step:

[source, text]
....
ajc -aspectpath tracelib.jar -argfile tracing/notrace.lst -outjar tracedapp.jar
....

Run the application with tracing:

[source, text]
....
java -classpath "$ajrt;tracedapp.jar;tracelib.jar" tracing.ExampleMain
....
@@ -376,6 +386,7 @@ Build the application with tracing from binaries in two steps:
* (a) Build the application classes (using javac for
demonstration's sake):
+
[source, text]
....
mkdir classes
javac -d classes tracing/*.java
@@ -383,18 +394,21 @@ jar cfM app.jar -C classes .
....
* (b) Build the application with tracing:
+
[source, text]
....
ajc -inpath app.jar -aspectpath tracelib.jar -outjar tracedapp.jar
....

Run the application with tracing (same as above):

[source, text]
....
java -classpath "$ajrt;tracedapp.jar;tracelib.jar" tracing.ExampleMain
....

Run the application without tracing:

[source, text]
....
java -classpath "app.jar" tracing.ExampleMain
....
@@ -418,6 +432,7 @@ to collect the messages, use `MessageHandler` as your `IMessageHolder`.
For example, compile and run the following with `aspectjtools.jar` on
the classpath:

[source, java]
....
import org.aspectj.bridge.*;
import org.aspectj.tools.ajc.Main;
@@ -454,6 +469,7 @@ the -XnoInline option.)
Probably the only time you may see this format is when you view stack
traces, where you may encounter traces of the format

[source, text]
....
java.lang.NullPointerException
at Main.new$constructor_call37(Main.java;SynchAspect.java[1k]:1030)
@@ -461,12 +477,14 @@ java.lang.NullPointerException

where instead of the usual

[source, text]
....
File:LineNumber
....

format, you see

[source, text]
....
File0;File1[Number1];File2[Number2] ... :LineNumber
....

+ 33
- 36
docs/devGuideDB/ajdb.adoc View File

@@ -133,7 +133,7 @@ Pass a non-standard option to the VM

=== Capabilities

The AspectJ debugger implements all of `jdb`'s commands. In addition,
The AspectJ debugger implements all of ``jdb``'s commands. In addition,
the command `workingdir` allow you to set the AspectJ working directory,
and the breakpoint command, `stop on`, has been extended to allow the
setting of breakpoint on a source file line.
@@ -158,25 +158,25 @@ For this example, we need to set the source path by: `
To view the file to debug, type `list
spacewar/Ship.java` which generates the following output:

[source, java]
....
209 void fire() {
210 // firing a shot takes energy
211 if (!expendEnergy(BULLET_ENERGY))
212 return;
213
214 //create a bullet object so it doesn't hit the ship that's firing it
215 double xV = getXVel() + BULLET_SPEED * (Math.cos(orientation));
216 double yV = getYVel() + BULLET_SPEED * (Math.sin(orientation));
217
218 // create the actual bullet
219 new Bullet(
220 getGame(),
221 (getXPos() + ((getSize()/2 + 2) * (Math.cos(orientation))) + xV),
222 (getYPos() + ((getSize()/2 + 2) * (Math.sin(orientation))) + yV),
223 xV,
224 yV);
225 }
/*209*/ void fire() {
/*210*/ // firing a shot takes energy
/*211*/ if (!expendEnergy(BULLET_ENERGY))
/*212*/ return;
/*213*/
/*214*/ //create a bullet object so it doesn't hit the ship that's firing it
/*215*/ double xV = getXVel() + BULLET_SPEED * (Math.cos(orientation));
/*216*/ double yV = getYVel() + BULLET_SPEED * (Math.sin(orientation));
/*217*/
/*218*/ // create the actual bullet
/*219*/ new Bullet(
/*220*/ getGame(),
/*221*/ (getXPos() + ((getSize()/2 + 2) * (Math.cos(orientation))) + xV),
/*222*/ (getYPos() + ((getSize()/2 + 2) * (Math.sin(orientation))) + yV),
/*223*/ xV,
/*224*/ yV);
/*225*/ }
....

This is different from `jdb` because it allows one to view files before
@@ -222,88 +222,88 @@ The following message appears notifying the user that the breakpoint has
been noted but will not be set until the class has been loaded by the
VM:

[source, text]
....
Deferring breakpoint spacewar.Ship.fire()
It will be set after the class is loaded.
....

To start Spacewar we type `run spacewar.Game`.

When the breakpoint is set, the following message appears:

[source, text]
....
Set deferred breakpoint spacewar.Ship.fire()
....

We are notified that we've hit the breakpoint:

[source, text]
....
Breakpoint hit: thread="Thread-2", spacewar.Ship.fire(), line=174, bci=0 209 void fire() {
....

The prompt changes to present the thread that has broken, and we can
view the current stack with the `where` command, as follows:

[source, text]
....
Thread-2[1] where
[1] fire (spacewar\Ship.java:209)
[2] run (spacewar\Robot.java:100)
[3] run [class java.lang.Thread]
....

Next, to stop on line 216 we type `stop on spacewar/Ship.java:216`

The following message tells us the breakpoint was set:

[source, text]
....
Set breakpoint Ship.java:216
....

To continue execution, we type `cont` and the breakpoint at line 216 is
hit

[source, text]
....
Breakpoint hit: thread="Thread-2", spacewar.Ship.fire(), line=216, bci=28
216 double yV = getYVel() + BULLET_SPEED * (Math.sin(orientation));
....

To view the visible local variables, we type `locals` and ajdb responds
with:

[source, text]
....
Local variables
xV = 12.242462584304468
....

To change the value of the local variable i to 15, we type
`set xV = 16.1`

[source, text]
....
Changed 'xV' from '12.242462584304468' to '16.1'
....

To see our changes we can print the value of `i` by the following:

[source, text]
....
print xV
Value for printing 'xV' = 12.242462584304468
....

We can now type exit or quit to leave the debugger, and we receive the
following message:

[source, text]
....
The application has exited.
....

=== The AspectJ debugger API
@@ -314,13 +314,10 @@ the method `org.aspectj.tools.debugger.Main.main(String[]
args)` where `args` are the standard `ajc` command line arguments.
This means that an alternative way to run the compiler is

java org.aspectj.tools.debugger.Main

option

class

arguments
[source, text]
....
java org.aspectj.tools.debugger.Main options class arguments
....

You must additionally include `tools.jar` from your Java developer's kit
in your classpath.

+ 5
- 3
docs/devGuideDB/ajdee.adoc View File

@@ -123,6 +123,7 @@ enable AspectJ mode on a per-project basis.
your `load-path` and are ``required''. This is an example for the 1.0
release:
+
[source, text]
....
;; I keep my emacs packages in C:/Emacs
(setq load-path
@@ -140,7 +141,6 @@ load-path))

(require 'jde)
(require 'ajdee) ; can also appear in prj.el

....
. _[Optional]_ add `-emacssym` switch to the `ajc` and `ajc.bat` files
in your AspectJ tools installations (in the `/bin` directory). If you
@@ -152,6 +152,7 @@ following in your `.emacs` file or in a JDE project file `prj.el` in
your project's hierarchy (see the `JDE Project File Name` option for the
latter). Here is a simple example:
+
[source, text]
....
;; A default version for simple projects, maybe good for
;;; .emacs file.
@@ -161,11 +162,11 @@ latter). Here is a simple example:

;; ajc requires all files to be named for a compile
'(aspectj-compile-file-specification "*.java"))

....
+
Here is an example for spacewar, in `examples/spacewar`.
+
[source, text]
....
;;; These options are for the spacewar, in examples/spacewar.
(custom-set-variables
@@ -180,7 +181,6 @@ Here is an example for spacewar, in `examples/spacewar`.
'(jde-compile-option-directory "..")
'(jde-run-working-directory ".."))
'(jde-run-application-class "spacewar.Game")

....
. _[XEmacs only]_ If you're installing JDE yourself, be sure to closely
follow the JDE installation directions for XEmacs, otherwise you may get
@@ -207,6 +207,7 @@ for problems not specific to AJDEE's features.
* _Symptom_: Get standard speedbar menus in JDE; no annotations display.
Message:
+
[source, text]
....
AspectJ Mode Warning: Can't find declarations file for...
....
@@ -235,6 +236,7 @@ AspectJ project's directory (see sample.prj in the distribution).
* _Symptom_: Reported bug fixes and new features to AJDEE are not seen,
or ajdee.el cannot be found or loaded, with message:
+
[source, text]
....
Error in init file: File error: "Cannot open load file", "ajdee"
....

+ 1
- 0
docs/devGuideDB/ajdoc.adoc View File

@@ -34,6 +34,7 @@ argfile (`@filename`) conventions as with `ajc`. For example, the
following documents all the source files listed in `argfile.lst`,
sending the output to the `docDir` output directory.

[source, text]
....
ajdoc -d docDir @argfile.lst
....

+ 15
- 1
docs/devGuideDB/antsupport.adoc View File

@@ -38,6 +38,7 @@ in `${ANT_HOME}/lib` where it will be added to the system class path by
the ant script. You may specify the task script names directly, or use
the "resource" attribute to specify the default names:

[source, xml]
....
<taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"/>
....
@@ -50,6 +51,7 @@ In Ant 1.6, third-party tasks are declared in their own namespace using
spacewar example, if you put the script in the examples directory and
`aspectjtools.jar` in the `${ANT_HOME}/lib` directory.

[source, xml]
....
<project name="aspectj-ant1.6" default="spacewar"
xmlns:aspectj="antlib:org.aspectj" basedir=".">
@@ -340,6 +342,7 @@ elements; these are `sourceroots`, `argfiles`, `injars`, `inpath`,
`classpath`, `bootclasspath`, `forkclasspath`, and `aspectpath`. In all
cases, these may be specified as nested elements, something like this:

[source, xml]
....
<iajc {attributes..} />
<{name}>
@@ -354,6 +357,7 @@ cases, these may be specified as nested elements, something like this:
As with other Path-like structures, they may be defined elsewhere and
specified using the refid attribute:

[source, xml]
....
<path id="aspect.path">
<pathelement path="${home}/lib/persist.jar"/>
@@ -369,6 +373,7 @@ specified using the refid attribute:
The task also supports an attribute `{name}ref` for each such parameter.
E.g., for `aspectpath`:

[source, xml]
....
<iajc {attributes..} aspectpathref="aspect.path"/>
....
@@ -379,6 +384,7 @@ E.g., for `aspectpath`:
A minimal build script defines the task and runs it, specifying the
sources:

[source, xml]
....
<project name="simple-example" default="compile" >
<taskdef
@@ -410,6 +416,7 @@ When this target is built, the compiler will build once and then wait
for input from the user. Messages are printed as usual. When the user
has quit, then this runs the application.

[source, xml]
....
<target name="build-test" >
<iajc outjar="${home.dir}/output/application.jar"
@@ -453,6 +460,7 @@ case where no files have been updated, there is no reason to recompile
sources. One way to implement that is with an explicit dependency check
using the uptodate task:

[source, xml]
....
<target name="check.aspects.jar">
<uptodate property="build.unnecessary"
@@ -512,6 +520,7 @@ example, the call below passes all out-of-date source files in the
`src/org/aspectj` subdirectories to the `ajc` command along with the
destination directory:

[source, text]
....
-- command:

@@ -525,6 +534,7 @@ destination directory:

To pass ajc-specific arguments, use a compilerarg entry.

[source, text]
....
-- command

@@ -598,6 +608,7 @@ This tells the compiler adapter to delete all .class files in the
destination directory and re-execute the javac task so javac can
recalculate the list of source files. e.g.,
+
[source, text]
....
Ant -Dbuild.compiler=org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter
-Dbuild.compiler.clean=anything ...
@@ -746,7 +757,7 @@ This task forms an implicit FileSet and supports all attributes of
`<exclude>`, and `<patternset>` elements. These can be used to specify
source files.

`ajc`'s `srcdir`, `classpath`, `bootclasspath`, `extdirs`, and `jvmarg`
``ajc``'s `srcdir`, `classpath`, `bootclasspath`, `extdirs`, and `jvmarg`
attributes are path-like structures and can also be set via nested
`<src>`, `<classpath>`, `<bootclasspath>`, `<extdirs>`, and `<jvmargs>`
elements, respectively.
@@ -758,6 +769,7 @@ Following is a declaration for the ajc task and a sample invocation that
uses the ajc compiler to compile the files listed in `default.lst` into
the dest dir:

[source, xml]
....
<project name="example" default="compile" >
<taskdef name="ajc"
@@ -782,6 +794,7 @@ the dest dir:

This build script snippet

[source, xml]
....
<ajc srcdir="${src}"
destdir="${build}"
@@ -796,6 +809,7 @@ are included.

This next example

[source, xml]
....
<ajc srcdir="${src}"
destdir="${build}"

+ 3
- 1
docs/devGuideDB/aspectj-mode.adoc View File

@@ -103,11 +103,11 @@ initialization file `sample.emacs` in the distribution.
. The files in this package need to be in the load-path and
``required''. For example, for the 1.0 release:
+
[source, text]
....
;; I keep my emacs packages in C:/Emacs
(setq load-path (cons "C:/Emacs/aspectj-emacsMode-1.0" load-path))
(require 'aspectj-mode)

....
. _[Optional]_ add `-emacssym` switch to the `ajc` and `ajc.bat` files
in your AspectJ tools installations (in the `/bin` directory). If you
@@ -130,6 +130,7 @@ given in the file `sample.emacs` in the distribution.

* _Symptom_: No annotations show. Message:
+
[source, text]
....
AspectJ Mode Warning: Can't find declarations file for...
....
@@ -160,6 +161,7 @@ menu.
* _Symptom_: Reported bug fixes and new features to aspectj-mode are not
seen, or aspectj-mode.el cannot be found or loaded, with message:
+
[source, text]
....
Error in init file: File error: "Cannot open load file", "aspectj-mode"
....

+ 9
- 2
docs/devGuideDB/ltw.adoc View File

@@ -125,6 +125,7 @@ Aspects defined in this way must extend an abstract aspect visible to
the weaver. The abstract aspect may define abstract pointcuts (but not
abstract methods). The following example shows a simple aop.xml file:

[source, xml]
....
<aspectj>

@@ -260,6 +261,7 @@ pointcuts at deployment time, and also gives control over precedence
through the `precedence` attribute of the `concrete-aspect` XML element.
Consider the following:

[source, java]
....
package mypack;

@@ -272,13 +274,14 @@ public abstract class AbstractAspect {

@Before("scope() && execution(* *..doSome(..))")
public void before(JoinPoint jp) {
....
// ...
}
}
....

This aspect is equivalent to the following in code style:

[source, java]
....
package mypack;

@@ -288,7 +291,7 @@ public abstract aspect AbstractAspect {
abstract pointcut scope();

before() : scope() && execution(* *..doSome(..)) {
....
// ...
}
}
....
@@ -318,6 +321,7 @@ If more complex aspect inheritance is required use regular aspect
inheritance instead of XML. The following XML definition shows a valid
concrete sub-aspect for the abstract aspects above:

[source, xml]
....
<aspectj>
<aspects>
@@ -339,6 +343,7 @@ aspect instance(s) (depending on the perclause of the aspect it extends)
you have to use the helper API `org.aspectj.lang.Aspects.aspectOf(..)`
as in:

[source, java]
....
// exception handling omitted
Class myConcreteAspectClass = Class.forName("mypack.__My__AbstractAspect");
@@ -359,6 +364,7 @@ abstract aspect. It is therefore possible to use the `concrete-aspect`
element without the `extends` attribute and without any `pointcut`
nested elements, just a `precedence` attribute. Consider the following:

[source, xml]
....
<aspectj>
<aspects>
@@ -459,6 +465,7 @@ weaving configuration files.
When using Java 5 the JVMTI agent can be used by starting the JVM with
the following option (adapt according to the path to aspectjweaver.jar):

[source, text]
....
-javaagent:pathto/aspectjweaver.jar
....

+ 3
- 0
docs/developer/amcDesignNotes.adoc View File

@@ -4,6 +4,7 @@ _Last updated: 2004-03-15 by acolyer_

== How Compilation Progresses in the JDT

[source, text]
....
Compiler.compile(ICompilationUnit[] sourceUnits) {

@@ -35,6 +36,7 @@ passed to the compiler, and the code generation phase is optional

== How (batch) Compilation Progresses in AspectJ 1.1.x

[source, text]
....
AjBuildManager.doBuild() {

@@ -90,6 +92,7 @@ that do different things).
This simple model ignores aspectpath, inpath, injars, outjar,
sourceDirs for now.

[source, text]
....
Compiler.compile(ICompilationUnit[] sourceUnits) {


+ 51
- 0
docs/developer/compiler-weaver/index.adoc View File

@@ -65,6 +65,7 @@ code generation

Let's trace the following example program through the compiler.

[source, java]
....
package example.parse.tree;

@@ -99,6 +100,7 @@ image:top-tree.gif[image]

Let's look more closely at the pointcut declaration:

[source, java]
....
pointcut entries(Main o): execution(void doit()) && this(o);
....
@@ -114,6 +116,7 @@ information might be needed to implement a declare soft.

Next we look at the processing for an advice declaration:

[source, java]
....
before(Main o): entries(o) {
o.counter++;
@@ -262,6 +265,7 @@ failures, resolve them with the AspectJ developers before moving on.

{empty}a. Create a new file in tests/design/pcds/Throw.java

[source, java]
....
import org.aspectj.testing.Tester;

@@ -290,6 +294,7 @@ aspect A {
{empty}b. Create a temporary test harness file to run just this test in
myTests.xml

[source, xml]
....
<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd">
<suite>
@@ -303,6 +308,7 @@ myTests.xml

{empty}c. Run this test using the harness. You should see:

[source, text]
....
about to execute: execution(void Throws.willThrow())
about to execute: call(java.lang.RuntimeException(String))
@@ -314,6 +320,7 @@ PASS Suite.Spec(c:\aspectj\eclipse\tests) 1 tests (1 passed) 2 seconds
Modify runtime/org.aspectj.lang/JoinPoint.java to add a name for the
Throw shadow kind.

[source, java]
....
static String THROW = "throw";
....
@@ -328,6 +335,7 @@ This is because the throw bytecode in Java operates on a single argument
that is a Throwable which must be the top element on the stack. This
argument is removed from the stack by the bytecode.

[source, java]
....
public static final Kind Throw = new Kind(JoinPoint.THROW, 12, true);
....
@@ -335,6 +343,7 @@ public static final Kind Throw = new Kind(JoinPoint.THROW, 12, true);
We also modify the neverHasTarget method to include the Throw kind
because in Java there is no target for the throwing of an exception.

[source, java]
....
public boolean neverHasTarget() {
return this == ConstructorCall
@@ -348,6 +357,7 @@ public boolean neverHasTarget() {
In the read method on Shadow.Kind, add another case to read in our new
Shadow.Kind.

[source, java]
....
case 12: return Throw;
....
@@ -357,6 +367,7 @@ case 12: return Throw;
Modify weaver/org.aspectj.weaver.bcel/BcelClassWeaver.java to recognize
this new joinpoint kind. In the method

[source, java]
....
private void match(
LazyMethodGen mg,
@@ -368,6 +379,7 @@ private void match(

Add a test for this instruction, i.e.

[source, java]
....
} else if (i == InstructionConstants.ATHROW) {
match(BcelShadow.makeThrow(world, mg, ih, enclosingShadow),
@@ -378,6 +390,7 @@ Add a test for this instruction, i.e.
Then, modify BcelShadow.java to create this new kind of join point
shadow:

[source, java]
....
public static BcelShadow makeThrow(
BcelWorld world,
@@ -408,6 +421,7 @@ public static BcelShadow makeThrow(
Finally modify weaver/org.aspectj.weaver/Member.java to generate the
needed signature

[source, java]
....
public static Member makeThrowSignature(TypeX inType, TypeX throwType) {
return new Member(
@@ -421,6 +435,7 @@ public static Member makeThrowSignature(TypeX inType, TypeX throwType) {

Run the proto test again and you should see:

[source, text]
....
about to execute: execution(void Throws.willThrow())
about to execute: call(java.lang.RuntimeException(String))
@@ -439,6 +454,7 @@ part of the clean-up. For now, let's go on with the interesting parts.

Add a second piece of before advice to the test aspect A:

[source, java]
....
before(): throw(Throwable) {
System.out.println("about to throw: " + thisJoinPoint);
@@ -448,6 +464,7 @@ before(): throw(Throwable) {
When we run the test again we'll get a long error message from the
harness. The interesting part of the message is the following:

[source, text]
....
[ 0] [error 0]: error can't find referenced pointcut at C:\aspectj\eclipse\tests\design\pcds\Throws.java:23:0
....
@@ -470,6 +487,7 @@ Modify the parseSinglePointcut method in
weaver/org.aspectj.weaver.patterns/PatternParser.java to add one more
else if clause for the throw pcd:

[source, java]
....
} else if (kind.equals("throw")) {
parseIdentifier(); eat("(");
@@ -485,6 +503,7 @@ else if clause for the throw pcd:
Modify the matches method in
weaver/org.aspectj.weaver.patterns/SignaturePattern.java to add:

[source, java]
....
if (kind == Member.HANDLER) {
return parameterTypes.matches(world.resolve(sig.getParameterTypes()),
@@ -494,6 +513,7 @@ if (kind == Member.HANDLER) {

Run the proto test again and you should see:

[source, text]
....
about to execute: execution(void Throws.willThrow())
about to execute: call(java.lang.RuntimeException(String))
@@ -513,6 +533,7 @@ case. Modify our test aspect A to be the following. In addition to
removing the overly generic withincode pcd, this change also prints the
actual object that is about to be thrown:

[source, java]
....
aspect A {
before(Throwable t): throw(*) && args(t) {
@@ -523,6 +544,7 @@ aspect A {

When we run the test again we should see the output below:

[source, text]
....
about to throw: 'java.lang.RuntimeException: expected exception' at throw(catch(Throwable))
PASS Suite.Spec(c:\aspectj\eclipse\tests) 1 tests (1 passed) 1 seconds
@@ -546,6 +568,7 @@ exception thrown to be 'Throwable'. Can we set this to be more accurate?
Looking at the source code, it seems easy to identify the static type of
the exception that is thrown:

[source, java]
....
throw new RuntimeException("expected exception");
....
@@ -585,6 +608,7 @@ thrown, we need to fix the parser for the throw pcd to remove this
information. We'll fix the PatternParser code that we added in step 1.6
to read as follows:

[source, java]
....
} else if (kind.equals("throw")) {
parseIdentifier(); eat("(");
@@ -602,6 +626,7 @@ before. To make this work we have a set of things to do. First, let's
create this new kind in org.aspectj.weaver.Member. Find where the
HANDLER kind is defined there, and add a corresponding throw kind:

[source, java]
....
public static final Kind THROW = new Kind("THROW", 8);
....
@@ -610,6 +635,7 @@ We also need to fix the serialization kind in
Member.Kind.read(DataInputStream) just above this constant list to add a
case for this new kind:

[source, java]
....
case 8: return THROW;
....
@@ -617,6 +643,7 @@ case 8: return THROW;
Still in this file, we also need to fix Member.makeThrowSignature to use
this new kind:

[source, java]
....
public static Member makeThrowSignature(TypeX inType, TypeX throwType) {
return new ResolvedMember(
@@ -631,6 +658,7 @@ public static Member makeThrowSignature(TypeX inType, TypeX throwType) {
If you run the test now you'll get an error from the parser reminding us
that the throw pcd now doesn't accept a type pattern:

[source, text]
....
------------ FAIL: simple throw join point()
...
@@ -642,6 +670,7 @@ FAIL Suite.Spec(c:\aspectj\eclipse\tests) 1 tests (1 failed) 1 seconds
This is an easy fix to the test case as we modify our pcd for the new
syntax in the aspect A in our Throws.java test code:

[source, java]
....
before(Throwable t): throw() && args(t) {
....
@@ -649,6 +678,7 @@ before(Throwable t): throw() && args(t) {
Now when we run the test case it looks like everything's fixed and we're
passing:

[source, text]
....
PASS Suite.Spec(c:\aspectj\eclipse\tests) 1 tests (1 passed) 2 seconds
....
@@ -664,6 +694,7 @@ that by adding code that notes when the advice runs and then checks for
this event. This code uses the Tester.event and Tester.checkEvent
methods:

[source, java]
....
import org.aspectj.testing.Tester;

@@ -694,6 +725,7 @@ aspect A {
Now when we run our test case it will fail. This failure is good because
we're not matching the throw join point anymore.

[source, text]
....
------------ FAIL: simple throw join point()
...
@@ -711,6 +743,7 @@ use combinations with other pcds to narrow their matches. So, find the
line for kind == Member.ADVICE and add the same line below it for
Member.THROW.

[source, java]
....
if (kind == Member.ADVICE) return true;
if (kind == Member.THROW) return true;
@@ -727,6 +760,7 @@ kind of printing back on the see what's happening. If you uncomment to
System.out.println in the test aspect A and rerun the test, you won't be
very happy with the results:

[source, text]
....
------------ FAIL: simple throw join point()
...
@@ -752,6 +786,7 @@ signature, these classes are extremely simple. Nevertheless, we have to
build them. Notice that when we add new source files to the system we
need to include the standard eclipse EPL license header.

[source, java]
....
/* *******************************************************************
* Copyright (c) 2006 Contributors.
@@ -771,6 +806,7 @@ import org.aspectj.lang.Signature;
public interface ThrowSignature extends Signature { }
....

[source, java]
....
/* *******************************************************************
* Copyright (c) 2006 Contributors.
@@ -807,6 +843,7 @@ To finish up our work in the runtime module, we need to extend
org.aspectj.runtime.reflect.Factory to add a factory method for this new
signature kind:

[source, java]
....
public ThrowSignature makeThrowSig(String stringRep) {
ThrowSignatureImpl ret = new ThrowSignatureImpl(stringRep);
@@ -822,6 +859,7 @@ first place. First let's add a method to create a string for the throw
signature. This is a very simple method copied from the other
create*SignatureString methods.

[source, java]
....
private String getThrowSignatureString(World world) {
StringBuffer buf = new StringBuffer();
@@ -836,6 +874,7 @@ private String getThrowSignatureString(World world) {
Now we need to modify three methods to add cases for the new
Member.THROW kind. First, Member.getSignatureMakerName add:

[source, java]
....
} else if (kind == THROW) {
return "makeThrowSig";
@@ -843,6 +882,7 @@ Member.THROW kind. First, Member.getSignatureMakerName add:

Next, to Member.getSignatureType add:

[source, java]
....
} else if (kind == THROW) {
return "org.aspectj.lang.reflect.ThrowSignature";
@@ -850,6 +890,7 @@ Next, to Member.getSignatureType add:

Finally, to Member.getSignatureString add:

[source, java]
....
} else if (kind == THROW) {
return getThrowSignatureString(world);
@@ -859,6 +900,7 @@ With all of these changes in place we should have working code for
thisJoinPoint reflection using our new join point and signature kinds.
Rerun the test to confirm:

[source, text]
....
about to throw: 'java.lang.RuntimeException: expected exception' at throw(throw)
PASS Suite.Spec(c:\aspectj\eclipse\tests) 1 tests (1 passed) 1 seconds
@@ -869,6 +911,7 @@ PASS Suite.Spec(c:\aspectj\eclipse\tests) 1 tests (1 passed) 1 seconds
Modify the before advice to include at least minimal checks of the new
reflective information:

[source, java]
....
before(Throwable t): throw() && args(t) {
Tester.event("before throw");
@@ -908,6 +951,7 @@ tests.
You should expect to see at least one other test case fail when you run
ajcTests.xml. Here's the failure message:

[source, text]
....
------------ FAIL: validate (enclosing) join point and source locations()
...
@@ -948,6 +992,7 @@ that the only occurence of throw is just before the handler for
catch(Error) and right after the call to new Error. We should add our
new expected event between these two:

[source, text]
....
, "before AllTargetJoinPoints call(java.lang.Error(String))"
, "before AllTargetJoinPoints throw(throw)" // added for new throw join point
@@ -964,6 +1009,7 @@ to make sure that the new join point kind is compatible with all 5 kinds
of advice. Let's extend our current simple Throws test to check for
before and the three kinds of after advice:

[source, java]
....
import org.aspectj.testing.Tester;

@@ -1019,6 +1065,7 @@ point kind work for before and all three kinds of after advice.
Let's create a new test case to see how this new join point interacts
with around advice.

[source, java]
....
import org.aspectj.testing.Tester;

@@ -1050,6 +1097,7 @@ aspect A {

When we run this test case we get a very unpleasant result:

[source, text]
....
------------ FAIL: simple throw join point with around()
...
@@ -1080,6 +1128,7 @@ implemented in the org.aspectj.weaver.Shadow.match(Shadow, World)
method. We can add our new rule at the beginning of the if(kind ==
AdviceKind.Around) block:

[source, java]
....
} else if (kind == AdviceKind.Around) {
if (shadow.getKind() == Shadow.Throw) {
@@ -1093,6 +1142,7 @@ AdviceKind.Around) block:
Now if we rerun our test we'll see errors telling us that around is
prohibited on throw join points:

[source, text]
....
------------ FAIL: simple throw join point with around()
...
@@ -1106,6 +1156,7 @@ To finish this test case up we need to modify the specification to be
looking for these errors as the correct behavior. This will produce the
following specification:

[source, xml]
....
<ajc-test dir="design/pcds"
title="simple throw join point with around">

+ 1
- 0
docs/dist/LICENSE-AspectJ.adoc View File

@@ -50,6 +50,7 @@ http://asm.objectweb.org/download/.
The ASM license is available at http://asm.objectweb.org/license.html.
The license is also reproduced here:

[source, text]
....
Copyright (c) 2000-2005 INRIA, France Telecom
All rights reserved.

+ 226
- 220
docs/dist/doc/README-11.adoc View File

@@ -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

+ 95
- 106
docs/dist/doc/README-12.adoc View File

@@ -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

+ 12
- 11
docs/dist/doc/README-121.adoc View File

@@ -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

+ 5
- 6
docs/dist/doc/README-153.adoc View File

@@ -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()
....

+ 13
- 6
docs/dist/doc/README-160.adoc View File

@@ -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) * *(..)) {

+ 3
- 6
docs/dist/doc/README-161.adoc View File

@@ -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);
}
....

'''''

+ 1
- 0
docs/dist/doc/README-1610.adoc View File

@@ -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
....

+ 2
- 0
docs/dist/doc/README-1611.adoc View File

@@ -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() {

+ 13
- 7
docs/dist/doc/README-1612.adoc View File

@@ -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();

+ 16
- 23
docs/dist/doc/README-164.adoc View File

@@ -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.

'''''

+ 24
- 26
docs/dist/doc/README-167.adoc View File

@@ -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)

+ 18
- 20
docs/dist/doc/README-168.adoc View File

@@ -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

+ 15
- 20
docs/dist/doc/README-169.adoc View File

@@ -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>

+ 38
- 31
docs/dist/doc/README-170.adoc View File

@@ -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
}
....

+ 2
- 0
docs/dist/doc/README-174.adoc View File

@@ -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
....

+ 3
- 2
docs/dist/doc/README-180.adoc View File

@@ -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< ===
....

+ 12
- 19
docs/dist/doc/README-182.adoc View File

@@ -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

+ 4
- 0
docs/dist/doc/README-183.adoc View File

@@ -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(* *(..)))
....

+ 5
- 10
docs/dist/doc/README-187.adoc View File

@@ -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
....

+ 24
- 14
docs/dist/doc/README-190.adoc View File

@@ -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

+ 1
- 0
docs/dist/doc/README-191.adoc View File

@@ -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) {

+ 6
- 3
docs/dist/doc/README-193.adoc View File

@@ -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

+ 5
- 2
docs/dist/doc/README-195.adoc View File

@@ -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

+ 9
- 6
docs/dist/doc/README-196.adoc View File

@@ -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())

+ 3
- 3
docs/dist/doc/changes.adoc View File

@@ -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

+ 174
- 105
docs/dist/doc/porting.adoc View File

@@ -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);

+ 47
- 37
docs/faq/faq.adoc View File

@@ -140,9 +140,9 @@ must be able to reach classes in the small (< 100K) runtime library
*A:* From AspectJ's http://eclipse.org/aspectj[web page] , download the
AspectJ distribution. The `jar` file is installed by executing

[source, text]
....
java -jar jar file name

....

Do *not* try to extract the `jar` file contents and then attempt to
@@ -503,6 +503,7 @@ AKA agile methods)?

*A:* From a question on the user list:

[source, text]
....
> Anyone know the connections between AOP and Extreme Programming?
> I am really confused. It seems AOP is a programming paradigm, which
@@ -510,7 +511,6 @@ AKA agile methods)?
> this is a lightweight software development process. One of the common
> motivations of AOP and XP is designed to adopt to the requirement
> changes, so that it can save the cost of software development.

....

This is Raymond Lee's answer:
@@ -649,6 +649,7 @@ in a modular way, something that would otherwise be spread throughout
the code. Consider the following code, adapted from the AspectJ
tutorial:

[source, java]
....
aspect PublicErrorLogging {
Log log = new Log();
@@ -660,7 +661,6 @@ aspect PublicErrorLogging {
log.write(o, e);
}
}

....

The effect of this code is to ensure that whenever any public method of
@@ -838,6 +838,7 @@ below shows how the different profiles build on top of the two
configurations CDC (Connected Device Configuration) and CLDC (Connected
Limited Device Configuration):

[source, text]
....
--------------
| Personal |
@@ -848,7 +849,6 @@ Limited Device Configuration):
------------------------------------------
| Java |
------------------------------------------

....

Which configuration you have dictates the restrictions when running
@@ -1007,18 +1007,18 @@ Environment Guide] link:devguide/ajc-ref.html[Reference for ajc].
line-delimited text file and direct ajc to that file using `-argfile` or
`@`:

[source, text]
....
ajc @sources.lst
ajc -argfile sources.lst

....

Another way in AspectJ 1.1 is to use the `-sourceroots` options, which
reads all source files in a given set of directories:

[source, text]
....
ajc -sourceroots "src;testsrc"

....

For more information, see the link:devguide/index.html[Development
@@ -1063,23 +1063,23 @@ Here's an example of using `ajc` in this sort of cross-compilation mode
(assuming a Windows platform with all the default installation
directories):

[source, text]
....
ajc -target 1.1 -bootclasspath c:\jdk1.1.7\lib\classes.zip \
-classpath c:\aspectj1.0\lib\aspectjrt.jar -extdirs "" \
-argfile jdk11system.lst

....

This same technique can be used if you want to run `ajc` on a JDK 1.3
JVM (highly recommended) but need to generate code for JDK 1.2. That
would look something like:

[source, text]
....
ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \
-classpath c:\aspectj1.0\lib\aspectjrt.jar \
-extdirs c:\jdk1.2\jre\lib\ext
-argfile jdk12system.lst

....

*Q:* Does the `ajc` compiler support the `assert` keyword in Java 1.4?
@@ -1226,10 +1226,10 @@ which will be affected by any advice specifying the same pointcut. For
example, the following will print a warning whereever some code in class
Bar gets a field value from Foo:

[source, java]
....
declare warning: get(* Foo.*) && within(Bar)
: "reading Foo state from Bar";

....

When you are running your program, you can trace advice as it executes.
@@ -1282,6 +1282,7 @@ use implement a hybrid build process by listing the production source
files into a javac-compliant argfile, and the development source files
in another ajc argfiles:

[source, text]
....
-- file "production.lst":
One.java
@@ -1295,21 +1296,20 @@ Trace.java
-- file "development.lst":
@production.lst
@tracing.lst

....

Then your development build can use `ajc`:

[source, text]
....
ajc @development.lst

....

And your development build can use `ajc` or `javac` or `jikes`:

[source, text]
....
jikes @production.lst

....

*Q:* We compile module jars and then assemble them. Can we continue this
@@ -1331,6 +1331,7 @@ are visible to other clients, which themselves are otherwise unaffected
by the aspects. In this case, the common library can be built using ajc,
and used on the classpath for the module builds:

[source, text]
....
ajc -outjar common.jar -sourceroots "aspectj-src:src" ...
cd ../otherProject
@@ -1342,6 +1343,7 @@ should affect two or more modules that are in a dependency relationship
to one another. It should work to reuse the aspects in binary form for
each compile, in dependency order:

[source, text]
....
ajc -outjar common-aspects.jar
-sourceroots "aspectj-src" ...
@@ -1380,6 +1382,7 @@ libraries).
In Eclipse's AJDT, you can create a top-level project with symbolic
links out to the sources:

[source, text]
....
app-assembly/
{link common/aspects}
@@ -1425,6 +1428,7 @@ Here's some code Jim Hugunin wrote to trace join points and posted to
the users list. To reuse the aspect, define a subaspect and implement
the pointcuts, for example:

[source, java]
....
aspect JoinPointSampleAspect extends aj.TraceJoinPoints {
protected pointcut entry() :
@@ -1442,11 +1446,11 @@ aspect JoinPointSampleAspect extends aj.TraceJoinPoints {
class JoinPointSample {
public static void main(String[] args) {}
}

....

Here's the aspect:

[source, java]
....
/* TraceJoinPoints.java */

@@ -1639,6 +1643,7 @@ call? How about the most-recent prior entrypoint?
most-recent recursive call or (b) the current and original recursive
call:

[source, java]
....
aspect LogFactorial {
pointcut f(int i) : call(int factorial(int)) && args(i);
@@ -1654,7 +1659,6 @@ aspect LogFactorial {
System.err.println(i + "@" + j);
}
}

....

*Q:* What is the difference between constructor call, constructor
@@ -1672,6 +1676,7 @@ constructor call obtained using `TraceJointPoints.java` from
#q:seeingjoinpoints[Q:I don't understand what join points exist. How can
I see them?].

[source, java]
....
public class Init {
public static void main (String[] args) {
@@ -1689,6 +1694,7 @@ class Test extends Super implements I {

For a program compiled with AspectJ 1.0, the result is this:

[source, xml]
....
<constructor-call sig="Test()" >
<staticinitialization sig="Super._init_" />
@@ -1723,9 +1729,9 @@ of thumb:
* If you want the join point on the "outside" of object creation, use
after returning from call to the constructor:
+
[source, java]
....
after() returning (Foo newlyCreatedObject): call(Foo.new(..)) { ... }

....
+
You might be tempted to use "this" or "target" to expose the new object,
@@ -1734,9 +1740,9 @@ object itself might not be created yet... it only exists "on the way
out", when you return the object.
* If you want the join point inside a particular constructor, use:
+
[source, java]
....
after(Foo newlyCreatedObject) returning: this(newlyCreatedObject) && execution(Foo.new(..)) { ... }

....
+
Remember, though, that if you use "before" advice here, the body of the
@@ -1747,9 +1753,9 @@ object that call each other with `this(...)` and you want exactly one
join point for each initialization of `Foo`, regardless of the path of
constructors it takes, then use:
+
[source, java]
....
after(Foo f) returning: this(f) && initialization(Foo.new(..)) { ... }

....

*Q:* I want advice to run at two join points, but it doesn't run at all.
@@ -1759,9 +1765,9 @@ What gives?
mistake. Most likely you want to do something like "run the advice for
all public and private calls," and the code looks something like this:

[source, java]
....
within(com.xerox.printing..*) && call(public * *(..)) && call(private * *(..))

....

But a pointcut is evaluated at *each* join point. The expression above
@@ -1770,9 +1776,9 @@ has both public and private access. In a pointcut, `pc1() && pc2()`
means both must be true at a given join point for advice to run at that
join point. The correct pointcut would use `||` as follows:

[source, java]
....
within(com.xerox.printing..*) && (call(public * *(..)) || call(private * *(..)))

....

Then the advice will run at the join point.
@@ -1796,6 +1802,7 @@ limited to a certain set of classes. Do I have to retype it each time?
*A:* No. You can declare that all the types implement an interface you
define, and then use the interface type in your program. For example:

[source, java]
....
/**
* Example of using an interface to represent a type pattern.
@@ -1821,7 +1828,6 @@ abstract aspect MarkerExample {
aspect MyMarker extends MarkerExample {
declare parents: com.mycompany.whatever..* implements Marked;
}

....

*Q:* Where do I find example programs and how-to's?
@@ -1886,6 +1892,7 @@ Specification] .
here is the HTML code for an HTML editor applet that contains some
debugging aspects:

[source, xml]
....
<APPLET
CODE='com.company.swing.applets.EditorApplet'
@@ -1914,6 +1921,7 @@ types to Object, so that highly polymorphic advice may be written. This
works if an advice parameter or the return type for around is typed to
Object. So:

[source, java]
....
class Test {
static int i;
@@ -1928,15 +1936,14 @@ aspect TraceSet {
System.err.println(val.class);
}
}

....

will print out

[source, text]
....
37
java.lang.Integer

....

For more information, see the Programming Guide
@@ -1951,10 +1958,10 @@ flag as an argument.
To programmatically detect the version of the AspectJ runtime while
running under Java 1.4 or later, get the version from the package:

[source, java]
....
Package lang = org.aspectj.lang.JoinPoint.class.getPackage();
String version = lang.getImplementationVersion();

....

When running under Java 1.3 or earlier, read the manifest directly. For
@@ -1973,13 +1980,13 @@ in `org.aspectj.bridge.Version`.
*A:* The only modifier advice can take is `strictfp`. However, you can
enclose the body of the advice in a synchronized clause:

[source, java]
....
before() : pc() {
synchronized (this) {
// advice code here
}
}

....

It should not be necessary to synchronize a percflow aspect, but you
@@ -1999,6 +2006,7 @@ VM exhausts itself in the recursion.

Of course, infinite recursion is possible in Java:

[source, java]
....
public class Main {
public static void main(String[] args) {
@@ -2009,7 +2017,6 @@ public class Main {
}
}
}

....

If you compile and run this program, and it will fail silently, trying
@@ -2018,11 +2025,11 @@ StackOverflowError.

Here's a similar AspectJ program where the recursion is not so obvious:

[source, java]
....
aspect A {
after(): call(* *(..)) { System.out.println("after " + thisJoinPoint); }
}

....

This re-invokes itself because it advises any call. It invokes itself
@@ -2042,19 +2049,20 @@ finally clause, understanding that it may run after some failure.
{empty}(2) Avoid writing advice that advises itself. One simple way to
do so is to exclude the code within the current aspect:

[source, java]
....
aspect A {
after() returning: !within(A) && call(* *(..)) {
System.out.println("after " + thisJoinPoint);
}
}

....

A better way is often to re-write the pointcut. If the advice is
advising itself accidentally, that's a sign that the pointcut is not
saying what you mean.

[source, java]
....
aspect A {
pointcut withinTargetClasses() : within(A+) || within(B+);
@@ -2062,12 +2070,12 @@ aspect A {
System.out.println("after " + thisJoinPoint);
}
}

....

*Q:* I've declared a field on every class in my package; how do I use it
in advice?

[source, java]
....
aspect A {
boolean com.xerox..*.dirtyFlag;
@@ -2076,7 +2084,6 @@ aspect A {
target.dirtyFlag = true; // compile fails here
}
}

....

*A:* You need a type to refer to any member, field or method. It's
@@ -2084,6 +2091,7 @@ generally better to introduce onto an interface and declare classes to
implement the interface, which permits you to use the interface type in
advice formals.

[source, java]
....
aspect A {
interface TrackingSets {}
@@ -2095,7 +2103,6 @@ aspect A {
target.dirtyFlag = true;
}
}

....

*Q:* The AspectJ compiler aborts with an OutOfMemoryError when compiling
@@ -2182,6 +2189,7 @@ How can I fix this?]. For your IDE, do something similar or follow the
provider's instructions. For example, to increase memory in JBuilder,
edit the `jbuilderX/bin/jbuilder.config` file to have an entry like:

[source, text]
....
vmparam -Xmx384m
....
@@ -2430,6 +2438,7 @@ not control the code for the method execution), test the context for
`invoke(..)`. Here's a pointcut that tests only if the method name is
correct:

[source, java]
....
aspect A {
pointcut runReflectiveCall(Method run) : target(run) &&
@@ -2438,7 +2447,6 @@ aspect A {
System.out.println("before reflective call " + thisJoinPoint);
}
}

....

*Q:* What are the bugs now most affecting users?
@@ -2502,11 +2510,11 @@ CGLIB generate code from the weaving process by appropriate use of the
exclude element in the aop.xml. A typical clause in the aop.xml might
look as follows:

[source, xml]
....
<weaver>
<exclude within="*CGLIB*" />
</weaver>

....

[[aj11]]
@@ -2653,6 +2661,7 @@ only XML. This means aspect developers can write abstract aspects, and
deployers need only configure `aop.xml` and run using the AspectJ weaver
in Java 5. For example, to run Java 5 VM with load-time weaving,

[source, text]
....
java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" ..
....
@@ -2661,6 +2670,7 @@ To declare a concrete aspect, add a a concrete-aspect XML entity to
`META-INF/aop.xml`. This example extends a tracing aspect to apply to
every type in the application:

[source, xml]
....
<concrete-aspect
name="com.company.tracing.ConcreteTracing"
@@ -2987,10 +2997,10 @@ AJDT development environment and running the correctness tests. Then:
* Create a file `aspectjlib.properties` within the `org.aspectj.ajde`
project and add the following two lines
+
[source, text]
....
aspectj.lib.dir=C:/eclipse/aspectj-workspace/aj-build/dist/tools/lib
aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspectj.ajde.doc/doc

....
+
making sure to change the path to correspond to your set up.
@@ -3043,6 +3053,7 @@ is a sample file with some example definitions, preceded by comments
showing the directory layout of the files referred to in the test
definitions.

[source, xml]
....
<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd">
<suite>
@@ -3137,10 +3148,10 @@ tree as described in #q:buildingsource[Q:How do I get and compile the
source code for AspectJ?] and then build the `build-testing-drivers`
target:

[source, text]
....
cd build
../lib/ant/bin/ant -f build.xml build-testing-drivers

....

This produces `../aj-build/jars/testing-drivers-all.jar` which you can
@@ -3237,8 +3248,7 @@ http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AJDT ).
Bug reports on ajbrowser should have version information for both Java
and AspectJ, and (most importantly) clear steps for reproducing the bug.
You may submit ajbrowser bugs against the IDE component of AspectJ via
the web form http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ
.
the web form http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ.

One of the benefits of open-source is that you can find and fix the bug
for yourself; when you submit the fix back to us, we can validate the
@@ -3422,7 +3432,7 @@ More details for 1.0 and earlier releases are available in changes.html.
*Q:* What is the AspectJ development schedule?

*A:* Below is a table describing the goals for the major releases. For
information about specific features, search the bug database for `RFE`'s
information about specific features, search the bug database for ``RFE``'s
("requests for enhancement") by
http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&bug_severity=enhancement[selecting
severity of "enhancement"]. Like many open-source projects, we don't

+ 1
- 1
docs/pdGuideDB/ajcore.adoc View File

@@ -44,6 +44,7 @@ dump configuration as well as the exception (with stack trace) that is
the source of the problem and any messages issued by the compiler. Most
importantly the exact version of AspectJ is included.

[source, text]
....
---- AspectJ Properties ---
AspectJ Compiler DEVELOPMENT built on Tuesday Jul 25, 2006 at 13:00:09 GMT
@@ -157,5 +158,4 @@ java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.aspectj.tools.ajc.Main.run(Main.java:367)
at org.aspectj.tools.ajc.Main.runMain(Main.java:246)
at org.aspectj.tools.ajc.Main.main(Main.java:86)
....

+ 3
- 0
docs/pdGuideDB/ltwdump.adoc View File

@@ -31,6 +31,7 @@ package (and subpackages) but not CGLIB generated classes in the
`com.foo.bar` package (and subpackages). It will also ensure all woven
byte-code is dumped both before and after weaving.

[source, xml]
....
<aspectj>
<aspects>
@@ -46,6 +47,7 @@ byte-code is dumped both before and after weaving.

You should see messages similar to this:

[source, text]
....
[WeavingURLClassLoader] info AspectJ Weaver Version 1.5.3 built on Thursday Oct 26, 2006 at 17:22:31 GMT
[WeavingURLClassLoader] info register classloader org.aspectj.weaver.loadtime.WeavingURLClassLoader
@@ -57,6 +59,7 @@ You should see messages similar to this:

On disk you would find the following files:

[source, text]
....
_ajdump/_before/com/foo/bar/Test.class
_ajdump/com/foo/bar/Test.class

+ 5
- 0
docs/pdGuideDB/messages.adoc View File

@@ -103,6 +103,7 @@ during LTW. The following example will produce basic informational
messages about the lifecyle of the weaver in addition to any warning or
error messages.

[source, xml]
....
<aspectj>
<weaver options="-verbose">
@@ -116,6 +117,7 @@ defining class loader associated with weaver. You can use this
information in a large system to distinguish between different
applications each of which will typically have its own class loader.

[source, text]
....
[AppClassLoader@92e78c] info AspectJ Weaver Version 1.5.3 built on Thursday Oct 26, 2006 at 17:22:31 GMT
[AppClassLoader@92e78c] info register classloader sun.misc.Launcher$AppClassLoader@92e78c
@@ -133,6 +135,7 @@ weaving (LTW), why advice has not been woven. Here is a quick guide to
the messages to look for. Firstly if you use the `-verbose` option you
should see the following message when your aspect is registered:

[source, text]
....
info register aspect MyAspect
....
@@ -140,6 +143,7 @@ info register aspect MyAspect
Secondly if you use the `-debug` option you should see a message
indicating that you class is being woven:

[source, text]
....
debug weaving 'HelloWorld'
....
@@ -150,6 +154,7 @@ determine whether your pointcuts match you can use the `-showWeaveInfo`
option which will cause a message to be issued each time a join point is
woven:

[source, text]
....
weaveinfo Join point 'method-execution(void HelloWorld.main(java.lang.String[]))' ...
....

+ 3
- 0
docs/pdGuideDB/trace.adoc View File

@@ -82,6 +82,7 @@ Below is an extract from that trace with method arguments removed. You
will notice the millisecond time stamp, thread id and indication of
entry/exit/event or message type for each line of trace.

[source, text]
....
15:44:18.630 main > org.aspectj.weaver.loadtime.Aj.<init>
15:44:18.660 main < org.aspectj.weaver.loadtime.Aj.<init>
@@ -133,6 +134,7 @@ below could be used to configure Java Logging. The resulting file, just
containing trace for the `org.aspectj.weaver.loadtime` package, will be
written to `java0.log` in your `user.home` directory.

[source, text]
....
handlers= java.util.logging.FileHandler

@@ -150,6 +152,7 @@ By setting the System property `-Dorg.aspectj.tracing.debug=true` you
should see a message confirming which trace infrastructure is being
used.

[source, text]
....
TraceFactory.instance=org.aspectj.weaver.tools.Jdk14TraceFactory@12dacd1
....

+ 89
- 42
docs/progGuideDB/examples.adoc View File

@@ -7,35 +7,27 @@ This chapter consists entirely of examples of AspectJ use.

The examples can be grouped into four categories:

technique

Examples which illustrate how to use one or more features of the
language.

development

Examples of using AspectJ during the development phase of a project.

production

Examples of using AspectJ to provide functionality in an application.

reusable

Examples of reuse of aspects and pointcuts.
technique::
Examples which illustrate how to use one or more features of the language
development::
Examples of using AspectJ during the development phase of a project
production::
Examples of using AspectJ to provide functionality in an application
reusable::
Examples of reuse of aspects and pointcuts

[[examples-howto]]
=== Obtaining, Compiling and Running the Examples

The examples source code is part of the AspectJ distribution which may
be downloaded from the AspectJ project page (
http://eclipse.org/aspectj[] ).
be downloaded from the https://eclipse.org/aspectj[AspectJ project page].

Compiling most examples is straightforward. Go the `InstallDir/examples`
directory, and look for a `.lst` file in one of the example
subdirectories. Use the `-arglist` option to `ajc` to compile the
example. For instance, to compile the telecom example with billing, type

[source, text]
....
ajc -argfile telecom/billing.lst
....
@@ -45,11 +37,13 @@ Java archive (`aspectjrt.jar`). You may either set the `CLASSPATH`
environment variable or use the `-classpath` command line option to the
Java interpreter:

[source, text]
....
(In Unix use a : in the CLASSPATH)
java -classpath ".:InstallDir/lib/aspectjrt.jar" telecom.billingSimulation
....

[source, text]
....
(In Windows use a ; in the CLASSPATH)
java -classpath ".;InstallDir/lib/aspectjrt.jar" telecom.billingSimulation
@@ -64,7 +58,7 @@ dynamic join points and advice, and with static introduction. Advice
changes an application's behavior. Introduction changes both an
application's behavior and its structure.

The first example, xref:#examples-joinPoints[Join Points and ], is about
The first example, xref:#examples-joinPoints[Join Points and `thisJoinPoint`], is about
gathering and using information about the join point that has triggered
some advice. The second example, xref:#examples-roles[Roles and Views],
concerns a crosscutting view of an existing class hierarchy.
@@ -87,6 +81,7 @@ join point. Here, for example, since the only join points picked out by
the pointcut are calls of a certain method, we can get the target value
and one of the argument values of the method calls directly.

[source, java]
....
before(Point p, int x): target(p)
&& args(x)
@@ -101,6 +96,7 @@ But sometimes the shape of the join point is not so clear. For instance,
suppose a complex application is being debugged, and we want to trace
when any method of some class is executed. The pointcut

[source, java]
....
pointcut execsInProblemClass(): within(ProblemClass)
&& execution(* *(..));
@@ -124,19 +120,16 @@ point
* the currently executing object
* the target object
* an object encapsulating the static information about the join point.
This is also available through the special variable
+
thisJoinPointStaticPart
+
.
This is also available through the special variable `thisJoinPointStaticPart`.

===== The `Demo` class

The class `tjp.Demo` in `tjp/Demo.java` defines two methods `foo` and
`bar` with different parameter lists and return types. Both are called,
with suitable arguments, by `Demo`'s `go` method which was invoked from
with suitable arguments, by ``Demo``'s `go` method which was invoked from
within its `main` method.

[source, java]
....
public class Demo {
static Demo d;
@@ -168,6 +161,7 @@ This aspect uses around advice to intercept the execution of methods
`foo` and `bar` in `Demo`, and prints out information garnered from
`thisJoinPoint` to the console.

[source, java]
....
aspect GetInfo {

@@ -207,6 +201,7 @@ aspect GetInfo {

The pointcut `goCut` is defined as

[source, java]
....
cflow(this(Demo)) && execution(void go())
....
@@ -221,7 +216,7 @@ advised.

The name of the method and that method's defining class are available as
parts of the
xref:../api/org/aspectj/lang/Signature.html[org.aspectj.lang.Signature]
xref:../api/org/aspectj/lang/Signature.html[`org.aspectj.lang.Signature`]
object returned by calling `getSignature()` on either `thisJoinPoint` or
`thisJoinPointStaticPart`.

@@ -274,7 +269,7 @@ are provided by AspectJ without having to modify the code for the class

The `Point` class defines geometric points whose interface includes
polar and rectangular coordinates, plus some simple operations to
relocate points. `Point`'s implementation has attributes for both its
relocate points. ``Point``'s implementation has attributes for both its
polar and rectangular coordinates, plus flags to indicate which
currently reflect the position of the point. Some operations cause the
polar coordinates to be updated from the rectangular, and some have the
@@ -292,20 +287,21 @@ image:aspects.gif[image]

===== The `CloneablePoint` aspect

This first aspect is responsible for `Point`'s implementation of the
This first aspect is responsible for ``Point``'s implementation of the
`Cloneable` interface. It declares that `Point implements Cloneable`
with a `declare parents` form, and also publically declares a
specialized `Point`'s `clone()` method. In Java, all objects inherit the
specialized ``Point``'s `clone()` method. In Java, all objects inherit the
method `clone` from the class `Object`, but an object is not cloneable
unless its class also implements the interface `Cloneable`. In addition,
classes frequently have requirements over and above the simple
bit-for-bit copying that `Object.clone` does. In our case, we want to
update a `Point`'s coordinate systems before we actually clone the
update a ``Point``'s coordinate systems before we actually clone the
`Point`. So our aspect makes sure that `Point` overrides `Object.clone`
with a new method that does what we want.

We also define a test `main` method in the aspect for convenience.

[source, java]
....
public aspect CloneablePoint {

@@ -338,7 +334,7 @@ public aspect CloneablePoint {

===== The `ComparablePoint` aspect

`ComparablePoint` is responsible for `Point`'s implementation of the
`ComparablePoint` is responsible for ``Point``'s implementation of the
`Comparable` interface.

The interface `Comparable` defines the single method `compareTo` which
@@ -349,11 +345,11 @@ class that implement it.
parents` to declare that `Point implements
Comparable`, and also publically declares the appropriate
`compareTo(Object)` method: A `Point` `p1` is said to be less than
another `Point``
p2` if `p1` is closer to the origin.
another `Point p2` if `p1` is closer to the origin.

We also define a test `main` method in the aspect for convenience.

[source, java]
....
public aspect ComparablePoint {

@@ -391,8 +387,8 @@ public aspect ComparablePoint {

===== The `HashablePoint` aspect

Our third aspect is responsible for `Point`'s overriding of `Object`'s
`equals` and `hashCode` methods in order to make `Point`s hashable.
Our third aspect is responsible for ``Point``'s overriding of ``Object``'s
`equals` and `hashCode` methods in order to make ``Point``s hashable.

The method `Object.hashCode` returns an integer, suitable for use as a
hash table key. It is not required that two objects which are not equal
@@ -408,14 +404,15 @@ values, or the same `rho` and `theta` values, not just when they refer
to the same object. We do this by overriding the methods `equals` and
`hashCode` in the class `Point`.

So `HashablePoint` declares `Point`'s `hashCode` and `equals` methods,
using `Point`'s rectangular coordinates to generate a hash code and to
So `HashablePoint` declares ``Point``'s `hashCode` and `equals` methods,
using ``Point``'s rectangular coordinates to generate a hash code and to
test for equality. The `x` and `y` coordinates are obtained using the
appropriate get methods, which ensure the rectangular coordinates are
up-to-date before returning their values.

And again, we supply a `main` method in the aspect for testing.

[source, java]
....
public aspect HashablePoint {

@@ -489,6 +486,7 @@ Throughout this example we will use a simple application that contains
only four classes. The application is about shapes. The `TwoDShape`
class is the root of the shape hierarchy:

[source, java]
....
public abstract class TwoDShape {
protected double x, y;
@@ -512,6 +510,7 @@ public abstract class TwoDShape {

`TwoDShape` has two subclasses, `Circle` and `Square`:

[source, java]
....
public class Circle extends TwoDShape {
protected double r;
@@ -533,6 +532,7 @@ public class Circle extends TwoDShape {
}
....

[source, java]
....
public class Square extends TwoDShape {
protected double s; // side
@@ -558,12 +558,14 @@ To run this application, compile the classes. You can do it with or
without ajc, the AspectJ compiler. If you've installed AspectJ, go to
the directory `InstallDir/examples` and type:

[source, text]
....
ajc -argfile tracing/notrace.lst
....

To run the program, type

[source, text]
....
java tracing.ExampleMain
....
@@ -571,6 +573,7 @@ java tracing.ExampleMain
(we don't need anything special on the classpath since this is pure Java
code). You should see the following output:

[source, text]
....
c1.perimeter() = 12.566370614359172
c1.area() = 12.566370614359172
@@ -588,6 +591,7 @@ by writing a `Trace` class that is exactly what we would write if we
didn't have aspects. The implementation is in `version1/Trace.java`. Its
public interface is:

[source, java]
....
public class Trace {
public static int TRACELEVEL = 0;
@@ -605,8 +609,9 @@ calls, and we would hope we had not forgotten any method. But we can do
that more consistently and reliably with the following aspect (found in
`version1/TraceMyClasses.java`):

[source, java]
....
aspect TraceMyClasses {
public aspect TraceMyClasses {
pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);
pointcut myConstructor(): myClass() && execution(new(..));
pointcut myMethod(): myClass() && execution(* *(..));
@@ -638,6 +643,7 @@ information, we can get it through `thisJoinPointStaticPart`.
To run this version of tracing, go to the directory
`InstallDir/examples` and type:

[source, text]
....
ajc -argfile tracing/tracev1.lst
....
@@ -645,6 +651,7 @@ ajc -argfile tracing/tracev1.lst
Running the main method of `tracing.version1.TraceMyClasses` should
produce the output:

[source, text]
....
--> tracing.TwoDShape(double, double)
<-- tracing.TwoDShape(double, double)
@@ -707,6 +714,7 @@ functionality of `Trace - version1` with the crosscutting support of
`TraceMyClasses - version1`. We end up with a `Trace` aspect (found in
`version2/Trace.java`) with the following public interface

[source, java]
....
abstract aspect Trace {

@@ -721,6 +729,7 @@ abstract aspect Trace {
In order to use it, we need to define our own subclass that knows about
our application classes, in `version2/TraceMyClasses.java`:

[source, java]
....
public aspect TraceMyClasses extends Trace {
pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);
@@ -737,6 +746,7 @@ Notice that we've simply made the pointcut `classes`, that was an
abstract pointcut in the super-aspect, concrete. To run this version of
tracing, go to the directory `examples` and type:

[source, text]
....
ajc -argfile tracing/tracev2.lst
....
@@ -748,6 +758,7 @@ the same trace information as that from version 1.

The entire implementation of the new `Trace` class is:

[source, java]
....
abstract aspect Trace {

@@ -869,6 +880,7 @@ bound property protocol.
The `Point` class is a very simple class with trivial getters and
setters, and a simple vector offset method.

[source, java]
....
class Point {

@@ -908,11 +920,12 @@ class Point {

===== The `BoundPoint` aspect

The `BoundPoint` aspect is responsible for `Point`'s "beanness". The
The `BoundPoint` aspect is responsible for ``Point``'s "beanness". The
first thing it does is privately declare that each `Point` has a
`support` field that holds reference to an instance of
`PropertyChangeSupport`.

[source, java]
....
private PropertyChangeSupport Point.support = new PropertyChangeSupport(this);
....
@@ -923,10 +936,11 @@ passing it `this`, an instance of `Point`. Since the `support` field is
private declared in the aspect, only the code in the aspect can refer to
it.

The aspect also declares `Point`'s methods for registering and managing
The aspect also declares ``Point``'s methods for registering and managing
listeners for property change events, which delegate the work to the
property change support object:

[source, java]
....
public void Point.addPropertyChangeListener(PropertyChangeListener listener){
support.addPropertyChangeListener(listener);
@@ -951,6 +965,7 @@ public void Point.hasListeners(String propertyName) {
The aspect is also responsible for making sure `Point` implements the
`Serializable` interface:

[source, java]
....
declare parents: Point implements Serializable;
....
@@ -959,13 +974,14 @@ Implementing this interface in Java does not require any methods to be
implemented. Serialization for `Point` objects is provided by the
default serialization method.

The `setters` pointcut picks out calls to the `Point`'s `set` methods:
The `setters` pointcut picks out calls to the ``Point``'s `set` methods:
any method whose name begins with "`set`" and takes one parameter. The
around advice on `setters()` stores the values of the `X` and `Y`
properties, calls the original `set` method and then fires the
appropriate property change event according to which set method was
called.

[source, java]
....
aspect BoundPoint {
private PropertyChangeSupport Point.support = new PropertyChangeSupport(this);
@@ -1025,6 +1041,7 @@ that point: calling its set methods and the offset method. Then it
serializes the point and writes it to a file and then reads it back. The
result of saving and restoring the point is that a new point is created.

[source, java]
....
class Demo implements PropertyChangeListener {

@@ -1059,6 +1076,7 @@ class Demo implements PropertyChangeListener {

To compile and run this example, go to the examples directory and type:

[source, text]
....
ajc -argfile bean/files.lst
java bean.Demo
@@ -1093,6 +1111,7 @@ The generic parts of the protocol are the interfaces `Subject` and
view `Observer` objects, and a method for getting data about state
changes:

[source, java]
....
interface Subject {
void addObserver(Observer obs);
@@ -1105,6 +1124,7 @@ interface Subject {
The `Observer` interface is just as simple, with methods to set and get
`Subject` objects, and a method to call when the subject gets updated.

[source, java]
....
interface Observer {
void setSubject(Subject s);
@@ -1117,6 +1137,7 @@ The `SubjectObserverProtocol` aspect contains within it all of the
generic parts of the protocol, namely, how to fire the `Observer`
objects' update methods when some state changes in a subject.

[source, java]
....
abstract aspect SubjectObserverProtocol {

@@ -1157,6 +1178,7 @@ its `Subject`.
`Button` objects extend `java.awt.Button`, and all they do is make sure
the `void click()` method is called whenever a button is clicked.

[source, java]
....
class Button extends java.awt.Button {

@@ -1187,6 +1209,7 @@ Note that this class knows nothing about being a Subject.
ColorLabel objects are labels that support the void colorCycle() method.
Again, they know nothing about being an observer.

[source, java]
....
class ColorLabel extends Label {

@@ -1212,6 +1235,7 @@ Finally, the `SubjectObserverProtocolImpl` implements the
subject/observer protocol, with `Button` objects as subjects and
`ColorLabel` objects as observers:

[source, java]
....
package observer;

@@ -1246,6 +1270,7 @@ all `ColorLabel` objects observing that button will `colorCycle`.
buttons and three observers and links them together as subjects and
observers. So to run the demo, go to the `examples` directory and type:

[source, text]
....
ajc -argfile observer/files.lst
java observer.Demo
@@ -1303,6 +1328,7 @@ involved in many calls at one time. image:telecom.gif[image]
`Customer` has methods `call`, `pickup`, `hangup` and `merge` for
managing calls.

[source, java]
....
public class Customer {

@@ -1377,6 +1403,7 @@ connection between customers. It does this with a simple state machine
connections can be observed. Connection is an abstract class with two
concrete subclasses: `Local` and `LongDistance`.

[source, java]
....
abstract class Connection {

@@ -1422,6 +1449,7 @@ abstract class Connection {
The two kinds of connections supported by our simulation are `Local` and
`LongDistance` connections.

[source, java]
....
class Local extends Connection {
Local(Customer a, Customer b) {
@@ -1432,6 +1460,7 @@ class Local extends Connection {
}
....

[source, java]
....
class LongDistance extends Connection {
LongDistance(Customer a, Customer b) {
@@ -1448,6 +1477,7 @@ The source files for the basic system are listed in the file
`basic.lst`. To build and run the basic system, in a shell window, type
these commands:

[source, text]
....
ajc -argfile telecom/basic.lst
java telecom.BasicSimulation
@@ -1466,6 +1496,7 @@ stopped, and returns their difference when asked for the elapsed time.
The aspect `TimerLog` (below) can be used to cause the start and stop
times to be printed to standard output.

[source, java]
....
class Timer {
long startTime, stopTime;
@@ -1490,6 +1521,7 @@ class Timer {
The `TimerLog` aspect can be included in a build to get the timer to
announce when it is started and stopped.

[source, java]
....
public aspect TimerLog {

@@ -1509,6 +1541,7 @@ The `Timing` aspect is declares an inter-type field `totalConnectTime`
for `Customer` to store the accumulated connection time per `Customer`.
It also declares that each `Connection` object has a timer.

[source, java]
....
public long Customer.totalConnectTime = 0;
private Timer Connection.timer = new Timer();
@@ -1518,6 +1551,7 @@ Two pieces of after advice ensure that the timer is started when a
connection is completed and and stopped when it is dropped. The pointcut
`endTiming` is defined so that it can be used by the `Billing` aspect.

[source, java]
....
public aspect Timing {

@@ -1556,10 +1590,11 @@ responsible to pay for it. It also declares the inter-type method
charged differently. The call charge must be calculated after the timer
is stopped; the after advice on pointcut `Timing.endTiming` does this,
and `Billing` is declared to be more precedent than `Timing` to make
sure that this advice runs after `Timing`'s advice on the same join
sure that this advice runs after ``Timing``'s advice on the same join
point. Finally, it declares inter-type methods and fields for `Customer`
to handle the `totalCharge`.

[source, java]
....
public aspect Billing {
// precedence required to get advice on endtiming in the right order
@@ -1613,6 +1648,7 @@ the method run of the superclass `AbstractSimulation`. This method is
intended to print out the status of the customer, with respect to the
`Timing` feature.

[source, java]
....
protected void report(Customer c){
Timing t = Timing.aspectOf();
@@ -1626,6 +1662,7 @@ The files timing.lst and billing.lst contain file lists for the timing
and billing configurations. To build and run the application with only
the timing feature, go to the directory examples and type:

[source, text]
....
ajc -argfile telecom/timing.lst
java telecom.TimingSimulation
@@ -1634,6 +1671,7 @@ java telecom.TimingSimulation
To build and run the application with the timing and billing features,
go to the directory examples and type:

[source, text]
....
ajc -argfile telecom/billing.lst
java telecom.BillingSimulation
@@ -1669,6 +1707,7 @@ the object whose methods are being traced. This can be achieved in at
least two ways. One way is keep the interface of the methods
`traceEntry` and `traceExit` as it was before,

[source, java]
....
public static void traceEntry(String str);
public static void traceExit(String str);
@@ -1678,6 +1717,7 @@ In this case, the caller is responsible for ensuring that the string
representation of the object is part of the string given as argument.
So, calls must look like:

[source, java]
....
Trace.traceEntry("Square.distance in " + toString());
....
@@ -1685,6 +1725,7 @@ Trace.traceEntry("Square.distance in " + toString());
Another way is to enforce the requirement with a second argument in the
trace operations, e.g.

[source, java]
....
public static void traceEntry(String str, Object obj);
public static void traceExit(String str, Object obj);
@@ -1694,6 +1735,7 @@ In this case, the caller is still responsible for sending the right
object, but at least there is some guarantees that some object will be
passed. The calls will look like:

[source, java]
....
Trace.traceEntry("Square.distance", this);
....
@@ -1709,6 +1751,7 @@ only a small effect inside the `Trace` class. Here's a partial view at
the implementation of `Trace`, version 3. The differences with respect
to version 2 are stressed in the comments:

[source, java]
....
abstract aspect Trace {

@@ -1794,6 +1837,7 @@ In fact, esimply excluding the execution join point may not be enough,
if there are calls to other traced methods within it -- in which case,
the restriction should be

[source, java]
....
&& !cflow(execution(String toString()))
....
@@ -1811,6 +1855,7 @@ every application class.
Finally, to run this version of tracing, go to the directory `examples`
and type:

[source, text]
....
ajc -argfile tracing/tracev3.lst
....
@@ -1819,12 +1864,14 @@ The file tracev3.lst lists the application classes as well as this
version of the files `Trace.java` and `TraceMyClasses.java`. To run the
program, type

[source, text]
....
java tracing.version3.TraceMyClasses
....

The output should be:

[source, text]
....
--> tracing.TwoDShape(double, double)
<-- tracing.TwoDShape(double, double)

+ 35
- 7
docs/progGuideDB/gettingstarted.adoc View File

@@ -39,7 +39,7 @@ testing and performance tuning of applications. And, in the section
following, xref:#starting-production[Production Aspects], we present
aspects that implement crosscutting functionality common in Java
applications. We will defer discussing a third category of aspects,
reusable aspects, until xref:language.adoc[The AspectJ Language].
reusable aspects, until xref:language.adoc#language[The AspectJ Language].

These categories are informal, and this ordering is not the only way to
adopt AspectJ. Some developers may want to use a production aspect right
@@ -56,7 +56,7 @@ language, but this is by no means a complete overview of AspectJ.

The features are presented using a simple figure editor system. A
`Figure` consists of a number of `FigureElements`, which can be either
`Point`s or `Line`s. The `Figure` class provides factory services. There
``Point``s or ``Line``s. The `Figure` class provides factory services. There
is also a `Display`. Most example programs later in this chapter are
based on this system as well.

@@ -143,17 +143,19 @@ context_ of the original call join point.
In AspectJ, _pointcuts_ pick out certain join points in the program
flow. For example, the pointcut

[source, java]
....
call(void Point.setX(int))
....

picks out each join point that is a call to a method that has the
signature `void Point.setX(int)` - that is, `Point`'s void `setX` method
signature `void Point.setX(int)` - that is, ``Point``'s void `setX` method
with a single `int` parameter.

A pointcut can be built out of other pointcuts with and, or, and not
(spelled `&&`, `||`, and `!`). For example:

[source, java]
....
call(void Point.setX(int)) ||
call(void Point.setY(int))
@@ -165,6 +167,7 @@ picks out each join point that is either a call to `setX` or a call to
Pointcuts can identify join points from many different types - in other
words, they can crosscut types. For example,

[source, java]
....
call(void FigureElement.setXY(int,int)) ||
call(void Point.setX(int)) ||
@@ -182,6 +185,7 @@ crosscutting concern, it is a bit of a mouthful. So AspectJ allows
programmers to define their own named pointcuts with the `pointcut`
form. So the following declares a new, named pointcut:

[source, java]
....
pointcut move():
call(void FigureElement.setXY(int,int)) ||
@@ -202,6 +206,7 @@ _property-based_ crosscutting. The simplest of these involve using
wildcards in certain fields of the method signature. For example, the
pointcut

[source, java]
....
call(void Figure.make*(..))
....
@@ -211,16 +216,18 @@ picks out each join point that's a call to a void method defined on
parameters. In our system, this picks out calls to the factory methods
`makePoint` and `makeLine`. The pointcut

[source, java]
....
call(public * Figure.* (..))
....

picks out each call to `Figure`'s public methods.
picks out each call to ``Figure``'s public methods.

But wildcards aren't the only properties AspectJ supports. Another
pointcut, `cflow`, identifies join points based on whether they occur in
the dynamic context of other join points. So

[source, java]
....
cflow(move())
....
@@ -245,6 +252,7 @@ For example, before advice on a method call join point runs before the
actual method starts running, just after the arguments to the method
call are evaluated.

[source, java]
....
before(): move() {
System.out.println("about to move");
@@ -260,6 +268,7 @@ of after advice: `after returning`, `after
throwing`, and plain `after` (which runs after returning _or_
throwing, like Java's `finally`).

[source, java]
....
after() returning: move() {
System.out.println("just successfully moved");
@@ -280,6 +289,7 @@ An advice declaration has a parameter list (like a method) that gives
names to all the pieces of context that it uses. For example, the after
advice

[source, java]
....
after(FigureElement fe, int x, int y) returning:
...SomePointcut... {
@@ -288,10 +298,11 @@ after(FigureElement fe, int x, int y) returning:
....

uses three pieces of exposed context, a `FigureElement` named fe, and
two `int`s named x and y.
two ``int``s named x and y.

The body of the advice uses the names just like method parameters, so

[source, java]
....
after(FigureElement fe, int x, int y) returning:
...SomePointcut... {
@@ -303,6 +314,7 @@ The advice's pointcut publishes the values for the advice's arguments.
The three primitive pointcuts `this`, `target` and `args` are used to
publish these values. So now we can write the complete piece of advice:

[source, java]
....
after(FigureElement fe, int x, int y) returning:
call(void FigureElement.setXY(int, int))
@@ -326,6 +338,7 @@ named pointcut is used (by advice, or in another named pointcut), it
publishes its context by name just like the `this`, `target` and `args`
pointcut. So another way to write the above advice is

[source, java]
....
pointcut setXY(FigureElement fe, int x, int y):
call(void FigureElement.setXY(int, int))
@@ -360,8 +373,9 @@ Suppose we want to have `Screen` objects observe changes to `Point`
objects, where `Point` is an existing class. We can implement this by
writing an aspect declaring that the class Point `Point` has an instance
field, `observers`, that keeps track of the `Screen` objects that are
observing `Point`s.
observing ``Point``s.

[source, java]
....
aspect PointObserving {
private Vector Point.observers = new Vector();
@@ -373,6 +387,7 @@ The `observers` field is private, so only `PointObserving` can see it.
So observers are added or removed with the static methods `addObserver`
and `removeObserver` on the aspect.

[source, java]
....
aspect PointObserving {
private Vector Point.observers = new Vector();
@@ -391,6 +406,7 @@ Along with this, we can define a pointcut `changes` that defines what we
want to observe, and the after advice defines what we want to do when we
observe a change.

[source, java]
....
aspect PointObserving {
private Vector Point.observers = new Vector();
@@ -417,7 +433,7 @@ aspect PointObserving {
}
....

Note that neither `Screen`'s nor `Point`'s code has to be modified, and
Note that neither ``Screen``'s nor ``Point``'s code has to be modified, and
that all the changes needed to support this new capability are local to
this aspect.

@@ -435,6 +451,7 @@ aspect instances. By default, each aspect is a singleton, so one aspect
instance is created. This means that advice may use non-static fields of
the aspect, if it needs to keep state around:

[source, java]
....
aspect Logging {
OutputStream logStream = System.err;
@@ -471,6 +488,7 @@ workings of a program. It is a simple tracing aspect that prints a
message at specified method calls. In our figure editor example, one
such aspect might simply trace whenever points are drawn.

[source, java]
....
aspect SimpleTracing {
pointcut tracedCall():
@@ -487,6 +505,7 @@ advice bodies this variable is bound to an object that describes the
current join point. The effect of this code is to print a line like the
following every time a figure element receives a `draw` method call:

[source, text]
....
Entering: call(void FigureElement.draw(GraphicsContext))
....
@@ -529,6 +548,7 @@ For example, the following aspect counts the number of calls to the
methods of a `Point` that happen within the control flow of those calls
to `rotate`:

[source, java]
....
aspect SetsInRotateCounting {
int rotateCount = 0;
@@ -589,6 +609,7 @@ properly do the work they are supposed to.
AspectJ makes it possible to implement pre- and post-condition testing
in modular form. For example, this code

[source, java]
....
aspect PointBoundsChecking {

@@ -636,6 +657,7 @@ the constraint that only the well-known factory methods can add an
element to the registry of figure elements. Enforcing this constraint
ensures that no figure element is added to the registry more than once.

[source, java]
....
aspect RegistrationProtection {

@@ -662,6 +684,7 @@ This advice throws a runtime exception at certain join points, but
AspectJ can do better. Using the `declare error` form, we can have the
_compiler_ signal the error.

[source, java]
....
aspect RegistrationProtection {

@@ -722,6 +745,7 @@ state of the dirty flag and resets it to false. The pointcut `move`
captures all the method calls that can move a figure element. The after
advice on `move` sets the dirty flag whenever an object moves.

[source, java]
....
aspect MoveTracking {
private static boolean dirty = false;
@@ -807,6 +831,7 @@ modular way. The following code adds after advice that runs only when
the factory methods of `Figure` are called in the control flow of a
method on a `ColorControllingClient`.

[source, java]
....
aspect ColorControl {
pointcut CCClientCflow(ColorControllingClient client):
@@ -841,6 +866,7 @@ captures the public method calls of the package, and the after advice
runs whenever one of those calls throws an Error. The advice logs that
Error and then the throw resumes.

[source, java]
....
aspect PublicErrorLogging {
Log log = new Log();
@@ -861,6 +887,7 @@ outermost call into the `com.bigboxco` package and the re-entrant call.
The `cflow` primitive pointcut can be used in a nice way to exclude
these re-entrant calls:

[source, java]
....
after() throwing (Error e):
publicMethodCall() && !cflow(publicMethodCall()) {
@@ -874,6 +901,7 @@ individual methods handle each of the different kinds of elements that
must be parsed. They have names like `parseMethodDec`, `parseThrows`,
and `parseExpr`.

[source, java]
....
aspect ContextFilling {
pointcut parse(JavaParser jp):

+ 5
- 0
docs/progGuideDB/idioms.adoc View File

@@ -11,6 +11,7 @@ Here's an example of how to enfore a rule that code in the java.sql
package can only be used from one particular package in your system.
This doesn't require any access to code in the java.sql package.

[source, java]
....
/* Any call to methods or constructors in java.sql */
pointcut restrictedCall():
@@ -27,6 +28,7 @@ declare error: restrictedCall() && illegalSource():
Any call to an instance of a subtype of AbstractFacade whose class is
not exactly equal to AbstractFacade:

[source, java]
....
pointcut nonAbstract(AbstractFacade af):
call(* *(..))
@@ -37,6 +39,7 @@ pointcut nonAbstract(AbstractFacade af):
If AbstractFacade is an abstract class or an interface, then every
instance must be of a subtype and you can replace this with:

[source, java]
....
pointcut nonAbstract(AbstractFacade af):
call(* *(..))
@@ -46,6 +49,7 @@ pointcut nonAbstract(AbstractFacade af):
Any call to a method which is defined by a subtype of AbstractFacade,
but which isn't defined by the type AbstractFacade itself:

[source, java]
....
pointcut callToUndefinedMethod():
call(* AbstractFacade+.*(..))
@@ -55,6 +59,7 @@ pointcut callToUndefinedMethod():
The execution of a method that is defined in the source code for a type
that is a subtype of AbstractFacade but not in AbstractFacade itself:

[source, java]
....
pointcut executionOfUndefinedMethod():
execution(* *(..))

+ 6
- 0
docs/progGuideDB/implementation.adoc View File

@@ -17,6 +17,7 @@ implementations should do tomorrow.

According to the AspectJ language semantics, the declaration

[source, java]
....
before(): get(int Point.x) { System.out.println("got x"); }
....
@@ -128,6 +129,7 @@ source code. This means that there may be call join points to
`Class.forName` or `StringBuffer.append` from programs that do not, at
first glance, appear to contain such calls:

[source, java]
....
class Test {
void main(String[] args) {
@@ -158,6 +160,7 @@ be the case. Before advice is allowed.
The second is that the control flow of a handler join point is not
picked out. For example, the following pointcut

[source, java]
....
cflow(call(void foo()) || handler(java.io.IOException))
....
@@ -173,6 +176,7 @@ This does not restrict programs from placing before advice on handlers
inside _other_ control flows. This advice, for example, is perfectly
fine:

[source, java]
....
before(): handler(java.io.IOException) && cflow(void parse()) {
System.out.println("about to handle an exception while parsing");
@@ -187,6 +191,7 @@ have fewer such restrictions.

The code for Java initializers, such as the assignment to the field d in

[source, java]
....
class C {
double d = Math.sqrt(2);
@@ -203,6 +208,7 @@ a super-constructor (as opposed to a `this` constructor), the target
type's initialization code will _not_ be run when that inter-type
constructor is called.

[source, java]
....
aspect A {
C.new(Object o) {} // implicitly calls super()

+ 79
- 36
docs/progGuideDB/language.adoc View File

@@ -24,30 +24,31 @@ exposed to the new terminology introduced by AspectJ.

Here's an example of an aspect definition in AspectJ:

....
1 aspect FaultHandler {
2
3 private boolean Server.disabled = false;
4
5 private void reportFault() {
6 System.out.println("Failure! Please fix it.");
7 }
8
9 public static void fixServer(Server s) {
10 s.disabled = false;
11 }
12
13 pointcut services(Server s): target(s) && call(public * *(..));
14
15 before(Server s): services(s) {
16 if (s.disabled) throw new DisabledException();
17 }
18
19 after(Server s) throwing (FaultException e): services(s) {
20 s.disabled = true;
21 reportFault();
22 }
23 }
[source, java]
....
/*01*/ aspect FaultHandler {
/*02*/
/*03*/ private boolean Server.disabled = false;
/*04*/
/*05*/ private void reportFault() {
/*06*/ System.out.println("Failure! Please fix it.");
/*07*/ }
/*08*/
/*09*/ public static void fixServer(Server s) {
/*10*/ s.disabled = false;
/*11*/ }
/*12*/
/*13*/ pointcut services(Server s): target(s) && call(public * *(..));
/*14*/
/*15*/ before(Server s): services(s) {
/*16*/ if (s.disabled) throw new DisabledException();
/*17*/ }
/*18*/
/*19*/ after(Server s) throwing (FaultException e): services(s) {
/*20*/ s.disabled = true;
/*21*/ reportFault();
/*22*/ }
/*23*/ }
....

The `FaultHandler` consists of one inter-type field on `Server` (line
@@ -69,6 +70,7 @@ invocations and executions, the handling of exceptions, field
assignments and accesses, etc. Take, for example, the pointcut
definition in line 13:

[source, java]
....
pointcut services(Server s): target(s) && call(public * *(..))
....
@@ -114,6 +116,7 @@ define aspect implementation that runs at join points picked out by the
pointcut. For example, the advice in lines 15-17 specifies that the
following piece of code

[source, java]
....
{
if (s.disabled) throw new DisabledException();
@@ -128,6 +131,7 @@ corresponding methods are executed.
The advice in lines 19-22 defines another piece of implementation that
is executed on the same pointcut:

[source, java]
....
{
s.disabled = true;
@@ -148,6 +152,7 @@ this guide.

Consider the following Java class:

[source, java]
....
class Point {
private int x, y;
@@ -166,6 +171,7 @@ In order to get an intuitive understanding of AspectJ's join points and
pointcuts, let's go back to some of the basic principles of Java.
Consider the following a method declaration in class Point:

[source, java]
....
void setX(int x) { this.x = x; }
....
@@ -192,6 +198,7 @@ complete listing.)

Pointcuts pick out these join points. For example, the pointcut

[source, java]
....
pointcut setter(): target(Point) &&
(call(void setX(int)) ||
@@ -201,6 +208,7 @@ pointcut setter(): target(Point) &&
picks out each call to `setX(int)` or `setY(int)` when called on an
instance of `Point`. Here's another example:

[source, java]
....
pointcut ioHandler(): within(MyClass) && handler(IOException);
....
@@ -230,7 +238,7 @@ when the target object is of type `SomeType`::
`target(SomeType)`
when the executing code belongs to class `MyClass`::
`within(MyClass)`
when the join point is in the control flow of a call to a `Test`'s
when the join point is in the control flow of a call to a ``Test``'s
no-argument `main` method::
`cflow(call(void Test.main()))`

@@ -256,9 +264,9 @@ such `set` method; this pointcut picks out calls to all of them.
means (1) the execution of any method with no parameters that returns an
`int`, (2) the call to any `setY` method that takes a `long` as an
argument, regardless of return type or declaring type, (3) the call to
any of `Point`'s `setY` methods that take an `int` as an argument,
any of ``Point``'s `setY` methods that take an `int` as an argument,
regardless of return type, and (4) the call to any classes' constructor,
so long as it takes exactly two `int`s as arguments.
so long as it takes exactly two ``int``s as arguments.
* You can compose pointcuts. For example,
[arabic]
. `target(Point) && call(int *())`
@@ -270,7 +278,7 @@ so long as it takes exactly two `int`s as arguments.
+
means (1) any call to an `int` method with no arguments on an instance
of `Point`, regardless of its name, (2) any call to any method where the
call is made from the code in `Point`'s or `Line`'s type declaration,
call is made from the code in ``Point``'s or ``Line``'s type declaration,
(3) the execution of any constructor taking exactly one `int` argument,
regardless of where the call is made from, and (4) any method call to an
`int` method when the executing object is any type except `Point`.
@@ -286,12 +294,13 @@ non-static method, and (3) any execution of a public, non-static method.
* Pointcuts can also deal with interfaces. For example, given the
interface
+
[source, java]
....
interface MyInterface { ... }
....
+
the pointcut `call(* MyInterface.*(..))` picks out any call to a method
in `MyInterface`'s signature -- that is, any method defined by
in ``MyInterface``'s signature -- that is, any method defined by
`MyInterface` or inherited by one of its a supertypes.

[[call-vs-execution]]
@@ -339,6 +348,7 @@ primitive pointcuts like `cflow` and `cflowbelow`. Here's an example:
`cflow(P)` picks out each join point in the control flow of the join
points picked out by <P>. So, pictorially:

[source, text]
....
P ---------------------
\
@@ -350,6 +360,7 @@ What does `cflow(P) &&
cflow(Q)` pick out? Well, it picks out each join point that is
in both the control flow of <P> and in the control flow of <Q>. So...

[source, text]
....
P ---------------------
\
@@ -370,6 +381,7 @@ But what does `cflow(P
&& Q)` mean? Well, it means the control flow of those join
points that are both picked out by <P> and picked out by <Q>.

[source, text]
....
P && Q -------------------
\
@@ -384,6 +396,7 @@ control flow of `(P &&

Here's some code that expresses this.

[source, java]
....
public class Test {
public static void main(String[] args) {
@@ -422,6 +435,7 @@ for more details.)

Consider again the first pointcut definition in this chapter:

[source, java]
....
pointcut setter(): target(Point) &&
(call(void setX(int)) ||
@@ -435,6 +449,7 @@ side. An empty parameter list means that none of the context from the
join points is published from this pointcut. But consider another
version of version of this pointcut definition:

[source, java]
....
pointcut setter(Point p): target(p) &&
(call(void setX(int)) ||
@@ -452,6 +467,7 @@ matched join point.
Here's another example that illustrates the flexible mechanism for
defining pointcut parameters:

[source, java]
....
pointcut testEquality(Point p): target(Point) &&
args(p) &&
@@ -464,10 +480,11 @@ access to a `Point` from each join point. But in this case, looking at
the right-hand side we find that the object named in the parameters is
not the target `Point` object that receives the call; it's the argument
(also of type `Point`) passed to the `equals` method when some other
`Point` is the target. If we wanted access to both `Point`s, then the
`Point` is the target. If we wanted access to both ``Point``s, then the
pointcut definition that would expose target `Point p1` and argument
`Point p2` would be

[source, java]
....
pointcut testEquality(Point p1, Point p2): target(p1) &&
args(p2) &&
@@ -476,6 +493,7 @@ pointcut testEquality(Point p1, Point p2): target(p1) &&

Let's look at another variation of the `setters` pointcut:

[source, java]
....
pointcut setter(Point p, int newval): target(p) &&
args(newval) &&
@@ -493,6 +511,7 @@ important rule is that all the pointcut parameters must be bound at
every join point picked out by the pointcut. So, for example, the
following pointcut definition will result in a compilation error:

[source, java]
....
pointcut badPointcut(Point p1, Point p2):
(target(p1) && call(void setX(int))) ||
@@ -512,6 +531,7 @@ operations to their `Partner` objects. The aspect `HandleLiveness`
ensures that, before the delegations, the partner exists and is alive,
or else it throws an exception.

[source, java]
....
class Handle {
Partner partner = new Partner();
@@ -594,6 +614,7 @@ given either by named pointcuts (like the ones you've seen above) or by
anonymous pointcuts. Here is an example of an advice on a named
pointcut:

[source, java]
....
pointcut setter(Point p1, int newval): target(p1) && args(newval)
(call(void setX(int) ||
@@ -607,6 +628,7 @@ before(Point p1, int newval): setter(p1, newval) {

And here is exactly the same example, but using an anonymous pointcut:

[source, java]
....
before(Point p1, int newval): target(p1) && args(newval)
(call(void setX(int)) ||
@@ -621,6 +643,7 @@ Here are examples of the different advice:
This before advice runs just before the join points picked out by the
(anonymous) pointcut:

[source, java]
....
before(Point p, int x): target(p) && args(x) && call(void setX(int)) {
if (!p.assertX(x)) return;
@@ -631,6 +654,7 @@ This after advice runs just after each join point picked out by the
(anonymous) pointcut, regardless of whether it returns normally or
throws an exception:

[source, java]
....
after(Point p, int x): target(p) && args(x) && call(void setX(int)) {
if (!p.assertX(x)) throw new PostConditionViolation();
@@ -642,6 +666,7 @@ by the (anonymous) pointcut, but only if it returns normally. The return
value can be accessed, and is named `x` here. After the advice runs, the
return value is returned:

[source, java]
....
after(Point p) returning(int x): target(p) && call(int getX()) {
System.out.println("Returning int value " + x + " for p = " + p);
@@ -653,6 +678,7 @@ the (anonymous) pointcut, but only when it throws an exception of type
`Exception`. Here the exception value can be accessed with the name `e`.
The advice re-raises the exception after it's done:

[source, java]
....
after() throwing(Exception e): target(Point) && call(void setX(int)) {
System.out.println(e);
@@ -663,6 +689,7 @@ This around advice traps the execution of the join point; it runs
_instead_ of the join point. The original action associated with the
join point can be invoked through the special `proceed` call:

[source, java]
....
void around(Point p, int x): target(p)
&& args(x)
@@ -683,6 +710,7 @@ class. Here are examples of some such inter-type declarations:
This declares that each `Server` has a `boolean` field named `disabled`,
initialized to `false`:

[source, java]
....
private boolean Server.disabled = false;
....
@@ -696,6 +724,7 @@ another aspect) there won't be a name collision, since no reference to
This declares that each `Point` has an `int` method named `getX` with no
arguments that returns whatever `this.x` is:

[source, java]
....
public int Point.getX() { return this.x; }
....
@@ -707,6 +736,7 @@ conflict.

This publically declares a two-argument constructor for `Point`:

[source, java]
....
public Point.new(int x, int y) { this.x = x; this.y = y; }
....
@@ -714,6 +744,7 @@ public Point.new(int x, int y) { this.x = x; this.y = y; }
This publicly declares that each `Point` has an `int` field named `x`,
initialized to zero:

[source, java]
....
public int Point.x = 0;
....
@@ -724,6 +755,7 @@ has a field named `x` (defined by `Point` or by another aspect).
This declares that the `Point` class implements the `Comparable`
interface:

[source, java]
....
declare parents: Point implements Comparable;
....
@@ -734,6 +766,7 @@ required by `Comparable`.
This declares that the `Point` class extends the `GeometricObject`
class.

[source, java]
....
declare parents: Point extends GeometricObject;
....
@@ -741,6 +774,7 @@ declare parents: Point extends GeometricObject;
An aspect can have several inter-type declarations. For example, the
following declarations

[source, java]
....
public String Point.name;
public void Point.setName(String name) { this.name = name; }
@@ -754,6 +788,7 @@ An inter-type member can only have one target type, but often you may
wish to declare the same member on more than one type. This can be done
by using an inter-type member in combination with a private interface:

[source, java]
....
aspect A {
private interface HasName {}
@@ -782,18 +817,20 @@ declarations in addition to public inter-type declarations. Private
means private in relation to the aspect, not necessarily the target
type. So, if an aspect makes a private inter-type declaration of a field

[source, java]
....
private int Foo.x;
....

Then code in the aspect can refer to `Foo`'s `x` field, but nobody else
Then code in the aspect can refer to ``Foo``'s `x` field, but nobody else
can. Similarly, if an aspect makes a package-protected introduction,

[source, java]
....
int Foo.x;
int Foo.x;
....

then everything in the aspect's package (which may or may not be `Foo`'s
then everything in the aspect's package (which may or may not be ``Foo``'s
package) can access `x`.

==== Example: `PointAssertions`
@@ -806,6 +843,7 @@ other parts of the program (including the code in `Point`) have no
business accessing the assert methods. Only the code inside of the
aspect can call those methods.

[source, java]
....
class Point {
int x, y;
@@ -856,6 +894,7 @@ One way to use it is simply to print it out. Like all Java objects,
`thisJoinPoint` has a `toString()` method that makes quick-and-dirty
tracing easy:

[source, java]
....
aspect TraceNonStaticMethods {
before(Point p): target(p) && call(* *(..)) {
@@ -868,6 +907,7 @@ The type of `thisJoinPoint` includes a rich reflective class hierarchy
of signatures, and can be used to access both static and dynamic
information about join points such as the arguments of the join point:

[source, java]
....
thisJoinPoint.getArgs()
....
@@ -876,6 +916,7 @@ In addition, it holds an object consisting of all the static information
about the join point such as corresponding line number and static
signature:

[source, java]
....
thisJoinPoint.getStaticPart()
....
@@ -888,6 +929,7 @@ necessary when using `thisJoinPoint` directly.

It is always the case that

[source, java]
....
thisJoinPointStaticPart == thisJoinPoint.getStaticPart()

@@ -903,8 +945,9 @@ but it is not the current but the enclosing join point. So, for example,
it is possible to print out the calling source location (if available)
with

[source, java]
....
before() : execution (* *(..)) {
System.err.println(thisEnclosingJoinPointStaticPart.getSourceLocation())
}
before() : execution (* *(..)) {
System.err.println(thisEnclosingJoinPointStaticPart.getSourceLocation())
}
....

+ 5
- 0
docs/progGuideDB/pitfalls.adoc View File

@@ -11,6 +11,7 @@ surprising behavior and how to understand them.

Here is a Java program with peculiar behavior

[source, java]
....
public class Main {
public static void main(String[] args) {
@@ -39,6 +40,7 @@ the completely silent abort.

The following short aspect will also generate this behavior:

[source, java]
....
aspect A {
before(): call(* *(..)) { System.out.println("before"); }
@@ -50,6 +52,7 @@ Why? Because the call to println is also a call matched by the pointcut
`call (* *(..))`. We get no output because we used simple after()
advice. If the aspect were changed to

[source, java]
....
aspect A {
before(): call(* *(..)) { System.out.println("before"); }
@@ -65,6 +68,7 @@ There's a simple idiom to use if you ever have a worry that your advice
might apply in this way. Just restrict the advice from occurring in join
points caused within the aspect. So:

[source, java]
....
aspect A {
before(): call(* *(..)) && !within(A) { System.out.println("before"); }
@@ -75,6 +79,7 @@ aspect A {
Other solutions might be to more closely restrict the pointcut in other
ways, for example:

[source, java]
....
aspect A {
before(): call(* MyObject.*(..)) { System.out.println("before"); }

+ 71
- 243
docs/progGuideDB/quickreference.adoc View File

@@ -9,16 +9,16 @@
|*Methods and Constructors* |

|`call(Signature)` |every call to any method or constructor matching
<Signature> at the call site
`<Signature>` at the call site

|`execution(Signature)` |every execution of any method or constructor
matching <Signature>
matching `<Signature>`

|*Fields* |

|`get(Signature)` |every reference to any field matching <Signature>
|`get(Signature)` |every reference to any field matching `<Signature>`

|`set(Signature)` |every assignment to any field matching <Signature>.
|`set(Signature)` |every assignment to any field matching `<Signature>`.
The assigned value can be exposed with an `args` pointcut

|*Exception Handlers* |
@@ -37,12 +37,12 @@ pointcut
initializer for any type in <TypePattern>

|`initialization(Signature)` |every initialization of an object when the
first constructor called in the type matches <Signature>, encompassing
first constructor called in the type matches `<Signature>`, encompassing
the return from the super constructor call to the return of the
first-called constructor

|`preinitialization(Signature)` |every pre-initialization of an object
when the first constructor called in the type matches <Signature>,
when the first constructor called in the type matches `<Signature>`,
encompassing the entry of the first-called constructor to the call to
the super constructor

@@ -52,7 +52,7 @@ the super constructor
<TypePattern>

|`withincode(Signature)` |every join point from code defined in a method
or constructor matching <Signature>
or constructor matching `<Signature>`
|===

[[quick-typePatterns]]
@@ -62,290 +62,118 @@ A type pattern is one of

[cols=",",]
|===
|<TypeNamePattern> |all types in <TypeNamePattern>
|*Type pattern* |

|<SubtypePattern> |all types in <SubtypePattern>, a pattern with a +.
|`<TypeNamePattern>` |all types in `<TypeNamePattern>`

|<ArrayTypePattern> |all types in <ArrayTypePattern>, a pattern with one
or more []s.
|`<SubtypePattern>` |all types in `<SubtypePattern>`, a pattern with a `+`

|`<ArrayTypePattern>` |all types in `<ArrayTypePattern>`, a pattern with one or more ``[]``s.

|`!TypePattern` |all types not in <TypePattern>

|`TypePattern0
&& TypePattern1` |all types in both <TypePattern0> and
<TypePattern1>
|`TypePattern0 && TypePattern1` |all types in both `<TypePattern0>` and `<TypePattern1>`

|`TypePattern0 || TypePattern1` |all types in either <TypePattern0> or
<TypePattern1>
|`TypePattern0 \|\| TypePattern1` |all types in either `<TypePattern0>` or `<TypePattern1>`

|`( TypePattern )` |all types in <TypePattern>
|`( TypePattern )` |all types in `<TypePattern>`
|===

where <TypeNamePattern> can either be a plain type name, the wildcard
`*` (indicating all types), or an identifier with embedded `*` and `..`
where `<TypeNamePattern>` can either be a plain type name, the wildcard
`\*` (indicating all types), or an identifier with embedded `*` and `..`
wildcards.

An embedded `*` in an identifier matches any sequence of characters, but
does not match the package (or inner-type) separator ".".
does not match the package (or inner-type) separator `.`.

An embedded `..` in an identifier matches any sequence of characters
that starts and ends with the package (or inner-type) separator ".".
that starts and ends with the package (or inner-type) separator `.`.

[[quick-advice]]
=== Advice

Each piece of advice is of the form

____
[ strictfp ]

AdviceSpec

[ throws

TypeList

] :

Pointcut
[source, text]
....
[ strictfp ] AdviceSpec [ throws TypeList ] : Pointcut { Body }
....

\{
where `<AdviceSpec>` is one of

Body

}
____

where <AdviceSpec> is one of

`before( Formals ) `::
`before( Formals )`::
runs before each join point
`after( Formals ) returning
[ ( Formal ) ] `::
`after( Formals ) returning [ ( Formal ) ]`::
runs after each join point that returns normally. The optional formal
gives access to the returned value
`after( Formals ) throwing [
( Formal ) ] `::
runs after each join point that throws a
+
Throwable
+
. If the optional formal is present, runs only after each join point
that throws a
+
Throwable
+
of the type of
+
Formal
+
, and
+
Formal
+
gives access to the
+
Throwable
+
exception value
`after( Formals ) `::
`after( Formals ) throwing [ ( Formal ) ]`::
runs after each join point that throws a `Throwable`.
If the optional formal is present, runs only after each join point
that throws a `Throwable` of the type of `Formal`, and `Formal` gives access to the
`Throwable` exception value
`after( Formals )`::
runs after each join point regardless of whether it returns normally
or throws a
+
Throwable
`Type
around( Formals ) `::
or throws a `Throwable`
`Type around( Formals )`::
runs in place of each join point. The join point can be executed by
calling
+
proceed
+
, which takes the same number and types of arguments as the around
calling `proceed`, which takes the same number and types of arguments as the around
advice.

Three special variables are available inside of advice bodies:

`thisJoinPoint`::
an object of type
+
org.aspectj.lang.JoinPoint
+
representing the join point at which the advice is executing.
an object of type `org.aspectj.lang.JoinPoint` representing the join point
at which the advice is executing
`thisJoinPointStaticPart`::
equivalent to
+
thisJoinPoint.getStaticPart()
+
, but may use fewer runtime resources.
equivalent to `thisJoinPoint.getStaticPart()`, but may use fewer runtime resources
`thisEnclosingJoinPointStaticPart`::
the static part of the dynamically enclosing join point.
the static part of the dynamically enclosing join point

[[quick-interType]]
=== Inter-type member declarations

Each inter-type member is one of

`
Modifiers ReturnType OnType . Id
( Formals )
[ throws TypeList ]
{ Body }
`::
a method on
+
OnType
+
.
`
abstract Modifiers ReturnType OnType . Id
( Formals )
[ throws TypeList ] ;
`::
an abstract method on
+
OnType
+
.
`
Modifiers OnType . new
( Formals )
[ throws TypeList ]
{ Body }
`::
a constructor on
+
OnType
+
.
`
Modifiers Type OnType . Id
[ = Expression ] ;
`::
a field on
+
OnType
+
.
`Modifiers ReturnType OnType . Id ( Formals ) [ throws TypeList ] { Body }`::
a method on `OnType`
`abstract Modifiers ReturnType OnType . Id ( Formals ) [ throws TypeList ] ;`::
an abstract method on `OnType`
`Modifiers OnType . new ( Formals ) [ throws TypeList ] { Body }`::
a constructor on `OnType`
`Modifiers Type OnType . Id [ = Expression ] ;`::
a field on `OnType`

[[quick-other]]
=== Other declarations

`
declare parents :
TypePattern extends
Type ;
`::
the types in
+
TypePattern
+
extend
+
Type
+
.
`
declare parents : TypePattern
implements TypeList ;
`::
the types in
+
TypePattern
+
implement the types in
+
TypeList
+
.
`
declare warning : Pointcut :
String ;
`::
if any of the join points in
+
Pointcut
+
possibly exist in the program, the compiler emits the warning
+
String
+
.
`
declare error : Pointcut :
String ;
`::
if any of the join points in
+
Pointcut
+
could possibly exist in the program, the compiler emits the error
+
String
+
.
`
declare soft :
Type :
Pointcut ;
`::
any
+
Type
+
exception that gets thrown at any join point picked out by
+
Pointcut
+
is wrapped in
+
org.aspectj.lang.SoftException
+
.
`
declare precedence :
TypePatternList ;
`::
`declare parents : TypePattern extends Type ;`::
the types in `TypePattern` extend `Type`
`declare parents : TypePattern implements TypeList ;`::
the types in `TypePattern` implement the types in `TypeList`
`declare warning : Pointcut : String ;`::
if any of the join points in `Pointcut` possibly exist in the program,
the compiler emits the warning `String`
`declare error : Pointcut : String ;`::
if any of the join points in `Pointcut` could possibly exist in the program,
the compiler emits the error `String`
`declare soft : Type : Pointcut ;`::
any `Type` exception that gets thrown at any join point picked out by `Pointcut`
is wrapped in `org.aspectj.lang.SoftException`
`declare precedence : TypePatternList ;`::
at any join point where multiple pieces of advice apply, the advice
precedence at that join point is in
+
TypePatternList
+
order.
precedence at that join point is in `TypePatternList` order

[[quick-aspectAssociations]]
=== Aspects

Each aspect is of the form

____
[ privileged ]

Modifiers

aspect

Id

[ extends

Type

] [ implements

TypeList

] [

PerClause

] \{

Body

}
____
[source, text]
....
[ privileged ] Modifiers aspect Id [ extends Type ] [ implements TypeList ] [ PerClause ] { Body }
....

where <PerClause> defines how the aspect is instantiated and associated
where `<PerClause>` defines how the aspect is instantiated and associated
(`issingleton()` by default):

[cols=",,",options="header",]
@@ -355,18 +183,18 @@ where <PerClause> defines how the aspect is instantiated and associated
default. |`aspectOf()` at all join points

|`perthis(Pointcut)` |An instance is associated with each object that is
the currently executing object at any join point in <Pointcut>.
the currently executing object at any join point in `<Pointcut>`.
|`aspectOf(Object)` at all join points

|`pertarget(Pointcut)` |An instance is associated with each object that
is the target object at any join point in <Pointcut>.
is the target object at any join point in `<Pointcut>`.
|`aspectOf(Object)` at all join points

|`percflow(Pointcut)` |The aspect is defined for each entrance to the
control flow of the join points defined by <Pointcut>. |`aspectOf()` at
control flow of the join points defined by `<Pointcut>`. |`aspectOf()` at
join points in `cflow(Pointcut)`

|`percflowbelow(Pointcut)` |The aspect is defined for each entrance to
the control flow below the join points defined by <Pointcut>.
the control flow below the join points defined by `<Pointcut>`.
|`aspectOf()` at join points in `cflowbelow(Pointcut)`
|===

+ 112
- 198
docs/progGuideDB/semantics.adoc View File

@@ -63,11 +63,7 @@ Constructor call::
Constructor execution::
When the body of code for an actual constructor executes, after its
this or super constructor call. The object being constructed is the
currently executing object, and so may be accessed with the
+
this
+
pointcut. The constructor execution join point for a constructor that
currently executing object, and so may be accessed with the `_this_` pointcut. The constructor execution join point for a constructor that
calls a super constructor also includes any non-static initializers of
enclosing class. No value is returned from a constructor execution
join point, so its return type is considered to be void.
@@ -80,15 +76,7 @@ Object pre-initialization::
This encompasses the time between the start of its first called
constructor and the start of its parent's constructor. Thus, the
execution of these join points encompass the join points of the
evaluation of the arguments of
+
this()
+
and
+
super()
+
constructor calls. No value is returned from an object
evaluation of the arguments of `_this()_` and `_super()_` constructor calls. No value is returned from an object
pre-initialization join point, so its return type is considered to be
void.
Object initialization::
@@ -97,11 +85,7 @@ Object initialization::
and the return of its first called constructor. It includes all the
dynamic initializers and constructors used to create the object. The
object being constructed is the currently executing object, and so may
be accessed with the
+
this
+
pointcut. No value is returned from a constructor execution join
be accessed with the `_this_` pointcut. No value is returned from a constructor execution join
point, so its return type is considered to be void.
Field reference::
When a non-constant field is referenced. [Note that references to
@@ -180,219 +164,84 @@ build up other pointcuts. The primitive pointcuts and combinators
provided by the language are:

`call(MethodPattern)`::
Picks out each method call join point whose signature matches
+
MethodPattern
+
.
Picks out each method call join point whose signature matches `_MethodPattern_`.
`execution(MethodPattern)`::
Picks out each method execution join point whose signature matches
+
MethodPattern
+
.
Picks out each method execution join point whose signature matches `_MethodPattern_`.
`get(FieldPattern)`::
Picks out each field reference join point whose signature matches
+
FieldPattern
+
. [Note that references to constant fields (static final fields bound
Picks out each field reference join point whose signature matches `_FieldPattern_`. [Note that references to constant fields (static final fields bound
to a constant string object or primitive value) are not join points,
since Java requires them to be inlined.]
`set(FieldPattern)`::
Picks out each field set join point whose signature matches
+
FieldPattern
+
. [Note that the initializations of constant fields (static final
Picks out each field set join point whose signature matches `_FieldPattern_`. [Note that the initializations of constant fields (static final
fields where the initializer is a constant string object or primitive
value) are not join points, since Java requires their references to be
inlined.]
`call(ConstructorPattern)`::
Picks out each constructor call join point whose signature matches
+
ConstructorPattern
+
.
Picks out each constructor call join point whose signature matches `_ConstructorPattern_`.
`execution(ConstructorPattern)`::
Picks out each constructor execution join point whose signature
matches
+
ConstructorPattern
+
.
matches `_ConstructorPattern_`.
`initialization(ConstructorPattern)`::
Picks out each object initialization join point whose signature
matches
+
ConstructorPattern
+
.
matches `_ConstructorPattern_`.
`preinitialization(ConstructorPattern)`::
Picks out each object pre-initialization join point whose signature
matches
+
ConstructorPattern
+
.
matches `_ConstructorPattern_`.
`staticinitialization(TypePattern)`::
Picks out each static initializer execution join point whose signature
matches
+
TypePattern
+
.
matches `_TypePattern_`.
`handler(TypePattern)`::
Picks out each exception handler join point whose signature matches
+
TypePattern
+
.
Picks out each exception handler join point whose signature matches `_TypePattern_`.
`adviceexecution()`::
Picks out all advice execution join points.
`within(TypePattern)`::
Picks out each join point where the executing code is defined in a
type matched by
+
TypePattern
+
.
type matched by `_TypePattern_`.
`withincode(MethodPattern)`::
Picks out each join point where the executing code is defined in a
method whose signature matches
+
MethodPattern
+
.
method whose signature matches `_MethodPattern_`.
`withincode(ConstructorPattern)`::
Picks out each join point where the executing code is defined in a
constructor whose signature matches
+
ConstructorPattern
+
.
constructor whose signature matches `_ConstructorPattern_`.
`cflow(Pointcut)`::
Picks out each join point in the control flow of any join point
+
P
+
picked out by
+
Pointcut
+
, including
+
P
+
itself.
Picks out each join point in the control flow of any join point `_P_` picked out by `_Pointcut_` , including `_P_` itself.
`cflowbelow(Pointcut)`::
Picks out each join point in the control flow of any join point
+
P
+
picked out by
+
Pointcut
+
, but not
+
P
+
itself.
Picks out each join point in the control flow of any join point `_P_` picked out by `_Pointcut_`, but not `_P_` itself.
`this(Type or Id)`::
Picks out each join point where the currently executing object (the
object bound to
+
this
+
) is an instance of
+
Type
+
, or of the type of the identifier
+
Id
+
(which must be bound in the enclosing advice or pointcut definition).
object bound to `_this_`) is an instance of `_Type_` , or of the type of the identifier `_Id_` (which must be bound in the enclosing advice or pointcut definition).
Will not match any join points from static contexts.
`target(Type or Id)`::
Picks out each join point where the target object (the object on which
a call or field operation is applied to) is an instance of
+
Type
+
, or of the type of the identifier
+
Id
+
(which must be bound in the enclosing advice or pointcut definition).
a call or field operation is applied to) is an instance of `_Type_` , or of the type of the identifier `_Id_` (which must be bound in the enclosing advice or pointcut definition).
Will not match any calls, gets, or sets of static members.
`args(Type or Id, ...)`::
Picks out each join point where the arguments are instances of the
appropriate type (or type of the identifier if using that form). A
+
null
+
argument is matched iff the static type of the argument (declared
appropriate type (or type of the identifier if using that form). A `_null_` argument is matched iff the static type of the argument (declared
parameter type or field type) is the same as, or a subtype of, the
specified args type.
`PointcutId(TypePattern or Id, ...)`::
Picks out each join point that is picked out by the user-defined
pointcut designator named by
+
PointcutId
+
.
pointcut designator named by `_PointcutId_` .
`if(BooleanExpression)`::
Picks out each join point where the boolean expression evaluates to
+
true
+
. The boolean expression used can only access static members,
parameters exposed by the enclosing pointcut or advice, and
+
thisJoinPoint
+
forms. In particular, it cannot call non-static methods on the aspect
Picks out each join point where the boolean expression evaluates to `_true_` . The boolean expression used can only access static members,
parameters exposed by the enclosing pointcut or advice, and `_thisJoinPoint_` forms. In particular, it cannot call non-static methods on the aspect
or use return values or exceptions exposed by after advice.
`! Pointcut`::
Picks out each join point that is not picked out by
+
Pointcut
+
.
Picks out each join point that is not picked out by `_Pointcut_` .
`Pointcut0 && Pointcut1`::
Picks out each join points that is picked out by both
+
Pointcut0
+
and
+
Pointcut1
+
.
Picks out each join points that is picked out by both `_Pointcut0_` and `_Pointcut1_` .
`Pointcut0 || Pointcut1`::
Picks out each join point that is picked out by either pointcuts.
+
Pointcut0
+
or
+
Pointcut1
+
.
Picks out each join point that is picked out by either pointcuts. `_Pointcut0_` or `_Pointcut1_` .
`( Pointcut )`::
Picks out each join points picked out by
+
Pointcut
+
.
Picks out each join points picked out by `_Pointcut_` .

==== Pointcut definition

Pointcuts are defined and named by the programmer with the `pointcut`
declaration.

[source, java]
....
pointcut publicIntCall(int i):
call(public * *(int)) && args(i);
@@ -402,6 +251,7 @@ A named pointcut may be defined in either a class or aspect, and is
treated as a member of the class or aspect where it is found. As a
member, it may have an access modifier such as `public` or `private`.

[source, java]
....
class C {
pointcut publicCall(int i):
@@ -418,6 +268,7 @@ Pointcuts that are not final may be declared abstract, and defined
without a body. Abstract pointcuts may only be declared within abstract
aspects.

[source, java]
....
abstract aspect A {
abstract pointcut publicCall(int i);
@@ -426,6 +277,7 @@ abstract aspect A {

In such a case, an extending aspect may override the abstract pointcut.

[source, java]
....
aspect B extends A {
pointcut publicCall(int i): call(public Foo.m(int)) && args(i);
@@ -444,6 +296,7 @@ is different than the scope of other members; the scope of other members
is the enclosing class _body_. This means that the following code is
legal:

[source, java]
....
aspect B percflow(publicCall()) {
pointcut publicCall(): call(public Foo.m(int));
@@ -466,6 +319,7 @@ collection of types. The pointcut designators that allow this are
rather than a type does two things. First, it selects join points as
based on the type of the formal parameter. So the pointcut

[source, java]
....
pointcut intArg(int i): args(i);
....
@@ -477,6 +331,7 @@ advice or pointcut.

Values can be exposed from named pointcuts as well, so

[source, java]
....
pointcut publicCall(int x): call(public *.*(int)) && intArg(x);
pointcut intArg(int i): args(i);
@@ -489,6 +344,7 @@ There is one special case for this kind of exposure. Exposing an
argument of type Object will also match primitive typed arguments, and
expose a "boxed" version of the primitive. So,

[source, java]
....
pointcut publicCall(): call(public *.*(..)) && args(Object);
....
@@ -496,6 +352,7 @@ pointcut publicCall(): call(public *.*(..)) && args(Object);
will pick out all unary methods that take, as their only argument,
subtypes of Object (i.e., not primitive types like `int`), but

[source, java]
....
pointcut publicCall(Object o): call(public *.*(..)) && args(o);
....
@@ -507,6 +364,7 @@ argument was an `int`, then the value passed to advice will be of type
The "boxing" of the primitive value is based on the _original_ primitive
type. So in the following program

[source, java]
....
public class InstanceOf {

@@ -569,6 +427,7 @@ field is being set to, so at a set join point, that value can be
accessed with an `args` pointcut. So an aspect guarding a static integer
variable x declared in type T might be written as

[source, java]
....
aspect GuardedX {
static final int MAX_CHANGE = 100;
@@ -632,6 +491,7 @@ the exception being handled. That value can be accessed with an `args`
pointcut. So an aspect used to put `FooException` objects into some
normal form before they are handled could be written as

[source, java]
....
aspect NormalizeFooException {
before(FooException e): handler(FooException) && args(e) {
@@ -650,6 +510,7 @@ of advice
This can be used, for example, to filter out any join point in the
control flow of advice from a particular aspect.

[source, java]
....
aspect TraceStuff {
pointcut myAdvice(): adviceexecution() && within(TraceStuff);
@@ -719,6 +580,7 @@ Object). If it is the "*" wildcard, then any argument will match, and if
it is the special wildcard "..", then any number of arguments will
match, just like in signature patterns. So the pointcut

[source, java]
....
args(int, .., String)
....
@@ -762,6 +624,7 @@ Anytime such state is accessed, it is accessed through the _most recent_
control flow that matched. So the "current arg" that would be printed by
the following program is zero, even though it is in many control flows.

[source, java]
....
class Test {
public static void main(String[] args) {
@@ -842,6 +705,7 @@ false. Within this expression, the `thisJoinPoint` object is available.
So one (extremely inefficient) way of picking out all call join points
would be to use the pointcut

[source, java]
....
if(thisJoinPoint.getKind().equals("call"))
....
@@ -922,6 +786,7 @@ while constructor declarations omit the return type and replace the
method name with the class name. The start of a particular method
declaration, in class `Test`, for example, might be

[source, java]
....
class C {
public final void foo() throws ArrayOutOfBoundsException { ... }
@@ -931,12 +796,14 @@ class C {
In AspectJ, method signature patterns have all these, but most elements
can be replaced by wildcards. So

[source, java]
....
call(public final void C.foo() throws ArrayOutOfBoundsException)
....

picks out call join points to that method, and the pointcut

[source, java]
....
call(public final void *.*() throws ArrayOutOfBoundsException)
....
@@ -949,12 +816,14 @@ throw `ArrayOutOfBounds` exceptions.
The defining type name, if not present, defaults to *, so another way of
writing that pointcut would be

[source, java]
....
call(public final void *() throws ArrayOutOfBoundsException)
....

The wildcard `..` indicates zero or more parameters, so

[source, java]
....
execution(void m(..))
....
@@ -962,6 +831,7 @@ execution(void m(..))
picks out execution join points for void methods named `m`, of any
number of arguments, while

[source, java]
....
execution(void m(.., int))
....
@@ -974,6 +844,7 @@ signature pattern should match methods without a particular modifier,
such as all non-public methods, the appropriate modifier should be
negated with the `!` operator. So,

[source, java]
....
withincode(!public void foo())
....
@@ -981,6 +852,7 @@ withincode(!public void foo())
picks out all join points associated with code in null non-public void
methods named `foo`, while

[source, java]
....
withincode(void foo())
....
@@ -991,12 +863,14 @@ named `foo`, regardless of access modifier.
Method names may contain the * wildcard, indicating any number of
characters in the method name. So

[source, java]
....
call(int *())
....

picks out all call join points to `int` methods regardless of name, but

[source, java]
....
call(int get*())
....
@@ -1009,6 +883,7 @@ than using a particular class name. So the execution join points of
private null constructor of a class C defined to throw an
ArithmeticException can be picked out with

[source, java]
....
execution(private C.new() throws ArithmeticException)
....
@@ -1027,6 +902,7 @@ type used to access the method. A common mistake is to specify a
declaring type for the `call` pointcut that is a subtype of the
originally-declaring type. For example, given the class

[source, java]
....
class Service implements Runnable {
public void run() { ... }
@@ -1035,12 +911,14 @@ class Service implements Runnable {

the following pointcut

[source, java]
....
call(void Service.run())
....

would fail to pick out the join point for the code

[source, java]
....
((Runnable) new Service()).run();
....
@@ -1049,6 +927,7 @@ Specifying the originally-declaring type is correct, but would pick out
any such call (here, calls to the `run()` method of any Runnable). In
this situation, consider instead picking out the target type:

[source, java]
....
call(void run()) && target(Service)
....
@@ -1058,6 +937,7 @@ method signature specifies a declaring type, the pointcut will only
match methods declared in that type, or methods that override methods
declared in or inherited by that type. So the pointcut

[source, java]
....
execution(public void Middle.*())
....
@@ -1068,6 +948,7 @@ Middle, even if those methods are overridden in a subclass of Middle. So
the pointcut would pick out the method-execution join point for Sub.m()
in this code:

[source, java]
....
class Super {
protected void m() { ... }
@@ -1085,6 +966,7 @@ Type patterns may 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
@@ -1190,6 +1072,7 @@ So exact type patterns match based on usual Java scope rules.
There is a special type name, *, which is also a type pattern. * picks
out all types, including primitive types. So

[source, java]
....
call(void foo(*))
....
@@ -1202,6 +1085,7 @@ patterns. The * wildcard matches zero or more characters characters
except for ".", so it can be used when types have a certain naming
convention. So

[source, java]
....
handler(java.util.*Map)
....
@@ -1209,6 +1093,7 @@ handler(java.util.*Map)
picks out the types java.util.Map and java.util.java.util.HashMap, among
others, and

[source, java]
....
handler(java.util.*)
....
@@ -1221,6 +1106,7 @@ The "`..`" wildcard matches any sequence of characters that start and
end with a ".", so it can be used to pick out all types in any
subpackage, or all inner types. So

[source, java]
....
within(com.xerox..*)
....
@@ -1238,6 +1124,7 @@ It is possible to pick out all subtypes of a type (or a collection of
types) with the "+" wildcard. The "+" wildcard follows immediately a
type name pattern. So, while

[source, java]
....
call(Foo.new())
....
@@ -1245,6 +1132,7 @@ call(Foo.new())
picks out all constructor call join points where an instance of exactly
type Foo is constructed,

[source, java]
....
call(Foo+.new())
....
@@ -1252,6 +1140,7 @@ call(Foo+.new())
picks out all constructor call join points where an instance of any
subtype of Foo (including Foo itself) is constructed, and the unlikely

[source, java]
....
call(*Handler+.new())
....
@@ -1271,6 +1160,7 @@ Type patterns are built up out of type name patterns, subtype patterns,
and array type patterns, and constructed with boolean operators `&&`,
`||`, and `!`. So

[source, java]
....
staticinitialization(Foo || Bar)
....
@@ -1278,6 +1168,7 @@ staticinitialization(Foo || Bar)
picks out the static initializer execution join points of either Foo or
Bar, and

[source, java]
....
call((Foo+ && ! Foo).new(..))
....
@@ -1289,6 +1180,7 @@ not Foo itself, is constructed.

Here is a summary of the pattern syntax used in AspectJ:

[source, text]
....
MethodPattern =
[ModifiersPattern] TypePattern
@@ -1397,6 +1289,7 @@ interpretations of after advice: After the execution of a join point
completes normally, after it throws an exception, or after it does
either one. AspectJ allows after advice for any of these situations.

[source, java]
....
aspect A {
pointcut publicCall(): call(public Object *(..));
@@ -1415,6 +1308,7 @@ aspect A {
After returning advice may not care about its returned object, in which
case it may be written

[source, java]
....
after() returning: call(public Object *(..)) {
System.out.println("Returned normally");
@@ -1448,6 +1342,7 @@ must be declared with a return type, like a method.
Thus, a simple use of around advice is to make a particular method
constant:

[source, java]
....
aspect A {
int around(): call(int C.foo()) {
@@ -1459,6 +1354,7 @@ aspect A {
Within the body of around advice, though, the computation of the
original join point can be executed with the special syntax

[source, java]
....
proceed( ... )
....
@@ -1468,6 +1364,7 @@ pointcut, and returns whatever the around is declared to return. So the
following around advice will double the second argument to `foo`
whenever it is called, and then halve its result:

[source, java]
....
aspect A {
int around(int i): call(int C.foo(Object, int)) && args(i) {
@@ -1483,6 +1380,7 @@ is originally a primitive value. And when the advice returns an Object
value, that value is converted back to whatever representation it was
originally. So another way to write the doubling and halving advice is:

[source, java]
....
aspect A {
Object around(int i): call(int C.foo(Object, int)) && args(i) {
@@ -1500,6 +1398,7 @@ program the first call to proceed will be treated as a method call to
the `ICanProceed` instance, whereas the second call to proceed is
treated as the special proceed form.

[source, java]
....
aspect A {
Object around(ICanProceed canProceed) : execution(* *(..)) && this(canProceed) {
@@ -1519,6 +1418,7 @@ method parameters. In particular, assigning to any parameter affects
only the value of the parameter, not the value that it came from. This
means that

[source, java]
....
aspect A {
after() returning (int i): call(int C.foo()) {
@@ -1536,6 +1436,7 @@ less-precedent advice and the underlying join point by supplying
different values for the variables. For example, this aspect replaces
the string bound to `s` in the named pointcut `privateData`:

[source, java]
....
aspect A {
Object around(String s): MyPointcuts.privateData(s) {
@@ -1551,6 +1452,7 @@ In the following aspect, the around advice replaces the declared target
`List` with an `ArrayList`. This is valid code at compile-time since the
types match.

[source, java]
....
import java.util.*;

@@ -1565,6 +1467,7 @@ But imagine a simple program where the actual target is `LinkedList`. In
this case, the advice would cause a `ClassCastException` at runtime, and
`peek()` is not declared in `ArrayList`.

[source, java]
....
public class Test {
public static void main(String[] args) {
@@ -1577,6 +1480,7 @@ The `ClassCastException` can occur even in situations where it appears
to be unnecessary, e.g., if the program is changed to call `size()`,
declared in `List`:

[source, java]
....
public class Test {
public static void main(String[] args) {
@@ -1605,6 +1509,7 @@ signalled by the compiler.

For example, in the following declarations:

[source, java]
....
import java.io.FileNotFoundException;

@@ -1626,22 +1531,14 @@ aspect A {

both pieces of advice are illegal. The first because the body throws an
undeclared checked exception, and the second because field get join
points cannot throw `FileNotFoundException`s.
points cannot throw ``FileNotFoundException``s.

The exceptions that each kind of join point in AspectJ may throw are:

method call and execution::
the checked exceptions declared by the target method's
+
throws
+
clause.
the checked exceptions declared by the target method's `_throws_` clause.
constructor call and execution::
the checked exceptions declared by the target constructor's
+
throws
+
clause.
the checked exceptions declared by the target constructor's `_throws_` clause.
field get and set::
no checked exceptions can be thrown from these join points.
exception handler execution::
@@ -1649,11 +1546,7 @@ exception handler execution::
static initializer execution::
no checked exceptions can be thrown from these join points.
pre-initialization and initialization::
any exception that is in the throws clause of
+
all
+
constructors of the initialized class.
any exception that is in the throws clause of all constructors of the initialized class.
advice execution::
any exception that is in the throws clause of the advice.

@@ -1700,6 +1593,7 @@ precedence over the one that appears later.

These rules can lead to circularity, such as

[source, java]
....
aspect A {
before(): execution(void main(String[] args)) {}
@@ -1747,6 +1641,7 @@ encapsulates some of the context of the advice's current or enclosing
join point. These variables exist because some pointcuts may pick out
very large collections of join points. For example, the pointcut

[source, java]
....
pointcut publicCall(): call(public * *(..));
....
@@ -1843,6 +1738,7 @@ The effect of such a declaration is to make <OnType> support the new
method. Even if <OnType> is an interface. Even if the method is neither
public nor abstract. So the following is legal AspectJ code:

[source, java]
....
interface Iface {}

@@ -1979,6 +1875,7 @@ Inter-type declarations raise the possibility of conflicts among locally
declared members and inter-type members. For example, assuming
`otherPackage` is not the package containing the aspect `A`, the code

[source, java]
....
aspect A {
private Registry otherPackage.onType.r;
@@ -2001,6 +1898,7 @@ there is no conflict: The aspect cannot see such a field, and no code in
If `onType` defines a public field "`r`", there is a conflict: The
expression

[source, java]
....
this.r = r
....
@@ -2071,6 +1969,7 @@ might define appropriate inter-type `void
fulfills the `Runnable` interface. In order to implement the methods in
the `Runnable` interface, the inter-type `run()` method must be public:

[source, java]
....
aspect A {
declare parents: SomeClass implements Runnable;
@@ -2091,9 +1990,10 @@ initializers. The order of super-interface instantiation is observable.
We fix this order with the following properties: A supertype is
initialized before a subtype, initialized code runs only once, and the
initializers for a type's superclass are run before the initializers for
its superinterfaces. Consider the following hierarchy where \{`Object`,
`C`, `D`, `E`} are classes, \{`M`, `N`, `O`, `P`, `Q`} are interfaces.
its superinterfaces. Consider the following hierarchy where {`Object`,
`C`, `D`, `E`} are classes, {`M`, `N`, `O`, `P`, `Q`} are interfaces.

[source, text]
....
Object M O
\ / \ /
@@ -2106,6 +2006,7 @@ its superinterfaces. Consider the following hierarchy where \{`Object`,

when a new `E` is instantiated, the initializers run in this order:

[source, text]
....
Object M C O N D Q P E
....
@@ -2158,6 +2059,7 @@ Pointcut

For example, the aspect

[source, java]
....
aspect A {
declare soft: Exception: execution(void main(String[] args));
@@ -2169,6 +2071,7 @@ Would, at the execution join point, catch any `Exception` and rethrow a

This is similar to what the following advice would do

[source, java]
....
aspect A {
void around() execution(void main(String[] args)) {
@@ -2187,6 +2090,7 @@ Like advice, the declare soft form has no effect in an abstract aspect
that is not extended by a concreate aspect. So the following code will
not compile unless it is compiled with an extending concrete aspect:

[source, java]
....
abstract aspect A {
abstract pointcut softeningPC();
@@ -2223,6 +2127,7 @@ of their name should have precedence over all other aspects, and (2) the
Logging aspect (and any aspect that extends it) should have precedence
over all non-security aspects, can be expressed by:

[source, java]
....
declare precedence: *..*Security*, Logging+, *;
....
@@ -2235,6 +2140,7 @@ accomplished by stating that CountEntry has precedence over
DisallowNulls. This declaration could be in either aspect, or in
another, ordering aspect:

[source, java]
....
aspect Ordering {
declare precedence: CountEntry, DisallowNulls;
@@ -2259,6 +2165,7 @@ aspect CountEntry {
It is an error for any aspect to be matched by more than one TypePattern
in a single decare precedence, so:

[source, java]
....
declare precedence: A, B, A ; // error
....
@@ -2267,6 +2174,7 @@ 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;
@@ -2280,6 +2188,7 @@ 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();
@@ -2313,12 +2222,14 @@ aspects, say, MyLogging and MyProfiling. Because advice only applies
from concrete aspects, the declare precedence form only matters when
declaring precedence with concrete aspects. So

[source, java]
....
declare precedence: Logging, Profiling;
....

has no effect, but both

[source, java]
....
declare precedence: MyLogging, MyProfiling;
declare precedence: Logging+, Profiling+;
@@ -2526,6 +2437,7 @@ All advice runs in the context of an aspect instance, but it is possible
to write a piece of advice with a pointcut that picks out a join point
that must occur before asopect instantiation. For example:

[source, java]
....
public class Client
{
@@ -2574,6 +2486,7 @@ private or protected resources of other types. To allow this, aspects
may be declared `privileged`. Code in priviliged aspects has access to
all members, even private ones.

[source, java]
....
class C {
private int i = 0;
@@ -2594,6 +2507,7 @@ If a privileged aspect can access multiple versions of a particular
member, then those that it could see if it were not privileged take
precedence. For example, in the code

[source, java]
....
class C {
private int i = 0;

+ 6
- 0
docs/sandbox/readme-sandbox.adoc View File

@@ -34,6 +34,7 @@ tells how.
extracts samples of the following form from any "source" file (currently
source, html, text, and shell scripts):

[source, text]
....
... some text, possibly including @author tags
{comment} START-SAMPLE [anchorName] [anchor title] {end-comment}
@@ -63,6 +64,7 @@ indented only once in the source code, even though they might normally
be indented more.
** In AspectJ, indent advice pointcuts beyond the block code:
+
[source, java]
....
before() : call(!public * com.company.library..*.*(String,..))
&& within(Runnable+) { // indent once more than code
@@ -107,6 +109,7 @@ suffixes necessary for clarity and to make sure there are unique titles
for each test. E.g., for a sample with the anchor
"`language-initialization`",
+
[source, xml]
....
<ajc-test
dir="common"
@@ -124,6 +127,7 @@ compile.
by verifying that the error message is produced, checking either or both
of the line number and the message text. E.g.,
+
[source, xml]
....
<compile files="declares/Declares.java, {others}"
<message kind="error" line="15" text="Factory"/>
@@ -135,6 +139,7 @@ message and the target code in sync. You can help with this by adding a
comment in the target code so people editing the code know not to fix or
move the code. E.g.,
+
[source, java]
....
void spawn() {
new Thread(this, toString()).start(); // KEEP CE 15 declares-factory
@@ -151,6 +156,7 @@ make it easier to find the test that will break if the code is modified.
If the code is broken (e.g., if it no longer works in the latest version
of AspectJ), then prefix SAMPLE with BROKEN in the tag:

[source, text]
....
{comment} START-BROKEN-SAMPLE ...
... sample code ...

+ 1
- 0
docs/sandbox/trails/j2ee.adoc View File

@@ -37,6 +37,7 @@ up ajc as the compiler, do the following before starting Tomcat:
tell Ant to use `ajc` by setting the compiler property to the AspectJ
compiler adapter:
+
[source, xml]
....
<servlet>
<servlet-name>jsp</servlet-name>

Loading…
Cancel
Save