diff options
author | Alexander Kriegisch <Alexander@Kriegisch.name> | 2021-04-10 19:19:39 +0700 |
---|---|---|
committer | Alexander Kriegisch <Alexander@Kriegisch.name> | 2021-04-10 19:19:39 +0700 |
commit | 92edca3ea7a482d59a9086b1cb61413ed8604b67 (patch) | |
tree | d709ab2fd24a563cf626fb5ff354a0972a1dc6a9 /docs | |
parent | 79c272eb9c158a976b7b3313c50759dd87b1b5fd (diff) | |
download | aspectj-92edca3ea7a482d59a9086b1cb61413ed8604b67.tar.gz aspectj-92edca3ea7a482d59a9086b1cb61413ed8604b67.zip |
Remove indentation from <programlisting> blocks in docs
Many dozens (hundreds?) of documentation code blocks were indented to
match the surrounding XML or just arbitrarily. The thing is: Inside
<programlisting> tags, similar to <pre> tags, line feeds and leading
whitespace are being preserved, which looked very awkward in the HTML
documentation. While a few files were mostly correct in this respect,
which shows that it was meant to be like that, many others were not.
This was tedious, stupid work to fix, but it had to be done.
Please note that the documentation was in no way updated content-wise.
This is also overdue, but not my focus here.
Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
Diffstat (limited to 'docs')
28 files changed, 4472 insertions, 4590 deletions
diff --git a/docs/adk15ProgGuideDB/annotations.xml b/docs/adk15ProgGuideDB/annotations.xml index 588b40b20..f9be0d0da 100644 --- a/docs/adk15ProgGuideDB/annotations.xml +++ b/docs/adk15ProgGuideDB/annotations.xml @@ -1,7 +1,7 @@ <chapter id="annotations" xreflabel="Annotations"> <title>Annotations</title> - + <sect1 id="annotations-inJava5"> <title>Annotations in Java 5</title> @@ -14,28 +14,28 @@ <sect2 id="using-annotations" xreflabel="using-annotations"> <title>Using Annotations</title> - + <para> Java 5 introduces <emphasis>annotation types</emphasis> which can be used to express metadata relating to program members in the - form of <emphasis>annotations</emphasis>. Annotations in Java 5 + form of <emphasis>annotations</emphasis>. Annotations in Java 5 can be applied to package and type declarations (classes, - interfaces, enums, and annotations), constructors, methods, + interfaces, enums, and annotations), constructors, methods, fields, parameters, and variables. Annotations are specified in the program source by using the <literal>@</literal> symbol. For example, the following piece of code uses the <literal>@Deprecated</literal> annotation to indicate that the <literal>obsoleteMethod()</literal> has been deprecated: </para> - + <programlisting><![CDATA[ - @Deprecated - public void obsoleteMethod() { ... } - ]]></programlisting> - +@Deprecated +public void obsoleteMethod() { ... } +]]> </programlisting> + <para> Annotations may be <emphasis>marker annotations</emphasis>, - <emphasis>single-valued annotations</emphasis>, or + <emphasis>single-valued annotations</emphasis>, or <emphasis>multi-valued annotations</emphasis>. Annotation types with no members or that provide default values for all members may be used simply as marker annotations, as in @@ -43,53 +43,53 @@ a single member, and the annotation may be written in one of two equivalent forms: </para> - + <programlisting><![CDATA[ - @SuppressWarnings({"unchecked"}) - public void someMethod() {...} - ]]></programlisting> - +@SuppressWarnings({"unchecked"}) +public void someMethod() {...} +]]> </programlisting> + <para> or </para> - + <programlisting><![CDATA[ - @SuppressWarnings(value={"unchecked"}) - public void someMethod() {...} - ]]></programlisting> - +@SuppressWarnings(value={"unchecked"}) +public void someMethod() {...} +]]> </programlisting> + <para> Multi-value annotations must use the <literal>member-name=value </literal> syntax to specify annotation values. For example: </para> - + <programlisting><![CDATA[ - @Authenticated(role="supervisor",clearanceLevel=5) - public void someMethod() {...} - ]]></programlisting> - +@Authenticated(role="supervisor",clearanceLevel=5) +public void someMethod() {...} +]]> </programlisting> + </sect2> <sect2 id="retention-policies" xreflabel="retention-policies"> - <title>Retention Policies</title> - + <title>Retention Policies</title> + <para> Annotations can have one of three retention policies: </para> - + <variablelist> - + <varlistentry> <term>Source-file retention</term> <listitem> <para> - Annotations with source-file retention are read by the + Annotations with source-file retention are read by the compiler during the compilation process, but are not rendered in the generated <literal>.class</literal> files. </para> </listitem> </varlistentry> - + <varlistentry> <term>Class-file retention</term> <listitem> @@ -101,7 +101,7 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>Runtime retention</term> <listitem> @@ -114,145 +114,145 @@ </listitem> </varlistentry> </variablelist> - + <para>Local variable annotations are not retained in class files (or at runtime) regardless of the retention policy set on the annotation type. See JLS 9.6.1.2.</para> - </sect2> + </sect2> <sect2 id="accessing-annotations-at-runtime" xreflabel="accessing-annotations-at-runtime"> <title>Accessing Annotations at Runtime</title> - + <para> - Java 5 supports a new interface, + Java 5 supports a new interface, <literal>java.lang.reflect.AnnotatedElement</literal>, that is - implemented by the reflection classes in Java (<literal>Class</literal>, + implemented by the reflection classes in Java (<literal>Class</literal>, <literal>Constructor</literal>, - <literal>Field</literal>, <literal>Method</literal>, and + <literal>Field</literal>, <literal>Method</literal>, and <literal>Package</literal>). This interface gives you access to annotations <emphasis>that have runtime retention</emphasis> via - the <literal>getAnnotation</literal>, <literal>getAnnotations</literal>, + the <literal>getAnnotation</literal>, <literal>getAnnotations</literal>, and <literal>isAnnotationPresent</literal>. Because annotation types are just regular Java classes, the annotations returned by these methods can be queried just like any regular Java object. </para> - + </sect2> - + <sect2 id="annotation-inheritance" xreflabel="annotation-inheritance"> <title>Annotation Inheritance</title> - + <para> It is important to understand the rules relating to inheritance of annotations, as these have a bearing on join point matching based on the presence or absence of annotations. </para> - + <para> By default annotations are <emphasis>not</emphasis> inherited. Given the following program </para> <programlisting><![CDATA[ - @MyAnnotation - class Super { - @Oneway public void foo() {} - } - - class Sub extends Super { - public void foo() {} - } - ]]></programlisting> +@MyAnnotation +class Super { + @Oneway public void foo() {} +} + +class Sub extends Super { + public void foo() {} +} +]]> </programlisting> <para> Then <literal>Sub</literal> <emphasis>does not</emphasis> have - the <literal>MyAnnotation</literal> annotation, and + the <literal>MyAnnotation</literal> annotation, and <literal>Sub.foo()</literal> is not an <literal>@Oneway</literal> - method, despite the fact that it overrides + method, despite the fact that it overrides <literal>Super.foo()</literal> which is. </para> - + <para> If an annotation type has the meta-annotation <literal>@Inherited</literal> then an annotation of that type on a <emphasis>class</emphasis> will cause the annotation to be inherited by sub-classes. So, in the example above, if the <literal>MyAnnotation</literal> type had the <literal>@Inherited</literal> attribute, then <literal>Sub</literal> - would have the <literal>MyAnnotation</literal> annotation. + would have the <literal>MyAnnotation</literal> annotation. </para> - + <para> <literal>@Inherited</literal> annotations are not inherited when used to annotate anything other than a type. A type that implements one or more interfaces never inherits any annotations from the interfaces it implements. </para> - + </sect2> </sect1> - + <!-- ============================== --> - + <sect1 id="annotations-aspectmembers"> <title>Annotating Aspects</title> - + <para> AspectJ 5 supports annotations on aspects, and on method, field, - constructor, advice, and inter-type declarations within aspects. + constructor, advice, and inter-type declarations within aspects. Method and advice parameters may also be annotated. - Annotations are not permitted on pointcut declarations or on + Annotations are not permitted on pointcut declarations or on <literal>declare</literal> statements. </para> - + <para> The following example illustrates the use of annotations in aspects: </para> <programlisting><![CDATA[ - @AspectAnnotation - public abstract aspect ObserverProtocol { - - @InterfaceAnnotation - interface Observer {} - - @InterfaceAnnotation - interface Subject {} - - @ITDFieldAnnotation - private List<Observer> Subject.observers; - - @ITDMethodAnnotation - public void Subject.addObserver(Observer o) { - observers.add(o); - } - - @ITDMethodAnnotation - public void Subject.removeObserver(Observer o) { - observers.remove(o); - } - - @MethodAnnotation - private void notifyObservers(Subject subject) { - for(Observer o : subject.observers) - notifyObserver(o,subject); - } - - /** - * Delegate to concrete sub-aspect the actual form of - * notification for a given type of Observer. - */ - @MethodAnnotation - protected abstract void notifyObserver(Observer o, Subject s); - - /* no annotations on pointcuts */ - protected abstract pointcut observedEvent(Subject subject); - - @AdviceAnnotation - after(Subject subject) returning : observedEvent(subject) { - notifyObservers(subject); - } - } - ]]></programlisting> +@AspectAnnotation +public abstract aspect ObserverProtocol { + + @InterfaceAnnotation + interface Observer {} + + @InterfaceAnnotation + interface Subject {} + + @ITDFieldAnnotation + private List<Observer> Subject.observers; + + @ITDMethodAnnotation + public void Subject.addObserver(Observer o) { + observers.add(o); + } + + @ITDMethodAnnotation + public void Subject.removeObserver(Observer o) { + observers.remove(o); + } + + @MethodAnnotation + private void notifyObservers(Subject subject) { + for(Observer o : subject.observers) + notifyObserver(o,subject); + } + + /** + * Delegate to concrete sub-aspect the actual form of + * notification for a given type of Observer. + */ + @MethodAnnotation + protected abstract void notifyObserver(Observer o, Subject s); + + /* no annotations on pointcuts */ + protected abstract pointcut observedEvent(Subject subject); + + @AdviceAnnotation + after(Subject subject) returning : observedEvent(subject) { + notifyObservers(subject); + } +} +]]></programlisting> <para> An annotation on an aspect will be inherited by sub-aspects, iff it has @@ -262,39 +262,39 @@ <para> AspectJ 5 supports a new XLint warning, "the pointcut associated with this advice does not match any join points". The warning is enabled by default and - will be emitted by the compiler if the pointcut expression associated with an + will be emitted by the compiler if the pointcut expression associated with an advice statement can be statically determined to not match any join points. The - warning can be suppressed for an individual advice statement by using the + warning can be suppressed for an individual advice statement by using the <literal>@SuppressAjWarnings({"adviceDidNotMatch"})</literal> annotation. This works in the same way as the Java 5 SuppressWarnings annotation (See JLS 9.6.1.5), but has class file retention. </para> - + <programlisting><![CDATA[ - import org.aspectj.lang.annotation.SuppressAjWarnings; - - public aspect AnAspect { - - pointcut anInterfaceOperation() : execution(* AnInterface.*(..)); - - - @SuppressAjWarnings // may not match if there are no implementers of the interface... - before() : anInterfaceOperation() { - // do something... - } - - @SuppressAjWarnings("adviceDidNotMatch") // alternate form - after() returning : anInterfaceOperation() { - // do something... - } - } - ]]></programlisting> - - +import org.aspectj.lang.annotation.SuppressAjWarnings; + +public aspect AnAspect { + + pointcut anInterfaceOperation() : execution(* AnInterface.*(..)); + + + @SuppressAjWarnings // may not match if there are no implementers of the interface... + before() : anInterfaceOperation() { + // do something... + } + + @SuppressAjWarnings("adviceDidNotMatch") // alternate form + after() returning : anInterfaceOperation() { + // do something... + } +} +]]></programlisting> + + </sect1> <!-- ============================== --> - + <sect1 id="annotations-pointcuts-and-advice"> <title>Join Point Matching based on Annotations</title> @@ -304,19 +304,19 @@ annotations. We then discuss means of exposing annotation values within the body of advice. </para> - + <sect2 id="annotation-patterns" xreflabel="annotation-patterns"> <title>Annotation Patterns</title> - + <para> - For any kind of annotated element (type, method, constructor, package, etc.), + For any kind of annotated element (type, method, constructor, package, etc.), an annotation pattern can be used to match against the set of annotations on the annotated element.An annotation pattern element has one of two basic forms: - </para> - + </para> + <itemizedlist> - <listitem>@<qualified-name>, for example, @Foo, or + <listitem>@<qualified-name>, for example, @Foo, or @org.xyz.Foo.</listitem> <listitem>@(<type-pattern>), for example, @(org.xyz..*), or @(Foo || Boo)</listitem> @@ -326,8 +326,8 @@ combined by simple concatentation. The pattern <literal>@Foo @Boo</literal> matches an annotated element that has both an annotation of type <literal>Foo</literal> and an annotation of type <literal>Boo</literal>.</para> - - <para>Some examples of annotation patterns follow:</para> + + <para>Some examples of annotation patterns follow:</para> <variablelist> @@ -335,7 +335,7 @@ <term>@Immutable</term> <listitem> <para> - Matches any annotated element which has an annotation of + Matches any annotated element which has an annotation of type <literal>Immutable</literal>. </para> </listitem> @@ -345,7 +345,7 @@ <term>!@Persistent</term> <listitem> <para> - Matches any annotated element which does not have an annotation of + Matches any annotated element which does not have an annotation of type <literal>Persistent</literal>. </para> </listitem> @@ -366,7 +366,7 @@ <listitem> <para> Matches any annotated element which has either an annotation of a type matching - the type pattern <literal>(Foo || Goo)</literal>. + the type pattern <literal>(Foo || Goo)</literal>. In other words, an annotated element with either an annotation of type <literal>Foo</literal> or an annotation of type <literal>Goo</literal> (or both). (The parenthesis are required in this example). @@ -379,7 +379,7 @@ <listitem> <para> Matches any annotated element which has either an annotation of a type matching - the type pattern <literal>(org.xyz..*)</literal>. + the type pattern <literal>(org.xyz..*)</literal>. In other words, an annotated element with an annotation that is declared in the org.xyz package or a sub-package. (The parenthesis are required in this example). </para> @@ -387,35 +387,35 @@ </varlistentry> </variablelist> - + </sect2> - + <sect2 id="type-patterns" xreflabel="type-patterns"> <title>Type Patterns</title> - + <para>AspectJ 1.5 extends type patterns to allow an optional <literal>AnnotationPattern</literal> prefix.</para> <programlisting><![CDATA[ - TypePattern := SimpleTypePattern | - '!' TypePattern | - '(' AnnotationPattern? TypePattern ')' - TypePattern '&&' TypePattern | - TypePattern '||' TypePattern - - SimpleTypePattern := DottedNamePattern '+'? '[]'* - - DottedNamePattern := FullyQualifiedName RestOfNamePattern? | - '*' NotStarNamePattern? - - RestOfNamePattern := '..' DottedNamePattern | - '*' NotStarNamePattern? - - NotStarNamePattern := FullyQualifiedName RestOfNamePattern? | - '..' DottedNamePattern - - FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)* - ]]></programlisting> +TypePattern := SimpleTypePattern | + '!' TypePattern | + '(' AnnotationPattern? TypePattern ')' + TypePattern '&&' TypePattern | + TypePattern '||' TypePattern + +SimpleTypePattern := DottedNamePattern '+'? '[]'* + +DottedNamePattern := FullyQualifiedName RestOfNamePattern? | + '*' NotStarNamePattern? + +RestOfNamePattern := '..' DottedNamePattern | + '*' NotStarNamePattern? + +NotStarNamePattern := FullyQualifiedName RestOfNamePattern? | + '..' DottedNamePattern + +FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)* +]]></programlisting> <para>Note that in most cases when annotations are used as part of a type pattern, the parenthesis are required (as in <literal>(@Foo Hello+)</literal>). In @@ -424,9 +424,9 @@ pointcut expression), the parenthesis are optional:</para> <programlisting><![CDATA[ - OptionalParensTypePattern := AnnotationPattern? TypePattern - ]]></programlisting> - +OptionalParensTypePattern := AnnotationPattern? TypePattern +]]> </programlisting> + <para> The following examples illustrate the use of annotations in type patterns: @@ -478,7 +478,7 @@ <para> Matches any type in a package beginning with the prefix <literal>org.xyz</literal>, which has either the <literal>@Immutable</literal> annotation or the - <literal>@NonPersistent</literal> annotation. + <literal>@NonPersistent</literal> annotation. </para> </listitem> </varlistentry> @@ -499,7 +499,7 @@ <listitem> <para> Matches any type in a package beginning with the prefix <literal>org.xyz</literal>, - which has an inheritable annotation. The annotation pattern + which has an inheritable annotation. The annotation pattern <literal>@(@Inherited *)</literal> matches any annotation of a type matching the type pattern <literal>@Inherited *</literal>, which in turn matches any type with the <literal>@Inherited</literal> annotation. @@ -508,33 +508,33 @@ </varlistentry> </variablelist> - + </sect2> - + <sect2 id="signaturePatterns" xreflabel="Signature Patterns"> <title>Signature Patterns</title> - + <sect3 id="fieldPatterns" xreflabel="Field Patterns"> <title>Field Patterns</title> - + <para>A <literal>FieldPattern</literal> can optionally specify an annotation-matching pattern as the first element:</para> - - <programlisting><![CDATA[ - FieldPattern := - AnnotationPattern? FieldModifiersPattern? - TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern - - FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern* - - FieldModifier := 'public' | 'private' | 'protected' | 'static' | - 'transient' | 'final' - - DotOrDotDot := '.' | '..' - - SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)? - ]]></programlisting> - + + <programlisting><![CDATA[ +FieldPattern := + AnnotationPattern? FieldModifiersPattern? + TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern + +FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern* + +FieldModifier := 'public' | 'private' | 'protected' | 'static' | + 'transient' | 'final' + +DotOrDotDot := '.' | '..' + +SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)? +]]></programlisting> + <para> If present, the <literal>AnnotationPattern</literal> restricts matches to fields with annotations that match the pattern. For example: @@ -577,7 +577,7 @@ <term>@Foo (@Goo *) (@Hoo *).*</term> <listitem> <para> - Matches a field with an annotation <literal>@Foo</literal>, of a type with an + Matches a field with an annotation <literal>@Foo</literal>, of a type with an annotation <literal>@Goo</literal>, declared in a type with annotation <literal>@Hoo</literal>. </para> @@ -595,57 +595,54 @@ </varlistentry> </variablelist> - + </sect3> <sect3 id="methodPatterns" xreflabel="Method Patterns"> <title>Method and Constructor Patterns</title> - + <para>A <literal>MethodPattern</literal> can optionally specify an annotation-matching pattern as the first element.</para> - <programlisting><![CDATA[ - MethodPattern := - AnnotationPattern? MethodModifiersPattern? TypePattern - (TypePattern DotOrDotDot)? SimpleNamePattern - '(' FormalsPattern ')'ThrowsPattern? - - MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern* - - MethodModifier := 'public' | 'private' | 'protected' | 'static' | - 'synchronized' | 'final' - - FormalsPattern := '..' (',' FormalsPatternAfterDotDot)* | - OptionalParensTypePattern (',' FormalsPattern)* | - TypePattern '...' - - FormalsPatternAfterDotDot := - OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | - TypePattern '...' - - ThrowsPattern := 'throws' TypePatternList - - TypePatternList := TypePattern (',' TypePattern)* - - ]]></programlisting> - - +<programlisting><![CDATA[ +MethodPattern := + AnnotationPattern? MethodModifiersPattern? TypePattern + (TypePattern DotOrDotDot)? SimpleNamePattern + '(' FormalsPattern ')'ThrowsPattern? + +MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern* + +MethodModifier := 'public' | 'private' | 'protected' | 'static' | + 'synchronized' | 'final' + +FormalsPattern := '..' (',' FormalsPatternAfterDotDot)* | + OptionalParensTypePattern (',' FormalsPattern)* | + TypePattern '...' + +FormalsPatternAfterDotDot := + OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | + TypePattern '...' + +ThrowsPattern := 'throws' TypePatternList + +TypePatternList := TypePattern (',' TypePattern)* +]]></programlisting> + <para>A <literal>ConstructorPattern</literal> has the form</para> - <programlisting><![CDATA[ - ConstructorPattern := - AnnotationPattern? ConstructorModifiersPattern? - (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')' - ThrowsPattern? - - ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern* - - ConstructorModifier := 'public' | 'private' | 'protected' - - ]]></programlisting> - + <programlisting><![CDATA[ +ConstructorPattern := + AnnotationPattern? ConstructorModifiersPattern? + (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')' + ThrowsPattern? + +ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern* + +ConstructorModifier := 'public' | 'private' | 'protected' +]]></programlisting> + <para> - The optional <literal>AnnotationPattern</literal> at the beginning of a + The optional <literal>AnnotationPattern</literal> at the beginning of a method or constructor pattern restricts matches to methods/constructors with annotations that match the pattern. For example: </para> @@ -683,11 +680,11 @@ </listitem> </varlistentry> </variablelist> - + </sect3> </sect2> - + <sect2 id="example-pointcuts" xreflabel="example-pointcuts"> <title>Example Pointcuts</title> @@ -697,7 +694,7 @@ <term>within(@Secure *)</term> <listitem> <para> - Matches any join point where the code executing is declared in a + Matches any join point where the code executing is declared in a type with an <literal>@Secure</literal> annotation. The format of the <literal>within</literal> pointcut designator in AspectJ 5 is <literal>'within' '(' OptionalParensTypePattern ')'</literal>. @@ -710,7 +707,7 @@ <listitem> <para> Matches the staticinitialization join point of any type with the - <literal>@Persistent</literal> annotation. The format of the + <literal>@Persistent</literal> annotation. The format of the <literal>staticinitialization</literal> pointcut designator in AspectJ 5 is <literal>'staticinitialization' '(' OptionalParensTypePattern ')'</literal>. </para> @@ -730,8 +727,8 @@ <term>execution(public (@Immutable *) org.xyz..*.*(..))</term> <listitem> <para> - The execution of any public method in a package with prefix - <literal>org.xyz</literal>, where the method returns an + The execution of any public method in a package with prefix + <literal>org.xyz</literal>, where the method returns an immutable result. </para> </listitem> @@ -770,8 +767,8 @@ advice definition. These designators are <literal>@args, @this, @target, @within, @withincode</literal>, and <literal>@annotation</literal> </para> - - <para>It is a compilation error to attempt to match on an annotation type + + <para>It is a compilation error to attempt to match on an annotation type that does not have runtime retention using <literal>@this, @target</literal> or <literal>@args</literal>. It is a compilation error to attempt to use any of these designators to expose an annotation value that does not @@ -780,45 +777,44 @@ <para> The <literal>this()</literal>, <literal>target()</literal>, and <literal>args()</literal> pointcut designators allow matching based - on the runtime type of an object, as opposed to the statically + on the runtime type of an object, as opposed to the statically declared type. In AspectJ 5, these designators are supplemented with three new designators : <literal>@this()</literal> (read, "this - annotation"), <literal>@target()</literal>, and <literal>@args()</literal>. + annotation"), <literal>@target()</literal>, and <literal>@args()</literal>. </para> - + <para> - Like their counterparts, these pointcut designators can be used - both for join point matching, and to expose context. The format of + 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: </para> - - <programlisting><![CDATA[ - AtThis := '@this' '(' AnnotationOrIdentifer ')' - - AtTarget := '@target' '(' AnnotationOrIdentifier ')' - - AnnotationOrIdentifier := FullyQualifiedName | Identifier - - AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')' - - AnnotationsOrIdentifiersPattern := - '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? | - AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* | - '*' (',' AnnotationsOrIdentifiersPattern)* - - AnnotationsOrIdentifiersPatternAfterDotDot := - AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* | - '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)* - - ]]></programlisting> + + <programlisting><![CDATA[ +AtThis := '@this' '(' AnnotationOrIdentifer ')' + +AtTarget := '@target' '(' AnnotationOrIdentifier ')' + +AnnotationOrIdentifier := FullyQualifiedName | Identifier + +AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')' + +AnnotationsOrIdentifiersPattern := + '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? | + AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* | + '*' (',' AnnotationsOrIdentifiersPattern)* + +AnnotationsOrIdentifiersPatternAfterDotDot := + AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* | + '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)* +]]></programlisting> <para> The forms of <literal>@this()</literal> and <literal>@target()</literal> that take a single annotation name are analogous to their counterparts that take - a single type name. They match at join points where the object bound to + a single type name. They match at join points where the object bound to <literal>this</literal> (or <literal>target</literal>, respectively) has an - annotation of the specified type. For example: - </para> + annotation of the specified type. For example: + </para> <variablelist> @@ -843,26 +839,26 @@ </varlistentry> </variablelist> - + <para> - Annotations can be exposed as context in the body of advice by + Annotations can be exposed as context in the body of advice by using the forms of <literal>@this(), @target()</literal> and <literal>@args()</literal> that use bound variables in the place of annotation names. For example: </para> <programlisting><![CDATA[ - pointcut callToClassifiedObject(Classified classificationInfo) : - call(* *(..)) && @target(classificationInfo); +pointcut callToClassifiedObject(Classified classificationInfo) : + call(* *(..)) && @target(classificationInfo); - pointcut txRequiredMethod(Tx transactionAnnotation) : - execution(* *(..)) && @this(transactionAnnotation) - && if(transactionAnnotation.policy() == TxPolicy.REQUIRED); - ]]></programlisting> +pointcut txRequiredMethod(Tx transactionAnnotation) : + execution(* *(..)) && @this(transactionAnnotation) + && if(transactionAnnotation.policy() == TxPolicy.REQUIRED); +]]></programlisting> <para> The <literal>@args</literal> pointcut designator behaves as its <literal>args</literal> - counterpart, matching join points based on number and position of arguments, and + counterpart, matching join points based on number and position of arguments, and supporting the <literal>*</literal> wildcard and at most one <literal>..</literal> wildcard. An annotation at a given position in an <literal>@args</literal> expression indicates that the runtime type of the argument in that position at a join point must @@ -870,45 +866,45 @@ </para> <programlisting><![CDATA[ - /** - * matches any join point with at least one argument, and where the - * type of the first argument has the @Classified annotation - */ - pointcut classifiedArgument() : @args(Classified,..); - - /** - * matches any join point with three arguments, where the third - * argument has an annotation of type @Untrusted. - */ - pointcut untrustedData(Untrusted untrustedDataSource) : - @args(*,*,untrustedDataSource); - ]]></programlisting> +/** + * matches any join point with at least one argument, and where the + * type of the first argument has the @Classified annotation + */ +pointcut classifiedArgument() : @args(Classified,..); + +/** + * matches any join point with three arguments, where the third + * argument has an annotation of type @Untrusted. + */ +pointcut untrustedData(Untrusted untrustedDataSource) : + @args(*,*,untrustedDataSource); +]]></programlisting> <para>In addition to accessing annotation information at runtime through context binding, access to <literal>AnnotatedElement</literal> information is also available reflectively with the body of advice through the <literal>thisJoinPoint</literal>, - <literal>thisJoinPointStaticPart</literal>, and - <literal>thisEnclosingJoinPointStaticPart</literal> variables. To access + <literal>thisJoinPointStaticPart</literal>, and + <literal>thisEnclosingJoinPointStaticPart</literal> variables. To access annotations on the arguments, or object bound to this or target at a join point you can use the following code fragments:</para> <programlisting><![CDATA[ - Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); - Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); - Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations(); - ]]></programlisting> +Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); +Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); +Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations(); +]]></programlisting> <para> The <literal>@within</literal> and <literal>@withincode</literal> pointcut designators match any join point where the executing code is defined within a type (<literal>@within</literal>), - or a method/constructor (<literal>@withincode</literal>) that has an annotation of the specified + or a method/constructor (<literal>@withincode</literal>) that has an annotation of the specified type. The form of these designators is: </para> - - <programlisting><![CDATA[ - AtWithin := '@within' '(' AnnotationOrIdentifier ')' - AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')' - ]]></programlisting> + + <programlisting><![CDATA[ +AtWithin := '@within' '(' AnnotationOrIdentifier ')' +AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')' +]]></programlisting> <para>Some examples of using these designators follow:</para> @@ -918,73 +914,73 @@ <term>@within(Foo)</term> <listitem> <para> - Matches any join point where the executing code is defined + Matches any join point where the executing code is defined within a type which has an annotation of type <literal>Foo</literal>. </para> </listitem> </varlistentry> <varlistentry> - <term>pointcut insideCriticalMethod(Critical c) : + <term>pointcut insideCriticalMethod(Critical c) : @withincode(c);</term> <listitem> <para> Matches any join point where the executing code is defined in a method or constructor which has an annotation of type <literal>@Critical</literal>, - and exposes the value of the annotation in the parameter + and exposes the value of the annotation in the parameter <literal>c</literal>. </para> </listitem> </varlistentry> </variablelist> - + <para>The <literal>@annotation</literal> pointcut designator matches any - join point where the <emphasis>subject</emphasis> of the join point has + join point where the <emphasis>subject</emphasis> of the join point has an annotation of the given type. Like the other @pcds, it can also be used for context exposure.</para> - <programlisting><![CDATA[ - AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')' - ]]></programlisting> - + <programlisting><![CDATA[ +AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')' +]]></programlisting> + <para>The subject of a join point is defined in the table in chapter one of - this guide.</para> + this guide.</para> <para> Access to annotation information on members at a matched join point is also available through the <literal>getSignature</literal> method of the <literal>JoinPoint</literal> and <literal>JoinPoint.StaticPart</literal> interfaces. The <literal>Signature</literal> - interfaces are extended with additional operations that provide access to the - <literal>java.lang.reflect</literal> <literal>Method, Field</literal> and + interfaces are extended with additional operations that provide access to the + <literal>java.lang.reflect</literal> <literal>Method, Field</literal> and <literal>Constructor</literal> objects on which annnotations can be queried. The following fragment illustrates an example use of this interface to access annotation information. </para> <programlisting><![CDATA[ - Signature sig = thisJoinPointStaticPart.getSignature(); - AnnotatedElement declaringTypeAnnotationInfo = sig.getDeclaringType(); - if (sig instanceof MethodSignature) { - // this must be a call or execution join point - Method method = ((MethodSignature)sig).getMethod(); - } - ]]></programlisting> - +Signature sig = thisJoinPointStaticPart.getSignature(); +AnnotatedElement declaringTypeAnnotationInfo = sig.getDeclaringType(); +if (sig instanceof MethodSignature) { + // this must be a call or execution join point + Method method = ((MethodSignature)sig).getMethod(); +} +]]></programlisting> + <para> <emphasis>Note again that it would be nicer to add the method getAnnotationInfo directly to MemberSignature, but this would once more couple the runtime library to Java 5.</emphasis> </para> - + <para> - The <literal>@this,@target</literal> and <literal>@args</literal> - pointcut designators can only be used to match against annotations + The <literal>@this,@target</literal> and <literal>@args</literal> + pointcut designators can only be used to match against annotations that have runtime retention. The <literal>@within, @withincode</literal> and <literal>@annotation</literal> pointcut designators can only be used to match against annotations that have at least class-file retention, and - if used in the binding form the annotation must have runtime retention. + if used in the binding form the annotation must have runtime retention. </para> - + </sect2> @@ -994,37 +990,36 @@ <para> <emphasis>Matching on package annotations is not supported in AspectJ. Support for this capability may be considered in a future release.</emphasis> - + </para> - + <para> Parameter annotation matching is being added in AspectJ1.6. Initially only matching is supported but binding will be implemented at some point. Whether the annotation specified in a pointcut should be 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: </para> - - + + <programlisting><![CDATA[ - @SomeAnnotation - class AnnotatedType {} - - class C { - public void foo(AnnotatedType a) {} - public void goo(@SomeAnnotation String s) {} - } - - ]]></programlisting> - +@SomeAnnotation +class AnnotatedType {} + +class C { + public void foo(AnnotatedType a) {} + public void goo(@SomeAnnotation String s) {} +} +]]></programlisting> + <para> The method foo has a parameter of an annotated type, and can be matched by this pointcut: </para> <programlisting><![CDATA[ - pointcut p(): execution(* *(@SomeAnnotation *)); - ]]></programlisting> +pointcut p(): execution(* *(@SomeAnnotation *)); +]]></programlisting> <para> When there is a single annotation specified like this, it is considered to be part of the type pattern in the match against the parameter: 'a parameter of any type that has the annotation @SomeAnnotation'. @@ -1033,8 +1028,8 @@ To match the parameter annotation case, the method goo, this is the pointcut: </para> <programlisting><![CDATA[ - pointcut p(): execution(* *(@SomeAnnotation (*))); - ]]></programlisting> +pointcut p(): execution(* *(@SomeAnnotation (*))); +]]></programlisting> <para> The use of parentheses around the wildcard is effectively indicating that the annotation should be considered separately to the type pattern for the parameter type: 'a parameter of any type that has a parameter annotation of @@ -1044,8 +1039,8 @@ To match when there is a parameter annotation and an annotation on the type as well: </para> <programlisting><![CDATA[ - pointcut p(): execution(* *(@SomeAnnotation (@SomeOtherAnnotation *))); - ]]></programlisting> +pointcut p(): execution(* *(@SomeAnnotation (@SomeOtherAnnotation *))); +]]></programlisting> <para> The parentheses are grouping @SomeOtherAnnotation with the * to form the type pattern for the parameter, then the type @SomeAnnotation will be treated as a parameter annotation pattern. @@ -1056,32 +1051,32 @@ <!-- <para> Java 5 allows both packages and parameters to be annotated. To allow matching on package and parameter annotations, - AspectJ 5 introduces the <literal>@package</literal> and <literal>@parameters</literal> pointcut designators. + AspectJ 5 introduces the <literal>@package</literal> and <literal>@parameters</literal> pointcut designators. </para> - - <programlisting><![CDATA[ - PackageAnnotationPointcut := '@package' '(' AnnotationPattern ')' - ]]></programlisting> - - <para>The <literal>@package</literal> pointcut matches any join point + + <programlisting><![CDATA[ +PackageAnnotationPointcut := '@package' '(' AnnotationPattern ')' +]]></programlisting> + + <para>The <literal>@package</literal> pointcut matches any join point occuring within the scope of a package with annotations matching the giving <literal>AnnotationPattern</literal>. For example: </para> - - <programlisting><![CDATA[ - @package(@Model) - ]]></programlisting> - + + <programlisting><![CDATA[ +@package(@Model) +]]></programlisting> + <para> Matches any join point occuring within the scope of a package with the <literal>@Model</literal> annotation. </para> - + <para> <emphasis> Note: we added @package as a result of a conscious decision not to allow the - specification of package annotation patterns within a general TypePattern. A + specification of package annotation patterns within a general TypePattern. A consequence of this decision is that we lose the ability to say the following things: "a call to a method defined in a type in a package with annotations matching..." ; "the set of a field defined in a type in a package with annotations @@ -1094,157 +1089,137 @@ to allow for the others in the future when we better understanding how users will really use both package annotations and these features. </emphasis> - </para> - + </para> + <para> The <literal>@parameter</literal> pointcut designator acts in a similar manner to <literal>args</literal> in that it matches based on number and position of arguments at a join point (and supports the same wildcard options of <literal>*</literal> and - <literal>..</literal>. + <literal>..</literal>. </para> - <programlisting><![CDATA[ - ParamsAnnotationPointcut := '@parameters' '(' ParamsAnnotationPattern ')' - - ParamsAnnotationPattern := AnnotationPattern (',' ParamsAnnotationPattern)? | - '*' (',' ParamsAnnotationPattern)? | - '..' (',' SingleParamsAnnotationPattern)* - - SingleParamsAnnotationPattern := AnnotationPattern (',' SingleParamsAnnotationPattern)? | - '*' (',' SingleParamsAnnotationPattern)? - ]]></programlisting> - - <para>The <literal>*</literal> wildcard matches a single parameter regardless of its annotations. - The <literal>..</literal> wildcard matches zero or more parameters with any annotations. An - annotation pattern in a given parameter position matches a parameter in that position with annotations - matching the given annotation pattern. For example, the method signature</para> - <programlisting><![CDATA[ - public void foo(@Immutable int i, String s, @Cached Object o); - ]]></programlisting> +ParamsAnnotationPointcut := '@parameters' '(' ParamsAnnotationPattern ')' - <para> - Is matched by: - </para> +ParamsAnnotationPattern := AnnotationPattern (',' ParamsAnnotationPattern)? | + '*' (',' ParamsAnnotationPattern)? | + '..' (',' SingleParamsAnnotationPattern)* - <programlisting><![CDATA[ - @parameters(@Immutable, *, @Cached); - - and, - - @parameters(..,@Cached); - - and, - - @parameters(@Immutable, *, *); - ]]></programlisting> +SingleParamsAnnotationPattern := AnnotationPattern (',' SingleParamsAnnotationPattern)? | + '*' (',' SingleParamsAnnotationPattern)? +]]></programlisting> - <para> - It is not matched by: - </para> + <para>The <literal>*</literal> wildcard matches a single parameter regardless of its annotations. + The <literal>..</literal> wildcard matches zero or more parameters with any annotations. An + annotation pattern in a given parameter position matches a parameter in that position with annotations + matching the given annotation pattern. For example, the method signature</para> <programlisting><![CDATA[ - @parameters(@Immutable, *); - - or, - - @parameters(*,@Immutable); - - or, - - @parameters(*, int, @Cached); - ]]></programlisting> - +public void foo(@Immutable int i, String s, @Cached Object o); +]]></programlisting> + + <para>Is matched by:</para> + <programlisting><![CDATA[@parameters(@Immutable, *, @Cached);]]></programlisting> + <para>and,</para> + <programlisting><![CDATA[@parameters(..,@Cached);]]></programlisting> + <para>and,</para> + <programlisting><![CDATA[@parameters(@Immutable, *, *);]]></programlisting> + + <para>It is not matched by:</para> + <programlisting><![CDATA[@parameters(@Immutable, *);]]></programlisting> + <para>or,</para> + <programlisting><![CDATA[@parameters(*,@Immutable);]]></programlisting> + <para>or,</para> + <programlisting><![CDATA[@parameters(*, int, @Cached);]]></programlisting> + <para> - This last example will result in a compilation error since <literal>int</literal> is not a + This last example will result in a compilation error since <literal>int</literal> is not a valid annotation pattern. </para> + --> - --> - </sect2> <sect2 id="annotation-inheritance-and-pointcut-matching" xreflabel="annotation-inheritance-and-pointcut-matching"> <title>Annotation Inheritance and pointcut matching</title> - + <para> According to the Java 5 specification, non-type annotations are not - inherited, and annotations on types are only inherited if they have the + inherited, and annotations on types are only inherited if they have the <literal>@Inherited</literal> meta-annotation. - + Given the following program: </para> <programlisting><![CDATA[ - class C1 { - @SomeAnnotation - public void aMethod() {...} - } - - class C2 extends C1 { - public void aMethod() {...} - } - - class Main { - public static void main(String[] args) { - C1 c1 = new C1(); - C2 c2 = new C2(); - c1.aMethod(); - c2.aMethod(); - } - } - - aspect X { - - pointcut annotatedC2MethodCall() : - call(@SomeAnnotation * C2.aMethod()); - - pointcut annotatedMethodCall() : - call(@SomeAnnotation * aMethod()); - } - ]]></programlisting> - +class C1 { + @SomeAnnotation + public void aMethod() {...} +} + +class C2 extends C1 { + public void aMethod() {...} +} + +class Main { + public static void main(String[] args) { + C1 c1 = new C1(); + C2 c2 = new C2(); + c1.aMethod(); + c2.aMethod(); + } +} + +aspect X { + pointcut annotatedC2MethodCall() : + call(@SomeAnnotation * C2.aMethod()); + + pointcut annotatedMethodCall() : + call(@SomeAnnotation * aMethod()); +} +]]></programlisting> + <para> The pointcut <literal>annotatedC2MethodCall</literal> will not match anything since the definition of <literal>aMethod</literal> in <literal>C2</literal> does not have the annotation. </para> - + <para> - The pointcut <literal>annotatedMethodCall</literal> matches + The pointcut <literal>annotatedMethodCall</literal> matches <literal>c1.aMethod()</literal> but not <literal>c2.aMethod()</literal>. The call to <literal>c2.aMethod</literal> is not matched because join point matching for modifiers (the visibility modifiers, annotations, and throws clause) is based on the subject of the join point (the method actually being called). </para> - + </sect2> - + <sect2 id="matchingOnAnnotationValues" xreflabel="matchingOnAnnotationValues"> <title>Matching based on annotation values</title> <para> The <literal>if</literal> pointcut designator can be used to write pointcuts - that match based on the values annotation members. For example: + that match based on the values annotation members. For example: </para> <programlisting><![CDATA[ - pointcut txRequiredMethod(Tx transactionAnnotation) : - execution(* *(..)) && @this(transactionAnnotation) - && if(transactionAnnotation.policy() == TxPolicy.REQUIRED); - ]]></programlisting> +pointcut txRequiredMethod(Tx transactionAnnotation) : + execution(* *(..)) && @this(transactionAnnotation) + && if(transactionAnnotation.policy() == TxPolicy.REQUIRED); +]]></programlisting> </sect2> - + </sect1> <!-- ============================== --> <sect1 id="annotations-decp"> <title>Using Annotations with declare statements</title> - + <sect2 id="declare-error-and-declare-warning" xreflabel="declare-error-and-declare-warning"> <title>Declare error and declare warning</title> - + <para> Since pointcut expressions in AspectJ 5 support join point matching based on annotations, this facility can be exploited when writing @@ -1253,32 +1228,32 @@ </para> <programlisting><![CDATA[ - declare warning : withincode(@PerformanceCritical * *(..)) && - call(@ExpensiveOperation * *(..)) - : "Expensive operation called from within performance critical section"; - ]]></programlisting> +declare warning : withincode(@PerformanceCritical * *(..)) && + call(@ExpensiveOperation * *(..)) + : "Expensive operation called from within performance critical section"; +]]></programlisting> <programlisting><![CDATA[ - declare error : call(* org.xyz.model.*.*(..)) && - !@within(Trusted) - : "Untrusted code should not call the model classes directly"; - ]]></programlisting> - +declare error : call(* org.xyz.model.*.*(..)) && + !@within(Trusted) + : "Untrusted code should not call the model classes directly"; +]]></programlisting> + </sect2> - - + + <sect2 id="declare-parents" xreflabel="declare-parents"> <title>declare parents</title> - + <para> The general form of a <literal>declare parents</literal> statement is: </para> - + <programlisting><![CDATA[ - declare parents : TypePattern extends Type; - declare parents : TypePattern implements TypeList; - ]]></programlisting> - +declare parents : TypePattern extends Type; +declare parents : TypePattern implements TypeList; +]]></programlisting> + <para> Since AspectJ 5 supports annotations as part of a type pattern specification, it is now possible to match types based on the presence @@ -1287,7 +1262,7 @@ </para> <variablelist> - + <varlistentry> <term>declare parents : (@Secured *) implements SecuredObject;</term> <listitem> @@ -1297,19 +1272,19 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>declare parents : (@Secured BankAccount+) implements SecuredObject;</term> <listitem> <para> The subset of types drawn from the <literal>BankAccount</literal> type and any subtype of - <literal>BankAccount</literal>, where the + <literal>BankAccount</literal>, where the <literal>@Secured</literal> annotation is present, implement the <literal>SecuredObject</literal> interface. </para> </listitem> </varlistentry> - + </variablelist> <para>An annotation type may not be used as the target of a declare parents @@ -1328,13 +1303,13 @@ </para> <programlisting><![CDATA[ - declare precedence : TypePatList; - ]]></programlisting> +declare precedence : TypePatList; +]]></programlisting> <para> AspectJ 5 allows the type patterns in the list to include annotation information as part of the pattern specification. For example: - </para> + </para> <variablelist> @@ -1348,48 +1323,48 @@ </para> </listitem> </varlistentry> - + </variablelist> - </sect2> + </sect2> </sect1> - + <!-- ============================== --> - + <sect1 id="annotations-declare"> <title>Declare Annotation</title> - + <para>AspectJ 5 supports a new kind of declare statement, <literal>declare annotation</literal>. - This takes different forms according to the recipient of the annotation: + This takes different forms according to the recipient of the annotation: <literal>declare @type</literal> for types, <literal>declare @method</literal> for methods, <literal>declare @constructor</literal> for constructors, and <literal>declare @field</literal> for fields. <literal>declare @package</literal> may be supported in a future release. </para> - + <para>The general form is:</para> <programlisting><![CDATA[ - declare @<kind> : ElementPattern : Annotation ; - ]]></programlisting> +declare @<kind> : ElementPattern : Annotation ; +]]></programlisting> - <para>Where annotation is a regular annotation expression as defined in the Java 5 language. If the annotation has + <para>Where annotation is a regular annotation expression as defined in the Java 5 language. If the annotation has the <literal>@Target</literal> meta-annotation, then the elements matched by <literal>ElementPattern</literal> must be of the kind specified by the <literal>@Target</literal> annotation.</para> - + <para><literal>ElementPattern</literal> is defined as follows:</para> - + <programlisting><![CDATA[ - ElementPattern := TypePattern | - MethodPattern | - ConstructorPattern | - FieldPattern - ]]></programlisting> - +ElementPattern := TypePattern | + MethodPattern | + ConstructorPattern | + FieldPattern +]]></programlisting> + <para>The following examples illustrate the use of <literal>declare annotation</literal>.</para> <variablelist> - + <varlistentry> <term>declare @type : org.xyz.model..* : @BusinessDomain ;</term> <listitem> @@ -1399,7 +1374,7 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>declare @method : public * BankAccount+.*(..) : @Secured(role="supervisor")</term> <listitem> @@ -1409,7 +1384,7 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>declare @constructor : BankAccount+.new(..) : @Secured(role="supervisor")</term> <listitem> @@ -1419,7 +1394,7 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>declare @field : * DAO+.* : @Persisted;</term> <listitem> @@ -1429,17 +1404,17 @@ </para> </listitem> </varlistentry> - + </variablelist> </sect1> - + <sect1 id="annotations-itds"> <title>Inter-type Declarations</title> - + <para>An annotation type may not be the target of an inter-type declaration.</para> - </sect1> - + </sect1> + </chapter> diff --git a/docs/adk15ProgGuideDB/ataspectj.xml b/docs/adk15ProgGuideDB/ataspectj.xml index 0ac475cc6..7f8152d9c 100644 --- a/docs/adk15ProgGuideDB/ataspectj.xml +++ b/docs/adk15ProgGuideDB/ataspectj.xml @@ -42,15 +42,15 @@ </para> <programlisting><![CDATA[ - @Aspect - public class Foo {} - ]]></programlisting> +@Aspect +public class Foo {} +]]></programlisting> <para>Is equivalent to:</para> <programlisting><![CDATA[ - public aspect Foo {} - ]]></programlisting> +public aspect Foo {} +]]></programlisting> <para>To specify an aspect an aspect instantiation model (the default is singleton), provide the perclause as the @@ -60,15 +60,15 @@ </para> <programlisting><![CDATA[ - @Aspect("perthis(execution(* abc..*(..)))") - public class Foo {} - ]]></programlisting> +@Aspect("perthis(execution(* abc..*(..)))") +public class Foo {} +]]></programlisting> <para>is equivalent to...</para> <programlisting><![CDATA[ - public aspect Foo perthis(execution(* abc..*(..))) {} - ]]></programlisting> +public aspect Foo perthis(execution(* abc..*(..))) {} +]]></programlisting> <sect2 id="limitations" xreflabel="limitations"> <title>Limitations</title> @@ -76,15 +76,15 @@ <para>Privileged aspects are not supported by the annotation style.</para> <!-- <programlisting><![CDATA[ - @Aspect(isPrivileged=true) - public class Foo {} - ]]></programlisting> +@Aspect(isPrivileged=true) +public class Foo {} +]]></programlisting> <para>is equivalent to...</para> <programlisting><![CDATA[ - public privileged aspect Foo {} - ]]></programlisting> +public privileged aspect Foo {} +]]></programlisting> --> </sect2> @@ -136,44 +136,44 @@ <para>Here is a simple example of a pointcut declaration in both code and @AspectJ styles:</para> <programlisting><![CDATA[ - @Pointcut("call(* *.*(..))") - void anyCall() {} - ]]></programlisting> +@Pointcut("call(* *.*(..))") +void anyCall() {} +]]></programlisting> <para>is equivalent to...</para> <programlisting><![CDATA[ - pointcut anyCall() : call(* *.*(..)); - ]]></programlisting> +pointcut anyCall() : call(* *.*(..)); +]]></programlisting> <para>When binding arguments, simply declare the arguments as normal in the annotated method:</para> <programlisting><![CDATA[ - @Pointcut("call(* *.*(int)) && args(i) && target(callee)") - void anyCall(int i, Foo callee) {} - ]]></programlisting> +@Pointcut("call(* *.*(int)) && args(i) && target(callee)") +void anyCall(int i, Foo callee) {} +]]></programlisting> <para>is equivalent to...</para> <programlisting><![CDATA[ - pointcut anyCall(int i, Foo callee) : call(* *.*(int)) && args(i) && target(callee); - ]]></programlisting> +pointcut anyCall(int i, Foo callee) : call(* *.*(int)) && args(i) && target(callee); +]]></programlisting> <para>An example with modifiers (Remember that Java 5 annotations are not inherited, so the <literal>@Pointcut</literal> annotation must be present on the extending aspect's pointcut declaration too):</para> <programlisting><![CDATA[ - @Pointcut("") - protected abstract void anyCall(); - ]]></programlisting> +@Pointcut("") +protected abstract void anyCall(); +]]></programlisting> <para>is equivalent to...</para> <programlisting><![CDATA[ - protected abstract pointcut anyCall(); - ]]></programlisting> +protected abstract pointcut anyCall(); +]]></programlisting> <sect3> <title>Type references inside @AspectJ annotations</title> @@ -196,39 +196,34 @@ </para> <programlisting><![CDATA[ - package org.aspectprogrammer.examples; +package org.aspectprogrammer.examples; - import java.util.List; +import java.util.List; - public aspect Foo { - - pointcut listOperation() : call(* List.*(..)); - - pointcut anyUtilityCall() : call(* java.util..*(..)); - - } - ]]></programlisting> +public aspect Foo { + pointcut listOperation() : call(* List.*(..)); + pointcut anyUtilityCall() : call(* java.util..*(..)); +} +]]></programlisting> <para> Using the annotation style this would be written as: </para> <programlisting><![CDATA[ - package org.aspectprogrammer.examples; - - import java.util.List; // redundant but harmless +package org.aspectprogrammer.examples; - @Aspect - public class Foo { +import java.util.List; // redundant but harmless - @Pointcut("call(* java.util.List.*(..))") // must qualify - void listOperation() {} +@Aspect +public class Foo { + @Pointcut("call(* java.util.List.*(..))") // must qualify + void listOperation() {} - @Pointcut("call(* java.util..*(..))") - void anyUtilityCall() {} - - } - ]]></programlisting> + @Pointcut("call(* java.util..*(..))") + void anyUtilityCall() {} +} +]]></programlisting> </sect3> @@ -267,45 +262,45 @@ </para> <programlisting><![CDATA[ - @Pointcut("call(* *.*(int)) && args(i) && if()") - public static boolean someCallWithIfTest(int i) { - return i > 0; - } - ]]></programlisting> +@Pointcut("call(* *.*(int)) && args(i) && if()") +public static boolean someCallWithIfTest(int i) { + return i > 0; +} +]]></programlisting> <para>is equivalent to...</para> <programlisting><![CDATA[ - pointcut someCallWithIfTest(int i) : call(* *.*(int)) && args(i) && if(i > 0); - ]]></programlisting> +pointcut someCallWithIfTest(int i) : call(* *.*(int)) && args(i) && if(i > 0); +]]></programlisting> <para>and the following is also a valid form:</para> <programlisting><![CDATA[ - static int COUNT = 0; - - @Pointcut("call(* *.*(int)) && args(i) && if()") - public static boolean someCallWithIfTest(int i, JoinPoint jp, JoinPoint.EnclosingStaticPart esjp) { - // any legal Java expression... - return i > 0 - && jp.getSignature().getName.startsWith("doo") - && esjp.getSignature().getName().startsWith("test") - && COUNT++ < 10; - } - - @Before("someCallWithIfTest(anInt, jp, enc)") - public void beforeAdviceWithRuntimeTest(int anInt, JoinPoint jp, JoinPoint.EnclosingStaticPart enc) { - //... - } - - // Note that the following is NOT valid - /* - @Before("call(* *.*(int)) && args(i) && if()") - public void advice(int i) { - // so you were writing an advice or an if body ? - } - */ - ]]></programlisting> +static int COUNT = 0; + +@Pointcut("call(* *.*(int)) && args(i) && if()") +public static boolean someCallWithIfTest(int i, JoinPoint jp, JoinPoint.EnclosingStaticPart esjp) { + // any legal Java expression... + return i > 0 + && jp.getSignature().getName.startsWith("doo") + && esjp.getSignature().getName().startsWith("test") + && COUNT++ < 10; +} + +@Before("someCallWithIfTest(anInt, jp, enc)") +public void beforeAdviceWithRuntimeTest(int anInt, JoinPoint jp, JoinPoint.EnclosingStaticPart enc) { + //... +} + +// Note that the following is NOT valid +/* +@Before("call(* *.*(int)) && args(i) && if()") +public void advice(int i) { + // so you were writing an advice or an if body ? +} +*/ +]]></programlisting> <para> It is thus possible with the annotation style to use the @@ -377,19 +372,19 @@ both styles:</para> <programlisting><![CDATA[ - @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") - public void callFromFoo() { - System.out.println("Call from Foo"); - } - ]]></programlisting> +@Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") +public void callFromFoo() { + System.out.println("Call from Foo"); +} +]]></programlisting> <para>is equivalent to...</para> <programlisting><![CDATA[ - before() : call(* org.aspectprogrammer..*(..)) && this(Foo) { - System.out.println("Call from Foo"); - } - ]]></programlisting> +before() : call(* org.aspectprogrammer..*(..)) && this(Foo) { + System.out.println("Call from Foo"); +} +]]></programlisting> <!-- @@ -405,19 +400,18 @@ </para> <programlisting><![CDATA[ - @AdviceName("callFromFoo") - before() : call(* org.aspectprogrammer..*(..)) && this(Foo) { - System.out.println("Call from Foo"); - } - - is equivalent to... - - @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") - public void callFromFoo() { - System.out.println("Call from Foo"); - } - ]]></programlisting> - +@AdviceName("callFromFoo") +before() : call(* org.aspectprogrammer..*(..)) && this(Foo) { + System.out.println("Call from Foo"); +} + +is equivalent to... + +@Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") +public void callFromFoo() { + System.out.println("Call from Foo"); +} +]]></programlisting> --> <para>If the advice body needs to know which particular @@ -427,19 +421,19 @@ </para> <programlisting><![CDATA[ - before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) { - System.out.println("Call from Foo: " + foo); - } - ]]></programlisting> +before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) { + System.out.println("Call from Foo: " + foo); +} +]]></programlisting> <para>can be written as:</para> <programlisting><![CDATA[ - @Before("call(* org.aspectprogrammer..*(..)) && this(foo)") - public void callFromFoo(Foo foo) { - System.out.println("Call from Foo: " + foo); - } - ]]></programlisting> +@Before("call(* org.aspectprogrammer..*(..)) && this(foo)") +public void callFromFoo(Foo foo) { + System.out.println("Call from Foo: " + foo); +} +]]></programlisting> <para>If the advice body needs access to <literal>thisJoinPoint</literal> @@ -453,32 +447,32 @@ </para> <programlisting><![CDATA[ - @Before("call(* org.aspectprogrammer..*(..)) && this(foo)") - public void callFromFoo(JoinPoint thisJoinPoint, Foo foo) { - System.out.println("Call from Foo: " + foo + " at " - + thisJoinPoint); - } - ]]></programlisting> +@Before("call(* org.aspectprogrammer..*(..)) && this(foo)") +public void callFromFoo(JoinPoint thisJoinPoint, Foo foo) { + System.out.println("Call from Foo: " + foo + " at " + + thisJoinPoint); +} +]]></programlisting> <para>is equivalent to...</para> <programlisting><![CDATA[ - before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) { - System.out.println("Call from Foo: " + foo + " at " - + thisJoinPoint); - } - ]]></programlisting> +before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) { + System.out.println("Call from Foo: " + foo + " at " + + thisJoinPoint); +} +]]></programlisting> <para>Advice that needs all three variables would be declared:</para> <programlisting><![CDATA[ - @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") - public void callFromFoo(JoinPoint thisJoinPoint, - JoinPoint.StaticPart thisJoinPointStaticPart, - JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart) { - // ... - } - ]]></programlisting> +@Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") +public void callFromFoo(JoinPoint thisJoinPoint, + JoinPoint.StaticPart thisJoinPointStaticPart, + JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart) { + // ... +} +]]></programlisting> <para> <literal>JoinPoint.EnclosingStaticPart</literal> @@ -514,28 +508,28 @@ </para> <programlisting><![CDATA[ - @AfterReturning("criticalOperation()") - public void phew() { - System.out.println("phew"); - } +@AfterReturning("criticalOperation()") +public void phew() { + System.out.println("phew"); +} - @AfterReturning(pointcut="call(Foo+.new(..))",returning="f") - public void itsAFoo(Foo f) { - System.out.println("It's a Foo: " + f); - } - ]]></programlisting> +@AfterReturning(pointcut="call(Foo+.new(..))",returning="f") +public void itsAFoo(Foo f) { + System.out.println("It's a Foo: " + f); +} +]]></programlisting> <para>is equivalent to...</para> <programlisting><![CDATA[ - after() returning : criticalOperation() { - System.out.println("phew"); - } +after() returning : criticalOperation() { + System.out.println("phew"); +} - after() returning(Foo f) : call(Foo+.new(..)) { - System.out.println("It's a Foo: " + f); - } - ]]></programlisting> +after() returning(Foo f) : call(Foo+.new(..)) { + System.out.println("It's a Foo: " + f); +} +]]></programlisting> <para>(Note the use of the "pointcut=" prefix in front of the pointcut expression in the returning case).</para> @@ -557,11 +551,11 @@ </para> <programlisting><![CDATA[ - @Around("call(* org.aspectprogrammer..*(..))") - public Object doNothing() { - return proceed(); // CE on this line - } - ]]></programlisting> +@Around("call(* org.aspectprogrammer..*(..))") +public Object doNothing() { + return proceed(); // CE on this line +} +]]></programlisting> <para>will result in a "No such method" compilation error. For this @@ -573,50 +567,48 @@ </para> <programlisting><![CDATA[ - public interface ProceedingJoinPoint extends JoinPoint { - public Object proceed(Object[] args); - } - ]]></programlisting> +public interface ProceedingJoinPoint extends JoinPoint { + public Object proceed(Object[] args); +} +]]></programlisting> <para>The around advice given above can now be written as:</para> <programlisting><![CDATA[ - @Around("call(* org.aspectprogrammer..*(..))") - public Object doNothing(ProceedingJoinPoint thisJoinPoint) { - return thisJoinPoint.proceed(); - } - ]]></programlisting> +@Around("call(* org.aspectprogrammer..*(..))") +public Object doNothing(ProceedingJoinPoint thisJoinPoint) { + return thisJoinPoint.proceed(); +} +]]></programlisting> <para>Here's an example that uses parameters for the proceed call:</para> <programlisting><![CDATA[ - @Aspect - public class ProceedAspect { - - @Pointcut("call(* setAge(..)) && args(i)") - void setAge(int i) {} +@Aspect +public class ProceedAspect { - @Around("setAge(i)") - public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint, int i) { - return thisJoinPoint.proceed(new Object[]{i*2}); //using Java 5 autoboxing - } + @Pointcut("call(* setAge(..)) && args(i)") + void setAge(int i) {} - } + @Around("setAge(i)") + public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint, int i) { + return thisJoinPoint.proceed(new Object[]{i*2}); //using Java 5 autoboxing + } - ]]></programlisting> +} +]]></programlisting> <para>is equivalent to:</para> <programlisting><![CDATA[ - public aspect ProceedAspect { - pointcut setAge(int i): call(* setAge(..)) && args(i); - - Object around(int i): setAge(i) { - return proceed(i*2); - } - } - ]]></programlisting> +public aspect ProceedAspect { + pointcut setAge(int i): call(* setAge(..)) && args(i); + Object around(int i): setAge(i) { + return proceed(i*2); + } +} +]]></programlisting> <para>Note that the ProceedingJoinPoint does not need to be passed to the proceed(..) arguments. </para> @@ -626,15 +618,15 @@ <itemizedlist> <listitem>If 'this()' was used in the pointcut <emphasis>for binding</emphasis>, it must be passed first in proceed(..). </listitem> - <listitem>If 'target()' was used in the pointcut <emphasis>for binding</emphasis>, it must be passed next in proceed(..) - it will be the + <listitem>If 'target()' was used in the pointcut <emphasis>for binding</emphasis>, it must be passed next in proceed(..) - it will be the first argument to proceed(..) if this() was not used for binding. </listitem> - <listitem>Finally come <emphasis>all</emphasis> the arguments expected at the join point, in the order they - are supplied at the join point. Effectively the advice signature is ignored - it doesn't - matter if a subset of arguments were bound or the ordering was changed in the advice + <listitem>Finally come <emphasis>all</emphasis> the arguments expected at the join point, in the order they + are supplied at the join point. Effectively the advice signature is ignored - it doesn't + matter if a subset of arguments were bound or the ordering was changed in the advice signature, the proceed(..) calls takes all of them in the right order for the join point. </listitem> - </itemizedlist> + </itemizedlist> </para> <para>Since proceed(..) in this case takes an Object array, AspectJ cannot do as much compile time checking as it can for code style. If the rules above aren't obeyed then it will unfortunately @@ -650,11 +642,11 @@ <para> Inter-type declarations are challenging to support using an annotation style. For code style aspects compiled with the ajc compiler, the entire type system can be made aware of inter-type declarations (new - supertypes, new methods, new fields) and the completeness and correctness of it can be guaranteed. + supertypes, new methods, new fields) and the completeness and correctness of it can be guaranteed. Achieving this with an annotation style is hard because the source code may simply be compiled with javac where the type system cannot be influenced and what is compiled must be 'pure java'. </para> - <para> + <para> AspectJ 1.5.0 introduced @DeclareParents, an attempt to offer something like that which is achievable with code style declare parents and the other intertype declarations (fields, methods, constructors). However, it has proved too challenging to get close to the expressiveness and capabilities of code style in this area @@ -662,12 +654,12 @@ some interface I is mixed into some target type T then this means that all the methods from I are created in T and their implementations are simple forwarding methods that call a delegate which that provides an implementation of I. </para> - <para> - The next section covers @DeclareParents but AspectJ 1.6.4 introduces @DeclareMixin - an improved approach to defining - a mixin and the choice of a different name for the annotation will hopefully alleviate some of the confusion about - why @DeclareParents just doesn't offer the same semantics as the code style variant. Offering @DeclareMixin also gives - code style developers a new tool for a simple mixin whereas previously they would have avoided @DeclareParents - thinking what it could only do was already achievable with code style syntax. + <para> + The next section covers @DeclareParents but AspectJ 1.6.4 introduces @DeclareMixin - an improved approach to defining + a mixin and the choice of a different name for the annotation will hopefully alleviate some of the confusion about + why @DeclareParents just doesn't offer the same semantics as the code style variant. Offering @DeclareMixin also gives + code style developers a new tool for a simple mixin whereas previously they would have avoided @DeclareParents + thinking what it could only do was already achievable with code style syntax. </para> <para> The defaultImpl attribute of @DeclareParents may become deprecated if @DeclareMixin proves popular, leaving @@ -683,23 +675,23 @@ </para> <programlisting><![CDATA[ - public aspect MoodIndicator { +public aspect MoodIndicator { - public interface Moody {}; + public interface Moody {}; - private Mood Moody.mood = Mood.HAPPY; + private Mood Moody.mood = Mood.HAPPY; - public Mood Moody.getMood() { - return mood; - } + public Mood Moody.getMood() { + return mood; + } - declare parents : org.xyz..* implements Moody; + declare parents : org.xyz..* implements Moody; - before(Moody m) : execution(* *.*(..)) && this(m) { - System.out.println("I'm feeling " + m.getMood()); - } - } - ]]></programlisting> + before(Moody m) : execution(* *.*(..)) && this(m) { + System.out.println("I'm feeling " + m.getMood()); + } +} +]]></programlisting> <para> This declares an interface @@ -720,33 +712,33 @@ </para> <programlisting><![CDATA[ - @Aspect - public class MoodIndicator { - - // this interface can be outside of the aspect - public interface Moody { - Mood getMood(); - }; - - // this implementation can be outside of the aspect - public static class MoodyImpl implements Moody { - private Mood mood = Mood.HAPPY; - - public Mood getMood() { - return mood; - } - } - - // the field type must be the introduced interface. It can't be a class. - @DeclareParents(value="org.xzy..*",defaultImpl=MoodyImpl.class) - private Moody implementedInterface; - - @Before("execution(* *.*(..)) && this(m)") - void feelingMoody(Moody m) { - System.out.println("I'm feeling " + m.getMood()); - } - } - ]]></programlisting> +@Aspect +public class MoodIndicator { + + // this interface can be outside of the aspect + public interface Moody { + Mood getMood(); + }; + + // this implementation can be outside of the aspect + public static class MoodyImpl implements Moody { + private Mood mood = Mood.HAPPY; + + public Mood getMood() { + return mood; + } + } + + // the field type must be the introduced interface. It can't be a class. + @DeclareParents(value="org.xzy..*",defaultImpl=MoodyImpl.class) + private Moody implementedInterface; + + @Before("execution(* *.*(..)) && this(m)") + void feelingMoody(Moody m) { + System.out.println("I'm feeling " + m.getMood()); + } +} +]]></programlisting> <para> This is very similar to the mixin mechanism supported by AspectWerkz. The @@ -762,7 +754,7 @@ has access to the exact same set of members as in the code style example. </para> - + <para> Note that it is illegal to use the @DeclareParents annotation on an aspect' field of a non-interface type. The interface type is the inter-type declaration contract that dictates @@ -770,21 +762,21 @@ </para> <programlisting><![CDATA[ - // this type will be affected by the inter-type declaration as the type pattern matches - package org.xyz; - public class MoodTest { - - public void test() { - // see here the cast to the introduced interface (required) - Mood mood = ((Moody)this).getMood(); - ... - } - } - ]]></programlisting> +// this type will be affected by the inter-type declaration as the type pattern matches +package org.xyz; +public class MoodTest { + + public void test() { + // see here the cast to the introduced interface (required) + Mood mood = ((Moody)this).getMood(); + ... + } +} +]]></programlisting> <para>The <literal>@DeclareParents</literal> annotation can also be used without specifying - a <literal>defaultImpl</literal> value (for example, - <literal>@DeclareParents("org.xyz..*")</literal>). This is equivalent to a + a <literal>defaultImpl</literal> value (for example, + <literal>@DeclareParents("org.xyz..*")</literal>). This is equivalent to a <literal>declare parents ... implements</literal> clause, and does <emphasis>not</emphasis> make any inter-type declarations for default implementation of the interface methods. </para> @@ -794,32 +786,30 @@ </para> <programlisting><![CDATA[ - public aspect SerializableMarker { - - declare parents : org.xyz..* implements Serializable; - } - ]]></programlisting> +public aspect SerializableMarker { + declare parents : org.xyz..* implements Serializable; +} +]]></programlisting> <para>Using the annotation style this aspect can be written: </para> <programlisting><![CDATA[ - @Aspect - public class SerializableMarker { - - @DeclareParents("org.xyz..*") - Serializable implementedInterface; - } - ]]></programlisting> +@Aspect +public class SerializableMarker { + @DeclareParents("org.xyz..*") + Serializable implementedInterface; +} +]]></programlisting> <para> If the interface defines one or more operations, and these are not implemented by the target type, an error will be issued during weaving. </para> - + </sect2> - + <sect2 id="atDeclareMixin" xreflabel="atDeclareMixin"> <title>@DeclareMixin</title> <para> @@ -827,26 +817,26 @@ </para> <programlisting><![CDATA[ - public aspect MoodIndicator { +public aspect MoodIndicator { - public interface Moody {}; + public interface Moody {}; - private Mood Moody.mood = Mood.HAPPY; + private Mood Moody.mood = Mood.HAPPY; - public Mood Moody.getMood() { - return mood; - } + public Mood Moody.getMood() { + return mood; + } - declare parents : org.xyz..* implements Moody; + declare parents : org.xyz..* implements Moody; - before(Moody m) : execution(* *.*(..)) && this(m) { - System.out.println("I'm feeling " + m.getMood()); - } - } - ]]></programlisting> + before(Moody m) : execution(* *.*(..)) && this(m) { + System.out.println("I'm feeling " + m.getMood()); + } +} +]]></programlisting> <para> - This declares an interface <literal>Moody</literal>, and then makes two inter-type declarations on the interface + This declares an interface <literal>Moody</literal>, and then makes two inter-type declarations on the interface - a field that is private to the aspect, and a method that returns the mood. Within the body of the inter-type declared method <literal>getMoody</literal>, the type of <literal>this</literal> is <literal>Moody</literal> (the target type of the inter-type declaration). @@ -856,37 +846,37 @@ </para> <programlisting><![CDATA[ - @Aspect - public class MoodIndicator { - - // this interface can be outside of the aspect - public interface Moody { - Mood getMood(); - }; - - // this implementation can be outside of the aspect - public static class MoodyImpl implements Moody { - private Mood mood = Mood.HAPPY; - - public Mood getMood() { - return mood; - } - } - - // The DeclareMixin annotation is attached to a factory method that can return instances of the delegate - // which offers an implementation of the mixin interface. The interface that is mixed in is the - // return type of the method. - @DeclareMixin("org.xyz..*") - public static Moody createMoodyImplementation() { - return new MoodyImpl(); - } - - @Before("execution(* *.*(..)) && this(m)") - void feelingMoody(Moody m) { - System.out.println("I'm feeling " + m.getMood()); - } - } - ]]></programlisting> +@Aspect +public class MoodIndicator { + + // this interface can be outside of the aspect + public interface Moody { + Mood getMood(); + }; + + // this implementation can be outside of the aspect + public static class MoodyImpl implements Moody { + private Mood mood = Mood.HAPPY; + + public Mood getMood() { + return mood; + } + } + + // The DeclareMixin annotation is attached to a factory method that can return instances of the delegate + // which offers an implementation of the mixin interface. The interface that is mixed in is the + // return type of the method. + @DeclareMixin("org.xyz..*") + public static Moody createMoodyImplementation() { + return new MoodyImpl(); + } + + @Before("execution(* *.*(..)) && this(m)") + void feelingMoody(Moody m) { + System.out.println("I'm feeling " + m.getMood()); + } +} +]]></programlisting> <para> Basically, the <literal>@DeclareMixin</literal> annotation is attached to a factory method. The @@ -894,24 +884,24 @@ create an instance of a delegate that implements the interface. This is the interface which will be delegated to from any target matching the specified type pattern. </para> - + <para> 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: </para> - + <programlisting><![CDATA[ - // this type will be affected by the inter-type declaration as the type pattern matches - package org.xyz; - public class MoodTest { - - public void test() { - // see here the cast to the introduced interface (required) - Mood mood = ((Moody)this).getMood(); - ... - } - } - ]]></programlisting> +// this type will be affected by the inter-type declaration as the type pattern matches +package org.xyz; +public class MoodTest { + + public void test() { + // see here the cast to the introduced interface (required) + Mood mood = ((Moody)this).getMood(); + ... + } +} +]]></programlisting> <para> Sometimes the delegate instance may want to perform differently depending upon the type/instance for @@ -920,54 +910,52 @@ which a delegate should be created: </para> <programlisting><![CDATA[ - - @Aspect - public class Foo { - - @DeclareMixin("org.xyz..*") - public static SomeInterface createDelegate(Object instance) { - return new SomeImplementation(instance); - } - } - ]]></programlisting> - +@Aspect +public class Foo { + + @DeclareMixin("org.xyz..*") + public static SomeInterface createDelegate(Object instance) { + return new SomeImplementation(instance); + } +} +]]></programlisting> + <para> - It is also possible to make the factory method non-static - and in this case it can then exploit + 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: </para> <programlisting><![CDATA[ - - @Aspect - public class Foo { - public int maxLimit=35; - - @DeclareMixin("org.xyz..*") - public SomeInterface createDelegate(Object instance) { - return new SomeImplementation(instance,maxLimit); - } - } - ]]></programlisting> - +@Aspect +public class Foo { + public int maxLimit=35; + + @DeclareMixin("org.xyz..*") + public SomeInterface createDelegate(Object instance) { + return new SomeImplementation(instance,maxLimit); + } +} +]]></programlisting> + <para> Although the interface type is usually determined purely from the return type of the factory method, it can be specified in the annotation if 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: </para> <programlisting><![CDATA[ - // interfaces is an array of interface classes that should be mixed in - @DeclareMixin(value="org.xyz..*",interfaces={I.class,J.class}) - public static InterfaceExtendingLotsOfInterfaces createMoodyImplementation() { - return new MoodyImpl(); - } - ]]></programlisting> - +// interfaces is an array of interface classes that should be mixed in +@DeclareMixin(value="org.xyz..*",interfaces={I.class,J.class}) +public static InterfaceExtendingLotsOfInterfaces createMoodyImplementation() { + return new MoodyImpl(); +} +]]></programlisting> + <para> There are clearly similarities between <literal>@DeclareMixin</literal> and <literal>@DeclareParents</literal> but <literal>@DeclareMixin</literal> is not pretending to offer more than a simple mixin strategy. The flexibility in - being able to provide the factory method instead of requiring a no-arg constructor for the implementation also + being able to provide the factory method instead of requiring a no-arg constructor for the implementation also enables delegate instances to make decisions based upon the type for which they are the delegate. </para> - + <para> Any annotations defined on the interface methods are also put upon the delegate forwarding methods created in the matched target type. @@ -997,21 +985,24 @@ </para> <programlisting><![CDATA[ - public aspect SystemArchitecture { - declare precedence : Security*, TransactionSupport, Persistence; +public aspect SystemArchitecture { + declare precedence : Security*, TransactionSupport, Persistence; - // ... - } + // ... +} +]]></programlisting> - can be written as: - - @Aspect - @DeclarePrecedence("Security*,org.xyz.TransactionSupport,org.xyz.Persistence") - public class SystemArchitecture { + <para> + can be written as: + </para> - // ... - } - ]]></programlisting> + <programlisting><![CDATA[ +@Aspect +@DeclarePrecedence("Security*,org.xyz.TransactionSupport,org.xyz.Persistence") +public class SystemArchitecture { + // ... +} +]]></programlisting> <!-- note: below is not supported for now. @@ -1026,32 +1017,34 @@ </para> <programlisting><![CDATA[ - public aspect DeclareAnnotationExamples { - declare annotation : org.xyz.model..* : @BusinessDomain; +public aspect DeclareAnnotationExamples { + declare annotation : org.xyz.model..* : @BusinessDomain; - declare annotation : public * BankAccount+.*(..) : @Secured(role="supervisor"); + declare annotation : public * BankAccount+.*(..) : @Secured(role="supervisor"); - declare anotation : * DAO+.* : @Persisted; + declare anotation : * DAO+.* : @Persisted; - } +} +]]></programlisting> - can be written as... + <para>can be written as...</para> - @Aspect - public class DeclareAnnotationExamples { + <programlisting><![CDATA[ +@Aspect +public class DeclareAnnotationExamples { - @DeclareAnnotation("org.xyz.model..*) - @BusinessDomain Object modelClass; + @DeclareAnnotation("org.xyz.model..*) + @BusinessDomain Object modelClass; - // this example assumes that the @Secured annotation has a Target - // annotation with value ElementType.METHOD - @DeclareAnnotation("public * org.xyz.banking.BankAccount+.*(..)") - @Secured(role="supervisor) void bankAccountMethod(); + // this example assumes that the @Secured annotation has a Target + // annotation with value ElementType.METHOD + @DeclareAnnotation("public * org.xyz.banking.BankAccount+.*(..)") + @Secured(role="supervisor) void bankAccountMethod(); - @DeclareAnnotation("* DAO+.*") - @Persisted Object daoFields; - } - ]]></programlisting> + @DeclareAnnotation("* DAO+.*") + @Persisted Object daoFields; +} +]]></programlisting> <para> <emphasis>Note: Declare annotation is not available in AspectJ 1.5 M3 and syntax may change @@ -1069,29 +1062,29 @@ of a static method for example.</para> <programlisting><![CDATA[ - declare warning : call(* javax.sql..*(..)) && !within(org.xyz.daos..*) - : "Only DAOs should be calling JDBC."; - - declare error : execution(* IFoo+.*(..)) && !within(org.foo..*) - : "Only foo types can implement IFoo"; +declare warning : call(* javax.sql..*(..)) && !within(org.xyz.daos..*) + : "Only DAOs should be calling JDBC."; - can be written as... +declare error : execution(* IFoo+.*(..)) && !within(org.foo..*) + : "Only foo types can implement IFoo"; +]]></programlisting> - @DeclareWarning("call(* javax.sql..*(..)) && !within(org.xyz.daos..*)") - static final String aMessage = "Only DAOs should be calling JDBC."; + <para>can be written as...</para> - @DeclareError("execution(* IFoo+.*(..)) && !within(org.foo..*)") - static final String badIFooImplementors = "Only foo types can implement IFoo"; - - // the following is not valid since the message is not a String literal - @DeclareError("execution(* IFoo+.*(..)) && !within(org.foo..*)") - static final String badIFooImplementorsCorrupted = getMessage(); - static String getMessage() { - return "Only foo types can implement IFoo " + System.currentTimeMillis(); - } + <programlisting><![CDATA[ +@DeclareWarning("call(* javax.sql..*(..)) && !within(org.xyz.daos..*)") +static final String aMessage = "Only DAOs should be calling JDBC."; - ]]></programlisting> +@DeclareError("execution(* IFoo+.*(..)) && !within(org.foo..*)") +static final String badIFooImplementors = "Only foo types can implement IFoo"; +// the following is not valid since the message is not a String literal +@DeclareError("execution(* IFoo+.*(..)) && !within(org.foo..*)") +static final String badIFooImplementorsCorrupted = getMessage(); +static String getMessage() { + return "Only foo types can implement IFoo " + System.currentTimeMillis(); +} +]]></programlisting> </sect1> @@ -1117,27 +1110,27 @@ </para> <programlisting><![CDATA[ - public class Aspects { +public class Aspects { - /* variation used for singleton, percflow, percflowbelow */ - static<T> public static T aspectOf(T aspectType) {...} + /* variation used for singleton, percflow, percflowbelow */ + static<T> public static T aspectOf(T aspectType) {...} - /* variation used for perthis, pertarget */ - static<T> public static T aspectOf(T aspectType, Object forObject) {...} + /* variation used for perthis, pertarget */ + static<T> public static T aspectOf(T aspectType, Object forObject) {...} - /* variation used for pertypewithin */ - static<T> public static T aspectOf(T aspectType, Class forType) {...} + /* variation used for pertypewithin */ + static<T> public static T aspectOf(T aspectType, Class forType) {...} - /* variation used for singleton, percflow, percflowbelow */ - public static boolean hasAspect(Object anAspect) {...} + /* variation used for singleton, percflow, percflowbelow */ + public static boolean hasAspect(Object anAspect) {...} - /* variation used for perthis, pertarget */ - public static boolean hasAspect(Object anAspect, Object forObject) {...} + /* variation used for perthis, pertarget */ + public static boolean hasAspect(Object anAspect, Object forObject) {...} - /* variation used for pertypewithin */ - public static boolean hasAspect(Object anAspect, Class forType) {...} - } - ]]></programlisting> + /* variation used for pertypewithin */ + public static boolean hasAspect(Object anAspect, Class forType) {...} +} +]]></programlisting> <!-- TODO AV - stuff below is not done --> <!-- diff --git a/docs/adk15ProgGuideDB/autoboxing.xml b/docs/adk15ProgGuideDB/autoboxing.xml index ec19fb7fe..7a3cdaca1 100644 --- a/docs/adk15ProgGuideDB/autoboxing.xml +++ b/docs/adk15ProgGuideDB/autoboxing.xml @@ -1,54 +1,54 @@ <chapter id="autoboxing" xreflabel="Autoboxing and Unboxing"> <title>Autoboxing and Unboxing</title> - + <sect1 id="boxing-inJava5"> <title>Autoboxing and Unboxing in Java 5</title> - + <para> - Java 5 (and hence AspectJ 1.5) supports automatic conversion of + Java 5 (and hence AspectJ 1.5) supports automatic conversion of primitive types (int, float, double etc.) to their object equivalents (Integer, Float, Double,...) in assignments and method and constructor invocations. This conversion is know as autoboxing. </para> - + <para>Java 5 also supports automatic unboxing, where wrapper types are automatically converted into their primitive equivalents if needed for assignments or method or constructor invocations.</para> - + <para>For example:</para> <programlisting><![CDATA[ - int i = 0; - i = new Integer(5); // auto-unboxing - - Integer i2 = 5; // autoboxing - ]]></programlisting> - +int i = 0; +i = new Integer(5); // auto-unboxing + +Integer i2 = 5; // autoboxing +]]></programlisting> + </sect1> - + <sect1 id="autoboxing-in-aspectj5"> <title>Autoboxing and Join Point matching in AspectJ 5</title> - + <para>Most of the pointcut designators match based on signatures, and hence are unaffected by autoboxing. For example, a call to a method</para> <programlisting><![CDATA[ - public void foo(Integer i); - ]]></programlisting> - +public void foo(Integer i); +]]></programlisting> + <para>is <emphasis>not</emphasis> matched by a pointcut <literal>call(void foo(int))</literal> since the signature declares a single <literal>Integer</literal> parameter, not an <literal>int</literal>. </para> - + <para>The <literal>args</literal> pointcut designator is affected by autoboxing since it matches based on the runtime type of the arguments. AspectJ 5 applies autoboxing and unboxing in determining argument matching. In other words, <literal>args(Integer)</literal> will match any join point at which there is a single argument of type <literal>Integer</literal> or of type <literal>int</literal>.</para> - + <itemizedlist> <listitem>args(Integer) and args(int) are equivalent</listitem> <listitem>args(Float) and args(float) are equivalent</listitem> @@ -58,29 +58,29 @@ <listitem>args(Long) and args(long) are equivalent</listitem> <listitem>args(Boolean) and args(boolean) are equivalent</listitem> </itemizedlist> - + <para> - Autoboxing and unboxing are also applied when binding pointcut or - advice parameters, for example: + Autoboxing and unboxing are also applied when binding pointcut or + advice parameters, for example: </para> <programlisting><![CDATA[ - pointcut foo(int i) : args(i); - - before(Integer i) : foo(i) { - ... - } - ]]></programlisting> +pointcut foo(int i) : args(i); + +before(Integer i) : foo(i) { + ... +} +]]></programlisting> </sect1> - + <sect1 id="autoboxing-and-method-dispatch"> <title>Inter-type method declarations and method dispatch</title> - + <para>Autoboxing, unboxing, and also varargs all affect the method dispatch algorithm used in Java 5. In AspectJ 5, the target method of a call is selected according to the following algorithm:</para> - + <orderedlist> <listitem>Attempt to locate a matching method or inter-type declared method without considering @@ -90,11 +90,11 @@ <listitem>Finally try again considering both autoboxing, unboxing, and varargs.</listitem> </orderedlist> - + <para>One consequence is that a directly matching inter-type declared - method will take precedence over a method declared locally in the + method will take precedence over a method declared locally in the target class but that only matches via autoboxing.</para> </sect1> - + </chapter> diff --git a/docs/adk15ProgGuideDB/covariance.xml b/docs/adk15ProgGuideDB/covariance.xml index 2268258f3..e8845ddb8 100644 --- a/docs/adk15ProgGuideDB/covariance.xml +++ b/docs/adk15ProgGuideDB/covariance.xml @@ -1,64 +1,64 @@ <chapter id="covariance" xreflabel="Covariance"> <title>Covariance</title> - + <sect1 id="covariance-inJava5"> <title>Covariance in Java 5</title> - + <para> Java 5 (and hence AspectJ 5) allows you to narrow the return type in an overriding method. For example: </para> <programlisting><![CDATA[ - class A { - public A whoAreYou() {...} - } - - class B extends A { - // override A.whoAreYou *and* narrow the return type. - public B whoAreYou() {...} - } - ]]></programlisting> - +class A { + public A whoAreYou() {...} +} + +class B extends A { + // override A.whoAreYou *and* narrow the return type. + public B whoAreYou() {...} +} +]]></programlisting> + </sect1> - + <sect1 id="covariance-and-join-point-matching"> <title>Covariant methods and Join Point matching</title> - + <para>The join point matching rules for <literal>call</literal> and <literal>execution</literal> pointcut designators are extended to match against covariant methods.</para> - + <para> Given the classes <literal>A</literal> and <literal>B</literal> as defined in the previous section, and the program fragment </para> <programlisting><![CDATA[ - A a = new A(); - B b = new B(); - a.whoAreYou(); - b.whoAreYou(); - ]]></programlisting> - - <para>The signatures for the call join point <literal>a.whoAreYou()</literal> are - simply:</para> +A a = new A(); +B b = new B(); +a.whoAreYou(); +b.whoAreYou(); +]]></programlisting> - <programlisting><![CDATA[ - A A.whoAreYou() - ]]></programlisting> - - <para>The signatures for the call join point <literal>b.whoAreYou()</literal> are: - </para> +<para>The signatures for the call join point <literal>a.whoAreYou()</literal> are +simply:</para> + +<programlisting><![CDATA[ +A A.whoAreYou() +]]></programlisting> + +<para>The signatures for the call join point <literal>b.whoAreYou()</literal> are: +</para> + +<programlisting><![CDATA[ +A A.whoAreYou() +B B.whoAreYou() +]]></programlisting> - <programlisting><![CDATA[ - A A.whoAreYou() - B B.whoAreYou() - ]]></programlisting> - <para>Following the join point matching rules given in <xref linkend="jpsigs"/>,</para> - + <variablelist> <varlistentry> @@ -87,7 +87,7 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>call(A B.whoAreYou())</term> <listitem> @@ -98,22 +98,22 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>call(A+ B.whoAreYou())</term> <listitem> <para>Matches the call to <literal>b.whoAreYou()</literal> since - the signature pattern matches the signature <literal>B B.whoAreYou()</literal>. + the signature pattern matches the signature <literal>B B.whoAreYou()</literal>. A lint warning is given for the call <literal>a.whoAreYou()</literal> ("does not match because declaring type is A, if match required use target(B)"). </para> </listitem> </varlistentry> - + <varlistentry> <term>call(B A.whoAreYou())</term> <listitem> - <para>Does not match anything since neither join point has a + <para>Does not match anything since neither join point has a signature matched by this pattern. </para> </listitem> @@ -136,13 +136,13 @@ </varlistentry> </variablelist> - + <para>The rule for signature matching at call and execution join points is unchanged from AspectJ 1.2: a call or execution pointcut matches if the signature pattern matches at least one of the signatures of the join point, and if the modifiers of the method or constructor are matched by any modifier pattern or annotation pattern that may be present.</para> - + </sect1> </chapter> diff --git a/docs/adk15ProgGuideDB/enumeratedtypes.xml b/docs/adk15ProgGuideDB/enumeratedtypes.xml index 2fc2ec14e..717252435 100644 --- a/docs/adk15ProgGuideDB/enumeratedtypes.xml +++ b/docs/adk15ProgGuideDB/enumeratedtypes.xml @@ -1,38 +1,38 @@ <chapter id="enumeratedtypes" xreflabel="Enumerated Types"> <title>Enumerated Types</title> - + <sect1 id="enums-in-java5"> <title>Enumerated Types in Java 5</title> - + <para>Java 5 (and hence AspectJ 5) provides explicit support for enumerated types. In the simplest case, you can declare an enumerated type as follows:</para> - + <programlisting><![CDATA[ - public enum ProgrammingLanguages { - COBOL,C,JAVA,ASPECTJ - } - ]]></programlisting> - +public enum ProgrammingLanguages { + COBOL, C, JAVA, ASPECTJ +} +]]></programlisting> + <para>Enumerated types are just classes, and they can contain method and field declarations, and may implement interfaces. Enums may only have private constructors, and may not be extended.</para> - + <para>Enumerated types in Java 5 all implicitly extend the type <literal>java.lang.Enum</literal>. It is illegal to explicitly declare a subtype of this class.</para> </sect1> - + <sect1 id="enums-in-aspectj5"> <title>Enumerated Types in AspectJ 5</title> - + <para> AspectJ 5 supports the declaration of enumerated types just as Java 5 does. Because of the special restrictions Java 5 places around enumerated types, AspectJ makes the following additional restrictions: </para> - + <itemizedlist> <listitem>You cannot use declare parents to change the super type of an enum.</listitem> @@ -42,23 +42,23 @@ enum.</listitem> <listitem>You cannot extend the set of values in an enum via any ITD-like construct.</listitem> - <listitem>You cannot make inter-type method or field declarations on + <listitem>You cannot make inter-type method or field declarations on an enum.</listitem> <listitem>You cannot use declare parents to make an enum type implement an interface.</listitem> </itemizedlist> - + <para>In theory, the last of these two items <emphasis>could</emphasis> be supported. However, AspectJ 5 follows the simple rule that <emphasis> an enum type cannot be the target of an inter-type declaration or declare parents statement</emphasis>. This position may be relaxed in a future version of AspectJ.</para> - + <para>If an enum is named explicitly as the target of a declare parents statement, a compilation error will result. If an enumerated type is matched by a non-explicit type pattern used in a declare parents statement it will be ignored (and an XLint warning issued).</para> </sect1> - + </chapter> diff --git a/docs/adk15ProgGuideDB/generics.xml b/docs/adk15ProgGuideDB/generics.xml index 89370fee6..f780ff67d 100644 --- a/docs/adk15ProgGuideDB/generics.xml +++ b/docs/adk15ProgGuideDB/generics.xml @@ -3,7 +3,7 @@ <chapter id="generics" xreflabel="Generics"> <title>Generics</title> - + <sect1 id="generics-inJava5"> <title>Generics in Java 5</title> @@ -16,40 +16,40 @@ <sect2 id="declaring-generic-types" xreflabel="declaring-generic-types"> <title>Declaring Generic Types</title> - + <para> - A generic type is declared with one or more type parameters following the type name. - By convention formal type parameters are named using a single letter, though this is not required. + A generic type is declared with one or more type parameters following 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 <literal>E</literal>) could be declared: </para> - + <programlisting><![CDATA[ - interface List<E> { - Iterator<E> iterator(); - void add(E anItem); - E remove(E anItem); - } - ]]></programlisting> - - +interface List<E> { + Iterator<E> iterator(); + void add(E anItem); + E remove(E anItem); +} +]]></programlisting> + + <para> - It is important to understand that unlike template mechanisms there will only be one type, and one class file, corresponding to + It is important to understand that unlike template mechanisms there will only be one type, and one class file, corresponding to the <literal>List</literal> interface, regardless of how many different instantiations of the <literal>List</literal> interface a program has (each potentially providing a different value for the type parameter <literal>E</literal>). A consequence of this - is that you cannot refer to the type parameters of a type declaration in a static method or initializer, or in the declaration or - initializer of a static variable. - </para> + is that you cannot refer to the type parameters of a type declaration in a static method or initializer, or in the declaration or + initializer of a static variable. + </para> <para> - A <emphasis>parameterized type</emphasis> + A <emphasis>parameterized type</emphasis> is an invocation of a generic type with concrete values supplied for all of its type parameters (for example, <literal>List<String></literal> or <literal>List<Food></literal>). </para> - + <para>A generic type may be declared with multiple type parameters. In addition to simple type parameter names, type - parameter declarations can also constrain the set of types allowed by using the <literal>extends</literal> + parameter declarations can also constrain the set of types allowed by using the <literal>extends</literal> keyword. Some examples follow:</para> - + <variablelist> <varlistentry> @@ -67,7 +67,7 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>class Foo<T extends Number> {...}</term> <listitem> @@ -76,7 +76,7 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>class Foo<T, S extends T> {...}</term> <listitem> @@ -85,7 +85,7 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>class Foo<T extends Number & Comparable> {...}</term> <listitem> @@ -94,42 +94,42 @@ </para> </listitem> </varlistentry> - + </variablelist> - + </sect2> - + <sect2 id="using-generic-and-parameterized-types" xreflabel="using-generic-and-parameterized-types"> <title>Using Generic and Parameterized Types</title> - + <para>You declare a variable (or a method/constructor argument) of a 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:</para> - + <programlisting><![CDATA[ - List<String> strings; - List<Number> numbers; - ]]></programlisting> - +List<String> strings; +List<Number> numbers; +]]></programlisting> + <para>It is also possible to declare a variable of a generic type without specifying any values for the type - parameters (a <emphasis>raw</emphasis> type). For example, <literal>List strings</literal>. + parameters (a <emphasis>raw</emphasis> type). For example, <literal>List strings</literal>. In this case, unchecked warnings may be issued by the compiler - when the referenced object is passed as a parameter to a method expecting a parameterized type such as a + when the referenced object is passed as a parameter to a method expecting a parameterized type such as a <literal>List<String></literal>. New code written in the Java 5 language would not be expected to use raw types.</para> - + <para>Parameterized types are instantiated by specifying type parameter values in the constructor call expression as in - the following examples:</para> + the following examples:</para> <programlisting><![CDATA[ - List<String> strings = new MyListImpl<String>(); - List<Number> numbers = new MyListImpl<Number>(); - ]]></programlisting> +List<String> strings = new MyListImpl<String>(); +List<Number> numbers = new MyListImpl<Number>(); +]]></programlisting> <para> When declaring parameterized types, the <literal>?</literal> wildcard may be used, which stands for "some type". The <literal>extends</literal> and <literal>super</literal> keywords may be used in conjunction with the wildcard to provide upper and lower bounds on the types that may satisfy the type constraints. For example: - </para> + </para> <variablelist> @@ -158,11 +158,11 @@ </varlistentry> </variablelist> - + <para> A generic type may be extended as any other type. Given a generic type <literal>Foo<T></literal> then - a subtype <literal>Goo</literal> may be declared in one of the following ways: - </para> + a subtype <literal>Goo</literal> may be declared in one of the following ways: + </para> <variablelist> @@ -180,7 +180,7 @@ <listitem> <para><literal>Goo</literal> is a generic type, but the super-type <literal>Foo</literal> is used as a raw type and the appropriate warning messages will be - issued by the compiler on attempting to invoke methods defined by <literal>Foo</literal>. + issued by the compiler on attempting to invoke methods defined by <literal>Foo</literal>. </para> </listitem> </varlistentry> @@ -189,7 +189,7 @@ <term>class Goo<E> extends Foo<E></term> <listitem> <para>This is the most usual form. <literal>Goo</literal> is a generic type with one parameter that extends - the generic type <literal>Foo</literal> with that same parameter. So <literal>Goo<String<</literal> is + the generic type <literal>Foo</literal> with that same parameter. So <literal>Goo<String<</literal> is a subclass of <literal>Foo<String></literal>. </para> </listitem> @@ -200,7 +200,7 @@ <listitem> <para><literal>Goo</literal> is a generic type with two parameters that extends the generic type <literal>Foo</literal> with the first type parameter of <literal>Goo</literal> being used - to parameterize <literal>Foo</literal>. So <literal>Goo<String,Integer<</literal> is + to parameterize <literal>Foo</literal>. So <literal>Goo<String,Integer<</literal> is a subclass of <literal>Foo<String></literal>. </para> </listitem> @@ -216,29 +216,29 @@ </varlistentry> </variablelist> - + <para>A generic type may implement one or more generic interfaces, following the type binding rules given above. A type may also implement one or more parameterized interfaces (for example, <literal>class X implements List<String></literal>, however a type may not at the same time be a subtype of two interface types which are different parameterizations of the same interface.</para> </sect2> - + <sect2 id="subtypes-supertypes-and-assignability" xreflabel="subtypes-supertypes-and-assignability"> <title>Subtypes, Supertypes, and Assignability</title> - + <para> The supertype of a generic type <literal>C</literal> is the type given in the extends clause of <literal>C</literal>, or <literal>Object</literal> if no extends clause is present. Given the type declaration </para> <programlisting><![CDATA[ - public interface List<E> extends Collection<E> {... } - ]]></programlisting> - +public interface List<E> extends Collection<E> {... } +]]></programlisting> + <para> then the supertype of <literal>List<E></literal> is <literal>Collection<E></literal>. </para> - + <para> The supertype of a parameterized type <literal>P</literal> is the type given in the extends clause of <literal>P</literal>, or <literal>Object</literal> if no extends clause is present. Any type parameters in @@ -248,21 +248,21 @@ <literal>Collection<Double></literal>. <literal>List<Double></literal> is <emphasis>not</emphasis> considered to be a subtype of <literal>List<Number></literal>. </para> - + <para> - An instance of a parameterized type <literal>P<T1,T2,...Tn></literal>may be assigned to a variable of + An instance of a parameterized type <literal>P<T1,T2,...Tn></literal>may be assigned to a variable of the same type or a supertype without casting. In addition it may be assigned to a variable <literal>R<S1,S2,...Sm></literal> where - <literal>R</literal> is a supertype of <literal>P</literal> (the supertype relationship is reflexive), + <literal>R</literal> is a supertype of <literal>P</literal> (the supertype relationship is reflexive), <literal>m <= n</literal>, and for all type parameters <literal>S1..m</literal>, <literal>Tm</literal> equals - <literal>Sm</literal> <emphasis>or</emphasis> <literal>Sm</literal> is a wildcard type specification and + <literal>Sm</literal> <emphasis>or</emphasis> <literal>Sm</literal> is a wildcard type specification and <literal>Tm</literal> falls within the bounds of the wildcard. For example, <literal>List<String></literal> can be assigned to a variable of type <literal>Collection<?></literal>, and <literal>List<Double></literal> - can be assigned to a variable of type <literal>List<? extends Number></literal>. + can be assigned to a variable of type <literal>List<? extends Number></literal>. </para> - + </sect2> - + <sect2 id="generic-methods-and-constructors" xreflabel="generic-methods-and-constructors"> <title>Generic Methods and Constructors</title> <para> @@ -270,26 +270,26 @@ </para> <programlisting><![CDATA[ - static <T> T first(List<T> ts) { ... } - ]]></programlisting> - +static <T> T first(List<T> ts) { ... } +]]></programlisting> + <para> Such a definition can appear in any type, the type parameter <literal>T</literal> does not need to be declared as a type parameter of the enclosing type. </para> - + <para> Non-static methods may also be declared with one or more type parameters in a similar fashion: </para> - + <programlisting><![CDATA[ - <T extends Number> T max(T t1, T t2) { ... } - ]]></programlisting> - +<T extends Number> T max(T t1, T t2) { ... } +]]></programlisting> + <para>The same technique can be used to declare a generic constructor.</para> - + </sect2> - + <sect2 id="erasure" xreflabel="erasure"> <title>Erasure</title> <para>Generics in Java are implemented using a technique called <emphasis>erasure</emphasis>. All @@ -301,181 +301,177 @@ </sect1> <!-- ===================================================================== --> - + <sect1 id="generics-inAspectJ5"> <title>Generics in AspectJ 5</title> - + <para> - AspectJ 5 provides full support for all of the Java 5 language features, including generics. Any legal Java 5 program is a + AspectJ 5 provides full support for all of the Java 5 language features, including generics. Any legal Java 5 program is a legal AspectJ 5 progam. In addition, AspectJ 5 provides support for generic and parameterized types in pointcuts, inter-type - declarations, and declare statements. Parameterized types may freely be used within aspect members, and support is + declarations, and declare statements. Parameterized types may freely be used within aspect members, and support is also provided for generic <emphasis>abstract</emphasis> aspects. </para> - + <sect2 id="matching-generic-and-parameterized-types-in-pointcut-expressions" xreflabel="matching-generic-and-parameterized-types-in-pointcut-expressions"> <title>Matching generic and parameterized types in pointcut expressions</title> - + <para> The simplest way to work with generic and parameterized types in pointcut expressions and type patterns is simply to use the raw type name. For example, the type pattern <literal>List</literal> will match - the generic type <literal>List<E></literal> and any parameterization of that type - (<literal>List<String>, List<?>, List<? extends Number></literal> and so on. This + the generic type <literal>List<E></literal> and any parameterization of that type + (<literal>List<String>, List<?>, List<? extends Number></literal> and so on. This ensures that pointcuts written in existing code that is not generics-aware will continue to work as expected in AspectJ 5. It is also the recommended way to match against generic and parameterized types in AspectJ 5 unless you explicitly wish to narrow matches to certain parameterizations of a generic type. </para> - + <para>Generic methods and constructors, and members defined in generic types, may use type variables as part of their signature. For example:</para> <programlisting><![CDATA[ - public class Utils { - - /** static generic method */ - static <T> T first(List<T> ts) { ... } - - /** instance generic method */ - <T extends Number> T max(T t1, T t2) { ... } - - } - - public class G<T> { - - // field with parameterized type - T myData; - - // method with parameterized return type - public List<T> getAllDataItems() {...} - - } - ]]></programlisting> - +public class Utils { + + /** static generic method */ + static <T> T first(List<T> ts) { ... } + + /** instance generic method */ + <T extends Number> T max(T t1, T t2) { ... } + +} + +public class G<T> { + + // field with parameterized type + T myData; + + // method with parameterized return type + public List<T> getAllDataItems() {...} + +} +]]></programlisting> + <para> AspectJ 5 does not allow the use of type variables in pointcut expressions and type patterns. Instead, members that use type parameters as part of their signature are matched by their <emphasis>erasure</emphasis>. Java 5 defines the rules for determing the erasure of a type as follows. </para> - + <para>Let <literal>|T|</literal> represent the erasure of some type <literal>T</literal>. Then:</para> - + <simplelist> <member>The erasure of a parameterized type <literal>T<T1,...,Tn></literal> is <literal>|T|</literal>. For example, the erasure of <literal>List<String></literal> is <literal>List</literal>.</member> - + <member>The erasure of a nested type <literal>T.C</literal> is <literal>|T|.C</literal>. For example, the erasure of the nested type <literal>Foo<T>.Bar</literal> is <literal>Foo.Bar</literal>.</member> - + <member>The erasure of an array type <literal>T[]</literal> is <literal>|T|[]</literal>. For example, the erasure of <literal>List<String>[]</literal> is <literal>List[]</literal>.</member> - - <member>The erasure of a type variable is its leftmost bound. For example, the erasure of a + + <member>The erasure of a type variable is its leftmost bound. For example, the erasure of a type variable <literal>P</literal> is <literal>Object</literal>, and the erasure of a type variable <literal>N extends Number</literal> is <literal>Number</literal>.</member> - + <member>The erasure of every other type is the type itself</member> </simplelist> - + <!-- see tests/java5/generics/ajdk/ErasureMatching.aj --> <para>Applying these rules to the earlier examples, we find that the methods defined in <literal>Utils</literal> can be matched by a signature pattern matching <literal>static Object Utils.first(List)</literal> and <literal>Number Utils.max(Number, Number)</literal> respectively. The members of the generic type <literal>G</literal> can be matched by a signature pattern matching <literal>Object G.myData</literal> and <literal>public List G.getAllDataItems()</literal> respectively.</para> - + <sect3> <title>Restricting matching using parameterized types</title> - + <para>Pointcut matching can be further restricted to match only given parameterizations of parameter types (methods and constructors), return - types (methods) and field types (fields). This is achieved by specifying a parameterized type pattern at the appropriate point + 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 <literal>Foo</literal>:</para> <programlisting><![CDATA[ - public class Foo { - - List<String> myStrings; - List<Float> myFloats; - - public List<String> getStrings() { return myStrings; } - public List<Float> getFloats() { return myFloats; } - - public void addStrings(List<String> evenMoreStrings) { - myStrings.addAll(evenMoreStrings); - } - - } - ]]></programlisting> +public class Foo { + + List<String> myStrings; + List<Float> myFloats; + + public List<String> getStrings() { return myStrings; } + public List<Float> getFloats() { return myFloats; } + + public void addStrings(List<String> evenMoreStrings) { + myStrings.addAll(evenMoreStrings); + } + +} +]]></programlisting> <!-- see tests/java5/generics/ajdk/SimpleParameterizedTypeExamples.aj --> - + <para>Then a <literal>get</literal> join point for the field <literal>myStrings</literal> can be matched by the pointcut <literal>get(List Foo.myStrings)</literal> and by the pointcut <literal>get(List<String> Foo.myStrings)</literal>, but <emphasis>not</emphasis> by the pointcut <literal>get(List<Number> *)</literal>.</para> - + <para>A <literal>get</literal> join point for the field <literal>myFloats</literal> can be matched by the pointcut <literal>get(List Foo.myFloats)</literal>, the pointcut <literal>get(List<Float> *)</literal>, and the pointcut <literal>get(List<Number+> *)</literal>. This last example shows how AspectJ type patterns can be used to match type parameters types just like any other type. The pointcut <literal>get(List<Double> *)</literal> does <emphasis>not</emphasis> match.</para> - + <para>The execution of the methods <literal>getStrings</literal> and <literal>getFloats</literal> can be matched by the pointcut expression <literal>execution(List get*(..))</literal>, and the pointcut expression <literal>execution(List<*> get*(..))</literal>, but only <literal>getStrings</literal> is matched by <literal>execution(List<String> get*(..))</literal> and only <literal>getFloats</literal> is matched by <literal>execution(List<Number+> get*(..))</literal></para> - + <para>A call to the method <literal>addStrings</literal> can be matched by the pointcut expression <literal>call(* addStrings(List))</literal> and by the expression <literal>call(* addStrings(List<String>))</literal>, but <emphasis>not</emphasis> by the expression <literal>call(* addStrings(List<Number>))</literal>. </para> - + <para>Remember that any type variable reference in a generic member is <emphasis>always</emphasis> matched by its erasure. Thus given the following example:</para> - + <programlisting><![CDATA[ - class G<T> { - - List<T> foo(List<String> ls) { return null; } - - } - ]]></programlisting> - +class G<T> { + List<T> foo(List<String> ls) { return null; } +} +]]></programlisting> + <!-- see tests/java5/generics/ajdk/MixedParameterizedAndTypeVariables.aj --> <para>The execution of <literal>foo</literal> can be matched by - <literal>execution(List foo(List))</literal>, - <literal>execution(List foo(List<String>>))</literal>, and - <literal>execution(* foo(List<String<))</literal>but + <literal>execution(List foo(List))</literal>, + <literal>execution(List foo(List<String>>))</literal>, and + <literal>execution(* foo(List<String<))</literal>but <emphasis>not</emphasis> by <literal>execution(List<Object> foo(List<String>>)</literal> since the erasure of <literal>List<T></literal> is <literal>List</literal> and not <literal>List<Object></literal>. </para> - + </sect3> - + <sect3> <title>Generic wildcards and signature matching</title> - + <para> When it comes to signature matching, a type parameterized using a generic wildcard is a distinct type. For example, <literal>List<?></literal> is a very different type to <literal>List<String></literal>, even though a variable of type <literal>List<String></literal> can be assigned to a variable of type <literal>List<?></literal>. Given the methods: </para> - + <programlisting><![CDATA[ - class C { - - public void foo(List<? extends Number> listOfSomeNumberType) {} - - public void bar(List<?> listOfSomeType) {} - - public void goo(List<Double> listOfDoubles) {} - - } - ]]></programlisting> - +class C { + public void foo(List<? extends Number> listOfSomeNumberType) {} + + public void bar(List<?> listOfSomeType) {} + + public void goo(List<Double> listOfDoubles) {} +} +]]></programlisting> + <!-- see java5/generics/ajdk/SignatureWildcards.aj --> - + <variablelist> <varlistentry> @@ -491,57 +487,53 @@ <listitem> <para>matches only the execution of <literal>foo</literal>, and <emphasis>not</emphasis> the execution - of <literal>goo</literal> since <literal>List<? extends Number></literal> and + of <literal>goo</literal> since <literal>List<? extends Number></literal> and <literal>List<Double></literal> are distinct types. </para> </listitem> </varlistentry> - + <varlistentry> <term>execution(* C.*(List<?>))</term> <listitem> <para>matches only the execution of <literal>bar</literal>. </para> </listitem> - </varlistentry> - + </varlistentry> + <varlistentry> <term>execution(* C.*(List<? extends Object+>))</term> <listitem> - <para>matches both the execution of <literal>foo</literal> and the execution of <literal>bar</literal> + <para>matches both the execution of <literal>foo</literal> and the execution of <literal>bar</literal> since the upper bound of <literal>List<?></literal> is implicitly <literal>Object</literal>. </para> </listitem> - </varlistentry> - + </varlistentry> + </variablelist> - + </sect3> <sect3> <title>Treatment of bridge methods</title> - + <para>Under certain circumstances a Java 5 compiler is required to create <emphasis>bridge methods</emphasis> that support the compilation of programs using raw types. Consider the types</para> - + <programlisting><![CDATA[ - class Generic<T> { - - public T foo(T someObject) { - return someObject; - } - - } - - class SubGeneric<N extends Number> extends Generic<N> { - - public N foo(N someNumber) { - return someNumber; - } - - } - ]]></programlisting> - +class Generic<T> { + public T foo(T someObject) { + return someObject; + } +} + +class SubGeneric<N extends Number> extends Generic<N> { + public N foo(N someNumber) { + return someNumber; + } +} +]]></programlisting> + <para>The class <literal>SubGeneric</literal> extends <literal>Generic</literal> and overrides the method <literal>foo</literal>. Since the upper bound of the type variable <literal>N</literal> in <literal>SubGeneric</literal> is different to the upper bound of @@ -550,14 +542,14 @@ in <literal>Generic</literal>. This is an example of a case where a Java 5 compiler will create a <emphasis>bridge method</emphasis> in <literal>SubGeneric</literal>. Although you never see it, the bridge method will look something like this:</para> - + <programlisting><![CDATA[ - public Object foo(Object arg) { - Number n = (Number) arg; // "bridge" to the signature defined in this type - return foo(n); - } - ]]></programlisting> - +public Object foo(Object arg) { + Number n = (Number) arg; // "bridge" to the signature defined in this type +return foo(n); +} +]]></programlisting> + <!-- see java5/generics/ajdk/BridgeMethodExamples.aj --> <para>Bridge methods are synthetic artefacts generated as a result of a particular compilation strategy and have no execution join points in AspectJ 5. So the pointcut <literal>execution(Object SubGeneric.foo(Object))</literal> @@ -565,24 +557,24 @@ execution of <literal>foo</literal> in both <literal>Generic</literal> and <literal>SubGeneric</literal> since both are implementations of <literal>Generic.foo</literal>). </para> - + <para>It <emphasis>is</emphasis> possible to <emphasis>call</emphasis> a bridge method as the following short code snippet demonstrates. Such a call <emphasis>does</emphasis> result in a call join point for the call to - the method. + the method. </para> <programlisting><![CDATA[ - SubGeneric rawType = new SubGeneric(); - rawType.foo("hi"); // call to bridge method (will result in a runtime failure in this case) - Object n = new Integer(5); - rawType.foo(n); // call to bridge method that would succeed at runtime - ]]></programlisting> - +SubGeneric rawType = new SubGeneric(); +rawType.foo("hi"); // call to bridge method (will result in a runtime failure in this case) +Object n = new Integer(5); +rawType.foo(n); // call to bridge method that would succeed at runtime +]]></programlisting> + </sect3> <sect3> <title>Runtime type matching with this(), target() and args()</title> - + <para>The <literal>this()</literal>, <literal>target()</literal>, and <literal>args()</literal> pointcut expressions all match based on the runtime type of their arguments. Because Java 5 implements generics using erasure, it is not @@ -594,19 +586,17 @@ </para> <programlisting><![CDATA[ - public class C { - - public void foo(List<String> listOfStrings) {} - - public void bar(List<Double> listOfDoubles) {} - - public void goo(List<? extends Number> listOfSomeNumberType) {} - - } - ]]></programlisting> - +public class C { + public void foo(List<String> listOfStrings) {} + + public void bar(List<Double> listOfDoubles) {} + + public void goo(List<? extends Number> listOfSomeNumberType) {} +} +]]></programlisting> + <!-- see java5/generics/ajdk/ArgsExamples.aj --> - + <variablelist> <varlistentry> @@ -617,7 +607,7 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>args(List<String>)</term> <listitem> @@ -638,27 +628,25 @@ In this situation a runtime test would normally be applied to ascertain whether or not the argument was indeed an instance of the required type. However, in the case of parameterized types such a test is not possible and therefore AspectJ 5 considers this a match, but issues an <emphasis>unchecked</emphasis> warning. - For example, compiling the aspect <literal>A</literal> below with the class <literal>C</literal> produces the - compilation warning: "unchecked match of List<Double> with List<? extends Number> when argument is + For example, compiling the aspect <literal>A</literal> below with the class <literal>C</literal> produces the + compilation warning: "unchecked match of List<Double> with List<? extends Number> when argument is an instance of List at join point method-execution(void C.goo(List<? extends Number>)) [Xlint:uncheckedArgument]"; </para> </listitem> </varlistentry> - + </variablelist> - + <programlisting><![CDATA[ - public aspect A { - - before(List<Double> listOfDoubles) : execution(* C.*(..)) && args(listOfDoubles) { - for (Double d : listOfDoubles) { - // do something - } - } - - } - ]]></programlisting> - +public aspect A { + before(List<Double> listOfDoubles) : execution(* C.*(..)) && args(listOfDoubles) { + for (Double d : listOfDoubles) { + // do something + } + } +} +]]></programlisting> + <para>Like all Lint messages, the <literal>uncheckedArgument</literal> warning can be configured in severity from the default warning level to error or even ignore if preferred. In addition, AspectJ 5 offers the annotation <literal>@SuppressAjWarnings</literal> which is @@ -666,246 +654,231 @@ advice is annotated with <literal>@SuppressWarnings</literal> then <emphasis>all</emphasis> lint warnings issued during matching of pointcut associated with the advice will be suppressed. To suppress just an <literal>uncheckedArgument</literal> warning, use the - annotation <literal>@SuppressWarnings("uncheckedArgument")</literal> as in the following + annotation <literal>@SuppressWarnings("uncheckedArgument")</literal> as in the following examples: </para> <programlisting><![CDATA[ - import org.aspectj.lang.annotation.SuppressAjWarnings - public aspect A { - - @SuppressAjWarnings // will not see *any* lint warnings for this advice - before(List<Double> listOfDoubles) : execution(* C.*(..)) && args(listOfDoubles) { - for (Double d : listOfDoubles) { - // do something - } - } - - @SuppressAjWarnings("uncheckedArgument") // will not see *any* lint warnings for this advice - before(List<Double> listOfDoubles) : execution(* C.*(..)) && args(listOfDoubles) { - for (Double d : listOfDoubles) { - // do something - } - } - - } - ]]></programlisting> - +import org.aspectj.lang.annotation.SuppressAjWarnings +public aspect A { + @SuppressAjWarnings // will not see *any* lint warnings for this advice + before(List<Double> listOfDoubles) : execution(* C.*(..)) && args(listOfDoubles) { + for (Double d : listOfDoubles) { + // do something + } + } + + @SuppressAjWarnings("uncheckedArgument") // will not see *any* lint warnings for this advice + before(List<Double> listOfDoubles) : execution(* C.*(..)) && args(listOfDoubles) { + for (Double d : listOfDoubles) { + // do something + } + } +} +]]></programlisting> + <para> The safest way to deal with <literal>uncheckedArgument</literal> warnings however is to restrict the pointcut to match only at those join points where the argument is guaranteed to match. This is achieved by combining - <literal>args</literal> with a <literal>call</literal> or <literal>execution</literal> signature matching + <literal>args</literal> with a <literal>call</literal> or <literal>execution</literal> signature matching pointcut. In the following example the advice will match the execution of <literal>bar</literal> but not of <literal>goo</literal> since the signature of <literal>goo</literal> is not matched by the execution pointcut expression. </para> - + <programlisting><![CDATA[ - public aspect A { - - before(List<Double> listOfDoubles) : execution(* C.*(List<Double>)) && args(listOfDoubles) { - for (Double d : listOfDoubles) { - // do something - } - } - - } - ]]></programlisting> - +public aspect A { + before(List<Double> listOfDoubles) : execution(* C.*(List<Double>)) && args(listOfDoubles) { + for (Double d : listOfDoubles) { + // do something + } + } +} +]]></programlisting> + <para>Generic wildcards can be used in args type patterns, and matching follows regular Java 5 assignability rules. For - example, <literal>args(List<?>)</literal> will match a list argument of any type, and + example, <literal>args(List<?>)</literal> will match a list argument of any type, and <literal>args(List<? extends Number>)</literal> will match an argument of type - <literal>List<Number>, List<Double>, List<Float></literal> and so on. Where a match cannot be + <literal>List<Number>, List<Double>, List<Float></literal> and so on. Where a match cannot be fully statically determined, the compiler will once more issue an <literal>uncheckedArgument</literal> warning. </para> <para>Consider the following program:</para> - + <programlisting><![CDATA[ - public class C { - - public static void main(String[] args) { - C c = new C(); - List<String> ls = new ArrayList<String>(); - List<Double> ld = new ArrayList<Double>(); - c.foo("hi"); - c.foo(ls); - c.foo(ld); - } - - public void foo(Object anObject) {} - } - - aspect A { - before(List<? extends Number> aListOfSomeNumberType) - : call(* foo(..)) && args(aListOfSomeNumberType) { - // process list... - } - } - ]]></programlisting> - +public class C { + public static void main(String[] args) { + C c = new C(); + List<String> ls = new ArrayList<String>(); + List<Double> ld = new ArrayList<Double>(); + c.foo("hi"); + c.foo(ls); + c.foo(ld); + } + + public void foo(Object anObject) {} +} + +aspect A { + before(List<? extends Number> aListOfSomeNumberType) + : call(* foo(..)) && args(aListOfSomeNumberType) { + // process list... + } +} +]]></programlisting> + <!-- see java5/generics/ajdk/WildcardArgsExamples.aj --> - - <para>From the signature of <literal>foo</literal> all we know is that the runtime argument will be an instance of - <literal>Object</literal>.Compiling this program gives the unchecked argument warning: - "unchecked match of List<? extends Number> with List when argument is + + <para>From the signature of <literal>foo</literal> all we know is that the runtime argument will be an instance of + <literal>Object</literal>.Compiling this program gives the unchecked argument warning: + "unchecked match of List<? extends Number> with List when argument is an instance of List at join point method-execution(void C.foo(Object)) [Xlint:uncheckedArgument]". The advice will not execute at the call join point for <literal>c.foo("hi")</literal> since <literal>String</literal> is not an instance of <literal>List</literal>. The advice <emphasis>will</emphasis> execute at the call join points for <literal>c.foo(ls)</literal> and <literal>c.foo(ld)</literal> since in both cases the argument is an instance of <literal>List</literal>. </para> - + <para>Combine a wildcard argument type with a signature pattern to avoid unchecked argument matches. In the example below we use the signature pattern <literal>List<Number+></literal> to match a call to any method taking - a <literal>List<Number>, List<Double>, List<Float></literal> and so on. In addition the + a <literal>List<Number>, List<Double>, List<Float></literal> and so on. In addition the signature pattern <literal>List<? extends Number+></literal> can be used to match a call to a method declared to take a <literal>List<? extends Number></literal>, <literal>List<? extends Double></literal> and so on. Taken together, these restrict matching to only those join points at which the argument is guaranteed to be an instance of <literal>List<? extends Number></literal>.</para> - - + + <programlisting><![CDATA[ - aspect A { - before(List<? extends Number> aListOfSomeNumberType) - : (call(* foo(List<Number+>)) || call(* foo(List<? extends Number+>))) - && args(aListOfSomeNumberType) { - // process list... - } - } - ]]></programlisting> - +aspect A { + before(List<? extends Number> aListOfSomeNumberType) + : (call(* foo(List<Number+>)) || call(* foo(List<? extends Number+>))) + && args(aListOfSomeNumberType) { + // process list... + } +} +]]></programlisting> + </sect3> <sect3> <title>Binding return values in after returning advice</title> - + <para> After returning advice can be used to bind the return value from a matched join point. AspectJ 5 supports the use of a parameterized type in the returning clause, with matching following the same rules as described for args. For example, the following aspect matches the execution of any method returning a <literal>List</literal>, and makes - the returned list available to the body of the advice. + the returned list available to the body of the advice. </para> <programlisting><![CDATA[ - public aspect A { - - pointcut executionOfAnyMethodReturningAList() : execution(List *(..)); - - after() returning(List<?> listOfSomeType) : executionOfAnyMethodReturningAList() { - for (Object element : listOfSomeType) { - // process element... - } - } - - } - ]]></programlisting> - +public aspect A { + pointcut executionOfAnyMethodReturningAList() : execution(List *(..)); + + after() returning(List<?> listOfSomeType) : executionOfAnyMethodReturningAList() { + for (Object element : listOfSomeType) { + // process element... + } + } +} +]]></programlisting> + <!-- see java5/generics/ajdk/AfterReturningExamples.aj --> <para>The pointcut uses the raw type pattern <literal>List</literal>, and hence it - matches methods returning any kind of list (<literal>List<String>, List<Double></literal>, - and so on). We've chosen to bind the returned list as the parameterized type + matches methods returning any kind of list (<literal>List<String>, List<Double></literal>, + and so on). We've chosen to bind the returned list as the parameterized type <literal>List<?></literal> in the advice since Java's type checking will now ensure that we only perform safe operations on the list.</para> - + <para>Given the class</para> - + <programlisting><![CDATA[ - public class C { - - public List<String> foo(List<String> listOfStrings) {...} - - public List<Double> bar(List<Double> listOfDoubles) {...} - - public List<? extends Number> goo(List<? extends Number> listOfSomeNumberType) {...} - - } - ]]></programlisting> +public class C { + public List<String> foo(List<String> listOfStrings) {...} + + public List<Double> bar(List<Double> listOfDoubles) {...} + + public List<? extends Number> goo(List<? extends Number> listOfSomeNumberType) {...} +} +]]></programlisting> <para>The advice in the aspect below will run after the execution of <literal>bar</literal> and bind the return value. It will also run after the execution of <literal>goo</literal> and bind the return value, but gives an <literal>uncheckedArgument</literal> warning during compilation. It does <emphasis>not</emphasis> run after the execution of <literal>foo</literal>. - </para> + </para> <programlisting><![CDATA[ - public aspect Returning { - - after() returning(List<Double> listOfDoubles) : execution(* C.*(..)) { - for(Double d : listOfDoubles) { - // process double... - } - } - - } - ]]></programlisting> - +public aspect Returning { + after() returning(List<Double> listOfDoubles) : execution(* C.*(..)) { + for(Double d : listOfDoubles) { + // process double... + } + } +} +]]></programlisting> + <para>As with <literal>args</literal> you can guarantee that after returning advice only executes on lists <emphasis>statically determinable</emphasis> to be of the right - type by specifying a return type pattern in the associated pointcut. The + type by specifying a return type pattern in the associated pointcut. The <literal>@SuppressAjWarnings</literal> annotation can also be used if desired.</para> - + </sect3> <sect3> <title>Declaring pointcuts inside generic types</title> - + <para>Pointcuts can be declared in both classes and aspects. A pointcut declared in a generic type may use the type variables of the type in which it is declared. All references to - a pointcut declared in a generic type from outside of that type must be via a parameterized type reference, + a pointcut declared in a generic type from outside of that type must be via a parameterized type reference, and not a raw type reference.</para> <para>Consider the generic type <literal>Generic</literal> with a pointcut <literal>foo</literal>: </para> - + <programlisting><![CDATA[ - public class Generic<T> { - - /** - * matches the execution of any implementation of a method defined for T - */ - public pointcut foo() : execution(* T.*(..)); - - } - ]]></programlisting> - - <!-- see java5/generics/ajdk/PointcutInGenericClassExample.aj --> - +public class Generic<T> { + /** + * matches the execution of any implementation of a method defined for T + */ + public pointcut foo() : execution(* T.*(..)); +} +]]></programlisting> + + <!-- see java5/generics/ajdk/PointcutInGenericClassExample.aj --> + <para>Such a pointcut must be refered to using a parameterized reference as shown below.</para> - + <programlisting><![CDATA[ - public aspect A { - - // runs before the execution of any implementation of a method defined for MyClass - before() : Generic<MyClass>.foo() { - // ... - } - - // runs before the execution of any implementation of a method defined for YourClass - before() : Generic<YourClass>.foo() { - // ... - } - - // results in a compilation error - raw type reference - before() : Generic.foo() { } - - } - ]]></programlisting> - +public aspect A { + // runs before the execution of any implementation of a method defined for MyClass + before() : Generic<MyClass>.foo() { + // ... + } + + // runs before the execution of any implementation of a method defined for YourClass + before() : Generic<YourClass>.foo() { + // ... + } + + // results in a compilation error - raw type reference + before() : Generic.foo() { } +} +]]></programlisting> + </sect3> - + </sect2> - + <sect2 id="inter-type-declarations" xreflabel="inter-type-declarations"> <title>Inter-type Declarations</title> - + <para> AspectJ 5 supports the inter-type declaration of generic methods, and of members on generic types. For generic methods, the syntax is exactly as for a regular method declaration, with the addition of the target type specification: </para> - + <variablelist> <varlistentry> @@ -940,15 +913,15 @@ </varlistentry> </variablelist> - + <para> A generic type may be the target of an inter-type declaration, used either in its raw form or with type parameters specified. If type parameters are specified, then the number of type parameters given must match the number of type parameters in the generic type declaration. Type parameter <emphasis>names</emphasis> do not have to match. - For example, given the generic type <literal>Foo<T,S extends Number></literal> then: - </para> - + For example, given the generic type <literal>Foo<T,S extends Number></literal> then: + </para> + <variablelist> <varlistentry> @@ -965,9 +938,9 @@ <listitem> <para>Declares a method <literal>getMagnitude</literal> on the generic class <literal>Foo</literal>. The method returns an instance of the type substituted for the second type parameter in an invocation - of <literal>Foo</literal> If <literal>Foo</literal> is declared as + of <literal>Foo</literal> If <literal>Foo</literal> is declared as <literal>Foo<T,N extends Number> {...}</literal> then this inter-type declaration is - equivalent to the declaration of a method <literal>public N getMagnitude()</literal> + equivalent to the declaration of a method <literal>public N getMagnitude()</literal> within the body of <literal>Foo</literal>. </para> </listitem> @@ -984,19 +957,19 @@ </varlistentry> </variablelist> - + <para>A parameterized type may not be the target of an inter-type declaration. This is because there is only one type (the generic type) regardless of how many different invocations (parameterizations) of that generic type are made in a program. Therefore it does not make sense to try and declare a member on behalf of (say) <literal>Bar<String></literal>, you can only declare members on the generic - type <literal>Bar<T></literal>. + type <literal>Bar<T></literal>. </para> - + </sect2> - + <sect2 id="declare-parents-java5" xreflabel="declare-parents-java5"> <title>Declare Parents</title> - + <para>Both generic and parameterized types can be used as the parent type in a <literal>declare parents</literal> statement (as long as the resulting type hierarchy would be well-formed in accordance with Java's sub-typing rules). Generic types may also be used as the target type of a <literal>declare parents</literal> statement.</para> @@ -1008,8 +981,8 @@ <listitem> <para>The <literal>Foo</literal> type implements the <literal>List<String></literal> interface. If <literal>Foo</literal> already implements some other parameterization of the <literal>List</literal> - interface (for example, <literal>List<Integer></literal> then a compilation error will result since a - type cannot implement multiple parameterizations of the same generic interface type. + interface (for example, <literal>List<Integer></literal> then a compilation error will result since a + type cannot implement multiple parameterizations of the same generic interface type. </para> </listitem> </varlistentry> @@ -1017,7 +990,7 @@ </variablelist> </sect2> - + <sect2 id="declare-soft" xreflabel="declare-soft"> <title>Declare Soft</title> <para>It is an error to use a generic or parameterized type as the softened exception type in a declare soft statement. Java 5 does @@ -1026,21 +999,21 @@ <sect2 id="generic-aspects" xreflabel="generic-aspects"> <title>Generic Aspects</title> - + <para> AspectJ 5 allows an <emphasis>abstract</emphasis> aspect to be declared as a generic type. Any concrete aspect extending a generic abstract aspect must extend a parameterized version of the abstract aspect. - Wildcards are not permitted in this parameterization. + Wildcards are not permitted in this parameterization. </para> - + <para>Given the aspect declaration:</para> - + <programlisting><![CDATA[ - public abstract aspect ParentChildRelationship<P,C> { - ... - } - ]]></programlisting> - +public abstract aspect ParentChildRelationship<P,C> { + ... +} +]]></programlisting> + <para>then</para> <variablelist> @@ -1081,105 +1054,104 @@ </varlistentry> </variablelist> - + <para>The type parameter variables from a generic aspect declaration may be used in place of a type within any - member of the aspect, <emphasis>except for within inter-type declarations</emphasis>. + member of the aspect, <emphasis>except for within inter-type declarations</emphasis>. For example, we can declare a <literal>ParentChildRelationship</literal> aspect to manage the bi-directional relationship between parent and child nodes as follows: </para> <programlisting><![CDATA[ - /** - * a generic aspect, we've used descriptive role names for the type variables - * (Parent and Child) but you could use anything of course - */ - public abstract aspect ParentChildRelationship<Parent,Child> { - - /** generic interface implemented by parents */ - interface ParentHasChildren<C extends ChildHasParent>{ - List<C> getChildren(); - void addChild(C child); - void removeChild(C child); - } - - /** generic interface implemented by children */ - interface ChildHasParent<P extends ParentHasChildren>{ - P getParent(); - void setParent(P parent); - } - - /** ensure the parent type implements ParentHasChildren<child type> */ - declare parents: Parent implements ParentHasChildren<Child>; - - /** ensure the child type implements ChildHasParent<parent type> */ - declare parents: Child implements ChildHasParent<Parent>; - - // Inter-type declarations made on the *generic* interface types to provide - // default implementations. - - /** list of children maintained by parent */ - private List<C> ParentHasChildren<C>.children = new ArrayList<C>(); - - /** reference to parent maintained by child */ - private P ChildHasParent<P>.parent; - - /** Default implementation of getChildren for the generic type ParentHasChildren */ - public List<C> ParentHasChildren<C>.getChildren() { - return Collections.unmodifiableList(children); - } - - /** Default implementation of getParent for the generic type ChildHasParent */ - public P ChildHasParent<P>.getParent() { - return parent; - } - - /** - * Default implementation of addChild, ensures that parent of child is - * also updated. - */ - public void ParentHasChildren<C>.addChild(C child) { - if (child.parent != null) { - child.parent.removeChild(child); - } - children.add(child); - child.parent = this; - } - - /** - * Default implementation of removeChild, ensures that parent of - * child is also updated. - */ - public void ParentHasChildren<C>.removeChild(C child) { - if (children.remove(child)) { - child.parent = null; - } - } - - /** - * Default implementation of setParent for the generic type ChildHasParent. - * Ensures that this child is added to the children of the parent too. - */ - public void ChildHasParent<P>.setParent(P parent) { - parent.addChild(this); - } - - /** - * Matches at an addChild join point for the parent type P and child type C - */ - public pointcut addingChild(Parent p, Child c) : - execution(* ParentHasChildren.addChild(ChildHasParent)) && this(p) && args(c); - - /** - * Matches at a removeChild join point for the parent type P and child type C - */ - public pointcut removingChild(Parent p, Child c) : - execution(* ParentHasChildren.removeChild(ChildHasParent)) && this(p) && args(c); - - } - - ]]></programlisting> - - +/** + * a generic aspect, we've used descriptive role names for the type variables + * (Parent and Child) but you could use anything of course + */ +public abstract aspect ParentChildRelationship<Parent,Child> { + + /** generic interface implemented by parents */ + interface ParentHasChildren<C extends ChildHasParent>{ + List<C> getChildren(); + void addChild(C child); + void removeChild(C child); + } + + /** generic interface implemented by children */ + interface ChildHasParent<P extends ParentHasChildren>{ + P getParent(); + void setParent(P parent); + } + + /** ensure the parent type implements ParentHasChildren<child type> */ + declare parents: Parent implements ParentHasChildren<Child>; + + /** ensure the child type implements ChildHasParent<parent type> */ + declare parents: Child implements ChildHasParent<Parent>; + + // Inter-type declarations made on the *generic* interface types to provide + // default implementations. + + /** list of children maintained by parent */ + private List<C> ParentHasChildren<C>.children = new ArrayList<C>(); + + /** reference to parent maintained by child */ + private P ChildHasParent<P>.parent; + + /** Default implementation of getChildren for the generic type ParentHasChildren */ + public List<C> ParentHasChildren<C>.getChildren() { + return Collections.unmodifiableList(children); + } + + /** Default implementation of getParent for the generic type ChildHasParent */ + public P ChildHasParent<P>.getParent() { + return parent; + } + + /** + * Default implementation of addChild, ensures that parent of child is + * also updated. + */ + public void ParentHasChildren<C>.addChild(C child) { + if (child.parent != null) { + child.parent.removeChild(child); + } + children.add(child); + child.parent = this; + } + + /** + * Default implementation of removeChild, ensures that parent of + * child is also updated. + */ + public void ParentHasChildren<C>.removeChild(C child) { + if (children.remove(child)) { + child.parent = null; + } + } + + /** + * Default implementation of setParent for the generic type ChildHasParent. + * Ensures that this child is added to the children of the parent too. + */ + public void ChildHasParent<P>.setParent(P parent) { + parent.addChild(this); + } + + /** + * Matches at an addChild join point for the parent type P and child type C + */ + public pointcut addingChild(Parent p, Child c) : + execution(* ParentHasChildren.addChild(ChildHasParent)) && this(p) && args(c); + + /** + * Matches at a removeChild join point for the parent type P and child type C + */ + public pointcut removingChild(Parent p, Child c) : + execution(* ParentHasChildren.removeChild(ChildHasParent)) && this(p) && args(c); + +} +]]></programlisting> + + <para> The example aspect captures the protocol for managing a bi-directional parent-child relationship between any two types playing the role of parent and child. In a compiler implementation managing an abstract syntax @@ -1187,15 +1159,13 @@ </para> <programlisting><![CDATA[ - public aspect ASTNodeContainment extends ParentChildRelationship<ASTNode,ASTNode> { - - before(ASTNode parent, ASTNode child) : addingChild(parent, child) { - ... - } - - } - ]]></programlisting> - +public aspect ASTNodeContainment extends ParentChildRelationship<ASTNode,ASTNode> { + before(ASTNode parent, ASTNode child) : addingChild(parent, child) { + ... + } +} +]]></programlisting> + <para> As a result of this declaration, <literal>ASTNode</literal> gains members: </para> @@ -1208,17 +1178,16 @@ <member><literal>void addChild(ASTNode child)</literal></member> <member><literal>void removeChild(ASTNode child)</literal></member> <member><literal>void setParent(ASTNode parent)</literal></member> - </simplelist> - + </simplelist> + <para> In a system managing orders, we could declare the concrete aspect: </para> <programlisting><![CDATA[ - public aspect OrderItemsInOrders extends ParentChildRelationship<Order,OrderItem> { - - } - ]]></programlisting> +public aspect OrderItemsInOrders extends ParentChildRelationship<Order, OrderItem> { +} +]]></programlisting> <para> As a result of this declaration, <literal>Order</literal> gains members: @@ -1229,73 +1198,73 @@ <member><literal>List<OrderItem> getChildren()</literal></member> <member><literal>void addChild(OrderItem child)</literal></member> <member><literal>void removeChild(OrderItem child)</literal></member> - </simplelist> + </simplelist> <para>and <literal>OrderItem</literal> gains members:</para> - + <simplelist> <member><literal>Order parent</literal></member> <member><literal>Order getParent()</literal></member> <member><literal>void setParent(Order parent)</literal></member> - </simplelist> - - + </simplelist> + + <para>A second example of an abstract aspect, this time for handling exceptions in a uniform manner, is shown below:</para> - + <programlisting><![CDATA[ - abstract aspect ExceptionHandling<T extends Throwable> { - - /** - * method to be implemented by sub-aspects to handle thrown exceptions - */ - protected abstract void onException(T anException); - - /** - * to be defined by sub-aspects to specify the scope of exception handling - */ - protected abstract pointcut inExceptionHandlingScope(); - - /** - * soften T within the scope of the aspect - */ - declare soft: T : inExceptionHandlingScope(); - - /** - * bind an exception thrown in scope and pass it to the handler - */ - after() throwing (T anException) : inExceptionHandlingScope() { - onException(anException); - } - - } - ]]></programlisting> +abstract aspect ExceptionHandling<T extends Throwable> { + + /** + * method to be implemented by sub-aspects to handle thrown exceptions + */ + protected abstract void onException(T anException); + + /** + * to be defined by sub-aspects to specify the scope of exception handling + */ + protected abstract pointcut inExceptionHandlingScope(); + + /** + * soften T within the scope of the aspect + */ + declare soft: T : inExceptionHandlingScope(); + + /** + * bind an exception thrown in scope and pass it to the handler + */ + after() throwing (T anException) : inExceptionHandlingScope() { + onException(anException); + } + +} +]]></programlisting> <para>Notice how the type variable <literal>T extends Throwable</literal> allows the components 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 + following concrete sub-aspect shows how the abstract aspect might be extended to handle <literal>IOExceptions</literal>.</para> <programlisting><![CDATA[ - public aspect IOExceptionHandling extends ExceptionHandling<IOException>{ - - protected pointcut inExceptionHandlingScope() : - call(* doIO*(..)) && within(org.xyz..*); - - /** - * called whenever an IOException is thrown in scope. - */ - protected void onException(IOException ex) { - System.err.println("handled exception: " + ex.getMessage()); - throw new MyDomainException(ex); - } - } - ]]></programlisting> +public aspect IOExceptionHandling extends ExceptionHandling<IOException>{ + + protected pointcut inExceptionHandlingScope() : + call(* doIO*(..)) && within(org.xyz..*); + + /** + * called whenever an IOException is thrown in scope. + */ + protected void onException(IOException ex) { + System.err.println("handled exception: " + ex.getMessage()); + throw new MyDomainException(ex); + } +} +]]></programlisting> </sect2> - + </sect1> - + </chapter> diff --git a/docs/adk15ProgGuideDB/grammar.xml b/docs/adk15ProgGuideDB/grammar.xml index 1de50b7bf..048118c34 100644 --- a/docs/adk15ProgGuideDB/grammar.xml +++ b/docs/adk15ProgGuideDB/grammar.xml @@ -1,192 +1,190 @@ <appendix id="grammar" xreflabel="AspectJ 5 Grammar"> <title>A Grammar for the AspectJ 5 Language</title> - + <programlisting><![CDATA[ - === type patterns === - - TypePattern := SimpleTypePattern | - '!' TypePattern | - '(' AnnotationPattern? TypePattern ')' - TypePattern '&&' TypePattern | - TypePattern '||' TypePattern - - SimpleTypePattern := DottedNamePattern '+'? '[]'* - - DottedNamePattern := FullyQualifiedName RestOfNamePattern? | - '*' NotStarNamePattern? - - RestOfNamePattern := '..' DottedNamePattern | - '*' NotStarNamePattern? - - NotStarNamePattern := FullyQualifiedName RestOfNamePattern? | - '..' DottedNamePattern - - FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)* - - === annotation patterns === - - AnnotationPattern := '!'? '@' AnnotationTypePattern AnnotationPattern* - - - AnnotationTypePattern := FullyQualifiedName | - '(' TypePattern ')' - - === signature patterns === - - -- field -- - - FieldPattern := - AnnotationPattern? FieldModifiersPattern? - TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern - - FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern* - - FieldModifier := 'public' | 'private' | 'protected' | 'static' | - 'transient' | 'final' - - DotOrDotDot := '.' | '..' - - SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)? - - -- method -- - - MethodPattern := - AnnotationPattern? MethodModifiersPattern? TypePattern - (TypePattern DotOrDotDot)? SimpleNamePattern - '(' FormalsPattern ')' ThrowsPattern? - - MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern* - - MethodModifier := 'public' | 'private' | 'protected' | 'static' | - 'synchronized' | 'final' - - FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? | - OptionalParensTypePattern (',' FormalsPattern)* | - TypePattern '...' - - FormalsPatternAfterDotDot := - OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | - TypePattern '...' - - ThrowsPattern := 'throws' TypePatternList - - TypePatternList := TypePattern (',' TypePattern)* - - -- constructor -- - - ConstructorPattern := - AnnotationPattern? ConstructorModifiersPattern? - (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')' - ThrowsPattern? - - ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern* - - ConstructorModifier := 'public' | 'private' | 'protected' - - === Pointcuts === - - PointcutPrimitive := - Call | Execution | Get | Set | Handler | - Initialization | PreInitialization | - StaticInitialization | AdviceExecution | - This | Target | Args | CFlow | CFlowBelow | - Within | WithinCode | If | - AnnotationPointcut - - AnnotationPointcut := AtAnnotation | AtThis | AtTarget | - AtWithin | AtWithinCode | AtArgs - - - Call := 'call' '(' MethodOrConstructorPattern ')' - - MethodOrConstructorPattern := MethodPattern | ConstructorPattern - - Execution := 'execution' '(' MethodOrConstructorPattern ')' - - Get := 'get' '(' FieldPattern ')' - Set := 'set' '(' FieldPattern ')' - Handler := 'handler' '(' OptionalParensTypePattern ')' - Initialization := 'initialization' '(' ConstructorPattern ')' - PreInitialization := 'preinitialization' '(' ConstructorPattern ')' - StaticInitialization := 'staticinitialization' '(' OptionalParensTypePattern ')' - AdviceExecution := 'adviceexecution' '(' ')' - This := 'this' '(' TypeOrIdentifier ')' - Target := 'target' '(' TypeOrIdentifier ')' - Args := 'args' '(' FormalsOrIdentifiersPattern ')' - CFlow := 'cflow' '(' Pointcut ')' - CFlowBelow := 'cflowbelow' '(' Pointcut ')' - Within := 'within' '(' OptionalParensTypePattern ')' - WithinCode := 'withincode' '(' OptionalParensTypePattern ')' - If := 'if' '(' BooleanJavaExpression ')' - - TypeOrIdentifier := FullyQualifiedName ('[' ']')* | Identifier - Identifier := JavaIdentifierChar+ - - FormalsOrIdentifiersPattern := - '..' (',' FormalsOrIdentifiersPatternAfterDotDot)? | - TypeOrIdentifier (',' FormalsOrIdentifiersPattern)* | - '*' (',' FormalsOrIdentifiersPattern)* - - FormalsOrIdentifiersPatternAfterDotDot := - TypeOrIdentifier (',' FormalsOrIdentifiersPatternAfterDotDot)* | - '*' (',' FormalsOrIdentifiersPatternAfterDotDot)* - - AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')' - AtThis := '@this' '(' AnnotationOrIdentifer ')' - AtTarget := '@target' '(' AnnotationOrIdentifier ')' - AtWithin := '@within' '(' AnnotationOrIdentifier ')' - AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')' - - AnnotationOrIdentifier := FullyQualifiedName | Identifier - - AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')' - - AnnotationsOrIdentifiersPattern := - '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? | - AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* | - '*' (',' AnnotationsOrIdentifiersPattern)* - - AnnotationsOrIdentifiersPatternAfterDotDot := - AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* | - '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)* - - PointcutDeclaration := PointcutModifiers? 'pointcut' Identifier Formals - ':' PointcutExpression - - PointcutModifiers := PointcutModifier* - - PointcutModifier := 'public' | 'private' | 'protected' | 'abstract' - - Formals := '(' ParamList? ')' - ParamList := FullyQualifiedName Identifier (',' ParamList)* - - ReferencePointcut := (FullyQualifiedName '.')? Identifier Formals - - PointcutExpression := (PointcutPrimitive | ReferencePointcut) | - '!' PointcutExpression | - '(' PointcutExpression ')' | - PointcutExpression '&&' PointcutExpression | - PointcutExpression '||' PointcutExpression - - === Advice === - - to be written... - - === Inter-type Declarations === - - to be written... - - === Declare Statements === - - to be written... - - === Aspects === - - to be written... - - ]]></programlisting> +=== type patterns === + +TypePattern := SimpleTypePattern | + '!' TypePattern | + '(' AnnotationPattern? TypePattern ')' + TypePattern '&&' TypePattern | + TypePattern '||' TypePattern + +SimpleTypePattern := DottedNamePattern '+'? '[]'* + +DottedNamePattern := FullyQualifiedName RestOfNamePattern? | + '*' NotStarNamePattern? + +RestOfNamePattern := '..' DottedNamePattern | + '*' NotStarNamePattern? + +NotStarNamePattern := FullyQualifiedName RestOfNamePattern? | + '..' DottedNamePattern + +FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)* + +=== annotation patterns === + +AnnotationPattern := '!'? '@' AnnotationTypePattern AnnotationPattern* + + +AnnotationTypePattern := FullyQualifiedName | + '(' TypePattern ')' + +=== signature patterns === + +-- field -- + +FieldPattern := + AnnotationPattern? FieldModifiersPattern? + TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern + +FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern* + +FieldModifier := 'public' | 'private' | 'protected' | 'static' | + 'transient' | 'final' + +DotOrDotDot := '.' | '..' + +SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)? + +-- method -- + +MethodPattern := + AnnotationPattern? MethodModifiersPattern? TypePattern + (TypePattern DotOrDotDot)? SimpleNamePattern + '(' FormalsPattern ')' ThrowsPattern? + +MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern* + +MethodModifier := 'public' | 'private' | 'protected' | 'static' | + 'synchronized' | 'final' + +FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? | + OptionalParensTypePattern (',' FormalsPattern)* | + TypePattern '...' + +FormalsPatternAfterDotDot := + OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | + TypePattern '...' + +ThrowsPattern := 'throws' TypePatternList + +TypePatternList := TypePattern (',' TypePattern)* + +-- constructor -- + +ConstructorPattern := + AnnotationPattern? ConstructorModifiersPattern? + (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')' + ThrowsPattern? + +ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern* + +ConstructorModifier := 'public' | 'private' | 'protected' + +=== Pointcuts === + +PointcutPrimitive := + Call | Execution | Get | Set | Handler | + Initialization | PreInitialization | + StaticInitialization | AdviceExecution | + This | Target | Args | CFlow | CFlowBelow | + Within | WithinCode | If | + AnnotationPointcut + +AnnotationPointcut := AtAnnotation | AtThis | AtTarget | + AtWithin | AtWithinCode | AtArgs + + +Call := 'call' '(' MethodOrConstructorPattern ')' + +MethodOrConstructorPattern := MethodPattern | ConstructorPattern + +Execution := 'execution' '(' MethodOrConstructorPattern ')' + +Get := 'get' '(' FieldPattern ')' +Set := 'set' '(' FieldPattern ')' +Handler := 'handler' '(' OptionalParensTypePattern ')' +Initialization := 'initialization' '(' ConstructorPattern ')' +PreInitialization := 'preinitialization' '(' ConstructorPattern ')' +StaticInitialization := 'staticinitialization' '(' OptionalParensTypePattern ')' +AdviceExecution := 'adviceexecution' '(' ')' +This := 'this' '(' TypeOrIdentifier ')' +Target := 'target' '(' TypeOrIdentifier ')' +Args := 'args' '(' FormalsOrIdentifiersPattern ')' +CFlow := 'cflow' '(' Pointcut ')' +CFlowBelow := 'cflowbelow' '(' Pointcut ')' +Within := 'within' '(' OptionalParensTypePattern ')' +WithinCode := 'withincode' '(' OptionalParensTypePattern ')' +If := 'if' '(' BooleanJavaExpression ')' + +TypeOrIdentifier := FullyQualifiedName ('[' ']')* | Identifier +Identifier := JavaIdentifierChar+ + +FormalsOrIdentifiersPattern := + '..' (',' FormalsOrIdentifiersPatternAfterDotDot)? | + TypeOrIdentifier (',' FormalsOrIdentifiersPattern)* | + '*' (',' FormalsOrIdentifiersPattern)* + +FormalsOrIdentifiersPatternAfterDotDot := + TypeOrIdentifier (',' FormalsOrIdentifiersPatternAfterDotDot)* | + '*' (',' FormalsOrIdentifiersPatternAfterDotDot)* + +AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')' +AtThis := '@this' '(' AnnotationOrIdentifer ')' +AtTarget := '@target' '(' AnnotationOrIdentifier ')' +AtWithin := '@within' '(' AnnotationOrIdentifier ')' +AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')' + +AnnotationOrIdentifier := FullyQualifiedName | Identifier + +AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')' + +AnnotationsOrIdentifiersPattern := + '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? | + AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* | + '*' (',' AnnotationsOrIdentifiersPattern)* + +AnnotationsOrIdentifiersPatternAfterDotDot := + AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* | + '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)* + +PointcutDeclaration := PointcutModifiers? 'pointcut' Identifier Formals + ':' PointcutExpression + +PointcutModifiers := PointcutModifier* + +PointcutModifier := 'public' | 'private' | 'protected' | 'abstract' + +Formals := '(' ParamList? ')' +ParamList := FullyQualifiedName Identifier (',' ParamList)* + +ReferencePointcut := (FullyQualifiedName '.')? Identifier Formals + +PointcutExpression := (PointcutPrimitive | ReferencePointcut) | + '!' PointcutExpression | + '(' PointcutExpression ')' | + PointcutExpression '&&' PointcutExpression | + PointcutExpression '||' PointcutExpression + +=== Advice === + +to be written... + +=== Inter-type Declarations === + +to be written... + +=== Declare Statements === + +to be written... + +=== Aspects === +to be written... +]]></programlisting> </appendix> diff --git a/docs/adk15ProgGuideDB/joinpointsignatures.xml b/docs/adk15ProgGuideDB/joinpointsignatures.xml index 013b9003b..e803b9cfd 100644 --- a/docs/adk15ProgGuideDB/joinpointsignatures.xml +++ b/docs/adk15ProgGuideDB/joinpointsignatures.xml @@ -9,76 +9,76 @@ for understanding the matching rules in the presence of annotations, generics, covariance, varargs, and autoboxing. </para> - + <sect1 id="join-point-matching"> <title>Join Point Matching</title> - + <para>AspectJ supports 11 different kinds of join points. These are the <literal>method call, method execution, constructor call, constructor execution, field get, field set, pre-initialization, initialization, static initialization, handler,</literal> and <literal>advice execution</literal> join points.</para> - + <para>The <emphasis>kinded</emphasis> pointcut designators match based on the kind of a join point. These are the <literal>call, - execution, get, set, preinitialization, initialization, + execution, get, set, preinitialization, initialization, staticinitialization, handler,</literal> and <literal>adviceexecution</literal> designators.</para> - - <para>A kinded pointcut is written using patterns, some of which + + <para>A kinded pointcut is written using patterns, some of which match based on <emphasis>signature</emphasis>, and some of which - match based on <emphasis>modifiers</emphasis>. For example, in + match based on <emphasis>modifiers</emphasis>. For example, in the <literal>call</literal> pointcut designator:</para> - + <programlisting><![CDATA[ - call(ModifierPattern TypePattern TypePattern.IdPattern(TypePatternList) ThrowsPattern) - ]]></programlisting> - +call(ModifierPattern TypePattern TypePattern.IdPattern(TypePatternList) ThrowsPattern) +]]></programlisting> + <para>the modifiers matching patterns are <literal>ModifierPattern</literal> and <literal>ThrowsPattern</literal>, and the signature matching patterns are <literal>TypePattern TypePattern.IdPattern(TypePatternList)</literal>. </para> - + <para> A join point has potentially multiple signatures, but only one set of - modifiers. <emphasis>A kinded primitive pointcut matches a particular join point + modifiers. <emphasis>A kinded primitive pointcut matches a particular join point if and only if</emphasis>: </para> - + <orderedlist> <listitem>They are of the same kind</listitem> - <listitem>The signature pattern (exactly) matches at least one + <listitem>The signature pattern (exactly) matches at least one signature of the join point</listitem> <listitem>The modifiers pattern matches the modifiers of the subject of the join point</listitem> </orderedlist> - - <para>These rules make it very easily to quickly determine whether a + + <para>These rules make it very easily to quickly determine whether a given pointcut matches a given join point. In the next two sections, we describe what the signature(s) of a join point are, and what the subjects of join points are.</para> - + </sect1> - + <sect1 id="join-point-signatures"> <title>Join Point Signatures</title> - + <para>Call, execution, get, and set join points may potentially have multiple signatures. All other join points have exactly one signature. The following table summarizes the constituent parts of a join point signature for the different kinds of join point.</para> - + <informaltable> <tgroup cols="7"> <thead> <row> <entry>Join Point Kind</entry> - <entry>Return Type</entry> - <entry>Declaring Type</entry> - <entry>Id</entry> - <entry>Parameter Types</entry> - <entry>Field Type</entry> - <entry>Exception Type</entry> + <entry>Return Type</entry> + <entry>Declaring Type</entry> + <entry>Id</entry> + <entry>Parameter Types</entry> + <entry>Field Type</entry> + <entry>Exception Type</entry> </row> </thead> <tbody> @@ -184,25 +184,25 @@ </tbody> </tgroup> </informaltable> - + <para>Note that whilst an advice execution join point has a signature comprising the declaring type of the advice and the advice parameter types, the <literal>adviceexecution</literal> pointcut designator does not support matching based on this signature.</para> - + <para>The signatures for most of the join point kinds should be self-explanatory, except for field get and set, and method call and execution - join points, which can have multiple signatures. Each signature of + join points, which can have multiple signatures. Each signature of a method call or execution join point has the same id and parameter types, but the declaring type and return type (with covariance) may vary. Each signature of a field get or set join point has the same id and field type, but the declaring type may vary. </para> - - <para>The following sections examine signatures for these join points + + <para>The following sections examine signatures for these join points in more detail.</para> - + <sect2 id="method-call-join-point-signatures" xreflabel="method-call-join-point-signatures"> <title>Method call join point signatures</title> @@ -213,72 +213,71 @@ </para> <programlisting><![CDATA[ - T t = new T(); - t.m("hello"); <= call join point occurs when this line is executed - ]]></programlisting> - +T t = new T(); +t.m("hello"); <= call join point occurs when this line is executed +]]></programlisting> + <para> Then the signature <literal>R(T) T.m(parameter_types)</literal> is a signature of the call join point, where <literal>R(T)</literal> is the return - type of <literal>m</literal> in <literal>T</literal>, and + type of <literal>m</literal> in <literal>T</literal>, and <literal>parameter_types</literal> are the parameter types of <literal>m</literal>. If <literal>T</literal> itself does not - declare a definition of <literal>m(parameter_types)</literal>, then - <literal>R(T)</literal> is the return type in the definition of + declare a definition of <literal>m(parameter_types)</literal>, then + <literal>R(T)</literal> is the return type in the definition of <literal>m</literal> that <literal>T</literal> inherits. Given the - call above, and the definition of <literal>T.m</literal>: + call above, and the definition of <literal>T.m</literal>: </para> - + <programlisting><![CDATA[ - interface Q { - R m(String s); - } - - class P implements Q { - R m(String s) {...} - } - - class S extends P { - R' m(String s) {...} - } - - class T extends S {} - - ]]></programlisting> - +interface Q { + R m(String s); +} + +class P implements Q { + R m(String s) {...} +} + +class S extends P { + R' m(String s) {...} +} + +class T extends S {} +]]></programlisting> + <para>Then <literal>R' T.m(String)</literal> is a signature of the call join point for <literal>t.m("hello")</literal>.</para> - + <para> - For each ancestor (super-type) <literal>A</literal> of <literal>T</literal>, + For each ancestor (super-type) <literal>A</literal> of <literal>T</literal>, if <literal>m(parameter_types)</literal> is defined for that super-type, then <literal>R(A) A.m(parameter_types)</literal> is a signature of the call join point, where <literal>R(A)</literal> is the return type of <literal> m(parameter_types)</literal> as defined in <literal>A</literal>, or as inherited by <literal>A</literal> if <literal>A</literal> itself does not - provide a definition of <literal>m(parameter_types)</literal>. + provide a definition of <literal>m(parameter_types)</literal>. </para> - + <para> Continuing the example from above,we can deduce that </para> <programlisting><![CDATA[ - R' S.m(String) - R P.m(String) - R Q.m(String) - ]]></programlisting> - +R' S.m(String) +R P.m(String) +R Q.m(String) +]]></programlisting> + <para>are all additional signatures for the call join point arising from the call <literal>t.m("hello")</literal>. Thus this call join point has four signatures in total. Every signature has the same id and parameter types, and a different declaring type.</para> - + </sect2> - + <sect2 id="method-execution-join-point-signatures" xreflabel="method-execution-join-point-signatures"> <title>Method execution join point signatures</title> - + <para>Join point signatures for execution join points are defined in a similar manner to signatures for call join points. Given the hierarchy: @@ -286,39 +285,38 @@ <programlisting><![CDATA[ - interface Q { - R m(String s); - } - - class P implements Q { - R m(String s) {...} - } - - class S extends P { - R' m(String s) {...} - } - - class T extends S { } - - class U extends T { - R' m(String s) {...} - } - - ]]></programlisting> - +interface Q { + R m(String s); +} + +class P implements Q { + R m(String s) {...} +} + +class S extends P { + R' m(String s) {...} +} + +class T extends S { } + +class U extends T { + R' m(String s) {...} +} +]]></programlisting> + <para>Then the execution join point signatures arising as a result of the call to <literal>u.m("hello")</literal> are: </para> <programlisting><![CDATA[ - R' U.m(String) - R' S.m(String) - R P.m(String) - R Q.m(String) - ]]></programlisting> +R' U.m(String) +R' S.m(String) +R P.m(String) +R Q.m(String) +]]></programlisting> - <para>Each signature has the same id and parameter types, and a + <para>Each signature has the same id and parameter types, and a different declaring type. There is one signature for each type - that provides its own declaration of the method. Hence in this + that provides its own declaration of the method. Hence in this example there is no signature <literal>R' T.m(String)</literal> as <literal>T</literal> does not provide its own declaration of the method.</para> @@ -330,11 +328,11 @@ <para> For a field get join point where an access is made to a field - <literal>f</literal> of type <literal>F</literal> + <literal>f</literal> of type <literal>F</literal> on a object with declared type <literal>T</literal>, then - <literal>F T.f</literal> is a signature of the get join point. + <literal>F T.f</literal> is a signature of the get join point. </para> - + <para> If <literal>T</literal> does not directly declare a member <literal>f</literal>, then for each super type <literal>S</literal> @@ -344,18 +342,18 @@ of the join point. For example, given the hierarchy: </para> - <programlisting><![CDATA[ - class P { - F f; - } - - class S extends P { - F f; - } - - class T extends S { } - ]]></programlisting> - + <programlisting><![CDATA[ +class P { + F f; +} + +class S extends P { + F f; +} + +class T extends S { } +]]></programlisting> + <para> Then the join point signatures for a field get join point of the field <literal>f</literal> on an object with declared type @@ -363,26 +361,26 @@ </para> <programlisting><![CDATA[ - F S.f - F T.f - ]]></programlisting> +F S.f +F T.f +]]></programlisting> <para>The signatures for a field set join point are derived in an identical manner.</para> - + </sect2> - + </sect1> - + <sect1 id="join-point-modifiers"> <title>Join Point Modifiers</title> - + <para>Every join point has a single set of modifiers - these include the standard Java modifiers such as <literal>public, private, static, abstract</literal> etc., any annotations, and the throws clauses of methods and constructors. These modifiers are the modifiers of the <emphasis>subject</emphasis> of the join point.</para> - + <para> The following table defines the join point subject for each kind of join point. @@ -447,40 +445,40 @@ </row> </tbody> </tgroup> - </informaltable> + </informaltable> <para>For example, given the following types</para> <programlisting><![CDATA[ - public class X { - @Foo - protected void doIt() {...} - } - - public class Y extends X { - public void doIt() {...} - } - ]]></programlisting> - +public class X { + @Foo + protected void doIt() {...} +} + +public class Y extends X { + public void doIt() {...} +} +]]></programlisting> + <para>Then the modifiers for a call to <literal>(Y y) y.doIt()</literal> are simply <literal>{public}</literal>. The modifiers for a call to <literal>(X x) x.doIt()</literal> are <literal>{@Foo,protected}</literal>. </para> - + </sect1> - + <sect1 id="join-point-matching-summary"> <title>Summary of Join Point Matching</title> <para> A join point has potentially multiple signatures, but only one set of - modifiers. <emphasis>A kinded primitive pointcut matches a particular join point + modifiers. <emphasis>A kinded primitive pointcut matches a particular join point if and only if</emphasis>: </para> - + <orderedlist> <listitem>They are of the same kind</listitem> - <listitem>The signature pattern (exactly) matches at least one + <listitem>The signature pattern (exactly) matches at least one signature of the join point</listitem> <listitem>The modifiers pattern matches the modifiers of the subject of the join point</listitem> @@ -489,39 +487,38 @@ <para>Given the hierarchy</para> <programlisting><![CDATA[ - interface Q { - R m(String s); - } - - class P implements Q { - @Foo - public R m(String s) {...} - } - - class S extends P { - @Bar - public R' m(String s) {...} - } - - class T extends S {} - - ]]></programlisting> +interface Q { + R m(String s); +} + +class P implements Q { + @Foo + public R m(String s) {...} +} + +class S extends P { + @Bar + public R' m(String s) {...} +} + +class T extends S {} +]]></programlisting> <para>and the program fragment:</para> - + <programlisting><![CDATA[ - P p = new P(); - S s = new S(); - T t = new T(); - ... - p.m("hello"); - s.m("hello"); - t.m("hello"); - ]]></programlisting> - +P p = new P(); +S s = new S(); +T t = new T(); +... +p.m("hello"); +s.m("hello"); +t.m("hello"); +]]></programlisting> + <para> The the pointcut <literal>call(@Foo R P.m(String))</literal> matches the - call <literal>p.m("hello")</literal> since both the signature and the + call <literal>p.m("hello")</literal> since both the signature and the modifiers match. It does not match the call <literal>s.m("hello")</literal> because even though the signature pattern matches one of the signatures of the join point, the modifiers pattern does not match the modifiers of @@ -534,6 +531,6 @@ signature pattern does not match any signature for the call join point of m in P.</para> </sect1> - + </chapter> diff --git a/docs/adk15ProgGuideDB/miscellaneous.xml b/docs/adk15ProgGuideDB/miscellaneous.xml index d7aceb851..df9aa3f87 100644 --- a/docs/adk15ProgGuideDB/miscellaneous.xml +++ b/docs/adk15ProgGuideDB/miscellaneous.xml @@ -1,10 +1,10 @@ <chapter id="miscellaneous" xreflabel="Miscellaneous Changes"> <title>Other Changes in AspectJ 5</title> - + <sect1 id="pointcuts-change"> <title>Pointcuts</title> - + <para> 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 @@ -12,10 +12,10 @@ </para> <programlisting><![CDATA[ - pointcut foo(Foo foo) : (execution(* *(..)) && this(foo) ) || - (set(* *) && target(foo)); - ]]></programlisting> - +pointcut foo(Foo foo) : (execution(* *(..)) && this(foo) ) || + (set(* *) && target(foo)); +]]></programlisting> + <para> whereas this expression is permitted in AspectJ 5. Each context variable must be bound exactly once in each branch of a disjunction, and the disjunctive branches @@ -23,63 +23,59 @@ can be both an execution join point and a set join point so the two branches are mutually exclusive. </para> - + </sect1> - + <sect1 id="declare-soft-change"> <title>Declare Soft</title> <para> - The semantics of the <literal>declare soft</literal> statement have been - refined in AspectJ 5 to only soften exceptions that are not already runtime + The semantics of the <literal>declare soft</literal> statement have been + refined in AspectJ 5 to only soften exceptions that are not already runtime exceptions. If the exception type specified in a declare soft statement is <literal>RuntimeException</literal> or a subtype of <literal>RuntimeException</literal> then a new XLint warning will be issued:</para> - + <programlisting><![CDATA[ - declare soft : SomeRuntimeException : execution(* *(..)); - - >> "SomeRuntimeException will not be softened as it is already a RuntimeException" [XLint:runtimeExceptionNotSoftened] - ]]></programlisting> - +declare soft : SomeRuntimeException : execution(* *(..)); + +>> "SomeRuntimeException will not be softened as it is already a RuntimeException" [XLint:runtimeExceptionNotSoftened] +]]></programlisting> + <para> This XLint message can be controlled by setting the <literal>runtimeExceptionNotSoftened</literal> XLint parameter. </para> - + <para> If the exception type specified in a declare soft statement is a super type of <literal>RuntimeException</literal> - (such as <literal>Exception</literal> for example) then any <emphasis>checked</emphasis> exception thrown at a matched join point, - where the exception is an instance of the softened exception, will be softened to an - <literal>org.aspectj.lang.SoftException</literal>. + (such as <literal>Exception</literal> for example) then any <emphasis>checked</emphasis> exception thrown at a matched join point, + where the exception is an instance of the softened exception, will be softened to an + <literal>org.aspectj.lang.SoftException</literal>. </para> - + <programlisting><![CDATA[ - public aspect SoftenExample { - - declare soft : Exception : execution(* Foo.*(..)); - - } - - class Foo { - - public static void main(String[] args) { - Foo foo = new Foo(); - foo.foo(); - foo.bar(); - } - - void foo() throws Exception { - throw new Exception(); // this will be converted to a SoftException - } - - void bar() throws Exception { - throw new RuntimeException(); // this will remain a RuntimeException - } - - } - ]]></programlisting> - - +public aspect SoftenExample { + declare soft : Exception : execution(* Foo.*(..)); +} + +class Foo { + public static void main(String[] args) { + Foo foo = new Foo(); + foo.foo(); + foo.bar(); + } + + void foo() throws Exception { + throw new Exception(); // this will be converted to a SoftException + } + + void bar() throws Exception { + throw new RuntimeException(); // this will remain a RuntimeException + } +} +]]></programlisting> + + </sect1> - + </chapter> diff --git a/docs/adk15ProgGuideDB/pertypewithin.xml b/docs/adk15ProgGuideDB/pertypewithin.xml index 4a5e9bbab..3d901a2f7 100644 --- a/docs/adk15ProgGuideDB/pertypewithin.xml +++ b/docs/adk15ProgGuideDB/pertypewithin.xml @@ -3,61 +3,61 @@ <title>The pertypewithin Aspect Instantiation Model</title> <para> - AspectJ 5 defines a new per-clause type for aspect instantiation: + AspectJ 5 defines a new per-clause type for aspect instantiation: <literal>pertypewithin</literal>. Unlike the other per-clauses, - <literal>pertypewithin</literal> takes a type pattern: + <literal>pertypewithin</literal> takes a type pattern: </para> - + <programlisting><![CDATA[ - PerTypeWithin := 'pertypewithin' '(' OptionalParensTypePattern ')' - ]]></programlisting> - +PerTypeWithin := 'pertypewithin' '(' OptionalParensTypePattern ')' +]]></programlisting> + <para> When an aspect is declared using the <literal>pertypewithin</literal> instantiation model, one new aspect instance will be created for each type matched by the associated type pattern. </para> - + <para> - Pertypewithin aspects have <literal>aspectOf</literal> and + Pertypewithin aspects have <literal>aspectOf</literal> and <literal>hasAspect</literal> methods with the following signatures: </para> - + <programlisting><![CDATA[ - /** - * return true if this aspect has an instance associated with - * the given type. - */ - public static boolean hasAspect(Class clazz) - - /** - * return the instance associated with the given type. - * Throws NoAspectBoundException if there is no such - * aspect. - */ - public static P aspectOf(Class clazz) - ]]></programlisting> - +/** + * return true if this aspect has an instance associated with + * the given type. + */ +public static boolean hasAspect(Class clazz) + +/** + * return the instance associated with the given type. + * Throws NoAspectBoundException if there is no such + * aspect. + */ +public static P aspectOf(Class clazz) +]]></programlisting> + <para> Where <literal>P</literal> is the type of the <literal>pertypewithin</literal> aspect. </para> - + <para> - In addition, <literal>pertypewithin</literal> aspects have a + In addition, <literal>pertypewithin</literal> aspects have a <literal>getWithinTypeName</literal> method that can be called to return the package qualified name of the type for which the aspect instance has been created. </para> - + <programlisting><![CDATA[ - /** - * return the package qualified name (eg. com.foo.MyClass) of the type - * for which the aspect instance has been instantiated. - */ - public String getWithinTypeName() - ]]></programlisting> - +/** + * return the package qualified name (eg. com.foo.MyClass) of the type + * for which the aspect instance has been instantiated. + */ +public String getWithinTypeName() +]]></programlisting> + <para> In common with the other per-clause instantiation models, the execution of any advice declared within a <literal>pertypewithin</literal> aspect @@ -68,24 +68,24 @@ </para> <programlisting><![CDATA[ - import java.util.*; - - public aspect InstanceTracking pertypewithin(org.xyz..*) { - - // use WeakHashMap for auto-garbage collection of keys - private Map<Object,Boolean> instances = new WeakHashMap<Object,Boolean>(); - - after(Object o) returning() : execution(new(..)) && this(o) { - instances.put(o,true); - } - - public Set<?> getInstances() { - return instances.keySet(); - } - - } - ]]></programlisting> - +import java.util.*; + +public aspect InstanceTracking pertypewithin(org.xyz..*) { + + // use WeakHashMap for auto-garbage collection of keys + private Map<Object,Boolean> instances = new WeakHashMap<Object,Boolean>(); + + after(Object o) returning() : execution(new(..)) && this(o) { + instances.put(o,true); + } + + public Set<?> getInstances() { + return instances.keySet(); + } + +} +]]></programlisting> + <para> Then one aspect instance will be created for each type within <literal>org.xyz..*</literal>. For each aspect instance, the @@ -93,18 +93,18 @@ within the matched per-type-within type. The net result is that the aspect tracks all known instances of each type within <literal>org.xyz..*</literal>. To get access to the instances, a - programmer can simply write + programmer can simply write <literal>InstanceTracking.aspectOf(org.xyz.SomeType.class).getInstances()</literal>. </para> - + <para> The <literal>pertypewithin</literal> aspect instantiation model should be used when the implementation of a crosscutting concern requires that some state be maintained for each type in a set of types. To maintain state for a single type, it is easier to use a static inter-type declared field. Examples of usage include instance tracking, profiling, and the - implementation of a common tracing idiom that uses one Logger per + implementation of a common tracing idiom that uses one Logger per traced class. - </para> + </para> </chapter> diff --git a/docs/adk15ProgGuideDB/varargs.xml b/docs/adk15ProgGuideDB/varargs.xml index 487a8c01d..31dddde80 100644 --- a/docs/adk15ProgGuideDB/varargs.xml +++ b/docs/adk15ProgGuideDB/varargs.xml @@ -1,21 +1,21 @@ <chapter id="varargs" xreflabel="Varargs"> <title>Varargs</title> - + <sect1 id="varargs-inJava5" xreflabel="Varargs in Java 5"> <title>Variable-length Argument Lists in Java 5</title> - + <para> - Java 5 (and hence AspectJ 5) allows you to specify methods that take a + 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: + an ellipsis (...) in the method signature as shown: </para> <programlisting><![CDATA[ - public void foo(int i, String... strings) { - } - ]]></programlisting> - +public void foo(int i, String... strings) { +} +]]></programlisting> + <para> A method or constructor may take at most one variable length argument, and this must always be the last declared argument in the signature. @@ -23,82 +23,81 @@ <sect2 id="calling-methods-and-constructors-with-variable-length-arguments" xreflabel="calling-methods-and-constructors-with-variable-length-arguments"> <title>Calling Methods and Constructors with variable-length arguments</title> - + <para> A <emphasis>varargs</emphasis> method may be called with zero or more arguments - in the variable argument position. For example, given the definition of + in the variable argument position. For example, given the definition of <literal>foo</literal> above, the following calls are all legal: </para> <programlisting><![CDATA[ - foo(5); - foo(5,"One String"); - foo(7,"One String","Two Strings"); - foo(3,"One String","Two Strings","Three Strings"); - ]]></programlisting> +foo(5); +foo(5,"One String"); +foo(7,"One String","Two Strings"); +foo(3,"One String","Two Strings","Three Strings"); +]]></programlisting> - <para>A <emphasis>varargs</emphasis> parameter is treated as an array within the + <para>A <emphasis>varargs</emphasis> parameter is treated as an array within the defining member. So in the body of <literal>foo</literal> we could write for example: </para> <programlisting><![CDATA[ - public void foo(int i, String... strings) { - String[] someStrings = strings; - // rest of method body - } - ]]></programlisting> +public void foo(int i, String... strings) { + String[] someStrings = strings; + // rest of method body +} +]]></programlisting> <para>One consequence of this treatment of a varargs parameter as an array is that you can also call a varargs method with an array:</para> <programlisting><![CDATA[ - foo(7,new String[] {"One String","Two Strings"}); - ]]></programlisting> - +foo(7,new String[] {"One String","Two Strings"}); +]]></programlisting> + </sect2> - + </sect1> <sect1 id="varargs-in-pcds"> <title>Using Variable-length arguments in advice and pointcut expressions</title> - + <para>AspectJ 5 allows variable-length arguments to be used for methods declared within aspects, and for inter-type declared methods and constructors, in accordance with the rules outlined in the previous section.</para> - + <para> AspectJ 5 also allows variable length arguments to be matched by pointcut expressions and bound as formals in advice. </para> - + <sect2 id="matching-signatures-based-on-variable-length-argument-types" xreflabel="matching-signatures-based-on-variable-length-argument-types"> <title>Matching signatures based on variable length argument types</title> - + <para> Recall from the definition of signature patterns given in the chapter on annotations (<xref linkend="signaturePatterns"/>), that <literal>MethodPattern</literal> and <literal>ConstructorPattern</literal> are extended to allow a <literal>varargs</literal> pattern in the last argument position of a method or constructor signature. </para> - - <programlisting><![CDATA[ - FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? | - OptionalParensTypePattern (',' FormalsPattern)* | - TypePattern '...' - - FormalsPatternAfterDotDot := - OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | - TypePattern '...' - - ]]></programlisting> - + + <programlisting><![CDATA[ +FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? | + OptionalParensTypePattern (',' FormalsPattern)* | + TypePattern '...' + +FormalsPatternAfterDotDot := + OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | + TypePattern '...' +]]></programlisting> + <para> Method and constructor patterns are used in the <literal>call</literal>, <literal>execution</literal>, <literal>initialization</literal>, <literal>preinitialization</literal>, and <literal>withincode</literal> pointcut designators. Some examples of usage follow: - </para> - + </para> + <variablelist> <varlistentry> @@ -121,7 +120,7 @@ </para> </listitem> </varlistentry> - + <varlistentry> <term>initialization(org.xyz.*.new((Foo || Goo)...))</term> <listitem> @@ -134,30 +133,30 @@ </para> </listitem> </varlistentry> - + </variablelist> - + <para>A variable argument parameter and an array parameter are treated as distinct signature elements, so given the method definitions: </para> <programlisting><![CDATA[ - void foo(String...); - void bar(String[]); - ]]></programlisting> - +void foo(String...); +void bar(String[]); +]]></programlisting> + <para> The pointcut <literal>execution(* *.*(String...))</literal> matches the execution join point - for <literal>foo</literal>, but not <literal>bar</literal>. The pointcut + for <literal>foo</literal>, but not <literal>bar</literal>. The pointcut <literal>execution(* *.*(String[]))</literal> matches the execution join point for <literal>bar</literal> but not <literal>foo</literal>. </para> - + </sect2> - + <sect2 id="exposing-variable-length-arguments-as-context-in-pointcuts-and-advice" xreflabel="exposing-variable-length-arguments-as-context-in-pointcuts-and-advice"> <title>Exposing variable-length arguments as context in pointcuts and advice</title> - + <para> When a varargs parameter is used within the body of a method, it has an array type, as discussed in the introduction to this section. We follow the @@ -166,9 +165,9 @@ </para> <programlisting><![CDATA[ - public void foo(int i, String... strings) { - } - ]]></programlisting> +public void foo(int i, String... strings) { +} +]]></programlisting> <para> The call or execution join points for <literal>foo</literal> will be matched @@ -176,34 +175,34 @@ to use the varargs syntax within an args pointcut designator - so you <emphasis>cannot</emphasis> write <literal>args(int,String...)</literal>. </para> - + <para> Binding of a varargs parameter in an advice statement is straightforward: </para> - + <programlisting><![CDATA[ - before(int i, String[] ss) : call(* foo(int,String...)) && args(i,ss) { - // varargs String... argument is accessible in advice body through ss - // ... - } - ]]></programlisting> - +before(int i, String[] ss) : call(* foo(int,String...)) && args(i,ss) { + // varargs String... argument is accessible in advice body through ss + // ... +} +]]></programlisting> + <para>Since you cannot use the varargs syntax in the <literal>args</literal> pointcut designator, you also cannot use the varargs syntax to declare - advice parameters.</para> - - <para>Note: the proposal in this section does not allow you to + advice parameters.</para> + + <para>Note: the proposal in this section does not allow you to distinguish between a join point with a signature (int, String...) - and a join point with a signature (int, String[]) based + and a join point with a signature (int, String[]) based <emphasis>solely</emphasis> on the use of the <literal>args</literal> pointcut designator. If this distinction is required, <literal>args</literal> - can always be coupled with <literal>call</literal> or + can always be coupled with <literal>call</literal> or <literal>execution</literal>.</para> </sect2> - + </sect1> - + </chapter> diff --git a/docs/devGuideDB/aj.xml b/docs/devGuideDB/aj.xml index 1604d540c..fd250d055 100644 --- a/docs/devGuideDB/aj.xml +++ b/docs/devGuideDB/aj.xml @@ -1,9 +1,9 @@ <refentry id="aj-ref" xreflabel="The aj Command-line Reference"> - - <refnamediv> + + <refnamediv> <refname>aj</refname> <refpurpose>command-line launcher for basic load-time weaving</refpurpose> - </refnamediv> + </refnamediv> <refsynopsisdiv> <cmdsynopsis> @@ -16,39 +16,39 @@ </refsynopsisdiv> <refsect1 id="aj" xreflabel="aj"> <title>Description</title> - + <para>The <command>aj</command> command runs Java programs in Java 1.4 or later by setting up <literal>WeavingURLClassLoader</literal> as the system class loader, to do load-time bytecode weaving. </para> - + <para> The arguments are the same as those used to launch the Java program. Users should define the environment variables <literal>CLASSPATH</literal> and <literal>ASPECTPATH</literal>. </para> - + <para>For more information and alternatives for load-time weaving, see <xref linkend="ltw"/>. </para> - + <refsect2> <title>Examples</title> - + <example id="simpleajexample"> <title>A simple example</title> - + <para>Use ajc to build a library, then weave at load time</para> - - <programlisting><![CDATA[ - REM compile library - ${ASPECTJ_HOME}\bin\ajc.bat -outjar lib\aspects.jar @aspects.lst - - REM run, weaving into application at load-time set - ASPECTPATH=lib\aspects.jar set CLASSPATH=app\app.jar - ${ASPECTJ_HOME}\bin\aj.bat com.company.app.Main "Hello, World!" -]]> </programlisting> - + + <programlisting><![CDATA[ +REM compile library +${ASPECTJ_HOME}\bin\ajc.bat -outjar lib\aspects.jar @aspects.lst + +REM run, weaving into application at load-time set +ASPECTPATH=lib\aspects.jar set CLASSPATH=app\app.jar +${ASPECTJ_HOME}\bin\aj.bat com.company.app.Main "Hello, World!" +]]> </programlisting> + </example> </refsect2> </refsect1> diff --git a/docs/devGuideDB/ajbrowser.xml b/docs/devGuideDB/ajbrowser.xml index fd48169bc..a276ca11b 100644 --- a/docs/devGuideDB/ajbrowser.xml +++ b/docs/devGuideDB/ajbrowser.xml @@ -5,33 +5,33 @@ <sect1 id="ajbrowser-intro"> <title>Introduction</title> <para> - AJBrowser presents a GUI for compiling programs with ajc + AJBrowser presents a GUI for compiling programs with ajc and navigating crosscutting structure. </para> <para> The AspectJ Browser can edit program source files, compile using the AspectJ compiler <literal>ajc</literal> run a program, - and graphically navigate the program's + and graphically navigate the program's crosscutting structure. - For more information on <literal>ajc</literal>, + For more information on <literal>ajc</literal>, see <xref linkend="ajc-ref"/>. - - + + </para> - + <para> Launch the browser from the command line either by typing "ajbrowser" to invoke the script in <literal>{aspectj}/bin</literal> - (if AspectJ is installed correctly) + (if AspectJ is installed correctly) or by using the <literal>aspectjtools.jar</literal> directly, and specifying no arguments or some number of - build configuration files + build configuration files (suffix <literal>.lst</literal>): <programlisting> - java -jar aspectj1.1/lib/aspectjtools.jar aspectj1.1/doc/examples/spacewar/debug.lst +java -jar aspectj1.1/lib/aspectjtools.jar aspectj1.1/doc/examples/spacewar/debug.lst </programlisting> </para> @@ -47,35 +47,35 @@ Because <literal>ajc</literal> requires all sources to be specified (at least using the <literal>-sourceroots</literal> option), most users create <literal>.lst</literal> files that list - the files to compile (one argument per line, globbing + the files to compile (one argument per line, globbing permitted - for more details, see <xref linkend="ajc-ref"/>). </para> <para> - To work with a particular program, select the + To work with a particular program, select the corresponding ".lst" build configuration file - from the GUI using the File menu, "open" item, - or by using the + from the GUI using the File menu, "open" item, + or by using the "Open Build Configuration" button (<inlinemediaobject> <imageobject> <imagedata fileref="openConfig.gif"/> </imageobject> </inlinemediaobject>). - + You can populate the build list from the command line - by passing any number of ".lst" paths. - (However, if you pass in any non-".lst" arguments, + by passing any number of ".lst" paths. + (However, if you pass in any non-".lst" arguments, it will run the command-line compiler directly.) </para> <para> To switch between build configurations, select, add, or remove them - using the corresponding toolbar buttons. + using the corresponding toolbar buttons. </para> - <para>Global build options are stored in an + <para>Global build options are stored in an <literal>.ajbrowser</literal> file in your HOME directory. - Edit these from the GUI by clicking the "Options" button - or selecting the Tools menu item "Options...". + Edit these from the GUI by clicking the "Options" button + or selecting the Tools menu item "Options...". This is how to set classpath, aspectpath, etc. </para> <para>The following sections walk through a build. @@ -90,8 +90,8 @@ <imageobject> <imagedata fileref="build.gif"/> </imageobject> - </inlinemediaobject>), or - or use the tools menu. + </inlinemediaobject>), or + or use the tools menu. </para> <!-- <para>To build using AspectJ 1.1's incremental mode, @@ -99,7 +99,7 @@ the <literal>AspectJ Build Options</literal> tab of the <literal>Options</literal> dialog. Once in incremental mode, you can force a full rebuild - by holding the shift key down when selecting the + by holding the shift key down when selecting the build menu item or button. </para> --> @@ -120,7 +120,7 @@ <sect1 id="ajbrowser-navigating"> <title>Navigating Program Structure</title> - + <para> Select nodes in the program structure by clicking them (see label 2). If one node is related to one or more other nodes by an association the @@ -175,9 +175,9 @@ </inlinemediaobject>). Click the <literal>Build Options</literal> tab to view the Build Paths pane. Edit the classpath entry to use your install location. For example, if you ran from the base Aspectj - directory, the classpath need only include + directory, the classpath need only include <literal>lib/aspectjrt.jar</literal> (though the browser may populate - the classpath with the bootclasspath and classpath initially.) + the classpath with the bootclasspath and classpath initially.) Be sure to use the <literal>lib/aspectjrt.jar</literal> that came with the browser. </para> @@ -274,13 +274,13 @@ <literal>affects</literal> relations will list different kinds of join points - constructor or method calls, etc. </para> - <para>Note that the AspectJ browser can only display + <para>Note that the AspectJ browser can only display static structure (whether hierarchical or crosscutting). That means that dynamicly-determined pointcuts (like - <literal>cflow(pointcut)</literal>) + <literal>cflow(pointcut)</literal>) will not be shown as picking out static points in source code. Displayable pointcuts roughly correspond - to those that can be used in a + to those that can be used in a <literal>declare error</literal> statement. </para> </listitem> @@ -297,19 +297,19 @@ You can run in the same VM or spawn a new process; the latter is generally better for GUI programs. </para> - <para>Both require that any classpath you set be specified + <para>Both require that any classpath you set be specified using platform-specific paths and path separators (the compiler might be more tolerant). Output and error streams will be merged into the streams of the browser (using separate threads, so it may take a few seconds for the pipe - threads to gain control.) Errors should + threads to gain control.) Errors should be detected and displayed in a dialog. </para> <para> The GUI does not support killing a running program, so if your program might hang, - be sure to save your files since you may need to + be sure to save your files since you may need to kill the browser itself to kill its child processes. </para> </sect1> @@ -318,36 +318,36 @@ <title>Isolating problems running the AspectJ browser</title> <para> - If you have problems with the browser not solved by the documentation, - please try to see if you have the same problems when running ajc + If you have problems with the browser not solved by the documentation, + please try to see if you have the same problems when running ajc directly on the command line. </para> <itemizedlist> <listitem><para> - If the problem occurs on the command line also, then the problem - is not in the browser. + If the problem occurs on the command line also, then the problem + is not in the browser. (It may be in the compiler; please send bug reports.) </para></listitem> <listitem><para> - If the problem does not occur on the command line, then it may + If the problem does not occur on the command line, then it may lie in the parameters you are supplying in the build options. </para></listitem> <listitem><para> - If the build options look correct and the problem only occurs + If the build options look correct and the problem only occurs when building from the browser, then please submit a bug report. - </para></listitem> + </para></listitem> </itemizedlist> <sect2 id="ajbrowser-knownProblems"> <title>Known issues with the AspectJ browser</title> <para> - For the most up-to-date information on known problems, - see the + For the most up-to-date information on known problems, + see the <ulink url="http://bugs.eclipse.org/bugs">bug database</ulink> - for unresolved + for unresolved <ulink url="http://bugs.eclipse.org/bugs/buglist.cgi?&product=AspectJ&component=Compiler&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED"> compiler bugs - </ulink> or + </ulink> or <ulink url="http://bugs.eclipse.org/bugs/buglist.cgi?&product=AspectJ&component=IDE&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED"> IDE bugs </ulink>. @@ -355,55 +355,55 @@ <para> <itemizedlist> <listitem><para> - Memory and forking: Users email most about the browser task running - out of memory. - This is not a problem with the browser; some compiles take a lot of + Memory and forking: Users email most about the browser task running + out of memory. + This is not a problem with the browser; some compiles take a lot of memory, often more than similar compiles using javac. The browser does not support forking, so the only solution is to edit the java command line or script that launches the browser to add memory. - </para></listitem> + </para></listitem> <listitem><para> Editing build configuration files: this is not currently supported. - </para></listitem> + </para></listitem> <listitem><para> The structure model is incomplete after incremental compiles. To get a complete structure model requires a full build. - </para></listitem> + </para></listitem> <listitem><para> If you change the output directory, you must do a - full build. - </para></listitem> + full build. + </para></listitem> </itemizedlist> - </para> + </para> </sect2> <sect2 id="ajbrowser-limitations"> <title>Limitations</title> - <para> + <para> <itemizedlist> <listitem><para> - The AJBrowser expects the package and directory structure to match. If they do not + The AJBrowser expects the package and directory structure to match. If they do not it will be unable to browse to the corresponding file. - </para></listitem> + </para></listitem> <listitem><para> The "Run" feature launches applications in the same VM. As a result, if a Swing application is disposed the AJBrowser will be disposed as well. - </para></listitem> + </para></listitem> </itemizedlist> </para> </sect2> <sect2 id="ajbrowser-feedback"> <title>AspectJ Browser questions and bugs</title> - <para> - You can send email to + <para> + You can send email to <ulink url="mailto:aspectj-users@dev.eclipse.org"> - aspectj-users@dev.eclipse.org</ulink>. - (Do join the list to participate!) - We also welcome any bug reports, patches, and feature requests; - you can submit them to the bug database at + aspectj-users@dev.eclipse.org</ulink>. + (Do join the list to participate!) + We also welcome any bug reports, patches, and feature requests; + you can submit them to the bug database at <ulink url="http://bugs.eclipse.org/bugs"> http://bugs.eclipse.org/bugs</ulink> - using the AspectJ product and IDE component. + using the AspectJ product and IDE component. </para> </sect2> </sect1> diff --git a/docs/devGuideDB/ajc.xml b/docs/devGuideDB/ajc.xml index dc0db0e04..763c54fba 100644 --- a/docs/devGuideDB/ajc.xml +++ b/docs/devGuideDB/ajc.xml @@ -1,9 +1,9 @@ <refentry id="ajc-ref" xreflabel="The ajc Command-line Reference"> - - <refnamediv> + + <refnamediv> <refname>ajc</refname> <refpurpose>compiler and bytecode weaver for the AspectJ and Java languages</refpurpose> - </refnamediv> + </refnamediv> <refsynopsisdiv> <cmdsynopsis> @@ -19,8 +19,8 @@ <refsect1 id="ajc" xreflabel="ajc"> <title>Description</title> - <para>The <command>ajc</command> command compiles and weaves AspectJ and - Java source and .class files, producing .class files compliant with any + <para>The <command>ajc</command> command compiles and weaves AspectJ and + Java source and .class files, producing .class files compliant with any Java VM (1.1 or later). It combines compilation and bytecode weaving and supports incremental builds; you can also weave bytecode at run-time using <xref linkend="ltw"/>. @@ -29,28 +29,28 @@ <para> The arguments after the options specify the source file(s) to compile. To specify source classes, use <parameter>-inpath</parameter> (below). Files may be listed directly on the command line or in a file. - The <parameter>-argfile <replaceable>file</replaceable></parameter> + The <parameter>-argfile <replaceable>file</replaceable></parameter> and <parameter>@<replaceable>file</replaceable></parameter> forms - are equivalent, and are interpreted as meaning all the arguments - listed in the specified file. + are equivalent, and are interpreted as meaning all the arguments + listed in the specified file. </para> - <para> - <command>Note:</command> + <para> + <command>Note:</command> You must explicitly pass <command>ajc</command> all necessary sources. Be sure to include the source not only for the - aspects or pointcuts but also for any affected types. - Specifying all sources is necessary because, unlike javac, ajc does not + aspects or pointcuts but also for any affected types. + Specifying all sources is necessary because, unlike javac, ajc does not search the sourcepath for classes. (For a discussion of what affected types might be required, see <ulink url="../progguide/implementation.html">The AspectJ Programming Guide, Implementation Appendix</ulink>.) </para> <para> - To specify sources, you can list source files as arguments or use the + To specify sources, you can list source files as arguments or use the options <parameter>-sourceroots</parameter> or <parameter>-inpath</parameter>. If there are multiple sources for any type, the result is undefined - since ajc has no way to determine which source is correct. (This + since ajc has no way to determine which source is correct. (This happens most often when users include the destination directory on the inpath and rebuild.) </para> @@ -71,12 +71,12 @@ <varlistentry> <term>-inpath <replaceable>Path</replaceable></term> <listitem><para> - Accept as source bytecode any .class files in the - .jar files or directories on Path. + Accept as source bytecode any .class files in the + .jar files or directories on Path. The output will include these classes, possibly as woven with any applicable aspects. Path is a single argument containing - a list of paths to zip files or directories, + a list of paths to zip files or directories, delimited by the platform-specific path delimiter. </para></listitem> </varlistentry> @@ -87,7 +87,7 @@ Weave binary aspects from jar files and directories on path into all sources. The aspects should have been output by the same version of the compiler. - When running the output classes, the run classpath should contain + When running the output classes, the run classpath should contain all aspectpath entries. Path, like classpath, is a single argument containing a list of paths to jar files, delimited by the platform- @@ -100,7 +100,7 @@ <listitem><para> The file contains a line-delimited list of arguments. Each line in the file should contain one option, filename, or - argument string (e.g., a classpath or inpath). + argument string (e.g., a classpath or inpath). Arguments read from the file are inserted into the argument list for the command. Relative paths in the file are calculated from the directory containing the file (not the current working directory). @@ -146,8 +146,8 @@ <varlistentry> <term>-sourceroots <replaceable>DirPaths</replaceable></term> - <listitem><para>Find and build all .java or .aj source files under - any directory listed in DirPaths. + <listitem><para>Find and build all .java or .aj source files under + any directory listed in DirPaths. DirPaths, like classpath, is a single argument containing a list of paths to directories, delimited by the platform- specific classpath delimiter. @@ -183,7 +183,7 @@ <listitem><para>Set default level for messages about potential programming mistakes in crosscutting code. {level} may be ignore, warning, or error. - This overrides entries in + This overrides entries in org/aspectj/weaver/XlintDefault.properties from aspectjtools.jar, but does not override levels set using the -Xlintfile option. @@ -193,7 +193,7 @@ <varlistentry> <term>-Xlintfile <replaceable>PropertyFile</replaceable></term> <listitem><para>Specify properties file to set levels for - specific crosscutting messages. + specific crosscutting messages. PropertyFile is a path to a Java .properties file that takes the same property names and values as org/aspectj/weaver/XlintDefault.properties @@ -220,7 +220,7 @@ <listitem><para> Specify where to find user class files. Path is a single argument containing - a list of paths to zip files or directories, + a list of paths to zip files or directories, delimited by the platform-specific path delimiter. </para></listitem> </varlistentry> @@ -228,10 +228,10 @@ <varlistentry> <term>-bootclasspath <replaceable>Path</replaceable></term> <listitem><para> - Override location of VM's bootclasspath + Override location of VM's bootclasspath for purposes of evaluating types when compiling. Path is a single argument containing - a list of paths to zip files or directories, + a list of paths to zip files or directories, delimited by the platform-specific path delimiter. </para></listitem> </varlistentry> @@ -239,10 +239,10 @@ <varlistentry> <term>-extdirs <replaceable>Path</replaceable></term> <listitem><para> - Override location of VM's extension directories + Override location of VM's extension directories for purposes of evaluating types when compiling. Path is a single argument containing - a list of paths to directories, + a list of paths to directories, delimited by the platform-specific path delimiter. </para></listitem> </varlistentry> @@ -251,7 +251,7 @@ <term>-d <replaceable>Directory</replaceable></term> <listitem><para> Specify where to place generated .class files. - If not specified, <replaceable>Directory</replaceable> + If not specified, <replaceable>Directory</replaceable> defaults to the current working dir. </para></listitem> </varlistentry> @@ -264,7 +264,7 @@ <varlistentry> <term>-1.3</term> - <listitem><para>Set compliance level to 1.3 + <listitem><para>Set compliance level to 1.3 This implies -source 1.3 and -target 1.1. </para></listitem> </varlistentry> @@ -288,11 +288,11 @@ <listitem><para>Toggle assertions (1.3, 1.4, or 1.5 - default is 1.4). When using -source 1.3, an assert() statement valid under Java 1.4 will result in a compiler error. - When using -source 1.4, - treat <literal>assert</literal> as a keyword and + When using -source 1.4, + treat <literal>assert</literal> as a keyword and implement assertions according to the 1.4 language spec. When using -source 1.5, - Java 5 language features are permitted. + Java 5 language features are permitted. </para></listitem> </varlistentry> @@ -308,22 +308,22 @@ <varlistentry> <term>-warn: <replaceable>items</replaceable></term> <listitem><para>Emit warnings for any instances of - the comma-delimited list of questionable code + the comma-delimited list of questionable code (eg '-warn:unusedLocals,deprecation'): <programlisting><!-- unable to embed itemizedlist? --> - constructorName method with constructor name - packageDefaultMethod attempt to override package-default method - deprecation usage of deprecated type or member - maskedCatchBlocks hidden catch block - unusedLocals local variable never read - unusedArguments method argument never read - unusedImports import statement not used by code in file - none suppress all compiler warnings +constructorName method with constructor name +packageDefaultMethod attempt to override package-default method +deprecation usage of deprecated type or member +maskedCatchBlocks hidden catch block +unusedLocals local variable never read +unusedArguments method argument never read +unusedImports import statement not used by code in file +none suppress all compiler warnings </programlisting> <literal>-warn:none</literal> does not suppress messages generated by <literal>declare warning</literal> or <literal>Xlint</literal>. - + </para></listitem> </varlistentry> @@ -341,7 +341,7 @@ <varlistentry> <term>-proceedOnError</term> - <listitem><para>Keep compiling after error, + <listitem><para>Keep compiling after error, dumping class files with problem methods </para></listitem> </varlistentry> @@ -351,12 +351,12 @@ <listitem> <para>debug attributes level, that may take three forms: <programlisting> - -g all debug info ('-g:lines,vars,source') - -g:none no debug info - -g:{items} debug info for any/all of [lines, vars, source], e.g., - -g:lines,source +-g all debug info ('-g:lines,vars,source') +-g:none no debug info +-g:{items} debug info for any/all of [lines, vars, source], e.g., + -g:lines,source </programlisting> - + </para></listitem> </varlistentry> @@ -383,16 +383,16 @@ <varlistentry> <term>-verbose</term> - <listitem><para>Emit messages about accessed/processed compilation units + <listitem><para>Emit messages about accessed/processed compilation units </para></listitem> </varlistentry> <varlistentry> <term>-showWeaveInfo</term> - <listitem><para>Emit messages about weaving + <listitem><para>Emit messages about weaving </para></listitem> </varlistentry> - + <varlistentry> <term>-log <replaceable>file</replaceable></term> <listitem><para>Specify a log file for compiler messages. @@ -420,7 +420,7 @@ <varlistentry> <term>-repeat <replaceable>N</replaceable></term> - <listitem><para>Repeat compilation process N times + <listitem><para>Repeat compilation process N times (typically to do performance analysis). </para></listitem> </varlistentry> @@ -430,7 +430,7 @@ <listitem><para>Causes compiler to terminate before weaving </para></listitem> </varlistentry> - + <varlistentry> <term>-XaddSerialVersionUID</term> <listitem><para>Causes the compiler to calculate and add @@ -440,10 +440,10 @@ taken place. </para></listitem> </varlistentry> - + <varlistentry> <term>-Xreweavable[:compress]</term> - <listitem><para>(Experimental - deprecated as now default) + <listitem><para>(Experimental - deprecated as now default) Runs weaver in reweavable mode which causes it to create woven classes that can be rewoven, subject to the restriction that on attempting a reweave all the types that advised the woven type must be accessible. @@ -458,8 +458,8 @@ <varlistentry> <term>-XincrementalFile <replaceable>file</replaceable></term> - <listitem><para>(Experimental) This works like incremental mode, - but using a file rather than standard input to control the compiler. + <listitem><para>(Experimental) This works like incremental mode, + but using a file rather than standard input to control the compiler. It will recompile each time file is changed and and halt when file is deleted. </para></listitem> @@ -497,7 +497,7 @@ </refsect2> - <refsect2> + <refsect2> <title>File names</title> <para>ajc accepts source files with either the <filename>.java</filename> @@ -511,7 +511,7 @@ <para>We'd like to discourage other means of mechanical distinction such as naming conventions or sub-packages in favor of the <filename>.aj</filename> extension.</para> - + <itemizedlist> <listitem><para>Filename conventions are hard to enforce and lead to awkward names @@ -560,7 +560,7 @@ <para>Compile two files:</para> <programlisting> - ajc HelloWorld.java Trace.java +ajc HelloWorld.java Trace.java </programlisting> </example> @@ -569,28 +569,29 @@ <title>An example using -argfile/@</title> <para> - To avoid specifying file names on the command line, + To avoid specifying file names on the command line, list source files in a line-delimited text argfile. Source file paths may be absolute or relative to the argfile, and may include other argfiles by @-reference. The following file <literal>sources.lst</literal> contains absolute and relative files and @-references: </para> - <programlisting> + <programlisting> Gui.java /home/user/src/Library.java data/Repository.java data/Access.java @../../common/common.lst @/home/user/src/lib.lst -view/body/ArrayView.java</programlisting> +view/body/ArrayView.java + </programlisting> <para>Compile the files using either the -argfile or @ form:</para> <programlisting> ajc -argfile sources.lst ajc @sources.lst</programlisting> <para> - Argfiles are also supported by jikes and javac, so you + Argfiles are also supported by jikes and javac, so you can use the files in hybrid builds. However, the support varies: </para> <itemizedlist> @@ -604,110 +605,110 @@ ajc @sources.lst</programlisting> <example id="examplebytecode"> <title>An example using -inpath and -aspectpath</title> <para>Bytecode weaving using -inpath: - AspectJ 1.2 supports weaving .class files in input zip/jar files - and directories. - Using input jars is like compiling the corresponding - source files, and all binaries are emitted to output. Although - Java-compliant compilers may differ in their output, ajc should - take as input any class files produced by javac, jikes, eclipse, + AspectJ 1.2 supports weaving .class files in input zip/jar files + and directories. + Using input jars is like compiling the corresponding + source files, and all binaries are emitted to output. Although + Java-compliant compilers may differ in their output, ajc should + take as input any class files produced by javac, jikes, eclipse, and, of course, ajc. Aspects included in -inpath will be woven into like other .class files, and they will affect other types as usual. </para> <para>Aspect libraries using -aspectpath: - AspectJ 1.1 supports weaving from read-only libraries containing - aspects. Like input jars, they affect all input; unlike input - jars, they themselves are not affected or emitted as output. - Sources compiled with aspect libraries must be run with the same - aspect libraries on their classpath. + AspectJ 1.1 supports weaving from read-only libraries containing + aspects. Like input jars, they affect all input; unlike input + jars, they themselves are not affected or emitted as output. + Sources compiled with aspect libraries must be run with the same + aspect libraries on their classpath. </para> - <para>The following example builds the tracing example in a - command-line environment; it creates a read-only aspect library, - compiles some classes for use as input bytecode, and + <para>The following example builds the tracing example in a + command-line environment; it creates a read-only aspect library, + compiles some classes for use as input bytecode, and compiles the classes and other sources with the aspect library. </para> - <para>The tracing example is in the AspectJ distribution + <para>The tracing example is in the AspectJ distribution ({aspectj}/doc/examples/tracing). This uses the following files: </para> <para><programlisting> - aspectj1.1/ - bin/ - ajc - lib/ - aspectjrt.jar - examples/ - tracing/ - Circle.java - ExampleMain.java - lib/ - AbstractTrace.java - TraceMyClasses.java - notrace.lst - Square.java - tracelib.lst - tracev3.lst - TwoDShape.java - version3/ - Trace.java - TraceMyClasses.java +aspectj1.1/ + bin/ + ajc + lib/ + aspectjrt.jar + examples/ + tracing/ + Circle.java + ExampleMain.java + lib/ + AbstractTrace.java + TraceMyClasses.java + notrace.lst + Square.java + tracelib.lst + tracev3.lst + TwoDShape.java + version3/ + Trace.java + TraceMyClasses.java </programlisting></para> -<para>Below, the path separator is taken as ";", but file separators -are "/". All commands are on one line. Adjust paths and -commands to your environment as needed. +<para>Below, the path separator is taken as ";", but file separators +are "/". All commands are on one line. Adjust paths and +commands to your environment as needed. + +</para><para>Setup the path, classpath, and current directory:</para> -</para><para>Setup the path, classpath, and current directory:</para> - <programlisting> - cd examples - export ajrt=../lib/aspectjrt.jar - export CLASSPATH="$ajrt" - export PATH="../bin:$PATH" +cd examples +export ajrt=../lib/aspectjrt.jar +export CLASSPATH="$ajrt" +export PATH="../bin:$PATH" </programlisting> -<para>Build a read-only tracing library:</para> +<para>Build a read-only tracing library:</para> <programlisting> - ajc -argfile tracing/tracelib.lst -outjar tracelib.jar + ajc -argfile tracing/tracelib.lst -outjar tracelib.jar </programlisting> -<para>Build the application with tracing in one step:</para> +<para>Build the application with tracing in one step:</para> <programlisting> - ajc -aspectpath tracelib.jar -argfile tracing/notrace.lst -outjar tracedapp.jar +ajc -aspectpath tracelib.jar -argfile tracing/notrace.lst -outjar tracedapp.jar </programlisting> -<para>Run the application with tracing:</para> +<para>Run the application with tracing:</para> <programlisting> - java -classpath "$ajrt;tracedapp.jar;tracelib.jar" tracing.ExampleMain +java -classpath "$ajrt;tracedapp.jar;tracelib.jar" tracing.ExampleMain </programlisting> -<para>Build the application with tracing from binaries in two steps:</para> +<para>Build the application with tracing from binaries in two steps:</para> <itemizedlist><listitem><para> -(a) Build the application classes (using javac for demonstration's sake):</para> +(a) Build the application classes (using javac for demonstration's sake):</para> <programlisting> - mkdir classes - javac -d classes tracing/*.java - jar cfM app.jar -C classes . +mkdir classes +javac -d classes tracing/*.java +jar cfM app.jar -C classes . </programlisting> </listitem> <listitem><para> -(b) Build the application with tracing:</para> +(b) Build the application with tracing:</para> <programlisting> - ajc -inpath app.jar -aspectpath tracelib.jar -outjar tracedapp.jar +ajc -inpath app.jar -aspectpath tracelib.jar -outjar tracedapp.jar </programlisting> </listitem></itemizedlist> -<para>Run the application with tracing (same as above):</para> +<para>Run the application with tracing (same as above):</para> <programlisting> - java -classpath "$ajrt;tracedapp.jar;tracelib.jar" tracing.ExampleMain +java -classpath "$ajrt;tracedapp.jar;tracelib.jar" tracing.ExampleMain </programlisting> -<para>Run the application without tracing:</para> +<para>Run the application without tracing:</para> <programlisting> - java -classpath "app.jar" tracing.ExampleMain +java -classpath "app.jar" tracing.ExampleMain </programlisting> </example> @@ -721,7 +722,7 @@ commands to your environment as needed. called as a Java class. The only interface that should be considered public are the public methods in <literal>org.aspectj.tools.ajc.Main</literal>. E.g., <literal>main(String[] args)</literal> takes the - the standard <command>ajc</command> command line arguments. + the standard <command>ajc</command> command line arguments. This means that an alternative way to run the compiler is </para> @@ -736,9 +737,9 @@ commands to your environment as needed. <literal>ajc</literal> reports each message to the holder using <literal>IMessageHolder.handleMessage(..)</literal>. If you just want to collect the messages, use - <literal>MessageHandler</literal> as your + <literal>MessageHandler</literal> as your <literal>IMessageHolder</literal>. - For example, compile and run the following with + For example, compile and run the following with <literal>aspectjtools.jar</literal> on the classpath: </para> <programlisting> @@ -763,19 +764,19 @@ public class WrapAjc { <para>Unlike traditional java compilers, the AspectJ compiler may in certain cases generate classfiles from multiple source files. - Unfortunately, the original Java class file format does not support + Unfortunately, the original Java class file format does not support multiple SourceFile attributes. In order to make sure all source file information is available, the AspectJ compiler may in some cases - encode multiple filenames in the SourceFile attribute. + encode multiple filenames in the SourceFile attribute. When the Java VM generates stack traces, it uses this attribute to specify the source file. </para> <para>(The AspectJ 1.0 compiler also supports the .class file extensions of JSR-45. - These permit compliant debuggers (such as jdb in Java 1.4.1) to identify + These permit compliant debuggers (such as jdb in Java 1.4.1) to identify the right file and line even given many source files for a single class. JSR-45 support is planned for ajc in AspectJ 1.1, but is not in the initial - release. To get fully debuggable .class files, use the -XnoInline option.) + release. To get fully debuggable .class files, use the -XnoInline option.) </para> <para>Probably the only time you may see this format is when you view @@ -787,7 +788,7 @@ java.lang.NullPointerException at Main.new$constructor_call37(Main.java;SynchAspect.java[1k]:1030) </programlisting> - <para>where instead of the usual + <para>where instead of the usual </para> <programlisting> @@ -801,14 +802,14 @@ File:LineNumber File0;File1[Number1];File2[Number2] ... :LineNumber </programlisting> - <para>In this case, LineNumber is the usual offset in lines plus the - "start line" of the actual source file. That means you use LineNumber - both to identify the source file and to find the line at issue. + <para>In this case, LineNumber is the usual offset in lines plus the + "start line" of the actual source file. That means you use LineNumber + both to identify the source file and to find the line at issue. The number in [brackets] after each file tells you the - virtual "start line" for that file (the first file has a start of 0). + virtual "start line" for that file (the first file has a start of 0). </para> - <para> In our example from the null pointer exception trace, + <para> In our example from the null pointer exception trace, the virtual start line is 1030. Since the file SynchAspect.java "starts" at line 1000 [1k], the LineNumber points to line 30 of SynchAspect.java. diff --git a/docs/devGuideDB/ajdb.xml b/docs/devGuideDB/ajdb.xml index 832002823..3af587e4c 100644 --- a/docs/devGuideDB/ajdb.xml +++ b/docs/devGuideDB/ajdb.xml @@ -43,11 +43,11 @@ <para> Note: As of the 1.0.3 release, AspectJ supports JSR-45, which provides source-level debugging from many source files per class - and non-Java source files. - JSR-45 is implemented in the J2SE 1.4 debugger support, so + and non-Java source files. + JSR-45 is implemented in the J2SE 1.4 debugger support, so you may be able to use your existing debugger to step through AspectJ source code if both the source and target VM's are - running under Java 1.4 or later. + running under Java 1.4 or later. However, existing debuggers will display synthetic methods in the stack frame. </para> <!-- todo find docs on JSR-45 --> @@ -132,23 +132,23 @@ spacewar/Ship.java</userinput> which generates the following output: <programlisting> - 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 } </programlisting> </para> <para>This is different from <command>jdb</command> because it allows @@ -187,8 +187,8 @@ breakpoint has been noted but will not be set until the class has been loaded by the VM: </para> <programlisting> - Deferring breakpoint spacewar.Ship.fire() - It will be set after the class is loaded. +Deferring breakpoint spacewar.Ship.fire() +It will be set after the class is loaded. </programlisting> <para> @@ -198,14 +198,14 @@ <para> When the breakpoint is set, the following message appears: <programlisting> - Set deferred breakpoint spacewar.Ship.fire() +Set deferred breakpoint spacewar.Ship.fire() </programlisting> </para> <para> We are notified that we've hit the breakpoint: <programlisting> - Breakpoint hit: thread="Thread-2", spacewar.Ship.fire(), line=174, bci=0 209 void fire() { +Breakpoint hit: thread="Thread-2", spacewar.Ship.fire(), line=174, bci=0 209 void fire() { </programlisting></para> <para> @@ -213,10 +213,10 @@ can view the current stack with the <literal>where</literal> command, as follows: <programlisting> - Thread-2[1] where - [1] fire (spacewar\Ship.java:209) - [2] run (spacewar\Robot.java:100) - [3] run [class java.lang.Thread] +Thread-2[1] where +[1] fire (spacewar\Ship.java:209) +[2] run (spacewar\Robot.java:100) +[3] run [class java.lang.Thread] </programlisting> </para> @@ -228,23 +228,23 @@ <para> The following message tells us the breakpoint was set: <programlisting> - Set breakpoint Ship.java:216 +Set breakpoint Ship.java:216 </programlisting> </para> <para> To continue execution, we type <userinput>cont</userinput> and the breakpoint at line 216 is hit <programlisting> - Breakpoint hit: thread="Thread-2", spacewar.Ship.fire(), line=216, bci=28 - 216 double yV = getYVel() + BULLET_SPEED * (Math.sin(orientation)); +Breakpoint hit: thread="Thread-2", spacewar.Ship.fire(), line=216, bci=28 +216 double yV = getYVel() + BULLET_SPEED * (Math.sin(orientation)); </programlisting></para> <para> To view the visible local variables, we type <userinput>locals</userinput> and ajdb responds with: <programlisting> - Local variables - xV = 12.242462584304468 +Local variables +xV = 12.242462584304468 </programlisting></para> <para> @@ -252,22 +252,22 @@ <userinput>set xV = 16.1</userinput> <programlisting> - Changed 'xV' from '12.242462584304468' to '16.1' +Changed 'xV' from '12.242462584304468' to '16.1' </programlisting></para> <para> To see our changes we can print the value of <literal>i</literal> by the following: <programlisting> - print xV - Value for printing 'xV' = 12.242462584304468 +print xV +Value for printing 'xV' = 12.242462584304468 </programlisting></para> <para>We can now type exit or quit to leave the debugger, and we receive the following message: <programlisting> - The application has exited. +The application has exited. </programlisting></para> </example> diff --git a/docs/devGuideDB/ajdee.xml b/docs/devGuideDB/ajdee.xml index 7c42a90fd..652a82f7b 100644 --- a/docs/devGuideDB/ajdee.xml +++ b/docs/devGuideDB/ajdee.xml @@ -274,22 +274,23 @@ your <literal>load-path</literal> and are ``required''. This is an example for the 1.0 release: <programlisting> - ;; I keep my emacs packages in C:/Emacs - (setq load-path - (append - '( - "C:/Emacs/aspectj-emacsMode-1.0" ; for AJDEE - "C:/Emacs/aspectj-emacsAJDEE-1.0" - "C:/Emacs/jde-2.2.9beta6/lisp" - "C:/Emacs/elib-1.0" ; for JDEE - "C:/Emacs/speedbar-0.14beta2" ; for JDEE - "C:/Emacs/semantic-1.4beta12" ; for JDEE/speedbar - "C:/Emacs/eieio-0.17beta3" ; for JDEE - ) - load-path)) - - (require 'jde) - (require 'ajdee) ; can also appear in prj.el</programlisting> + ;; I keep my emacs packages in C:/Emacs + (setq load-path + (append +'( + "C:/Emacs/aspectj-emacsMode-1.0" ; for AJDEE + "C:/Emacs/aspectj-emacsAJDEE-1.0" + "C:/Emacs/jde-2.2.9beta6/lisp" + "C:/Emacs/elib-1.0" ; for JDEE + "C:/Emacs/speedbar-0.14beta2" ; for JDEE + "C:/Emacs/semantic-1.4beta12" ; for JDEE/speedbar + "C:/Emacs/eieio-0.17beta3" ; for JDEE + ) +load-path)) + + (require 'jde) + (require 'ajdee) ; can also appear in prj.el + </programlisting> </para> </listitem> @@ -315,31 +316,33 @@ Here is a simple example: <programlisting> - ;; A default version for simple projects, maybe good for - ;;; .emacs file. - (custom-set-variables - '(jde-compiler '("ajc" "ajc")) - '(jde-javadoc-command-path "ajdoc") +;; A default version for simple projects, maybe good for +;;; .emacs file. +(custom-set-variables +'(jde-compiler '("ajc" "ajc")) +'(jde-javadoc-command-path "ajdoc") - ;; ajc requires all files to be named for a compile - '(aspectj-compile-file-specification "*.java"))</programlisting> +;; ajc requires all files to be named for a compile +'(aspectj-compile-file-specification "*.java")) + </programlisting> Here is an example for spacewar, in <filename>examples/spacewar</filename>. <programlisting> - ;;; These options are for the spacewar, in examples/spacewar. - (custom-set-variables - '(jde-compiler '("ajc" "ajc")) - '(jde-javadoc-command-path "ajdoc") - - ;; ajc provides an ``argfile'' mechanism for specifying all files. - '(aspectj-compile-file-specification "-argfile demo.lst") - - ;; *if* compiling packages, name root dir for package hierarchy - ;; to tell ajc where .class files should go. - '(jde-compile-option-directory "..") - '(jde-run-working-directory "..")) - '(jde-run-application-class "spacewar.Game")</programlisting> +;;; These options are for the spacewar, in examples/spacewar. +(custom-set-variables +'(jde-compiler '("ajc" "ajc")) +'(jde-javadoc-command-path "ajdoc") + +;; ajc provides an ``argfile'' mechanism for specifying all files. +'(aspectj-compile-file-specification "-argfile demo.lst") + +;; *if* compiling packages, name root dir for package hierarchy +;; to tell ajc where .class files should go. +'(jde-compile-option-directory "..") +'(jde-run-working-directory "..")) +'(jde-run-application-class "spacewar.Game") + </programlisting> </para> </listitem> <listitem> diff --git a/docs/devGuideDB/antsupport.xml b/docs/devGuideDB/antsupport.xml index 79b0d99a4..2414bac8e 100644 --- a/docs/devGuideDB/antsupport.xml +++ b/docs/devGuideDB/antsupport.xml @@ -6,86 +6,82 @@ <title>Introduction</title> <para> - AspectJ contains a compiler, <literal>ajc</literal>, - that can be run from Ant. + AspectJ contains a compiler, <literal>ajc</literal>, + that can be run from Ant. Included in the <literal>aspectjtools.jar</literal> - are Ant binaries to support three + are Ant binaries to support three ways of running the compiler: <orderedlist> <listitem> <para> - <xref linkend="antTasks-iajc"/>, - a task to run the AspectJ post-1.1 compiler, + <xref linkend="antTasks-iajc"/>, + a task to run the AspectJ post-1.1 compiler, which supports all the eclipse and ajc options, including incremental mode. </para> </listitem> <listitem> <para> - <xref linkend="antTasks-adapter"/>, - an adapter class to run the new compiler using Javac tasks + <xref linkend="antTasks-adapter"/>, + an adapter class to run the new compiler using Javac tasks by setting the build.compiler property </para> </listitem> <listitem> <para> - <xref linkend="antTasks-ajc"/>, + <xref linkend="antTasks-ajc"/>, a task to run build scripts compatible with the AspectJ 1.0 tasks </para> </listitem> </orderedlist> </para> - + <para> - This describes how to install and use the tasks and the adapter. - For an example Ant script, see + This describes how to install and use the tasks and the adapter. + For an example Ant script, see <ulink url="../examples/build.xml">examples/build.xml</ulink>. </para> </sect1> - + <!-- . . . . . . . . . . . . . . . . . . . . . . . . . . . install --> <sect1 id="antTasks-install" xreflabel="Installing Ant Tasks"> <title>Installing Ant Tasks</title> <para> - Install Jakarta Ant 1.5.1: - Please see the official Jakarta Ant website for more information - and the 1.5.1 distribution. This release is source-compatible - with Ant 1.3 and Ant 1.4, but the task sources must be - compiled with those versions of the Ant libraries to be used - under those versions of Ant. - Sources are available under the Eclipse Public License v. 1.0 + Install Jakarta Ant 1.5.1: + Please see the official Jakarta Ant website for more information + and the 1.5.1 distribution. This release is source-compatible + with Ant 1.3 and Ant 1.4, but the task sources must be + compiled with those versions of the Ant libraries to be used + under those versions of Ant. + Sources are available under the Eclipse Public License v. 1.0 at <ulink url="http://eclipse.org/aspectj">http://eclipse.org/aspectj</ulink>. </para> <para> - In Ant 1.5, third-party tasks can be declared using a taskdef entry in - the build script, to identify the name and classes. - When declaring a task, include the - <literal>aspectjtools.jar</literal> either in the - taskdef classpath or in <literal>${ANT_HOME}/lib</literal> where it will be added - to the system class path by the ant script. - You may specify the task script names directly, + In Ant 1.5, third-party tasks can be declared using a taskdef entry in + the build script, to identify the name and classes. + When declaring a task, include the + <literal>aspectjtools.jar</literal> either in the + taskdef classpath or in <literal>${ANT_HOME}/lib</literal> 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: </para> - <programlisting> - <![CDATA[ - <taskdef - resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"/> -]]> - </programlisting> + <programlisting><![CDATA[ +<taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"/> +]]></programlisting> <para> - The current resource file retains the name "ajc" for the Ajc10 task, + The current resource file retains the name "ajc" for the Ajc10 task, and uses "iajc" for the AspectJ post-1.1 task. </para> <para> - In Ant 1.6, third-party tasks are declared in their own namespace + In Ant 1.6, third-party tasks are declared in their own namespace using <literal>antlib.xml</literal>. For example, the following script would build and run the spacewar example, if you put the script in the examples directory and <literal>aspectjtools.jar</literal> in the <literal>${ANT_HOME}/lib</literal> directory. </para> - <programlisting> - <![CDATA[ -<project name="aspectj-ant1.6" default="spacewar" + <programlisting><![CDATA[ +<project name="aspectj-ant1.6" default="spacewar" xmlns:aspectj="antlib:org.aspectj" basedir="."> <target name="spacewar"> <aspectj:iajc @@ -97,10 +93,9 @@ classpath="spacewar.jar:../../lib/aspectjrt.jar"/> </target> </project> -]]> - </programlisting> +]]></programlisting> <para> - For more information on using Ant, please refer to Jakarta's + For more information on using Ant, please refer to Jakarta's documentation on integrating user-defined Ant tasks into builds. </para> @@ -109,51 +104,51 @@ <sect1 id="antTasks-iajc" xreflabel="AjcTask (iajc)"> <title>AjcTask (iajc)</title> <para> - This task uses the AspectJ post-1.1 compiler ajc. - The AspectJ compiler can be used like Javac to compile Java sources, - but it can also compile AspectJ sources or weave binary aspects - with Java bytecode. - It can run in normal "batch" mode or in an "incremental" mode, - where it only recompiles files it has to revisit. + This task uses the AspectJ post-1.1 compiler ajc. + The AspectJ compiler can be used like Javac to compile Java sources, + but it can also compile AspectJ sources or weave binary aspects + with Java bytecode. + It can run in normal "batch" mode or in an "incremental" mode, + where it only recompiles files it has to revisit. For more information on ajc, see <xref linkend="ajc-ref"/>. - Unlike Javac or the Javac Ant task, this task always compiles the + Unlike Javac or the Javac Ant task, this task always compiles the specified files since aspects can apply to other (updated) files. For a workaround, see <xref linkend="antTasks-iajc-uptodate"/>. </para> <para> Beyond the normal ajc compiler options, this task also supports an experimental option for an incremental "tag" file, and it - can copy resources from source directories or + can copy resources from source directories or input jars to the output jar or directory. </para> - + <para> - This task is named iajc to avoid conflict with the 1.0 task ajc. + This task is named iajc to avoid conflict with the 1.0 task ajc. </para> <sect2 id="antTasks-iajc-options" xreflabel="AjcTask (iajc) Options"> <title>AjcTask (iajc) Options</title> <para> - The following tables list the supported parameters. - For any parameter specified as a Path, a single path can be - specified directly as an attribute, - multiple paths can be specified using a nested element of + The following tables list the supported parameters. + For any parameter specified as a Path, a single path can be + specified directly as an attribute, + multiple paths can be specified using a nested element of the same name, and a common path can be reused by defining it as a - global and passing the id to the corresponding {name}ref attribute. - See <xref linkend="antTasks-iajc-paths"/> + global and passing the id to the corresponding {name}ref attribute. + See <xref linkend="antTasks-iajc-paths"/> below for more details. </para> <para> - Most attributes and nested elements are optional. - The compiler requires that the same version of + Most attributes and nested elements are optional. + The compiler requires that the same version of <literal>aspectjrt.jar</literal> be specified on the classpath, and that some sources be be specified - (using one or more of + (using one or more of <literal>sourceroots</literal>, <literal>injars</literal>, <literal>inpath</literal>, - <literal>argfiles</literal>, and/or + <literal>argfiles</literal>, and/or <literal>srcdir</literal> (with patterns)). When in incremental mode, only <literal>sourceroots</literal> may be specified. @@ -163,14 +158,14 @@ </para> <!-- . . . . . . . . . . . . . . . . iajc options table --> - <!-- table (and caption/title) not supported by fop --> + <!-- table (and caption/title) not supported by fop --> <para> <emphasis role="strong"> AjcTask (iajc) options for specifying sources - </emphasis> - </para> + </emphasis> + </para> <informaltable> - + <tgroup cols="2"> <thead> <row> @@ -184,9 +179,9 @@ (<xref linkend="antTasks-iajc-paths"/>) </para></entry> <entry><para> - An argument file contains a list of arguments read by the compiler. - Each line is read into one element of the argument array - and may include another argfile by reference. + An argument file contains a list of arguments read by the compiler. + Each line is read into one element of the argument array + and may include another argfile by reference. </para></entry> </row> <row> @@ -194,19 +189,19 @@ (<xref linkend="antTasks-iajc-paths"/>) </para></entry> <entry><para> - Directories containing source files (ending with .java or .aj) to compile. + Directories containing source files (ending with .java or .aj) to compile. </para></entry> </row> <row> <entry><para>srcdir (<xref linkend="antTasks-iajc-paths"/>) </para></entry> - <entry><para> - Base directory of sources to compile, assuming there are + <entry><para> + Base directory of sources to compile, assuming there are <xref linkend="antTasks-nested-includes"/>. - This approach uses the Ant process - for matching .java files and is not compatible with incremental - mode. Unless using filters to limit the sources included, + This approach uses the Ant process + for matching .java files and is not compatible with incremental + mode. Unless using filters to limit the sources included, use sourceroots instead. </para></entry> </row> @@ -226,7 +221,7 @@ </para></entry> <entry><para> Read .class files for bytecode weaving - from directories or zip files (like classpath). + from directories or zip files (like classpath). </para></entry> </row> <row> @@ -244,25 +239,25 @@ (<xref linkend="antTasks-iajc-paths"/>) </para></entry> <entry><para> - The bootclasspath specifies types to use instead of the - invoking VM's when seeking types during compilation. + The bootclasspath specifies types to use instead of the + invoking VM's when seeking types during compilation. </para></entry> </row> <row> <entry><para>extDirs, extDirsRef (<xref linkend="antTasks-iajc-paths"/>) </para></entry> - <entry><para> - The extension directories to use instead of those in the - invoking VM when seeking types during compilation. + <entry><para> + The extension directories to use instead of those in the + invoking VM when seeking types during compilation. </para></entry> </row> <row> <entry><para>aspectPath, aspectPathRef (<xref linkend="antTasks-iajc-paths"/>) </para></entry> - <entry><para> - Similar to classpath, aspectpath contains read-only, + <entry><para> + Similar to classpath, aspectpath contains read-only, binary aspect libraries that are woven into sources but not included in the output. <literal>aspectpath</literal> accepts jar/zip files @@ -271,13 +266,13 @@ </row> </tbody> </tgroup> - </informaltable> + </informaltable> <para> <emphasis role="strong"> AjcTask (iajc) options for specifying output - </emphasis> - </para> + </emphasis> + </para> <informaltable> <tgroup cols="2"> <thead> @@ -290,18 +285,18 @@ <row> <entry><para>destDir </para></entry> - <entry><para> - The directory in which to place the generated class files. - Only one of <literal>destDir</literal> and + <entry><para> + The directory in which to place the generated class files. + Only one of <literal>destDir</literal> and <literal>outJar</literal> may be set. </para></entry> </row> <row> <entry><para>outJar </para></entry> - <entry><para> - The zip file in which to place the generated output class files. - Only one of <literal>destDir</literal> and + <entry><para> + The zip file in which to place the generated output class files. + Only one of <literal>destDir</literal> and <literal>outJar</literal> may be set. </para></entry> </row> @@ -309,9 +304,9 @@ <entry><para>copyInjars </para></entry> <entry><para> - (Deprecated/ignored; ajc does this.) - If true, copy all non-.class files from input jar(s) - to the output jar or destination directory after the + (Deprecated/ignored; ajc does this.) + If true, copy all non-.class files from input jar(s) + to the output jar or destination directory after the compile (or incremental compile) completes. In forked mode, this copies only after the process completes, not after incremental compiles. @@ -320,13 +315,13 @@ <row> <entry><para>sourceRootCopyFilter </para></entry> - <entry><para> - When set, copy all files from the sourceroot directories to the output jar - or destination directory except those specified in the filter pattern. - The pattern should be compatible with an Ant fileset excludes filter; - when using this, most developers pass - <literal>**/CVS/*,**/*.java</literal> to exclude any CVS directories - or source files. + <entry><para> + When set, copy all files from the sourceroot directories to the output jar + or destination directory except those specified in the filter pattern. + The pattern should be compatible with an Ant fileset excludes filter; + when using this, most developers pass + <literal>**/CVS/*,**/*.java</literal> to exclude any CVS directories + or source files. See <literal>inpathDirCopyFilter</literal>. Requires <literal>destDir</literal> or <literal>outJar</literal>. </para></entry> @@ -335,30 +330,30 @@ <entry><para>inpathDirCopyFilter </para></entry> <entry> - <para> When set, copy all files from the inpath directories - to the output jar or destination directory except those - specified in the filter pattern. The pattern should be - compatible with an Ant fileset excludes filter; when - using this, most developers pass - <literal>**/CVS/*,**/*.java,**/*.class</literal> to - exclude any CVS directories, source files, or unwoven - .class files. (If <literal>**/*.class</literal> is not - specified, it will be prepended to the filter.) See - <literal>sourceRootCopyFilter</literal>. (Note that ajc - itself copies all resources from input jar/zip files on - the inpath.) Requires <literal>destDir</literal> or + <para> When set, copy all files from the inpath directories + to the output jar or destination directory except those + specified in the filter pattern. The pattern should be + compatible with an Ant fileset excludes filter; when + using this, most developers pass + <literal>**/CVS/*,**/*.java,**/*.class</literal> to + exclude any CVS directories, source files, or unwoven + .class files. (If <literal>**/*.class</literal> is not + specified, it will be prepended to the filter.) See + <literal>sourceRootCopyFilter</literal>. (Note that ajc + itself copies all resources from input jar/zip files on + the inpath.) Requires <literal>destDir</literal> or <literal>outJar</literal>.</para> </entry> </row> </tbody> </tgroup> - </informaltable> + </informaltable> <para> <emphasis role="strong"> AjcTask (iajc) options for specifying compiler behavior - </emphasis> - </para> + </emphasis> + </para> <informaltable> <tgroup cols="2"> <thead> @@ -371,16 +366,16 @@ <row> <entry><para>fork </para></entry> - <entry><para> - Run process in another VM. + <entry><para> + Run process in another VM. This gets the forking classpath either explicitly - from a <literal>forkclasspath</literal> entry + from a <literal>forkclasspath</literal> entry or by searching the task or system/Ant classpath for the first readable file with a name of the form <literal>aspectj{-}tools{.*}.jar</literal>. When forking you can specify the amount of memory used with <literal>maxmem</literal>. - Fork cannot be used in incremental mode, + Fork cannot be used in incremental mode, unless using a tag file. </para></entry> </row> @@ -395,38 +390,38 @@ <row> <entry><para>maxmem </para></entry> - <entry><para> - The maximum memory to use for the new VM when fork is true. - Values should have the same form as accepted by the VM, e.g., "128m". + <entry><para> + The maximum memory to use for the new VM when fork is true. + Values should have the same form as accepted by the VM, e.g., "128m". </para></entry> </row> <row> <entry><para>incremental </para></entry> - <entry><para> - incremental mode: Build once, then recompile only required source - files when user provides input. - Requires that source files be specified only using - <literal>sourceroots</literal>. + <entry><para> + incremental mode: Build once, then recompile only required source + files when user provides input. + Requires that source files be specified only using + <literal>sourceroots</literal>. Incompatible with forking. </para></entry> </row> <row> <entry><para>tagfile </para></entry> - <entry><para> - incremental mode: Build once, then recompile only required source - files when the tag file is updated, finally exiting when tag file + <entry><para> + incremental mode: Build once, then recompile only required source + files when the tag file is updated, finally exiting when tag file is deleted. - Requires that source files be specified only using - <literal>sourceroots</literal>. + Requires that source files be specified only using + <literal>sourceroots</literal>. </para></entry> </row> <row> <entry><para>X </para></entry> <entry><para> - Set experimental option(s), using comma-separated list of accepted options + Set experimental option(s), using comma-separated list of accepted options Options should not contain the leading X. Some commonly-used experimental options have their own entries. The other permitted ones (currently) are @@ -447,12 +442,12 @@ </row> </tbody> </tgroup> - </informaltable> + </informaltable> <para> <emphasis role="strong"> AjcTask (iajc) options for specifying compiler side-effects and messages - </emphasis> + </emphasis> </para> <informaltable> <tgroup cols="2"> @@ -489,37 +484,37 @@ </para></entry> <entry><para> If true, log compiler command elements as Project.INFO - (rather than the usual Project.VERBOSE level). + (rather than the usual Project.VERBOSE level). </para></entry> </row> <row> <entry><para>Xlistfileargs </para></entry> - <entry><para> - If true, emit list of file arguments during - the compile (but behaves now like verbose). + <entry><para> + If true, emit list of file arguments during + the compile (but behaves now like verbose). </para></entry> </row> <row> <entry><para>version </para></entry> - <entry><para> + <entry><para> If true, do not compile - just print AspectJ version. </para></entry> </row> <row> <entry><para>help </para></entry> - <entry><para> - If true, just print help for the command-line compiler. + <entry><para> + If true, just print help for the command-line compiler. </para></entry> </row> <row> <entry><para>Xlintwarnings </para></entry> - <entry><para> + <entry><para> Same as <literal>xlint:warning</literal>: - if true, set default level of all language + if true, set default level of all language usage messages to warning. </para></entry> </row> @@ -527,24 +522,24 @@ <entry><para>Xlint </para></entry> <entry><para> - Specify default level of all language usage messages to one of - [<literal>error warning ignore</literal>]. + Specify default level of all language usage messages to one of + [<literal>error warning ignore</literal>]. </para></entry> </row> <row> <entry><para>XlintFile </para></entry> - <entry><para> - Specify property file containing <literal>name:level</literal> associations - setting level for language messages emitted during compilation. - Any levels set override the default associations in - <literal>org/aspectj/weaver/XLintDefault.properties</literal>. + <entry><para> + Specify property file containing <literal>name:level</literal> associations + setting level for language messages emitted during compilation. + Any levels set override the default associations in + <literal>org/aspectj/weaver/XLintDefault.properties</literal>. </para></entry> </row> <row> <entry><para>failonerror </para></entry> - <entry><para> + <entry><para> If true, throw BuildException to halt build if there are any compiler errors. If false, continue notwithstanding compile errors. @@ -554,31 +549,31 @@ <row> <entry><para>messageHolderClass </para></entry> - <entry><para> - Specify a class to use as the message holder for the compile process. - The entry must be a fully-qualified name of a class resolveable from - the task classpath complying with the - <literal>org.aspectj.bridge.IMessageHolder</literal> interface - and having a public no-argument constructor. + <entry><para> + Specify a class to use as the message holder for the compile process. + The entry must be a fully-qualified name of a class resolveable from + the task classpath complying with the + <literal>org.aspectj.bridge.IMessageHolder</literal> interface + and having a public no-argument constructor. </para></entry> </row> <row> <entry><para>showWeaveInfo </para></entry> - <entry><para> + <entry><para> If true, emit weaver messages. Defaults to <literal>false</literal>. </para></entry> </row> </tbody> </tgroup> - </informaltable> + </informaltable> <para> <emphasis role="strong"> AjcTask (iajc) options for specifying Eclipse compiler options - </emphasis> + </emphasis> </para> <informaltable> <tgroup cols="2"> @@ -592,32 +587,32 @@ <row> <entry><para>nowarn </para></entry> - <entry><para> + <entry><para> If true, same as <literal>warn:none</literal>. </para></entry> </row> <row> <entry><para>deprecation </para></entry> - <entry><para> - If true, same as <literal>warn:deprecation</literal> + <entry><para> + If true, same as <literal>warn:deprecation</literal> </para></entry> </row> <row> <entry><para>warn </para></entry> - <entry><para> + <entry><para> One or more comma-separated warning specifications from - [<literal>constructorName packageDefaultMethod deprecation, - maskedCatchBlocks unusedLocals unusedArguments, - unusedImports syntheticAccess assertIdentifier</literal>]. + [<literal>constructorName packageDefaultMethod deprecation, + maskedCatchBlocks unusedLocals unusedArguments, + unusedImports syntheticAccess assertIdentifier</literal>]. </para></entry> </row> <row> <entry><para>debug </para></entry> <entry><para> - If true, same as <literal>debug:lines,vars,source</literal> + If true, same as <literal>debug:lines,vars,source</literal> </para></entry> </row> <row> @@ -625,79 +620,79 @@ </para></entry> <entry><para> One or more comma-separated debug specifications from - [<literal>lines vars source</literal>]. + [<literal>lines vars source</literal>]. </para></entry> </row> <row> <entry><para>PreserveAllLocals </para></entry> - <entry><para> - If true, code gen preserves all local variables (for debug purposes). + <entry><para> + If true, code gen preserves all local variables (for debug purposes). </para></entry> </row> <row> <entry><para>noimporterror </para></entry> - <entry><para> - If true, emit no errors for unresolved imports. + <entry><para> + If true, emit no errors for unresolved imports. </para></entry> </row> <row> <entry><para>referenceinfo </para></entry> - <entry><para> - If true, compute reference info. + <entry><para> + If true, compute reference info. </para></entry> </row> <row> <entry><para>log </para></entry> - <entry><para> - File to log compiler messages to. + <entry><para> + File to log compiler messages to. </para></entry> </row> <row> <entry><para>encoding </para></entry> <entry><para>Default source encoding format - (per-file encoding not supported in Ant tasks). + (per-file encoding not supported in Ant tasks). </para></entry> </row> <row> <entry><para>proceedOnError </para></entry> - <entry><para> - If true, keep compiling after errors encountered, - dumping class files with problem methods. + <entry><para> + If true, keep compiling after errors encountered, + dumping class files with problem methods. </para></entry> </row> <row> <entry><para>progress </para></entry> - <entry><para> - If true, emit progress (requires log). + <entry><para> + If true, emit progress (requires log). </para></entry> </row> <row> <entry><para>time </para></entry> - <entry><para> - If true, display speed information. + <entry><para> + If true, display speed information. </para></entry> </row> <row> <entry><para>target </para></entry> - <entry><para> + <entry><para> Specify target class file format as one of [<literal>1.1 1.2</literal>]. - Defaults to 1.1 class file. + Defaults to 1.1 class file. </para></entry> </row> <row> <entry><para>source </para></entry> - <entry><para> + <entry><para> Set source compliance level to one of [<literal>1.3 1.4 1.5</literal>] (default is 1.4). @@ -712,36 +707,36 @@ <entry><para> Set source assertion mode to one of [<literal>1.3 1.4</literal>]. - Default depends on compliance mode. + Default depends on compliance mode. </para></entry> </row> </tbody> </tgroup> - </informaltable> + </informaltable> <!-- . . . . . . . . . . . . . . . . iajc options table --> </sect2> - + <sect2 id="antTasks-nested-includes" xreflabel="nested matches"> <title>AjcTask matching parameters specified as nested elements</title> <para> - This task forms an implicit FileSet and supports all attributes of - <literal><fileset></literal> (dir becomes srcdir) as well as - the nested - <literal><include></literal>, - <literal><exclude></literal>, and + This task forms an implicit FileSet and supports all attributes of + <literal><fileset></literal> (dir becomes srcdir) as well as + the nested + <literal><include></literal>, + <literal><exclude></literal>, and <literal><patternset></literal> elements. - These can be used to specify source files. + These can be used to specify source files. However, it is better to use <literal>sourceroots</literal> - to specify source directories unless using filters to exclude + to specify source directories unless using filters to exclude some files from compilation. </para> </sect2> - + <sect2 id="antTasks-iajc-paths" xreflabel="Path"> <title>AjcTask Path-like Structures</title> <para> - Some parameters are path-like structures containing one or more + Some parameters are path-like structures containing one or more elements; these are <literal>sourceroots</literal>, <literal>argfiles</literal>, @@ -751,58 +746,51 @@ <literal>bootclasspath</literal>, <literal>forkclasspath</literal>, and <literal>aspectpath</literal>. - In all cases, these may be specified as nested elements, something + In all cases, these may be specified as nested elements, something like this: </para> - <programlisting> - <![CDATA[ - <iajc {attributes..} /> - <{name}> - <pathelement path="{first-location}"/> - <pathelement path="{second-location}"/> - ... - <{name}> + <programlisting><![CDATA[ +<iajc {attributes..} /> + <{name}> + <pathelement path="{first-location}"/> + <pathelement path="{second-location}"/> ... - </iajc> -]]> - </programlisting> + <{name}> + ... +</iajc> +]]></programlisting> <para> - As with other Path-like structures, they may be defined elsewhere + As with other Path-like structures, they may be defined elsewhere and specified using the refid attribute: </para> - <programlisting> - <![CDATA[ - <path id="aspect.path"> - <pathelement path="${home}/lib/persist.jar"/> - <pathelement path="${home}/lib/trace.jar"/> - </path> + <programlisting><![CDATA[ +<path id="aspect.path"> + <pathelement path="${home}/lib/persist.jar"/> + <pathelement path="${home}/lib/trace.jar"/> +</path> +... +<iajc {attributes..} /> + <aspectpath refid="aspect.path"/> ... - <iajc {attributes..} /> - <aspectpath refid="aspect.path"/> - ... - </iajc> -]]> - </programlisting> +</iajc> +]]></programlisting> <para> The task also supports an attribute <literal>{name}ref</literal> for each such parameter. E.g., for <literal>aspectpath</literal>: </para> - <programlisting> - <![CDATA[ - <iajc {attributes..} aspectpathref="aspect.path"/> -]]> - </programlisting> + <programlisting><![CDATA[ +<iajc {attributes..} aspectpathref="aspect.path"/> +]]></programlisting> </sect2> - + <sect2 id="antTasks-iajc-sample" xreflabel="Sample of iajc task"> <title>Sample of iajc task</title> <para> A minimal build script defines the task and runs it, specifying the sources: </para> - <programlisting> - <![CDATA[ + <programlisting><![CDATA[ <project name="simple-example" default="compile" > - <taskdef + <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"> <classpath> <pathelement location="${home.dir}/tools/aspectj/lib/aspectjtools.jar"/> @@ -810,12 +798,11 @@ </taskdef> <target name="compile" > - <iajc sourceroots="${home.dir}/ec/project/src" - classpath="${home.dir}/tools/aspectj/lib/aspectjrt.jar"/> + <iajc sourceroots="${home.dir}/ec/project/src" + classpath="${home.dir}/tools/aspectj/lib/aspectjrt.jar"/> </target> </project> -]]> - </programlisting> +]]></programlisting> <para> Below is script with most everything in it. The compile process... </para> @@ -829,7 +816,7 @@ </para> </listitem> <listitem> - <para>Reads binary .class files from input jar and directory; + <para>Reads binary .class files from input jar and directory; </para> </listitem> <listitem> @@ -841,51 +828,49 @@ </para> </listitem> <listitem> - <para>Copies resources from the source directories and binary input + <para>Copies resources from the source directories and binary input jar and directories to the application jar. </para> </listitem> </orderedlist> <para> - When this target is built, the compiler will build once and then - wait for input from the user. - Messages are printed as usual. + 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. </para> <!-- if program changed, test in docs/test/antScriptTest --> - <programlisting> - <![CDATA[ - <target name="build-test" > - <iajc outjar="${home.dir}/output/application.jar" - sourceRootCopyFilter="**/CVS/*,**/*.java" - inpathDirCopyFilter="**/CVS/*,**/*.java,**/*.class" - incremental="true" > - <sourceroots> - <pathelement location="${home.dir}/ec/project/src"/> - <pathelement location="${home.dir}/ec/project/testsrc"/> - </sourceroots> - <inpath> - <pathelement location="${home.dir}/build/module.jar"/> - <pathelement location="${home.dir}/build/binary-input"/> - </inpath> - <aspectpath> - <pathelement location="${home.dir}/ec/int/persist.jar"/> - </aspectpath> - <classpath> - <pathelement location="${home.dir}/tools/aspectj/lib/aspectjrt.jar"/> - </classpath> - </iajc> - - <java classname="org.smart.app.Main"> - <classpath> - <pathelement location="${home.dir}/tools/aspectj/lib/aspectjrt.jar"/> - <pathelement location="${home.dir}/ec/int/persist.jar"/> - <pathelement location="${home.dir}/output/application.jar"/> - </classpath> - </java> - </target> -]]> - </programlisting> + <programlisting><![CDATA[ +<target name="build-test" > + <iajc outjar="${home.dir}/output/application.jar" + sourceRootCopyFilter="**/CVS/*,**/*.java" + inpathDirCopyFilter="**/CVS/*,**/*.java,**/*.class" + incremental="true" > + <sourceroots> + <pathelement location="${home.dir}/ec/project/src"/> + <pathelement location="${home.dir}/ec/project/testsrc"/> + </sourceroots> + <inpath> + <pathelement location="${home.dir}/build/module.jar"/> + <pathelement location="${home.dir}/build/binary-input"/> + </inpath> + <aspectpath> + <pathelement location="${home.dir}/ec/int/persist.jar"/> + </aspectpath> + <classpath> + <pathelement location="${home.dir}/tools/aspectj/lib/aspectjrt.jar"/> + </classpath> + </iajc> + + <java classname="org.smart.app.Main"> + <classpath> + <pathelement location="${home.dir}/tools/aspectj/lib/aspectjrt.jar"/> + <pathelement location="${home.dir}/ec/int/persist.jar"/> + <pathelement location="${home.dir}/output/application.jar"/> + </classpath> + </java> +</target> +]]></programlisting> <para> For an example of a build script, see <ulink url="../examples/build.xml"> @@ -902,21 +887,19 @@ is no reason to recompile sources. One way to implement that is with an explicit dependency check using the uptodate task: </para> - <programlisting> - <![CDATA[ - <target name="check.aspects.jar"> - <uptodate property="build.unnecessary" - targetfile="${aspects.module-jar}" > - <srcfiles dir="${src1}" includes="**/*.aj"/> - <srcfiles dir="${src2}/" includes="**/*.aj"/> - </uptodate> - </target> + <programlisting><![CDATA[ +<target name="check.aspects.jar"> + <uptodate property="build.unnecessary" + targetfile="${aspects.module-jar}" > + <srcfiles dir="${src1}" includes="**/*.aj"/> + <srcfiles dir="${src2}/" includes="**/*.aj"/> + </uptodate> +</target> - <target name="compile.aspects" depends="prepare,check.aspects.jar" - unless="build.unnecessary"> - <iajc ... -]]> - </programlisting> +<target name="compile.aspects" depends="prepare,check.aspects.jar" + unless="build.unnecessary"> + <iajc ... +]]></programlisting> <para> When using this technique, be careful to verify that binary input jars are themselves up-to-date after they would have been @@ -927,19 +910,19 @@ <sect2 id="programmatically-handling-compiler-messages" xreflabel="programmatically-handling-compiler-messages"> <title>Programmatically handling compiler messages</title> <para> - Users may specify a message holder to which the compiler will pass - all messages as they are generated. This will override all of the - normal message printing, but does not prevent the task from failing - if exceptions were thrown or if failonerror is true and the compiler + Users may specify a message holder to which the compiler will pass + all messages as they are generated. This will override all of the + normal message printing, but does not prevent the task from failing + if exceptions were thrown or if failonerror is true and the compiler detected errors in the sources. </para> <para> - Handling messages programmatically could be useful when using the + Handling messages programmatically could be useful when using the compiler to verify code. If aspects consist of declare [error|warning], - then the compiler can act to detect invariants in the code being - processed. For code to compare expected and actual messages, see the - AspectJ testing module (which is not included in the binary - distribution). + then the compiler can act to detect invariants in the code being + processed. For code to compare expected and actual messages, see the + AspectJ testing module (which is not included in the binary + distribution). </para> </sect2> </sect1> @@ -948,10 +931,10 @@ <sect1 id="antTasks-adapter" xreflabel="Ajc11CompilerAdapter (javac)"> <title>Ajc11CompilerAdapter (javac)</title> <para> - This CompilerAdapter can be used in javac task calls by setting the - <literal>build.compiler</literal> property. - This enables users to to easily switch between the Javac and AspectJ - compilers. However, because there are differences in source file + This CompilerAdapter can be used in javac task calls by setting the + <literal>build.compiler</literal> property. + This enables users to to easily switch between the Javac and AspectJ + compilers. However, because there are differences in source file handling between the Javac task and the ajc compiler, not all Javac task invocations can be turned over to iajc. However, ajc can compile anything that Javac can, so it should be possible for any @@ -961,24 +944,23 @@ <sect2 id="antTasks-adapter-sample" xreflabel="Sample of compiler adapter"> <title>Sample of compiler adapter</title> <para> - To build using the adapter, put the - <literal>aspectjtools.jar</literal> - on the system/ant classpath (e.g., in - <literal>${ANT_HOME}/lib</literal>) - and define the + To build using the adapter, put the + <literal>aspectjtools.jar</literal> + on the system/ant classpath (e.g., in + <literal>${ANT_HOME}/lib</literal>) + and define the <literal>build.compiler</literal> - property as the fully-qualified name of the class, - <literal>org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter</literal>. + property as the fully-qualified name of the class, + <literal>org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter</literal>. </para> <para> - The AspectJ compiler should run for any compile using the Javac task - (for options, see the Ant documentation for the Javac task). - For example, the call below passes all out-of-date source files in the - <literal>src/org/aspectj</literal> subdirectories to the + The AspectJ compiler should run for any compile using the Javac task + (for options, see the Ant documentation for the Javac task). + For example, the call below passes all out-of-date source files in the + <literal>src/org/aspectj</literal> subdirectories to the <literal>ajc</literal> command along with the destination directory: </para> - <programlisting> - <![CDATA[ + <programlisting><![CDATA[ -- command: cp aspectj1.1/lib/aspectjtools.jar ant/lib @@ -987,34 +969,31 @@ -- task invocation in the build script: <javac srcdir="src" includes="org/aspectj/**/*.java" destdir="dest" /> -]]> - </programlisting> - +]]></programlisting> + <para> To pass ajc-specific arguments, use a compilerarg entry. </para> - <programlisting> - <![CDATA[ + <programlisting><![CDATA[ -- command Ant -Dbuild.compiler=org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter -- build script - <property name="ajc" + <property name="ajc" value="org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter"/> <javac srcdir="src" includes="org/aspectj/**/*.java" destdir="dest" > <compilerarg compiler="${ajc}" line="-argfile src/args.lst"/> <javac/> -]]> - </programlisting> - <para>The Javac task does special handling of source files that +]]></programlisting> + <para>The Javac task does special handling of source files that can interfere with ajc. It removes any files that are not out-of-date - with respect to the corresponding .class files. But ajc requires all + with respect to the corresponding .class files. But ajc requires all source files, since an aspect may affect a source file that is not out of date. (For a solution to this, see the <literal>build.compiler.clean</literal> - property described below.) Conversely, developers sometimes specify a source directory + property described below.) Conversely, developers sometimes specify a source directory to javac, and let it search for files for types it cannot find. AspectJ will not do this kind of searching under the source directory (since the programmer needs to control which sources are affected). @@ -1025,46 +1004,46 @@ the source files. </para> </sect2> - + <sect2 id="antTasks-adapter-options" xreflabel="Compiler adapter compilerarg options"> <title>Compiler adapter compilerarg options</title> <para> - The adapter supports any ajc command-line option passed using compilerarg, - as well as the following options available only in AjcTask. + The adapter supports any ajc command-line option passed using compilerarg, + as well as the following options available only in AjcTask. Find more details on the following options in <xref linkend="antTasks-iajc"/>. </para> <itemizedlist> <listitem><para> - <literal>-Xmaxmem</literal>: - set maximum memory for forking (also settable in javac). + <literal>-Xmaxmem</literal>: + set maximum memory for forking (also settable in javac). </para></listitem> <listitem><para> - <literal>-Xlistfileargs</literal>: - list file arguments (also settable in javac). + <literal>-Xlistfileargs</literal>: + list file arguments (also settable in javac). </para></listitem> <listitem><para> - <literal>-Xfailonerror</literal>: + <literal>-Xfailonerror</literal>: throw BuildException on compiler error (also settable in javac). </para></listitem> <listitem><para> - <literal>-Xmessageholderclass</literal>: - specify fully-qualified name of class to use as the message holder. + <literal>-Xmessageholderclass</literal>: + specify fully-qualified name of class to use as the message holder. </para></listitem> <listitem><para> - <literal>-Xcopyinjars</literal>: + <literal>-Xcopyinjars</literal>: copy resources from any input jars to output (default behavior since 1.1.1) </para></listitem> <listitem><para> - <literal>-Xsourcerootcopyfilter {filter}</literal>: + <literal>-Xsourcerootcopyfilter {filter}</literal>: copy resources from source directories to output (minus files specified in filter) </para></listitem> <listitem><para> - <literal>-Xtagfile {file}</literal>: - use file to control incremental compilation + <literal>-Xtagfile {file}</literal>: + use file to control incremental compilation </para></listitem> <listitem><para> - <literal>-Xsrcdir {dir}</literal>: + <literal>-Xsrcdir {dir}</literal>: add to list of ajc source roots (all source files will be included). </para></listitem> </itemizedlist> @@ -1073,67 +1052,65 @@ </para> <itemizedlist> <listitem><para> - The names above may differ slightly from what you might expect + The names above may differ slightly from what you might expect from AjcTask; use these forms when specifying compilerarg. </para></listitem> </itemizedlist> <itemizedlist> <listitem><para> - By default the adapter will mimic the Javac task's copying of resource - files by specifying + By default the adapter will mimic the Javac task's copying of resource + files by specifying <literal>"**/CVS/*,**/*.java,**/*.aj"</literal> - for the sourceroot copy filter. - To change this behavior, supply your own value + for the sourceroot copy filter. + To change this behavior, supply your own value (e.g., <literal>"**/*"</literal> to copy nothing). </para></listitem> </itemizedlist> <itemizedlist> <listitem><para> Warning - define the system property - <literal>build.compiler.clean</literal> to compile all files, + <literal>build.compiler.clean</literal> to compile all files, when available. - Javac prunes the source file list of "up-to-date" source files - based on the timestamps of corresponding .class files, - and will not compile if no sources are out of date. - This is wrong for ajc which requires all the files for each compile - and which may refer indirectly to sources using argument files. + Javac prunes the source file list of "up-to-date" source files + based on the timestamps of corresponding .class files, + and will not compile if no sources are out of date. + This is wrong for ajc which requires all the files for each compile + and which may refer indirectly to sources using argument files. </para> <para> - To work around this, set the global property - <literal>build.compiler.clean</literal>. - This tells the compiler adapter to delete all .class files - in the destination directory and re-execute the javac + To work around this, set the global property + <literal>build.compiler.clean</literal>. + 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., </para> - <programlisting> - <![CDATA[ - Ant -Dbuild.compiler=org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter - -Dbuild.compiler.clean=anything ... -]]> - </programlisting> - <para> - Caveats to consider when using this global + <programlisting><![CDATA[ +Ant -Dbuild.compiler=org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter + -Dbuild.compiler.clean=anything ... +]]></programlisting> + <para> + Caveats to consider when using this global <literal>build.compiler.clean</literal> property: - </para> + </para> <orderedlist> <listitem><para> - If javac believes there are no out-of-date source files, - then the adapter is never called and cannot clean up, - and the "compile" will appear to complete successfully + If javac believes there are no out-of-date source files, + then the adapter is never called and cannot clean up, + and the "compile" will appear to complete successfully though it did nothing. </para></listitem> <listitem><para> - Cleaning will makes stepwise build processes fail if - they depend on the results of the prior compilation being + Cleaning will makes stepwise build processes fail if + they depend on the results of the prior compilation being in the same directory, since cleaning deletes all .class files. </para></listitem> <listitem><para> - This clean process only permits one compile process at a - time for each destination directory because it tracks + This clean process only permits one compile process at a + time for each destination directory because it tracks recursion by writing a tag file to the destination directory. </para></listitem> <listitem><para> - When running incrementally, the clean happens only before + When running incrementally, the clean happens only before the initial compile. </para></listitem> </orderedlist> @@ -1147,27 +1124,27 @@ <title>Ajc10 (ajc)</title> <para> This task handles the same arguments as those used by the AspectJ 1.0 task. - This should permit those with existing build scripts using the Ajc Ant + This should permit those with existing build scripts using the Ajc Ant task to continue using the same scripts when compiling with 1.1. - This will list any use of options no longer supported in 1.1 - (e.g., <literal>lenient, strict, workingdir, preprocess, usejavac</literal>,...), - and does not provide access to the new features of AspectJ 1.1. - (Developers using AspectJ 1.1 only should upgrade their scripts + This will list any use of options no longer supported in 1.1 + (e.g., <literal>lenient, strict, workingdir, preprocess, usejavac</literal>,...), + and does not provide access to the new features of AspectJ 1.1. + (Developers using AspectJ 1.1 only should upgrade their scripts to use AjcTask instead. This will not work for AspectJ 1.2 or later.) </para> - + <sect2 id="antTasks-ajc-options" xreflabel="Ajc10 (ajc) Options"> <title>Ajc10 (ajc) Options</title> <para> </para> <para> - Most attributes and nested elements are optional. - The compiler requires that the same version of + Most attributes and nested elements are optional. + The compiler requires that the same version of <literal>aspectjrt.jar</literal> be specified on the classpath, and that some sources be be specified - (using one or more of - <literal>argfiles</literal> and + (using one or more of + <literal>argfiles</literal> and <literal>srcdir</literal> (with patterns)). </para> <para>Boolean parameters default to <literal>false</literal> @@ -1190,7 +1167,7 @@ </para></entry> <entry><para> The base directory of the java files. - See + See </para></entry> </row> <row> @@ -1243,18 +1220,18 @@ <entry><para>classpath, classpathref </para></entry> <entry><para> - The classpath to use, + The classpath to use, optionally given as a reference to a classpath Path - element defined elsewhere. + element defined elsewhere. </para></entry> </row> <row> <entry><para>bootclasspath, bootclasspathref </para></entry> <entry><para> - The bootclasspath to use, + The bootclasspath to use, optionally given as a reference to a bootclasspath Path - element defined elsewhere. + element defined elsewhere. </para></entry> </row> <row> @@ -1312,9 +1289,9 @@ </tbody> </tgroup> </table> - + <table> - <title>Parameters ignored by the old ajc taskdef, + <title>Parameters ignored by the old ajc taskdef, but now supported or buggy</title> <tgroup cols="3"> <thead> @@ -1392,7 +1369,7 @@ </table> <para> - The following table shows that many of the unique parameters in + The following table shows that many of the unique parameters in AspectJ 1.0 are no longer supported. </para> <table> @@ -1425,30 +1402,30 @@ <entry><para>argfiles </para></entry> <entry><para> - A comma-delimited list of argfiles that contain a line-delimited + A comma-delimited list of argfiles that contain a line-delimited list of source file paths (absolute or relative to the argfile). </para></entry> </row> </tbody> </tgroup> </table> - - + + <sect3> <title>argfiles - argument list files</title> <para> - An argument file is a file (usually <literal>{file}.lst</literal>) - containing a list of source file paths - (absolute or relative to the argfile). - You can use it to specify all source files to be compiled, - which ajc requires to avoid searching every possible source file - in the source path when building aspects. - If you specify an argfile to the ajc task, it will not include all - files in any specified source directory (which is the default - behavior for the Javac task when no includes are specified). - Conversely, if you specify excludes, they will be removed from - the list of files compiled even if they were specified - in an argument file. + An argument file is a file (usually <literal>{file}.lst</literal>) + containing a list of source file paths + (absolute or relative to the argfile). + You can use it to specify all source files to be compiled, + which ajc requires to avoid searching every possible source file + in the source path when building aspects. + If you specify an argfile to the ajc task, it will not include all + files in any specified source directory (which is the default + behavior for the Javac task when no includes are specified). + Conversely, if you specify excludes, they will be removed from + the list of files compiled even if they were specified + in an argument file. </para> <para> The compiler also accepts arguments that are not source files, @@ -1461,40 +1438,39 @@ <sect2 id="antTasks-ajc-nested"> <title>Ajc10 parameters specified as nested elements</title> <para> - This task forms an implicit FileSet and supports all attributes of - <literal><fileset></literal> (dir becomes srcdir) as well as - the nested - <literal><include></literal>, - <literal><exclude></literal>, and - <literal><patternset></literal> elements. - These can be used to specify source files. + This task forms an implicit FileSet and supports all attributes of + <literal><fileset></literal> (dir becomes srcdir) as well as + the nested + <literal><include></literal>, + <literal><exclude></literal>, and + <literal><patternset></literal> elements. + These can be used to specify source files. </para> <para> <literal>ajc</literal>'s - <literal>srcdir</literal>, - <literal>classpath</literal>, - <literal>bootclasspath</literal>, - <literal>extdirs</literal>, and + <literal>srcdir</literal>, + <literal>classpath</literal>, + <literal>bootclasspath</literal>, + <literal>extdirs</literal>, and <literal>jvmarg</literal> - attributes are path-like structures and can also be set via nested - <literal><src></literal>, - <literal><classpath></literal>, - <literal><bootclasspath></literal>, - <literal><extdirs></literal>, and + attributes are path-like structures and can also be set via nested + <literal><src></literal>, + <literal><classpath></literal>, + <literal><bootclasspath></literal>, + <literal><extdirs></literal>, and <literal><jvmargs></literal> elements, respectively. </para> </sect2> - + <sect2 id="antTasks-ajc-sample" xreflabel="Sample of ajc task"> <title>Sample of ajc task</title> <para> - Following is a declaration for the ajc task and a sample invocation - that uses the ajc compiler to compile the files listed in + Following is a declaration for the ajc task and a sample invocation + that uses the ajc compiler to compile the files listed in <literal>default.lst</literal> into the dest dir: </para> - <programlisting> - <![CDATA[ + <programlisting><![CDATA[ <project name="example" default="compile" > <taskdef name="ajc" classname="org.aspectj.tools.ant.taskdefs.Ajc10" > @@ -1514,39 +1490,34 @@ </ajc> </target> </project> -]]> - </programlisting> +]]></programlisting> <para> This build script snippet </para> - <programlisting> - <![CDATA[ - <ajc srcdir="${src}" - destdir="${build}" - argfiles="demo.lst" - /> -]]> - </programlisting> - <para> + <programlisting><![CDATA[ +<ajc srcdir="${src}" + destdir="${build}" + argfiles="demo.lst" +/> +]]></programlisting> + <para> compiles all .java files specified in the demo.lst and stores the .class files in the ${build} directory. Unlike the Javac task, the includes attribute is empty by default, so only those files specified in demo.lst are included. - </para> - <para> + </para> + <para> This next example </para> - <programlisting> - <![CDATA[ - <ajc srcdir="${src}" - destdir="${build}" - includes="spacewar/*,coordination/*" - excludes="spacewar/Debug.java" - /> -]]> - </programlisting> - <para> - compiles .java files under the <literal>${src}</literal> directory in the - spacewar and coordination packages, and stores the .class files in the - <literal>${build}</literal> directory. - All source files under spacewar/ and coordination/ are used, except Debug.java. + <programlisting><![CDATA[ +<ajc srcdir="${src}" + destdir="${build}" + includes="spacewar/*,coordination/*" + excludes="spacewar/Debug.java" +/> +]]></programlisting> + <para> + compiles .java files under the <literal>${src}</literal> directory in the + spacewar and coordination packages, and stores the .class files in the + <literal>${build}</literal> directory. + All source files under spacewar/ and coordination/ are used, except Debug.java. </para> <para> See <ulink url="../examples/build.xml">../examples/build.xml</ulink> @@ -1561,77 +1532,77 @@ <title>Isolating problems running the Ant tasks</title> <para> - If you have problems with the tasks not solved by the documentation, - please try to see if you have the same problems when running ajc + If you have problems with the tasks not solved by the documentation, + please try to see if you have the same problems when running ajc directly on the command line. </para> <itemizedlist> <listitem><para> - If the problem occurs on the command line also, then the problem - is not in the task. + If the problem occurs on the command line also, then the problem + is not in the task. (It may be in the tools; please send bug reports.) </para></listitem> <listitem><para> - If the problem does not occur on the command line, then it may - lie in the parameters you are supplying in Ant or in the task's + If the problem does not occur on the command line, then it may + lie in the parameters you are supplying in Ant or in the task's handling of them. </para></listitem> <listitem><para> - If the build script looks correct and the problem only occurs when - building from Ant, then please send a report + If the build script looks correct and the problem only occurs when + building from Ant, then please send a report (including your build file, if possible). </para></listitem> </itemizedlist> - + <sect2 id="antTasks-knownProblems"> <title>Known issues with the Ant tasks</title> <para> - For the most up-to-date information on known problems, - see the + For the most up-to-date information on known problems, + see the <ulink url="http://bugs.eclipse.org/bugs">bug database</ulink> - for unresolved + for unresolved <ulink url="http://bugs.eclipse.org/bugs/buglist.cgi?&product=AspectJ&component=Compiler&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED"> compiler bugs - </ulink> or + </ulink> or <ulink url="http://bugs.eclipse.org/bugs/buglist.cgi?&product=AspectJ&component=Ant&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED"> taskdef bugs </ulink>. </para> <para> - When running Ant build scripts under Eclipse 2.x variants, you will get a + When running Ant build scripts under Eclipse 2.x variants, you will get a VerifyError because the Eclipse Ant support fails to isolate the Ant runtime properly. To run in this context, set up iajc to fork (and use forkclasspath). Eclipse 3.0 will fork Ant processes to avoid problems like this. </para> <para> - Memory and forking: Users email most often about the ajc task running - out of memory. - This is not a problem with the task; some compiles take a lot of + Memory and forking: Users email most often about the ajc task running + out of memory. + This is not a problem with the task; some compiles take a lot of memory, often more than similar compiles using javac. - </para> - <para> - Forking is now supported in both the - <xref linkend="antTasks-adapter"/> and - <xref linkend="antTasks-iajc"/>, - and you can set the maximum memory available. - You can also not fork and increase the memory available to Ant - (see the Ant documentation, searching for ANT_OPTS, - the variable they use in their scripts to pass VM options, + </para> + <para> + Forking is now supported in both the + <xref linkend="antTasks-adapter"/> and + <xref linkend="antTasks-iajc"/>, + and you can set the maximum memory available. + You can also not fork and increase the memory available to Ant + (see the Ant documentation, searching for ANT_OPTS, + the variable they use in their scripts to pass VM options, e.g., ANT_OPTS=-Xmx128m). </para> </sect2> <sect2 id="antTasks-feedback"> <title>Ant task questions and bugs</title> <para> - For questions, you can send email to + For questions, you can send email to <ulink url="mailto:aspectj-users@dev.eclipse.org"> - aspectj-users@dev.eclipse.org</ulink>. - (Do join the list to participate!) - We also welcome any bug reports, patches, and features; - you can submit them to the bug database at + aspectj-users@dev.eclipse.org</ulink>. + (Do join the list to participate!) + We also welcome any bug reports, patches, and features; + you can submit them to the bug database at <ulink url="http://bugs.eclipse.org/bugs"> http://bugs.eclipse.org/bugs</ulink> - using the AspectJ product and Ant component. + using the AspectJ product and Ant component. </para> </sect2> </sect1> diff --git a/docs/devGuideDB/aspectj-mode.xml b/docs/devGuideDB/aspectj-mode.xml index b54837964..e2ee862db 100644 --- a/docs/devGuideDB/aspectj-mode.xml +++ b/docs/devGuideDB/aspectj-mode.xml @@ -118,7 +118,7 @@ <entry>M-x aspectj-jump-menu (C-x C-j)</entry> <entry> Display popup menu of advisers, advisees, and inter-type declarations. - Navigate to item by selecting with mouse + Navigate to item by selecting with mouse (see <link linkend="aspectjmodescreenshot2">figure</link> below). </entry> </row> @@ -208,9 +208,10 @@ The files in this package need to be in the load-path and ``required''. For example, for the 1.0 release: <programlisting> - ;; I keep my emacs packages in C:/Emacs - (setq load-path (cons "C:/Emacs/aspectj-emacsMode-1.0" load-path)) - (require 'aspectj-mode)</programlisting> +;; I keep my emacs packages in C:/Emacs +(setq load-path (cons "C:/Emacs/aspectj-emacsMode-1.0" load-path)) +(require 'aspectj-mode) + </programlisting> </para> </listitem> @@ -329,17 +330,17 @@ Error in init file: File error: "Cannot open load file", "aspectj-mode" <listitem> <para><emphasis>Symptom</emphasis>: When trying to get a jump menu, - I get the message "No crosscut elements at point" even though + I get the message "No crosscut elements at point" even though there is a [list] on the same line. </para> <para>The caret (point) is probably on or after the list. - To see the crosscut elements you need to hit the jump menu - on the same line that the annotated elements appear as a list - of items surrounded by '[' and ']' on the same line as the - affected declaration. If the caret is on the same line as the - elements and before the list (i.e. not at the end of the - list of elements) the jump menu should work. + To see the crosscut elements you need to hit the jump menu + on the same line that the annotated elements appear as a list + of items surrounded by '[' and ']' on the same line as the + affected declaration. If the caret is on the same line as the + elements and before the list (i.e. not at the end of the + list of elements) the jump menu should work. </para> </listitem> </itemizedlist> diff --git a/docs/devGuideDB/ltw.xml b/docs/devGuideDB/ltw.xml index bc5aac769..969070f44 100644 --- a/docs/devGuideDB/ltw.xml +++ b/docs/devGuideDB/ltw.xml @@ -146,54 +146,53 @@ may define abstract pointcuts (but not abstract methods). The following example shows a simple aop.xml file: </para> <programlisting><![CDATA[ - <aspectj> - - <aspects> - <!-- declare two existing aspects to the weaver --> - <aspect name="com.MyAspect"/> - <aspect name="com.MyAspect.Inner"/> - - <!-- define a concrete aspect inline --> - <concrete-aspect name="com.xyz.tracing.MyTracing" - extends="tracing.AbstractTracing" - precedence="com.xyz.first, *"> - <pointcut name="tracingScope" expression="within(org.maw.*)"/> - </concrete-aspect> - - <!-- Of the set of aspects declared to the weaver - use aspects matching the type pattern "com..*" for weaving. --> - <include within="com..*"/> - - <!-- Of the set of aspects declared to the weaver - do not use any aspects with the @CoolAspect annotation for weaving --> - <exclude within="@CoolAspect *"/> - - </aspects> - - <weaver options="-verbose"> - <!-- Weave types that are within the javax.* or org.aspectj.* - packages. Also weave all types in the foo package that do - not have the @NoWeave annotation. --> - <include within="javax.*"/> - <include within="org.aspectj.*"/> - <include within="(!@NoWeave foo.*) AND foo.*"/> - - <!-- Do not weave types within the "bar" pakage --> - <exclude within="bar.*"/> - - <!-- Dump all types within the "com.foo.bar" package - to the "./_ajdump" folder on disk (for diagnostic purposes) --> - <dump within="com.foo.bar.*"/> - - <!-- Dump all types within the "com.foo.bar" package and sub-packages, - both before are after they are woven, - which can be used for byte-code generated at runtime - <dump within="com.foo.bar..*" beforeandafter="true"/> - </weaver> - - </aspectj> - - ]]></programlisting> +<aspectj> + + <aspects> + <!-- declare two existing aspects to the weaver --> + <aspect name="com.MyAspect"/> + <aspect name="com.MyAspect.Inner"/> + + <!-- define a concrete aspect inline --> + <concrete-aspect name="com.xyz.tracing.MyTracing" + extends="tracing.AbstractTracing" + precedence="com.xyz.first, *"> + <pointcut name="tracingScope" expression="within(org.maw.*)"/> + </concrete-aspect> + + <!-- Of the set of aspects declared to the weaver + use aspects matching the type pattern "com..*" for weaving. --> + <include within="com..*"/> + + <!-- Of the set of aspects declared to the weaver + do not use any aspects with the @CoolAspect annotation for weaving --> + <exclude within="@CoolAspect *"/> + + </aspects> + + <weaver options="-verbose"> + <!-- Weave types that are within the javax.* or org.aspectj.* + packages. Also weave all types in the foo package that do + not have the @NoWeave annotation. --> + <include within="javax.*"/> + <include within="org.aspectj.*"/> + <include within="(!@NoWeave foo.*) AND foo.*"/> + + <!-- Do not weave types within the "bar" pakage --> + <exclude within="bar.*"/> + + <!-- Dump all types within the "com.foo.bar" package + to the "./_ajdump" folder on disk (for diagnostic purposes) --> + <dump within="com.foo.bar.*"/> + + <!-- Dump all types within the "com.foo.bar" package and sub-packages, + both before are after they are woven, + which can be used for byte-code generated at runtime + <dump within="com.foo.bar..*" beforeandafter="true"/> + </weaver> + +</aspectj> +]]></programlisting> <para> The DTD defining the format of this file is available here: @@ -301,37 +300,37 @@ Consider the following: </para> <programlisting><![CDATA[ - package mypack; +package mypack; - @Aspect - public abstract class AbstractAspect { +@Aspect +public abstract class AbstractAspect { - // abstract pointcut: no expression is defined - @Pointcut - abstract void scope(); + // abstract pointcut: no expression is defined + @Pointcut + abstract void scope(); - @Before("scope() && execution(* *..doSome(..))") - public void before(JoinPoint jp) { - .... - } - } - ]]></programlisting> + @Before("scope() && execution(* *..doSome(..))") + public void before(JoinPoint jp) { + .... + } +} +]]></programlisting> <para> This aspect is equivalent to the following in code style: </para> <programlisting><![CDATA[ - package mypack; +package mypack; - public abstract aspect AbstractAspect { +public abstract aspect AbstractAspect { - // abstract pointcut: no expression is defined - abstract pointcut scope(); + // abstract pointcut: no expression is defined + abstract pointcut scope(); - before() : scope() && execution(* *..doSome(..)) { - .... - } - } - ]]></programlisting> + before() : scope() && execution(* *..doSome(..)) { + .... + } +} +]]></programlisting> <para> This aspect (in either style) can be made concrete using <literal>META-INF/aop.xml</literal>. It defines the abstract pointcut <literal>scope()</literal>. When using this mechanism the @@ -361,14 +360,14 @@ The following XML definition shows a valid concrete sub-aspect for the abstract aspects above: </para> <programlisting><![CDATA[ - <aspectj> - <aspects> - <concrete-aspect name="mypack.__My__AbstractAspect" extends="mypack.AbstractAspect"> - <pointcut name="scope" expression="within(yourpackage..*)"/> - </concrete-aspect> - <aspects> - </aspectj> - ]]></programlisting> +<aspectj> + <aspects> + <concrete-aspect name="mypack.__My__AbstractAspect" extends="mypack.AbstractAspect"> + <pointcut name="scope" expression="within(yourpackage..*)"/> + </concrete-aspect> + <aspects> +</aspectj> +]]></programlisting> <para> It is important to remember that the <literal>name</literal> attribute in the <literal>concrete-aspect</literal> directive defines the fully qualified name that will be given to the @@ -381,12 +380,12 @@ as in: </para> <programlisting><![CDATA[ - // exception handling omitted - Class myConcreteAspectClass = Class.forName("mypack.__My__AbstractAspect"); +// exception handling omitted +Class myConcreteAspectClass = Class.forName("mypack.__My__AbstractAspect"); - // here we are using a singleton aspect - AbstractAspect concreteInstance = Aspects.aspectOf(myConcreteAspectClass); - ]]></programlisting> +// here we are using a singleton aspect +AbstractAspect concreteInstance = Aspects.aspectOf(myConcreteAspectClass); +]]></programlisting> </sect2> <sect2 id="concrete-aspect-precedence" xreflabel="concrete-aspect-precedence"> @@ -406,13 +405,13 @@ Consider the following: </para> <programlisting><![CDATA[ - <aspectj> - <aspects> - <concrete-aspect name="mypack.__MyDeclarePrecedence" - precedence="*..*Security*, Logging+, *"/> - </aspects> - </aspectj> - ]]></programlisting> +<aspectj> + <aspects> + <concrete-aspect name="mypack.__MyDeclarePrecedence" + precedence="*..*Security*, Logging+, *"/> + </aspects> +</aspectj> +]]></programlisting> <para> This deployment time definitions is only declaring a precedence rule. You have to remember that the <literal>name</literal> attribute must be a valid fully qualified class name @@ -430,13 +429,13 @@ search path. Everything that can be configured through XML can be configured using a Properties file, with the exception of declarative concrete aspects. For example: </para> <programlisting><![CDATA[ - aspects.names=com.MyAspect,com.MyAspect.Inner - aspects.include=com..* - aspects.exclude=@CoolAspect +aspects.names=com.MyAspect,com.MyAspect.Inner +aspects.include=com..* +aspects.exclude=@CoolAspect - weaver.options=-verbose - weaver.include=javax.* OR org.aspectj.* - ]]></programlisting> +weaver.options=-verbose +weaver.include=javax.* OR org.aspectj.* +]]></programlisting> </sect2> --> @@ -594,8 +593,8 @@ <para> 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): </para> <programlisting><![CDATA[ - -javaagent:pathto/aspectjweaver.jar - ]]></programlisting> +-javaagent:pathto/aspectjweaver.jar +]]></programlisting> </sect2> <sect2 id="jrockit" xreflabel="jrockit"> <title>JRockit with Java 1.3/1.4 (use JVMTI on Java 5)</title> diff --git a/docs/faq/faq.xml b/docs/faq/faq.xml index bcba754d7..d9a236e36 100644 --- a/docs/faq/faq.xml +++ b/docs/faq/faq.xml @@ -17,7 +17,7 @@ --> <article class="faq"> <title>Frequently Asked Questions about AspectJ</title> - <para>Copyright (c) 1997-2001 Xerox Corporation, + <para>Copyright (c) 1997-2001 Xerox Corporation, 2002 Palo Alto Research Center, Incorporated, 2003-2006 Contributors. All rights reserved. </para> @@ -36,27 +36,27 @@ </question> <answer> <para> - AspectJ(tm) is a simple and practical extension to the + AspectJ(tm) is a simple and practical extension to the Java(tm) programming language that adds to Java aspect-oriented programming (AOP) capabilities. AOP allows developers to reap the benefits of modularity for concerns that cut across the natural units of modularity. In object-oriented programs like Java, the natural unit of modularity is the class. In AspectJ, aspects modularize concerns that - affect more than one class. + affect more than one class. </para> - <para>You compile your program using the AspectJ compiler - (perhaps using the supported development environments) - and then run it, + <para>You compile your program using the AspectJ compiler + (perhaps using the supported development environments) + and then run it, supplying a small (< 100K) runtime library. </para> - <para>The AspectJ technologies include - a compiler (<literal>ajc</literal>), - a debugger (<literal>ajdb</literal>), - a documentation generator (<literal>ajdoc</literal>), - a program structure browser (<literal>ajbrowser</literal>), + <para>The AspectJ technologies include + a compiler (<literal>ajc</literal>), + a debugger (<literal>ajdb</literal>), + a documentation generator (<literal>ajdoc</literal>), + a program structure browser (<literal>ajbrowser</literal>), and integration with - Eclipse, Sun-ONE/Netbeans, GNU Emacs/XEmacs, + Eclipse, Sun-ONE/Netbeans, GNU Emacs/XEmacs, JBuilder, and Ant. </para> </answer> @@ -174,12 +174,12 @@ <ulink url="http://www.opensource.org/licenses/mozilla1.1">Mozilla Public License 1.1</ulink>. That documentation is available under a separate license that precludes for-profit or commercial - redistribution. + redistribution. </para> - <para>The runtime jar aspectjrt.jar and its distribution are also covered by the + <para>The runtime jar aspectjrt.jar and its distribution are also covered by the <ulink url="http://www.eclipse.org/org/documents/epl-v10.php">Eclipse Public License</ulink>. </para> - <para>For answers to common licensing questions, see the + <para>For answers to common licensing questions, see the <ulink url="http://www.eclipse.org/legal/eplfaq.php">Eclipse Public License FAQ</ulink>. </para> <para> @@ -194,27 +194,27 @@ <para>AspectJ is based on over ten years of research at <ulink url="http://www.parc.xerox.com"> Xerox Palo Alto Research Center - </ulink> + </ulink> as funded by Xerox, a U.S. Government grant (NISTATP), and a DARPA contract. </para> - <para>It has evolved through open-source releases + <para>It has evolved through open-source releases to a strong user community and now operates as an - open source project at + open source project at <ulink url="http://eclipse.org/aspectj"> http://eclipse.org/aspectj</ulink> The AspectJ team works closely with the community - to ensure AspectJ continues to evolve as an effective + to ensure AspectJ continues to evolve as an effective aspect-oriented programming language and tool set. </para> <para> - The latest release is 1.2 <!-- XXX todo Update me! --> - which can be downloaded from the + The latest release is 1.2 <!-- XXX todo Update me! --> + which can be downloaded from the <ulink url="http://eclipse.org/aspectj">AspectJ project page</ulink>, including sources as described <xref linkend="q:buildingsource"/>. - Development is focused on supporting applications, - improving quality and performance, + Development is focused on supporting applications, + improving quality and performance, enhancing integration with IDE's, and building the next generations of the language. </para> @@ -232,7 +232,7 @@ </question> <answer> <para> - The AspectJ compiler produces programs for any released version of the + The AspectJ compiler produces programs for any released version of the Java platform (jdk1.1 and later). When running, your program classes must be able to reach classes in the small (< 100K) runtime library (aspectjrt.jar) from the distribution. @@ -254,7 +254,7 @@ The <literal>jar</literal> file is installed by executing </para> <programlisting> - java -jar <emphasis>jar file name</emphasis> +java -jar <emphasis>jar file name</emphasis> </programlisting> <para>Do <emphasis role="bold">not</emphasis> try to extract the <literal>jar</literal> file contents and then attempt to execute @@ -263,12 +263,12 @@ thrown.) The AspectJ distribution is not designed to be installed this way. Use the <literal>java -jar</literal> form shown above. </para> - <para>To uninstall, remove the files the installer wrote in your + <para>To uninstall, remove the files the installer wrote in your file system. In most cases, you can delete the top-level install directory (and all contained files), after you remove any new or updated files you want to keep. On Windows, no registry settings were added or changed, so nothing needs to be - undone. Do not install over prior versions, which might have + undone. Do not install over prior versions, which might have different files. Delete the prior version first. </para> </answer> @@ -294,8 +294,8 @@ <emphasis role="bold"> In the development process </emphasis> Use AspectJ to trace or log - interesting information. You can do this by adding - simple AspectJ code that performs logging or tracing. + interesting information. You can do this by adding + simple AspectJ code that performs logging or tracing. This kind of addition may be removed ("unplugged") for the final build since it does not implement a design requirement; the functionality of the system is unaffected by @@ -309,10 +309,10 @@ </emphasis> Use AspectJ to more completely and accurately test the system. Add sophisticated code that can check contracts, - provide debugging support, or implement test strategies. - Like pure development aspects, this code may also be + provide debugging support, or implement test strategies. + Like pure development aspects, this code may also be unplugged from production builds. However, the same code - can often be helpful in diagnosing failures in deployed + can often be helpful in diagnosing failures in deployed production systems, so you may design the functionality to be deployed but disabled, and enable it when debugging. </para> @@ -322,7 +322,7 @@ <emphasis role="bold">As an essential part of your system </emphasis> Use AspectJ to modularize - crosscutting concerns in your system by design. + crosscutting concerns in your system by design. This uses AspectJ to implement logic integral to a system and is delivered in production builds. </para> @@ -342,8 +342,8 @@ </question> <answer> <para>AspectJ products are designed to make it easy to integrate - AspectJ into an existing development process. - Each release includes + AspectJ into an existing development process. + Each release includes Ant tasks for building programs, the AspectJ Development Environment (AJDE) for writing aspects inside popular IDE's, and @@ -369,7 +369,7 @@ <!-- restore ajdb, ajdoc --> </itemizedlist> </para> - <para>For debugging, AspectJ supports JSR-45, which provides a mechanism for + <para>For debugging, AspectJ supports JSR-45, which provides a mechanism for debugging .class files that have multiple source files. Debugger clients and VM's are beginning to support this; see Sun's J2SE 1.4.1 VM and jdb debugger @@ -377,11 +377,11 @@ </para> <para>The AspectJ Development Environment (AJDE) enables programmers to view and navigate the crosscutting structures - in their programs, integrated with existing support in + in their programs, integrated with existing support in popular Java IDE's for viewing and navigating object-oriented structures. For many programmers this provides a deeper understanding of how aspects work to modularize their concerns and permits them - to extend some of their development practices without + to extend some of their development practices without having to abandon their existing tools. </para> <para> @@ -398,8 +398,8 @@ </para> </listitem> <listitem> - <para>Emacs (GNU version 20.3) - and XEmacs (version 21.1 on Unix and 21.4 on Windows), + <para>Emacs (GNU version 20.3) + and XEmacs (version 21.1 on Unix and 21.4 on Windows), in the SourceForge AspectJ for Emacs project <ulink url="http://aspectj4emacs.sourceforge.net"> http://aspectj4emacs.sourceforge.net @@ -528,8 +528,8 @@ </question> <answer> <para> - Aspects for performance monitoring and diagnostic systems, - display updating or notifications generally, security, + Aspects for performance monitoring and diagnostic systems, + display updating or notifications generally, security, context passing, and error handling. </para> </answer> @@ -544,8 +544,8 @@ </question> <answer> <para> - "Scattering" is when similar code is distributed throughout many - program modules. This differs from a component being used by + "Scattering" is when similar code is distributed throughout many + program modules. This differs from a component being used by many other components since it involves the risk of misuse at each point and of inconsistencies across all points. Changes to the implementation may require @@ -558,7 +558,7 @@ </para> <para>"Crosscutting" is how to characterize a concern than spans multiple units of OO modularity - classes and objects. Crosscutting - concerns resist modularization using normal OO constructs, but + concerns resist modularization using normal OO constructs, but aspect-oriented programs can modularize crosscutting concerns. </para> </answer> @@ -630,7 +630,7 @@ <answer> <para>AspectJ enables you to declare members and supertypes of another class in an aspect, subject to Java's type-safety and access rules. These are - visible to other classes only if you declare them as accessible. + visible to other classes only if you declare them as accessible. You can also declare compile-time errors and warnings based on pointcuts. </para> </answer> @@ -782,9 +782,9 @@ <para>There are many mechanisms people use now to implement some crosscutting concerns. But they don't have a way to express the actual structure of the program so you (and your tools) - can reason about it. Using a language enables you to express the - crosscutting in first-class constructs. You can not only avoid the - maintenance problems and structural requirements of some other + can reason about it. Using a language enables you to express the + crosscutting in first-class constructs. You can not only avoid the + maintenance problems and structural requirements of some other mechanisms, but also combine forms of crosscutting so that all the mechanisms for a particular concern are one piece of code. </para> @@ -808,7 +808,7 @@ distinguished by the fact that it was designed from the ground up to be compatible with Java. </para> - <para>For more alternatives for aspect-oriented programming, see + <para>For more alternatives for aspect-oriented programming, see <ulink url="http://aosd.net">http://aosd.net</ulink>. </para> </answer> @@ -823,7 +823,7 @@ <answer> <para>Reflective and aspect-oriented languages have an important similarity: both provide programming support for dealing with - crosscutting concerns. In this sense reflective systems proved + crosscutting concerns. In this sense reflective systems proved that independent programming of crosscutting concerns is possible. </para> @@ -876,22 +876,22 @@ aspect. </question> <answer> <para> - Some AOP techniques are presented as "dynamic" because the weaving - occurs when classes are loaded, because aspects can be configured + Some AOP techniques are presented as "dynamic" because the weaving + occurs when classes are loaded, because aspects can be configured in a separate XML file before launch, or because some advice depends on runtime reflection. They are said to be more flexible than AspectJ. </para> <para> - This is a misconception. First, the AspectJ 1.1 weaver has always + This is a misconception. First, the AspectJ 1.1 weaver has always supported weaving at compile-time or class-load-time. Weaving at compile-time reduces application launch and running time, and it helps IDE's offer support for tracking down weaving errors and understanding the impact of aspects on a system. On the other hand, weaving at load-time simplifies build and deployment. - Before AspectJ 1.2, the user had to write a class loader that used the - weaver API to weave at load time; since 1.2, AspectJ comes with a - command-line launcher to support weaving at class-load-time without + Before AspectJ 1.2, the user had to write a class loader that used the + weaver API to weave at load time; since 1.2, AspectJ comes with a + command-line launcher to support weaving at class-load-time without any other changes to a build configuration. In AspectJ 5, we expect to get a similar level of support as AspectWerkz, and to exploit the class bytecode weaving hook available in Java 5 VM's. @@ -900,10 +900,10 @@ aspect. Second, AspectJ programs, like Java programs generally, can be written to support any level of XML configuration or to depend on runtime reflection. There are some benefits to using AspectJ; - e.g., the proceed() form within around advice simplifies a lot of - the work that otherwise would go into writing a generalized - interceptor, without introducing many of the runtime errors that can - result from interceptors. + e.g., the proceed() form within around advice simplifies a lot of + the work that otherwise would go into writing a generalized + interceptor, without introducing many of the runtime errors that can + result from interceptors. For AspectJ examples of configurable or reflection-dependent programs, see the sample code linked off the AspectJ documentation page or the examples discussed on the mailing list, e.g., @@ -914,9 +914,9 @@ aspect. </qandaentry> <qandaentry> <question id="q:aopandxp" - xreflabel="Q:What is the relationship between AOP and + xreflabel="Q:What is the relationship between AOP and XP (extreme programming AKA agile methods)?"> - <para>What is the relationship between AOP and + <para>What is the relationship between AOP and XP (extreme programming AKA agile methods)? </para> </question> @@ -1003,27 +1003,27 @@ aspect. <itemizedlist> <listitem> <para>AspectJ is an <emphasis>addition</emphasis> to - Java, and can be introduced into a project - in a way that limits risk. + Java, and can be introduced into a project + in a way that limits risk. See <xref linkend="q:startUsingAJ"/> for some suggestions on how to do this. </para> </listitem> <listitem> <para>The AspectJ compiler accepts standard Java as - input and produces standard Java bytecode as output. - In 1.0, an optional mode produces standard Java source code + input and produces standard Java bytecode as output. + In 1.0, an optional mode produces standard Java source code which may then be compiled with any compliant Java compiler - (e.g. Sun's <literal>javac</literal> compiler + (e.g. Sun's <literal>javac</literal> compiler or IBM's <literal>jikes</literal> compiler). - In 1.1, an optional mode accepts standard Java bytecode - from any compliant Java compiler + In 1.1, an optional mode accepts standard Java bytecode + from any compliant Java compiler and weaves in the aspects to produce new bytecode. </para> </listitem> <listitem> <para>AspectJ is available under a non-proprietary, open source license, - either the + either the <ulink url="http://www.opensource.org/licenses/mozilla1.1"> Mozilla Public License 1.1</ulink> for 1.0 or the @@ -1041,7 +1041,7 @@ aspect. </para> </listitem> <listitem> - <para>A number of significant open-source projects and industry + <para>A number of significant open-source projects and industry products use AspectJ successfully. One list is kept on <ulink url="http://www.aosd.net/wiki/index.php?title=FAQ"> the AOSD FAQ</ulink>, and more appear on the mailing @@ -1083,7 +1083,7 @@ aspect. important as knowing how to measure it, and neither is always apparent. </para> - <para>We aim for the performance of our implementation of AspectJ to + <para>We aim for the performance of our implementation of AspectJ to be on par with the same functionality hand-coded in Java. Anything significantly less should be considered a bug. </para> @@ -1097,14 +1097,14 @@ aspect. <para>Though we cannot show it without a benchmark suite, we believe that code generated by AspectJ has negligible performance overhead. Inter-type member and parent introductions should have very little - overhead, and advice should only have some indirection which + overhead, and advice should only have some indirection which could be optimized away by modern VM's. </para> - <para>The <literal>ajc</literal> compiler will use static typing information - to only insert the advice and dynamic pointcut tests that are absolutely necessary. - Unless you use 'thisJoinPoint' or 'if', the main dynamic checks will be - 'instanceof' checks which are generally quite fast. - These checks will only be inserted when they can not be inferred from + <para>The <literal>ajc</literal> compiler will use static typing information + to only insert the advice and dynamic pointcut tests that are absolutely necessary. + Unless you use 'thisJoinPoint' or 'if', the main dynamic checks will be + 'instanceof' checks which are generally quite fast. + These checks will only be inserted when they can not be inferred from the static type information. </para> <para>When measuring performance, write AspectJ code @@ -1130,18 +1130,18 @@ aspect. Well I haven't yet seen a language in which you can't write bad code! </para> <para> - But seriously, most AspectJ users find that just like when they learned - OO, it takes a while to really get the hang of it. They tend to start - in the usual way, by copying canonical examples and experimenting with + But seriously, most AspectJ users find that just like when they learned + OO, it takes a while to really get the hang of it. They tend to start + in the usual way, by copying canonical examples and experimenting with variations on them. </para> <para> - But users also find that rather than being dangerous, AspectJ helps them - write code that is more clear and has better encapsulation -- once they - understand the kind of modularity AspectJ supports. There are several - good papers that talk about this (see below), but here's a basic point - to keep in mind: when properly used, AspectJ makes it possible program - in a modular way, something that would otherwise be spread throughout + But users also find that rather than being dangerous, AspectJ helps them + write code that is more clear and has better encapsulation -- once they + understand the kind of modularity AspectJ supports. There are several + good papers that talk about this (see below), but here's a basic point + to keep in mind: when properly used, AspectJ makes it possible program + in a modular way, something that would otherwise be spread throughout the code. Consider the following code, adapted from the AspectJ tutorial: </para> <programlisting> @@ -1157,30 +1157,30 @@ aspect PublicErrorLogging { } </programlisting> <para> - The effect of this code is to ensure that whenever any public method of - an interface or class in the <literal>com.xerox</literal> package + The effect of this code is to ensure that whenever any public method of + an interface or class in the <literal>com.xerox</literal> package throws an error, that error is logged before being thrown to its caller. </para> <para> - Of course in the alternative implementation a large number of methods + Of course in the alternative implementation a large number of methods have a try/catch around their body. </para> <para> - The AspectJ implementation of this crosscutting concern is clearly - modular, whereas the other implementation is not. As a result, if you - want to change it, its easier in the AspectJ implementation. For - example, if you also want to pass the name of the method, or its - arguments to <literal>log.write</literal>, you only have to edit + The AspectJ implementation of this crosscutting concern is clearly + modular, whereas the other implementation is not. As a result, if you + want to change it, its easier in the AspectJ implementation. For + example, if you also want to pass the name of the method, or its + arguments to <literal>log.write</literal>, you only have to edit one place in the AspectJ code. </para> <para> - This is just a short example, but I hope it shows how what happens - with AOP and AspectJ is that the usual benefits of modularity are - achieved for crosscutting concerns, and that leads to better code, + This is just a short example, but I hope it shows how what happens + with AOP and AspectJ is that the usual benefits of modularity are + achieved for crosscutting concerns, and that leads to better code, not more dangerous code. </para> <para> - One paper someone else just reminded me of that talks some more + One paper someone else just reminded me of that talks some more about this is: <ulink url="http://www.cs.ubc.ca/~kdvolder/Workshops/OOPSLA2001/submissions/12-nordberg.pdf"> http://www.cs.ubc.ca/~kdvolder/Workshops/OOPSLA2001/submissions/12-nordberg.pdf @@ -1192,7 +1192,7 @@ aspect PublicErrorLogging { <question id="q:encapsulation" xreflabel="Q:Why does AspectJ permit aspects to access and add members of another type?"> <para> - Why does AspectJ permit aspects to access and add members of another type? + Why does AspectJ permit aspects to access and add members of another type? Isn't that violating OO encapsulation? </para> </question> @@ -1220,25 +1220,25 @@ aspect PublicErrorLogging { known as open classes. </para> <para> - Open classes have been used in many languages prior to AspectJ, - including CLOS, Python, Smalltalk, Objective-C, and others. - Building from Java, introduction in AspectJ provides better - name hygiene and access control than prior languages. - Introduced code obeys all of Java's normal accessibility rules - for its lexical location in the aspect that it is introduced from. - Such code can not even see, much less access, private members of + Open classes have been used in many languages prior to AspectJ, + including CLOS, Python, Smalltalk, Objective-C, and others. + Building from Java, introduction in AspectJ provides better + name hygiene and access control than prior languages. + Introduced code obeys all of Java's normal accessibility rules + for its lexical location in the aspect that it is introduced from. + Such code can not even see, much less access, private members of the class it is introduced into. Further, introductions can be declared private to the aspect, so they are not visible to other clients of the class. </para> <para> Privileged aspects do permit access to private members of another - class. They are a response to the very few cases where developers + class. They are a response to the very few cases where developers genuinely need such access (typically for testing purposes where it access is necessary), but it would be more risky to open access by putting the aspect in the same package, adding test code, or changing - access in the target class. We recommend using privileged aspects - only as necessary, and believe that marking them "privileged" makes + access in the target class. We recommend using privileged aspects + only as necessary, and believe that marking them "privileged" makes any potential misuse apparent. </para> </answer> @@ -1261,7 +1261,7 @@ aspect PublicErrorLogging { <listitem> <para> JSP: It is possible to use AspectJ to affect code in JSPs by precompiling - them into Java sources and compiling these with ajc. This can be used, e.g., to + them into Java sources and compiling these with ajc. This can be used, e.g., to customize displays by turning on and off custom JSP taglibs. The mapping from a given jsp source to java package and class name is not standardized, which means doing this imposes dependencies on specific container versions. @@ -1269,21 +1269,21 @@ aspect PublicErrorLogging { </listitem> <listitem> <para> - EJB: AspectJ supports a wide variety of aspects for EJBs. It can be used for + EJB: AspectJ supports a wide variety of aspects for EJBs. It can be used for logging, tracing, debugging, error handling by layers, correlated method-level interception (e.g., chargebacks), metering, fine-grained transactions, etc. Indeed, it can be used to enforce adherence to coding restrictions within an - EJB (e.g., not using java.io, creating a class loader, or listening on + EJB (e.g., not using java.io, creating a class loader, or listening on sockets) using <literal>declare error</literal>. </para> </listitem> </itemizedlist> <para> The basic limitations are that there is no built-in support for writing J2EE - analogs for AspectJ extensions to Java, like distributed aspects, distributed + analogs for AspectJ extensions to Java, like distributed aspects, distributed cflow, or managing state between invocations. These don't prevent one from using - AspectJ to do useful intra-container implementation, nor need they prevent one - from building distributed support, state management, and inter-component + AspectJ to do useful intra-container implementation, nor need they prevent one + from building distributed support, state management, and inter-component implementations that leverage AspectJ. It just takes some work. In more detail: </para> <para> @@ -1296,21 +1296,21 @@ aspect PublicErrorLogging { To avoid this problem, you can use the -XaddSafePrefix flag when compiling with ajc. </para> <para> - EJB components may be invoked remotely, and containers may passivate and + EJB components may be invoked remotely, and containers may passivate and pool EJB's. Servlets have similar limitations, and in both cases the - lifespan of the defining class loader is implementation-dependent + lifespan of the defining class loader is implementation-dependent (though it must span the operation of a particular request). </para> <para> - Being limited by lifecycle and namespace, the AspectJ 1.0 implementation - supports aspects that operate through non-remote invocations during the lifetime - of the namespace for a particular + Being limited by lifecycle and namespace, the AspectJ 1.0 implementation + supports aspects that operate through non-remote invocations during the lifetime + of the namespace for a particular deployment unit compiled in its entirety by the ajc compiler. This means AspectJ supports common aspects only within a single local runtime namespace (usually implemented as a class loader hierarchy). </para> <para> - Further, AspectJ recognizes language-level join points (object initialization, + Further, AspectJ recognizes language-level join points (object initialization, method calls, etc.), not their EJB analogs (ejb find or create methods...). These lead to the following consequences: </para> @@ -1327,7 +1327,7 @@ aspect PublicErrorLogging { EJB lifecycles are different from object lifecycles, so perthis and pertarget aspects will make little sense. They do not work in the current implementation, which uses synchronized methods - to ensure a correct association in threaded environments + to ensure a correct association in threaded environments (EJB's may not have synchronized methods). </para> </listitem> @@ -1336,7 +1336,7 @@ aspect PublicErrorLogging { Percflow or percflowbelow aspects are restricted to a chain of non-remote invocations. While EJB 2.0 permits declaring an interface local, this information is not available to the AspectJ compiler today. - For same reasons as stated above fore perthis, these will not work even + For same reasons as stated above fore perthis, these will not work even in the EJB container. </para> </listitem> @@ -1369,9 +1369,9 @@ aspect PublicErrorLogging { <para> The EJB container is permitted to change class loaders, even between invocations of a particular EJB component (by passivating and - activating with a new class loader). In this case, instances of singleton - aspects will not operate over multiple invocations of the component, or that - static initialization join point recur for a given class as it is re-loaded. + activating with a new class loader). In this case, instances of singleton + aspects will not operate over multiple invocations of the component, or that + static initialization join point recur for a given class as it is re-loaded. This behavior depends on the container implementation. </para> </listitem> @@ -1426,22 +1426,22 @@ aspect PublicErrorLogging { | CDC | | CLDC | ------------------------------------------ | Java | ------------------------------------------- +------------------------------------------ </programlisting> Which configuration you have dictates the restrictions when - running AspectJ compiled programs. + running AspectJ compiled programs. </para> <para> If you're running with a profile which sits on top of CDC then - there are not, as far as we are aware, any restrictions when - running AspectJ compiled code on this flavour of J2ME. + there are not, as far as we are aware, any restrictions when + running AspectJ compiled code on this flavour of J2ME. </para> <para> If you're running with a profile sitting on top of CLDC 1.1 you are currently unable to use the <literal>thisJoinPoint, thisJoinPointStaticPart</literal> and <literal> - thisEnclosingJoinPointStaticPart</literal> variables, the - <literal>cflow</literal> and <literal>cflowbelow</literal> + thisEnclosingJoinPointStaticPart</literal> variables, the + <literal>cflow</literal> and <literal>cflowbelow</literal> pointcuts and the <literal>percflow</literal> and <literal> percflowbelow</literal> perClauses. </para> @@ -1463,65 +1463,65 @@ aspect PublicErrorLogging { For more discussion and to raise any issues you have with AspectJ and J2ME, refer to <ulink url="https://bugs.eclipse.org/bugs/show_bug.cgi?id=92933"> - bugzilla entry 92933</ulink>. + bugzilla entry 92933</ulink>. </para> </answer> </qandaentry> <qandaentry> <question id="q:aopinjava" xreflabel="Q: Are you working to put AOP into Java?"> - <para> Are you working to put AOP into Java? - It seems that every AOP toolset currently uses proprietary mechanisms + <para> Are you working to put AOP into Java? + It seems that every AOP toolset currently uses proprietary mechanisms to describe point-cuts, etc. </para> </question> <answer> <para> - We are working on standardization, but it's - a question of timing/ripeness (imagine going from thousands of users - to millions). (See <xref linkend="q:standardization"/>.) We believe + We are working on standardization, but it's + a question of timing/ripeness (imagine going from thousands of users + to millions). (See <xref linkend="q:standardization"/>.) We believe AspectJ addresses this question in the best way possible now: <itemizedlist> <listitem> <para> - It's open-source. Rather than being proprietary or controlled by a + It's open-source. Rather than being proprietary or controlled by a vendor, it's available for anybody to use and build upon, forever. </para> </listitem> <listitem> <para> - AspectJ is not a set of mechanisms, it's a language. It is currently - implemented using certain techniques, but there's nothing that prevents - it from being implemented with other techniques. That means users can + AspectJ is not a set of mechanisms, it's a language. It is currently + implemented using certain techniques, but there's nothing that prevents + it from being implemented with other techniques. That means users can adopt the language with confidence that implementations will get better. </para> </listitem> <listitem> <para> - There is no engineering need to change Java. The AspectJ language uses - the join point model already in Java, so there is no need to extend the - programming model. Our implementation produces valid Java bytecode, which - runs in any compliant J2SE VM and supports standard debuggers for those VM's - that support JSR-45 (debugging support for multi-language/multi-file sources). - This is a huge benefit to Sun since Sun must be extremely cautious - about extensions to the language or VM; before adopting AOP, Sun should + There is no engineering need to change Java. The AspectJ language uses + the join point model already in Java, so there is no need to extend the + programming model. Our implementation produces valid Java bytecode, which + runs in any compliant J2SE VM and supports standard debuggers for those VM's + that support JSR-45 (debugging support for multi-language/multi-file sources). + This is a huge benefit to Sun since Sun must be extremely cautious + about extensions to the language or VM; before adopting AOP, Sun should demand the kind of actual-proof that AspectJ implementations offer. </para> </listitem> <listitem> <para> - On the issue of "proprietary mechanisms to describe pointcuts, etc.": Any AOP - has to have some language to describe pointcuts and the like ("pointcuts" - of course being the AspectJ term). Users would like to have one language - (to avoid having to learn or transform between many languages) and the - choice of multiple implementations (tailored for a configuration, subject + On the issue of "proprietary mechanisms to describe pointcuts, etc.": Any AOP + has to have some language to describe pointcuts and the like ("pointcuts" + of course being the AspectJ term). Users would like to have one language + (to avoid having to learn or transform between many languages) and the + choice of multiple implementations (tailored for a configuration, subject to competitive pressure, etc.). That's what AspectJ offers. </para> </listitem> <listitem> <para> - That said, we believe the AspectJ extensions to Java could form the basis - for bringing AOP to Java; when that happens, there will be engineering + That said, we believe the AspectJ extensions to Java could form the basis + for bringing AOP to Java; when that happens, there will be engineering opportunities to make the implementation and tool support better. </para> </listitem> @@ -1559,7 +1559,7 @@ aspect PublicErrorLogging { </para> </answer> </qandaentry> - + <qandaentry> <question id="q:mailingLists" xreflabel="Q: What mailing lists are there?"> @@ -1567,7 +1567,7 @@ aspect PublicErrorLogging { </question> <answer> <para> - The AspectJ users mailing list + The AspectJ users mailing list (<literal>aspectj-users@eclipse.org</literal>) provides an informal network of AspectJ language users who can answer usage questions about AspectJ programs @@ -1576,7 +1576,7 @@ aspect PublicErrorLogging { or how to write Ant or shell scripts to invoke the tools. </para> <para> - The AspectJ developers mailing list + The AspectJ developers mailing list (<literal>aspectj-dev@eclipse.org</literal>) provides an informal network of AspectJ technology experts who aim to understand the technology behind AspectJ. @@ -1587,15 +1587,15 @@ aspect PublicErrorLogging { </para> <para> For both mailing lists, only subscribed members may post messages. - To subscribe, visit the + To subscribe, visit the <ulink url="http://eclipse.org/aspectj">AspectJ web site</ulink>. </para> <para> - There you can also subscribe to + There you can also subscribe to <literal>aspectj-announce@eclipse.org</literal>, a low-traffic list containing only announcements about significant AspectJ events and product releases. - To get on a similar list for aspect-oriented software + To get on a similar list for aspect-oriented software development generally, see <ulink url="http://aosd.net">http://aosd.net</ulink>. </para> @@ -1635,19 +1635,19 @@ aspect PublicErrorLogging { </question> <answer> <para>You need to specify to the compiler the files that - contain your aspects and the files that contain the + contain your aspects and the files that contain the types affected by your aspects. See <xref linkend="q:knowWhenAspectsAffectClasses"/>. The AspectJ compiler will not search the source path for types that may be affected (unlike Javac and Jikes). In AspectJ 1.0, ajc requires all code to be in source form; in AspectJ 1.1, Java and AspectJ code may be in either source - or binary form. + or binary form. </para> <para>In some cases you should compile your entire system all at once. If this is too slow, then you can try to make reasonable divisions - between sets of source files whose aspects do not interact to - achieve a shorter compile cycle (particularly for development + between sets of source files whose aspects do not interact to + achieve a shorter compile cycle (particularly for development aspects). If you have aspects that apply to different modules, you can try compiling them into a binary form and using them to weave each module. However, if you get any problems @@ -1655,7 +1655,7 @@ aspect PublicErrorLogging { the entire system. </para> <para> - For more information, see the + For more information, see the <ulink url="devguide/index.html"> Development Environment Guide</ulink> <ulink url="devguide/ajc-ref.html"> @@ -1673,21 +1673,21 @@ aspect PublicErrorLogging { </question> <answer> <para> - Yes, use the argfile option to ajc. List source - files in a line-delimited text file and direct ajc to that + Yes, use the argfile option to ajc. List source + files in a line-delimited text file and direct ajc to that file using <literal>-argfile</literal> or <literal>@</literal>: </para> <programlisting>ajc @sources.lst ajc -argfile sources.lst </programlisting> - <para>Another way in AspectJ 1.1 is to use the + <para>Another way in AspectJ 1.1 is to use the <literal>-sourceroots</literal> options, which reads all source files in a given set of directories: </para> <programlisting>ajc -sourceroots "src;testsrc" </programlisting> <para> - For more information, see the + For more information, see the <ulink url="devguide/index.html"> Development Environment Guide</ulink> <ulink url="devguide/ajc-ref.html"> @@ -1710,7 +1710,7 @@ ajc -argfile sources.lst can find to run it on, the shorter your compile times will be. At a minimum you need to use a Java 2 or later JVM to run the compiler (J2SE 1.3 for AspectJ 1.1). - We realize that this constraint can be a problem for users who + We realize that this constraint can be a problem for users who don't currently have a Java 2 JVM available. We're sorry for the inconvenience, but we had to make the hard decision that the advantages of being able to rely on Java 2 were worth the cost of @@ -1797,7 +1797,7 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ <qandaentry> <question id="q:assert" xreflabel="Q:Does the ajc compiler support the assert keyword in Java 1.4?"> - <para>Does the <literal>ajc</literal> compiler support + <para>Does the <literal>ajc</literal> compiler support the <literal>assert</literal> keyword in Java 1.4? </para> </question> @@ -1815,7 +1815,7 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ <qandaentry> <question id="q:generics" xreflabel="Q:Does the ajc compiler support generics and the other new language features of Java 5?"> - <para>Does the <literal>ajc</literal> compiler support + <para>Does the <literal>ajc</literal> compiler support generics and the other new language features of Java 5? </para> </question> @@ -1837,19 +1837,19 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ </para> </question> <answer> - <para>Yes. Both <literal>ajc</literal> and + <para>Yes. Both <literal>ajc</literal> and <literal>aspectjrt.jar</literal> should work with versions - of aspect code and libraries back to AspectJ 1.2.1. + of aspect code and libraries back to AspectJ 1.2.1. Any aspects should be deployed - with the same version of <literal>aspectjrt.jar</literal> + with the same version of <literal>aspectjrt.jar</literal> they were compiled with. For more information, see the <ulink url="devguide/index.html"> Development Environment Guide</ulink> <ulink url="devguide/ajc-ref.html"> Reference for ajc</ulink> - and + and <ulink url="devguide/deployment.html"> - Deployment notes</ulink> section on + Deployment notes</ulink> section on <ulink url="devguide/versionCompatibility.html"> Version compatibility</ulink>. </para> @@ -1897,12 +1897,12 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ </question> <answer> <para>In AspectJ 1.0, - the PARSER for ajc is written by hand. This choice was made with full - awareness of the generator tools out there. (Jim had for example used - the excellent javacc tool for building the parser for JPython (now Jython)). - One of the reasons that AspectJ uses a hand-written parser is that using - javacc taught Jim about the LL-k design for parsers (pioneered by antlr). - As opposed to the state-machine parsers produced by yacc, these parsers are + the PARSER for ajc is written by hand. This choice was made with full + awareness of the generator tools out there. (Jim had for example used + the excellent javacc tool for building the parser for JPython (now Jython)). + One of the reasons that AspectJ uses a hand-written parser is that using + javacc taught Jim about the LL-k design for parsers (pioneered by antlr). + As opposed to the state-machine parsers produced by yacc, these parsers are very readable and writable by humans. </para> <para> @@ -1911,55 +1911,55 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ <itemizedlist> <listitem> <para> - Antlr's support for unicode in the lexer is still immature and this makes - using it with Java challenging. This was an even bigger issue 3 years ago + Antlr's support for unicode in the lexer is still immature and this makes + using it with Java challenging. This was an even bigger issue 3 years ago when we started on the Java implementation of ajc. </para> </listitem> <listitem> <para> - While javacc is freely available, it is not Open Source. Depending on a - closed-source tool to build an Open Source compiler would reduce some + While javacc is freely available, it is not Open Source. Depending on a + closed-source tool to build an Open Source compiler would reduce some of the transparency and control of open-source. </para> </listitem> </itemizedlist> <para> - There were also several things that were easier to implement with + There were also several things that were easier to implement with a hand-written parser than with any of the exiting tools. </para> <itemizedlist> <listitem> <para> - Semi-keywords -- it's important to us that - "every legal Java program is also a legal AspectJ program." - This wouldn't be true if we made 'before' and 'call' full keywords in - AspectJ. It is easier to support these sorts of semi-keywords with a - hand-written parser. (Note: ajc-1.0.x handles 'aspect' and 'pointcut' - slightly specially which can break a few unusual pure Java programs. + Semi-keywords -- it's important to us that + "every legal Java program is also a legal AspectJ program." + This wouldn't be true if we made 'before' and 'call' full keywords in + AspectJ. It is easier to support these sorts of semi-keywords with a + hand-written parser. (Note: ajc-1.0.x handles 'aspect' and 'pointcut' + slightly specially which can break a few unusual pure Java programs. This is a compiler limitation that will be fixed in a future release.) </para> </listitem> <listitem> <para> - Deprecated syntax warnings -- the syntax of AspectJ - changed many times from version 0.2 to the 1.0 release. It was easier - to provide helpful warning messages for these changes with our + Deprecated syntax warnings -- the syntax of AspectJ + changed many times from version 0.2 to the 1.0 release. It was easier + to provide helpful warning messages for these changes with our hand-written parser. </para> </listitem> <listitem> <para> - Grammar modularity -- We like being able to have + Grammar modularity -- We like being able to have AspectJParser extend JavaParser. </para> </listitem> <listitem> - <para> - Part of the grammar for AspectJ is extremely hard for existing tools to - capture. This is the type pattern syntax, i.e. "com.xerox..*.*(..)". - The sort of case that gives standard parser generators fits is something - like "*1.f(..)" which no one would ever write, but which must be + <para> + Part of the grammar for AspectJ is extremely hard for existing tools to + capture. This is the type pattern syntax, i.e. "com.xerox..*.*(..)". + The sort of case that gives standard parser generators fits is something + like "*1.f(..)" which no one would ever write, but which must be supported for a consistent language. </para> <para> @@ -2056,19 +2056,19 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ <literal>set</literal>, <literal>initialiation</literal>, and <literal>staticinitialiation</literal>.) - The compiler will list the static code points which will be + The compiler will list the static code points 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: <programlisting> - declare warning: get(* Foo.*) && within(Bar) - : "reading Foo state from Bar"; +declare warning: get(* Foo.*) && within(Bar) + : "reading Foo state from Bar"; </programlisting> </para> <para> When you are running your program, you can trace advice as it executes. This - enables you to identify advice on join points picked out + enables you to identify advice on join points picked out dynamically, which cannot be reflected precisely by IDE support. For a related tracing question, see <xref linkend="q:seeingjoinpoints"/> @@ -2096,7 +2096,7 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ The AspectJ team directly provided components for JBuilder, Forte, and Emacs and supported the open-source AspectJ plugin project at <ulink url="http://eclipse.org/ajdt">http://eclipse.org/ajdt</ulink> - which uses the AJDE API support for IDE's. + which uses the AJDE API support for IDE's. Supporting new IDE's is a matter of building on the AJDE API's, mostly likely adopting one of the existing open-source IDE extensions as a design template. @@ -2106,7 +2106,7 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ <itemizedlist> <title></title> <listitem> - <para>IDEA/IntelliJ has an enthusiastic community and + <para>IDEA/IntelliJ has an enthusiastic community and the developers are working on an extensibility API - <ulink url="http://intellij.com">http://intellij.com</ulink> </para> @@ -2151,7 +2151,7 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ <qandaentry> <question id="q:hybridbuilds" xreflabel="Q:Setting up hybrid builds"> - <para>I want the aspects for development builds but + <para>I want the aspects for development builds but remove them for production builds. How can I set up the build system so they are unpluggable? And so I use <literal>javac</literal> in my production build? @@ -2159,39 +2159,39 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ </question> <answer> <para> - If you are using development-time-only aspects - aspects that only - exist when you are developing the code, not when you ship it - + If you are using development-time-only aspects - aspects that only + exist when you are developing the code, not when you ship it - you can 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: </para> <programlisting> - -- file "production.lst": - One.java - two/Three.java - ... +-- file "production.lst": +One.java +two/Three.java +... - -- file "tracing.lst": - trace/Library.java - Trace.java +-- file "tracing.lst": +trace/Library.java +Trace.java - -- file "development.lst": - @production.lst - @tracing.lst +-- file "development.lst": +@production.lst +@tracing.lst </programlisting> <para> Then your development build can use <literal>ajc</literal>: </para> <programlisting> - ajc @development.lst +ajc @development.lst </programlisting> <para> - And your development build can use + And your development build can use <literal>ajc</literal> or <literal>javac</literal> or <literal>jikes</literal>: </para> <programlisting> - jikes @production.lst +jikes @production.lst </programlisting> </answer> </qandaentry> @@ -2204,12 +2204,12 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ </question> <answer> <para> - Aspects apply to everything in a namespace, as if everything is + Aspects apply to everything in a namespace, as if everything is compiled together. - Sometimes you can break the build down into separate steps without breaking + Sometimes you can break the build down into separate steps without breaking this model, but we haven't stated exactly where it could break because it depends on the interactions between all types. - You can try the approaches below, but remember to rebuild + You can try the approaches below, but remember to rebuild everything in one go if there are problems. </para> <para> @@ -2222,45 +2222,41 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ Next is the case where the aspects make changes to a common library that 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 + common library can be built using ajc, and used on the classpath for the module builds: - <programlisting> -<![CDATA[ - ajc -outjar common.jar -sourceroots "aspectj-src:src" ... - cd ../otherProject - javac -classpath "../common/common.jar:${aspectjrt.jar}" {src} -]]> - </programlisting> + <programlisting><![CDATA[ +ajc -outjar common.jar -sourceroots "aspectj-src:src" ... +cd ../otherProject +javac -classpath "../common/common.jar:${aspectjrt.jar}" {src} +]]></programlisting> </para> <para> - Combining these last two, + Combining these last two, there's the case where a common set of aspects should affect two or more modules that are in a dependency relationship - to one another. It should work to reuse the aspects + to one another. It should work to reuse the aspects in binary form for each compile, in dependency order: - - <programlisting> -<![CDATA[ - ajc -outjar common-aspects.jar - -sourceroots "aspectj-src" ... - ajc -outjar common.jar - -sourceroots "src" - -aspectpath common-aspects.jar ... + <programlisting><![CDATA[ +ajc -outjar common-aspects.jar + -sourceroots "aspectj-src" ... - cd ../module1 - ajc -outjar module1.jar - -sourceroots "src" - -classpath common.jar - -aspectpath ../common-aspects.jar ... +ajc -outjar common.jar + -sourceroots "src" + -aspectpath common-aspects.jar ... - cd ../module2 - ajc -outjar module2.jar - -sourceroots "src" - -classpath "common.jar;../module1.jar" - -aspectpath ../common-aspects.jar ... -]]> - </programlisting> +cd ../module1 +ajc -outjar module1.jar + -sourceroots "src" + -classpath common.jar + -aspectpath ../common-aspects.jar ... + +cd ../module2 +ajc -outjar module2.jar + -sourceroots "src" + -classpath "common.jar;../module1.jar" + -aspectpath ../common-aspects.jar ... +]]></programlisting> </para> <para> If two modules are visibly affected by aspects and @@ -2286,23 +2282,21 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ <answer> <para> Just incrementally-compile the whole system. - Specify to ajc the modules as multiple source roots + Specify to ajc the modules as multiple source roots (or input jars if you are weaving libraries). </para> <para> - In Eclipse's AJDT, you can create a top-level project with symbolic + In Eclipse's AJDT, you can create a top-level project with symbolic links out to the sources: - - <programlisting> -<![CDATA[ - app-assembly/ - {link common/aspects} - {link common/src} - {link module1/src} - ... -]]> - </programlisting> - + + <programlisting><![CDATA[ +app-assembly/ +{link common/aspects} +{link common/src} +{link module1/src} +... +]]></programlisting> + Then everything is part of one huge incremental compile. Also, you can close this master project and work the others using the Java compiler or AJDT. @@ -2320,17 +2314,17 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ <question id="q:methodsignatures" xreflabel="Q:Is it possible to change methods by introducing keywords, adding parameters, or changing the throws clause?"> <para>Is it possible to change methods by introducing keywords (like - <literal>synchronized</literal>), adding parameters, + <literal>synchronized</literal>), adding parameters, or changing the "throws" clause? </para> </question> <answer> <para>AspectJ does not enable you to change the signature of a method, - but you can (by express declaration) work around some + but you can (by express declaration) work around some limits imposed by the signature. You can convert a checked exception to unchecked using <literal>declare soft</literal>, privileged aspects - have access to private methods, and you can use a percflow aspect to - ferry additional state to a callee without changing intervening + have access to private methods, and you can use a percflow aspect to + ferry additional state to a callee without changing intervening signatures. For more details, see <ulink url="progguide/index.html">The AspectJ Programming Guide</ulink>. In the case of <literal>synchronized</literal>, @@ -2356,25 +2350,24 @@ ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \ <answer> <para> You can trace them using using an aspect. - For example, you can start logging at a particular method call and + For example, you can start logging at a particular method call and see what join points occur after the call and before it returns. </para> <para> Here's some code Jim Hugunin wrote to trace join points - and posted to the users list. To reuse the aspect, + and posted to the users list. To reuse the aspect, define a subaspect and implement the pointcuts, for example: <programlisting> - aspect JoinPointSampleAspect extends aj.TraceJoinPoints { - protected pointcut entry() : + protected pointcut entry() : execution(static void JoinPointSample.main(String[])); - protected pointcut exit() : + protected pointcut exit() : call(static void JoinPointSampleAspect.exit()); public static void main (String[] args) { - JoinPointSample.main(args); - JoinPointSampleAspect.exit(); - } + JoinPointSample.main(args); + JoinPointSampleAspect.exit(); + } public static void exit() {} } @@ -2384,8 +2377,7 @@ class JoinPointSample { </programlisting> </para> <para>Here's the aspect: - <programlisting> -<![CDATA[ + <programlisting><![CDATA[ /* TraceJoinPoints.java */ package aj; @@ -2494,8 +2486,7 @@ public abstract aspect TraceJoinPoints { while (i-- > 0) out.print(" "); } } -]]> - </programlisting> +]]></programlisting> </para> <para>Note that if you are using AspectJ 1.0, the line starting with <literal>declare precedence</literal> @@ -2548,8 +2539,8 @@ public abstract aspect TraceJoinPoints { this object to some method on the target object with a particular signature; and (2) the execution of the actual code in the particular method dispatched in the target object. - The call join point starts with the initial call and ends - when control returns to the call (by return or perhaps + The call join point starts with the initial call and ends + when control returns to the call (by return or perhaps thrown exception). The execution join point starts with the method body and ends when the body completes (again by return or throwing an exception), so the execution join @@ -2557,10 +2548,10 @@ public abstract aspect TraceJoinPoints { call join point. You can see this if you use the join-point tracing aspect in see <xref linkend="q:seeingjoinpoints"/>. </para> - <para>As you would expect, the context differs + <para>As you would expect, the context differs in advice on pointcuts picking out execution and call join - points; for call, <literal>this</literal> refers to the caller, whereas - for execution <literal>this</literal> refers to the called + points; for call, <literal>this</literal> refers to the caller, whereas + for execution <literal>this</literal> refers to the called (executing) object. </para> <para> @@ -2574,10 +2565,10 @@ public abstract aspect TraceJoinPoints { your sources within the code the compiler controls (described in the <ulink url="progguide/semantics.html">appendix</ulink> to the <literal>Programming Guide</literal>). - For example, to trace calls into a + For example, to trace calls into a method from classes which are outside the code the compiler controls at compile time, then using <literal>execution()</literal> will work - while using <literal>call()</literal>may not. Finally, since + while using <literal>call()</literal>may not. Finally, since <literal>super</literal> invocations are not considered method calls, to trace <literal>super.foo()</literal> would require using <literal>execution</literal>. @@ -2585,9 +2576,9 @@ public abstract aspect TraceJoinPoints { <para> Because of differences in the way AspectJ 1.0 and 1.1 are implemented, in 1.0 - you should use the <literal>call()</literal> + you should use the <literal>call()</literal> pointcut designator unless you have a good reason to use - <literal>execution()</literal>; in AspectJ 1.1, the + <literal>execution()</literal>; in AspectJ 1.1, the reverse is true. </para> </answer> @@ -2619,7 +2610,7 @@ public abstract aspect TraceJoinPoints { <answer> <para>This is best seen by way of example. Given a recursive call to <literal>int factorial(int)</literal> - you can print the arguments for + you can print the arguments for (a) the current and most-recent recursive call or (b) the current and original recursive call: </para> @@ -2628,13 +2619,13 @@ aspect LogFactorial { pointcut f(int i) : call(int factorial(int)) && args(i); // most-recent - before(int i, final int j) : f(i) && cflowbelow(f(j)) { + before(int i, final int j) : f(i) && cflowbelow(f(j)) { System.err.println(i + "-" + j); } // original - before(int i, final int j) : f(i) - && cflowbelow(cflow(f(j)) && !cflowbelow(f(int))) { + before(int i, final int j) : f(i) + && cflowbelow(cflow(f(j)) && !cflowbelow(f(int))) { System.err.println(i + "@" + j); } } @@ -2644,8 +2635,8 @@ aspect LogFactorial { <qandaentry> <question id="q:initializationjoinpoints" xreflabel="Q:What is the difference between constructor call, constructor execution, initialization, and static initialization join points?"> - <para>What is the difference between constructor call, - constructor execution, initialization, and static + <para>What is the difference between constructor call, + constructor execution, initialization, and static initialization join points? </para> </question> @@ -2655,21 +2646,20 @@ aspect LogFactorial { are akin to method call, and initialization generalizes this and picks out the first constructor called. </para> - <para>Their relations are best + <para>Their relations are best demonstrated by tracing the join points. Below is the class Test which implements an interface and extends a class along with a trace of the join points below and including - the constructor call obtained using + the constructor call obtained using <literal>TraceJointPoints.java</literal> from <xref linkend="q:seeingjoinpoints"/>. </para> - <programlisting> - <![CDATA[ + <programlisting><![CDATA[ public class Init { public static void main (String[] args) { - new Test(); + new Test(); end(); - } + } static void end() {} } class Super {} @@ -2677,37 +2667,33 @@ interface I {} class Test extends Super implements I { Test() {} } - -]]> - </programlisting> - <para>For a program compiled with AspectJ 1.0, +]]></programlisting> + <para>For a program compiled with AspectJ 1.0, the result is this:</para> - <programlisting> - <![CDATA[ - <constructor-call sig="Test()" > - <staticinitialization sig="Super._init_" /> - <staticinitialization sig="Test._init_" /> - <initialization sig="Super()" > - <instanceinitializer-execution sig="Super._init_" /> - <constructor-execution sig="Super()" /> - </initialization> - <initialization sig="I()" > - <instanceinitializer-execution sig="I._init_" /> - <constructor-execution sig="I()" /> - </initialization> - <initialization sig="Test()" > - <instanceinitializer-execution sig="Test._init_" /> - <constructor-execution sig="Test()" /> - </initialization> - </constructor-call> -]]> - </programlisting> - <para> - Ordinarily, using a <literal>call</literal> pointcut designator + <programlisting><![CDATA[ +<constructor-call sig="Test()" > + <staticinitialization sig="Super._init_" /> + <staticinitialization sig="Test._init_" /> + <initialization sig="Super()" > + <instanceinitializer-execution sig="Super._init_" /> + <constructor-execution sig="Super()" /> + </initialization> + <initialization sig="I()" > + <instanceinitializer-execution sig="I._init_" /> + <constructor-execution sig="I()" /> + </initialization> + <initialization sig="Test()" > + <instanceinitializer-execution sig="Test._init_" /> + <constructor-execution sig="Test()" /> + </initialization> +</constructor-call> +]]></programlisting> + <para> + Ordinarily, using a <literal>call</literal> pointcut designator is best because the call join point surrounds the others, but in the case of constructors there is no target object for the call (because it has not been constructed yet), so you - might prefer to use the <literal>initialization</literal> + might prefer to use the <literal>initialization</literal> pointcut designator. </para> </answer> @@ -2721,15 +2707,15 @@ class Test extends Super implements I { <answer> <para> You can advise some form of constructor join point. - Constructors are tricky in Java, and that's exposed in AspectJ. + Constructors are tricky in Java, and that's exposed in AspectJ. Here are some rules of thumb: <itemizedlist> <listitem> - <para>If you want the join point on the "outside" of object creation, + <para>If you want the join point on the "outside" of object creation, use after returning from call to the constructor: </para> <programlisting> - after() returning (Foo newlyCreatedObject): call(Foo.new(..)) { ... } +after() returning (Foo newlyCreatedObject): call(Foo.new(..)) { ... } </programlisting> <para> You might be tempted to use "this" or "target" to expose the new object, but remember @@ -2737,28 +2723,28 @@ class Test extends Super implements I { created yet... it only exists "on the way out", when you return the object. </para> </listitem> - <listitem> + <listitem> <para>If you want the join point inside a particular constructor, use: </para> <programlisting> - after(Foo newlyCreatedObject) returning: this(newlyCreatedObject) && execution(Foo.new(..)) { ... } +after(Foo newlyCreatedObject) returning: this(newlyCreatedObject) && execution(Foo.new(..)) { ... } </programlisting> <para> Remember, though, that if you use "before" advice here, the body of the constructor will not have run, and so the object may be somewhat uninitialized. </para> </listitem> - <listitem> + <listitem> <para> - In the rare case that there are all sorts of constructors for the object that call - each other with <literal>this(...)</literal> and you want exactly one join point - for each initialization of <literal>Foo</literal>, regardless of the path of + In the rare case that there are all sorts of constructors for the object that call + each other with <literal>this(...)</literal> and you want exactly one join point + for each initialization of <literal>Foo</literal>, regardless of the path of constructors it takes, then use: </para> <programlisting> - after(Foo f) returning: this(f) && initialization(Foo.new(..)) { ... } +after(Foo f) returning: this(f) && initialization(Foo.new(..)) { ... } </programlisting> - </listitem> + </listitem> </itemizedlist> </para> </answer> @@ -2773,11 +2759,11 @@ class Test extends Super implements I { <answer> <para> This usually reflects both a conceptual error and a programming mistake. - Most likely you want to do something like "run the advice for all + Most likely you want to do something like "run the advice for all public and private calls," and the code looks something like this: </para> <programlisting> - within(com.xerox.printing..*) && call(public * *(..)) && call(private * *(..)) +within(com.xerox.printing..*) && call(public * *(..)) && call(private * *(..)) </programlisting> <para> But a pointcut is evaluated at *each* join point. @@ -2788,7 +2774,7 @@ class Test extends Super implements I { The correct pointcut would use <literal>||</literal> as follows: </para> <programlisting> - within(com.xerox.printing..*) && (call(public * *(..)) || call(private * *(..))) +within(com.xerox.printing..*) && (call(public * *(..)) || call(private * *(..))) </programlisting> <para> Then the advice will run at the join point. @@ -2805,11 +2791,11 @@ class Test extends Super implements I { <answer> <para>There is no way in advice to refer to the type of the code executing in a static context except by specification. - This makes it impossible to refer to static members using + This makes it impossible to refer to static members using runtime information. </para> <para>However, AspectJ can determine the class for something - in the join point context, which you can use as a per-class key. + in the join point context, which you can use as a per-class key. Then you can actually declare an instance field to contain the per-class value (see the next question). This comes at the cost of an extra reference, but the field can be final. @@ -2830,7 +2816,7 @@ class Test extends Super implements I { your program. For example: </para> <programlisting> -/** +/** * Example of using an interface to represent a type pattern. * sub-aspects use declare parents to add to traced types, e.g., * declare parents: com.mycompany.whatever..* implements Marked; @@ -2867,37 +2853,37 @@ aspect MyMarker extends MarkerExample { and instructions for using AspectJ with other programming tools. <orderedlist> <listitem><para> - The AspectJ release includes examples in its + The AspectJ release includes examples in its <literal>doc</literal> directory. </para></listitem> - + <listitem><para> There is a community repository of sample code and tutorials - in the AspectJ CVS tree + in the AspectJ CVS tree <literal>docs</literal> module <literal>sandbox</literal> directory. - These are extracted and published (online only) + These are extracted and published (online only) <ulink url="http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/sample-code.html"> here </ulink>. </para></listitem> - + <listitem><para> - The <literal>teaching</literal> directory of the - <literal>docs</literal> module contains public materials - the AspectJ committers use for presentations, some of + The <literal>teaching</literal> directory of the + <literal>docs</literal> module contains public materials + the AspectJ committers use for presentations, some of which include example code. To access CVS, see - <xref linkend="q:buildingsource"/>. + <xref linkend="q:buildingsource"/>. </para></listitem> - + <listitem><para> - The archives for the user and developer mailing lists + The archives for the user and developer mailing lists contain many good examples. To search the archives, see <xref linkend="q:searchingsite"/>. </para></listitem> </orderedlist> This code can vary in quality. Code that we publish or include with AspectJ is generally - correct. However, code found in our CVS tree might not have + correct. However, code found in our CVS tree might not have been tested thoroughly, and code from the mailing lists might be untested or use older versions of the language. </para> @@ -2912,18 +2898,18 @@ aspect MyMarker extends MarkerExample { <para>Some libraries are distributed in the release under the examples folder in the distribution. These are "libraries" in the sense that they are reusable, - but they are delivered in source form. + but they are delivered in source form. Similarly, some of the sample code is reusable; for that, see <xref linkend="q:exampleprograms"/>. - If you develop such a library and want to make it available to + If you develop such a library and want to make it available to other users, feel to send it to the users mailing list <literal>aspectj-users@eclipse.org</literal>. </para> <para>In AspectJ 1.1, ajc supports binary aspects, so you can distribute aspect libraries without distributing the - source. For more information, see the + source. For more information, see the <literal>-aspectpath</literal> - option in the + option in the <ulink url="devguide/ajc-ref.html"> Reference for ajc</ulink>. </para> @@ -2964,28 +2950,26 @@ aspect MyMarker extends MarkerExample { </question> <answer> <para> - Just include the aspectjrt.jar as a required archive. - For example, here is the HTML code for an HTML editor + Just include the aspectjrt.jar as a required archive. + For example, here is the HTML code for an HTML editor applet that contains some debugging aspects: </para> - <programlisting> - <![CDATA[ + <programlisting><![CDATA[ <APPLET CODE='com.company.swing.applets.EditorApplet' WIDTH='700' HEIGHT='525'> <PARAM NAME="CODE" VALUE="com.company.swing.applets.EditorApplet" > - <PARAM NAME="ARCHIVE" + <PARAM NAME="ARCHIVE" VALUE ="../company-applets.jar,../aspectjrt.jar,../xmlrpc-applet.jar" > <PARAM NAME="type" VALUE="application/x-java-applet;version=1.4"> <PARAM NAME="scriptable" VALUE="false"> </APPLET> -]]> - </programlisting> +]]></programlisting> <para> The above markup has worked reliably with the Java Plugin - (included in the JRE 1.4.x) in IE 6, Mozilla 1.1 (Win32), - and Mozilla 1.0.1 (Red Hat Linux 8.0). + (included in the JRE 1.4.x) in IE 6, Mozilla 1.1 (Win32), + and Mozilla 1.0.1 (Red Hat Linux 8.0). The following link describes how to configure Mozilla/Netscape 6.x/7.x to use the Java Plugin from a JRE/SDK installation: <ulink url="http://java.sun.com/j2se/1.4.1/manual_install_linux.html"> @@ -3001,8 +2985,8 @@ aspect MyMarker extends MarkerExample { </question> <answer> <para> - In some cases, AspectJ allows conversion from values of primitive types to Object, - so that highly polymorphic advice may be written. This works if an advice parameter + In some cases, AspectJ allows conversion from values of primitive 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: </para> <programlisting> @@ -3049,8 +3033,8 @@ java.lang.Integer detect the version of the AspectJ runtime while running under Java 1.4 or later, get the version from the package: <programlisting> - Package lang = org.aspectj.lang.JoinPoint.class.getPackage(); - String version = lang.getImplementationVersion(); +Package lang = org.aspectj.lang.JoinPoint.class.getPackage(); +String version = lang.getImplementationVersion(); </programlisting> </para> <para>When running under Java 1.3 or earlier, read the manifest @@ -3102,8 +3086,8 @@ before() : pc() { </para> </question> <answer> - <para>Most likely this is a case of infinite recursion, - where advice is advising itself. It presents as a + <para>Most likely this is a case of infinite recursion, + where advice is advising itself. It presents as a <literal>StackOverflowError</literal> or silence as the VM exhausts itself in the recursion. </para> @@ -3122,7 +3106,7 @@ public class Main { <para>If you compile and run this program, and it will fail silently, trying to process the finally clause even after throwing the StackOverflowError. </para> - <para>Here's a similar AspectJ program where the recursion is + <para>Here's a similar AspectJ program where the recursion is not so obvious: </para> <programlisting> @@ -3132,18 +3116,18 @@ aspect A { </programlisting> <para>This re-invokes itself because it advises any call. It invokes itself even after an exception is thrown, since - <literal>after</literal> advice, like a finally clause, runs even + <literal>after</literal> advice, like a finally clause, runs even after exceptions are thrown. You can fix this by following two practices: </para> <para>In AspectJ 1.1, the String concatenation operator (+) is - advised in its StringBuffer form, so if your advise uses + advised in its StringBuffer form, so if your advise uses String + in a way that is picked out by your pointcut, you will get infinite recursion.</para> <para> (1) Use <literal>after returning</literal> to advise normal completions or <literal>after throwing</literal> to advise abrupt completions. - If you use <literal>after</literal> or <literal>after throwing</literal>, - write the advice with the same care you would a finally clause, + If you use <literal>after</literal> or <literal>after throwing</literal>, + write the advice with the same care you would a finally clause, understanding that it may run after some failure. </para> <para>(2) Avoid writing advice that advises itself. One simple way to @@ -3151,20 +3135,20 @@ aspect A { </para> <programlisting> aspect A { - after() returning: !within(A) && call(* *(..)) { - System.out.println("after " + thisJoinPoint); + after() returning: !within(A) && call(* *(..)) { + System.out.println("after " + thisJoinPoint); } } </programlisting> - <para>A better way is often to re-write the pointcut. - If the advice is advising itself accidentally, that's a sign that + <para>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. </para> <programlisting> aspect A { pointcut withinTargetClasses() : within(A+) || within(B+); - after() returning: withinTargetClasses() && call(* *(..)) { - System.out.println("after " + thisJoinPoint); + after() returning: withinTargetClasses() && call(* *(..)) { + System.out.println("after " + thisJoinPoint); } } </programlisting> @@ -3179,7 +3163,7 @@ aspect A { <programlisting> aspect A { boolean com.xerox..*.dirtyFlag; - after (Object target) returning + after (Object target) returning : target(target) && call(* com.xerox..*.set*(..)) { target.dirtyFlag = true; // compile fails here } @@ -3198,9 +3182,9 @@ aspect A { boolean TrackingSets.dirtyFlag; declare parents : com.xerox..* implements TrackingSets; - after (TrackingSets target) returning + after (TrackingSets target) returning : target(target) && call(* com.xerox..*.set*(..)) { - target.dirtyFlag = true; + target.dirtyFlag = true; } } </programlisting> @@ -3238,7 +3222,7 @@ aspect A { trades space for time in recompiles. </para> </answer> - </qandaentry> + </qandaentry> <qandaentry> <question id="q:duplicateclass" xreflabel="Q:Why do I get a message that my class is already defined?"> @@ -3251,7 +3235,7 @@ aspect A { Most commonly, a source file was specified twice on the command line (e.g., directly and by a *.java entry in a .lst file). However, sometimes you have defined a class in two files in the - same package, and you need to rename the class or change its + same package, and you need to rename the class or change its scope. You should get this message from any Java compiler. </para> </answer> @@ -3260,14 +3244,14 @@ aspect A { <question id="q:ajcrecompile" xreflabel="Q:ajc recompiles all files every time. How can I make it recompile only the files that have changed?"> <para> - <literal>ajc</literal> recompiles all files every time. + <literal>ajc</literal> recompiles all files every time. How can I make it recompile only the files that have changed? </para> </question> <answer> <para> <literal>ajc</literal> 1.0 does not support incremental - compilation, but since 1.1 <literal>ajc</literal> does when passed the + compilation, but since 1.1 <literal>ajc</literal> does when passed the <literal>-incremental</literal> option. It may still recompile files that have not changed, if they could be affected by aspects in particular ways, but the files compiled should be fewer @@ -3308,12 +3292,12 @@ aspect A { </question> <answer> <para> - When working with an unsupported IDE that objects to the syntax of - AspectJ source files (and, e.g., automatically gathers them - in a source tree as Java files based on the .java extension), - you can use the .aj extension for your AspectJ files. - The ajc compiler accepts both .java and .aj files, and you can - set up your build scripts to include the correct list of + When working with an unsupported IDE that objects to the syntax of + AspectJ source files (and, e.g., automatically gathers them + in a source tree as Java files based on the .java extension), + you can use the .aj extension for your AspectJ files. + The ajc compiler accepts both .java and .aj files, and you can + set up your build scripts to include the correct list of source files. (You will have to find another editor for editing AspectJ files; you can use the ajbrowser to view edit your AspectJ files and navigate the crosscutting structure.) @@ -3337,23 +3321,23 @@ aspect A { slow the process considerably. </para> <para> - If you are having problems and would like to find the optimal memory - allocation, iteratively decrease the amount of memory available until - AJDE or ajc signals out-of-memory errors, and then increase that + If you are having problems and would like to find the optimal memory + allocation, iteratively decrease the amount of memory available until + AJDE or ajc signals out-of-memory errors, and then increase that amount by 5-10%. </para> <para> To increase memory for the ajc compiler, see <xref linkend="q:ajcoom"/>. For your IDE, do something similar or follow the provider's instructions. - For example, to increase memory in JBuilder, edit the + For example, to increase memory in JBuilder, edit the <literal>jbuilderX/bin/jbuilder.config</literal> file to have an entry like: -<programlisting> +<programlisting> vmparam -Xmx384m -</programlisting> +</programlisting> </para> <para> - If it turns out that your project is too big to use with AJDE, your IDE + If it turns out that your project is too big to use with AJDE, your IDE may nonetheless support external commands or Ant build processes, which run outside the IDE memory space. For a JBuilder Ant plugin, some people have directed us to <ulink url="http://antrunner.sourceforge.net"/>. @@ -3374,21 +3358,21 @@ vmparam -Xmx384m that is being advised. We have seen this happen two ways: <itemizedlist> <listitem> - <para>You get a ClassNotFound message for - <literal>NoAspectBoundException</literal> when loading a - class affected by aspects if <literal>aspectjrt.jar</literal> - classes are not on the runtime classpath. + <para>You get a ClassNotFound message for + <literal>NoAspectBoundException</literal> when loading a + class affected by aspects if <literal>aspectjrt.jar</literal> + classes are not on the runtime classpath. To fix this, put the classes on the classpath. </para> </listitem> <listitem> <para> You can get a <literal>NoAspectBoundException</literal> when - there is a cycle in aspect initialization or static + there is a cycle in aspect initialization or static initialization, most commonly when an aspect advises its own initializer. To fix this, first find the class that - fails to load by running java in debug mode or looking - at the <literal>NoAspectBoundException</literal> trace, + fails to load by running java in debug mode or looking + at the <literal>NoAspectBoundException</literal> trace, and then fix the offending (probably unintended) dependency. Most often, it comes from a pointcut like <literal>staticinitialization(com.company..*)</literal> @@ -3401,10 +3385,10 @@ vmparam -Xmx384m </para> </listitem> </itemizedlist> - </para> + </para> </answer> </qandaentry> - + <qandaentry> <question id="q:stacktraces" xreflabel="Q:My stack traces don't make sense. What gives?"> @@ -3413,10 +3397,10 @@ vmparam -Xmx384m </para> </question> <answer> - <para>In 1.0, unless you are using the <literal>ajdb</literal> debugger, + <para>In 1.0, unless you are using the <literal>ajdb</literal> debugger, stack traces may have synthetic methods in the stack, and the line numbers may - not track your source code. The + not track your source code. The <ulink url="devguide/index.html"> Development Environment Guide</ulink> discusses how to interpret stack at the end of the @@ -3438,17 +3422,17 @@ vmparam -Xmx384m </question> <answer> <para> - When advice is not running, + When advice is not running, there is probably a problem in the pointcut. - Sometimes users specify pointcuts that + Sometimes users specify pointcuts that do not mean what they intend - most often when they misspell a type name. Run the compiler in <literal>-Xlint</literal> mode, which will flag some likely mistakes, - like the type name. + like the type name. If that does not work, and your pointcut is staticly-determinable, - use a declare statement to identify affected code. (For more + use a declare statement to identify affected code. (For more information, see <xref linkend="q:knowWhenAspectsAffectClasses"/>.) - If that does not work and your pointcut is dynamically determined, + If that does not work and your pointcut is dynamically determined, see if your join points are executing at all by using TraceJoinPoints.java from <xref linkend="q:seeingjoinpoints"/>. </para> @@ -3460,9 +3444,9 @@ vmparam -Xmx384m </para> <para> In the case of advice in abstract aspects, the advice will run once - for each concrete instance of the aspect. - If the pointcut for that advice picks out the same join point for two - concrete aspects, then the correct behavior is for the advice to run + for each concrete instance of the aspect. + If the pointcut for that advice picks out the same join point for two + concrete aspects, then the correct behavior is for the advice to run the advice twice at that join point. </para> <para> @@ -3470,16 +3454,16 @@ vmparam -Xmx384m can use IDE support, logging, or declare-warnings. If you are using IDE support, you should be able to trace back from the pointcut or advice to the join points which can be statically - determined to be affected. + determined to be affected. Without IDE support, you can write declare-warning statements to identify code affected by staticly- determinable pointcuts. To identify advised dynamic join points, - you can try using <literal>TraceJoinPoints.java</literal> as above, - or update the advice to print the source location of the join point. - Doing any of these should show if the advice applies to code that + you can try using <literal>TraceJoinPoints.java</literal> as above, + or update the advice to print the source location of the join point. + Doing any of these should show if the advice applies to code that you did not expect. - </para> + </para> <para>If you've done this and convinced yourself it's not working, it may be a bug. See <xref linkend="q:bugreports"/>. </para> @@ -3497,7 +3481,7 @@ vmparam -Xmx384m point and specifying the defining signature. Since all overriding methods share this signature, the advice runs for each method executed. - (This happens, e.g., when one method invokes the same method + (This happens, e.g., when one method invokes the same method in the superclass using <literal>super.{method}(..)</literal>). This is the correct behavior. </para> @@ -3506,7 +3490,7 @@ vmparam -Xmx384m out only the initial method-execution. </para> </answer> - </qandaentry> + </qandaentry> <qandaentry> <question id="q:tejpsp" xreflabel="Q:I don't understand when thisEnclosingJoinPointStaticPart is available."> @@ -3516,7 +3500,7 @@ vmparam -Xmx384m </question> <answer> <para> - <literal>thisEnclosingJoinPointStaticPart</literal> is a special + <literal>thisEnclosingJoinPointStaticPart</literal> is a special variable available in the context of advice to refer to the join point, if any, lexically enclosing the current join point: <table> @@ -3529,24 +3513,24 @@ vmparam -Xmx384m </row> <row> <entry> - constructor-execution, method-execution, + constructor-execution, method-execution, advice execution, initialization, pre-initialization, static initialization </entry> <entry> - constructor-call, method-call, handler, + constructor-call, method-call, handler, field-set, field-get </entry> </row> </tbody> - </tgroup> + </tgroup> </table> Expressions in the body of handlers have the same <literal>thisEnclosingJoinPointStaticPart</literal> as the handler itself. </para> </answer> - </qandaentry> + </qandaentry> <qandaentry> <question id="q:packagedeclares" xreflabel="Q:I declared a member on a class with package access, but other classes in the package cannot see it."> @@ -3570,19 +3554,19 @@ vmparam -Xmx384m <para>I declared a member on a interface, but javac does not see it. </para> </question> - + <answer> <para> You have to compile all the top-level implementating classes of the interface using <literal>ajc</literal>. - From an email by Jim Hugunin on the requirements for AspectJ 1.1 to + From an email by Jim Hugunin on the requirements for AspectJ 1.1 to implement members declared by an aspect on an interface: </para> <para> - If you introduce non-static fields or non-abstract methods on an interface - from an aspect, then all of the top-most implementors of that interface must - be woven by that same aspect. - (A class C is a top-most implementor of an interface I if C implements I + If you introduce non-static fields or non-abstract methods on an interface + from an aspect, then all of the top-most implementors of that interface must + be woven by that same aspect. + (A class C is a top-most implementor of an interface I if C implements I and the superclass of C does not implement I.) </para> </answer> @@ -3603,8 +3587,8 @@ vmparam -Xmx384m classes are found in <literal>tools.jar</literal> (in the <literal>lib</literal> directory of the JDK distribution), which must be on your classpath to make - <literal>ajc</literal> work with <literal>javac</literal>. - Inspect the java command that launches ajc to make sure that + <literal>ajc</literal> work with <literal>javac</literal>. + Inspect the java command that launches ajc to make sure that <literal>tools.jar</literal> is on the classpath for ajc; the -classpath option only applies to the sources compiled. </para> @@ -3614,7 +3598,7 @@ vmparam -Xmx384m <question id="q:ajdocneeds13" xreflabel="Q:I'm running under 1.4, but ajdoc asks for 1.3 (or throws IllegalAccessError for HtmlWriter.configuration)"> <para> - I'm running under 1.4, but <literal>ajdoc</literal> asks for 1.3 + I'm running under 1.4, but <literal>ajdoc</literal> asks for 1.3 (or throws IllegalAccessError for HtmlWriter.configuration) </para> </question> @@ -3635,7 +3619,7 @@ vmparam -Xmx384m (to make javac, et al work). That makes it impossible to run the ajdoc taskdef (which does not currently support forking), so you'll need to run a separate ant process, either from the command-line or via Ant's - exec task (the Ant task will propagate the classpath). + exec task (the Ant task will propagate the classpath). If the wrong tools.jar is not on the ant classpath, then it should work to put the 1.3 tools.jar in the taskdef classpath. </para> @@ -3652,11 +3636,11 @@ vmparam -Xmx384m <answer> <para>It is a bad practice to use the compilation unit to control crosscutting. Aspects and pointcuts especially - should be written to specify crosscutting precisely. + should be written to specify crosscutting precisely. Aspects will behave the same when you add files if you initially included all files affected by your aspects. If you use the compilation unit, then your code will behave - differently in AspectJ implementations that do not limit + differently in AspectJ implementations that do not limit themselves to specified files. </para> </answer> @@ -3684,7 +3668,7 @@ vmparam -Xmx384m <qandaentry> <question id="q:injection" xreflabel="Q:I've heard AspectJ can generate or inject code into my code. Is this true?"> - <para>I've heard AspectJ can generate or inject code into my code. + <para>I've heard AspectJ can generate or inject code into my code. Is this true? </para> </question> @@ -3699,7 +3683,7 @@ vmparam -Xmx384m join points. </para> <para> - So the semantic model of advice is like the semantic model of a + So the semantic model of advice is like the semantic model of a method -- it says "when any of these things happen, do this". </para> <para> @@ -3724,10 +3708,10 @@ vmparam -Xmx384m </para> </question> <answer> - <para>Users have sometimes wanted AspectJ to pick out + <para>Users have sometimes wanted AspectJ to pick out many more join points, including <itemizedlist> - <listitem><para>method-local field access</para></listitem> + <listitem><para>method-local field access</para></listitem> <listitem><para>array-element access</para></listitem> <listitem><para>loop iteration</para></listitem> <listitem><para>method parameter evaluation</para></listitem> @@ -3739,8 +3723,8 @@ vmparam -Xmx384m <listitem><para>there are very few use-cases for advice on the join point</para></listitem> <listitem><para>a seemingly-insignificant change to the underlying program causes a change in the join point</para></listitem> - <listitem><para>pointcuts can't really distinguish the join point in question</para></listitem> - <listitem><para>the join point would differ too much for different + <listitem><para>pointcuts can't really distinguish the join point in question</para></listitem> + <listitem><para>the join point would differ too much for different implementations of AspectJ, or would only be implementable in one way </para></listitem> @@ -3756,15 +3740,15 @@ vmparam -Xmx384m <question id="q:reflectiveCalls" xreflabel="Q:Why doesn't AspectJ pick out reflective calls?"> <para>Why doesn't AspectJ pick out reflective calls? - The pointcut <literal>call(void run())</literal> + The pointcut <literal>call(void run())</literal> won't pick out a call using reflection, like <literal>((Method)run).invoke(null, args)</literal>. </para> </question> <answer> - <para>The pointcut + <para>The pointcut <literal>execution(void run())</literal> will - work. The call pointcut doesn't work because + work. The call pointcut doesn't work because <literal>Method.invoke(..)</literal> is the Java method-call, and AspectJ cannot delve into the Java reflection library to implement call semantics. To advise a reflective call @@ -3776,9 +3760,9 @@ vmparam -Xmx384m <programlisting> aspect A { pointcut runReflectiveCall(Method run) : target(run) && - call(Object Method.invoke(..)) && if("run".equals(run.getName())); - before() : runReflectiveCall(Method) { - System.out.println("before reflective call " + thisJoinPoint); + call(Object Method.invoke(..)) && if("run".equals(run.getName())); + before() : runReflectiveCall(Method) { + System.out.println("before reflective call " + thisJoinPoint); } } </programlisting> @@ -3809,7 +3793,7 @@ aspect A { <para>When running classes produced by the AspectJ weaver or compiler, there are no significant hidden uses of memory. As would be expected, each aspect is instantiated. The per-object aspects (like - <literal>pertarget</literal> or <literal>perthis</literal>) + <literal>pertarget</literal> or <literal>perthis</literal>) in some implementations use a map to link aspects and the associated object. When using <literal>cflow</literal>-related pointcuts, a <literal>ThreadLocal</literal> @@ -3817,26 +3801,26 @@ aspect A { </para> <para>Of course, the size and code in an aspect can require memory. Aside from normal Java practices, take care with join point references. - When referencing the static part of a join point (e.g., + When referencing the static part of a join point (e.g., <literal>thisJoinPointStaticPart</literal>), only one object is created. However, if you reference the join point itself - (e.g., <literal>thisJoinPoint</literal>), then one - <literal>JoinPoint</literal> object will be created for each + (e.g., <literal>thisJoinPoint</literal>), then one + <literal>JoinPoint</literal> object will be created for each join point running advice. </para> - <para>Aspect instances will be garbage collected just like regular objects + <para>Aspect instances will be garbage collected just like regular objects after there are no more strong references to them. For the default aspect instantiation model, <literal>issingleton</literal>, the aspect - class retains a reference to the singleton instance, in order to - implement <literal>static {AspectClass} aspectOf()</literal>, so + class retains a reference to the singleton instance, in order to + implement <literal>static {AspectClass} aspectOf()</literal>, so singleton instances will not be garbage collected until the class is. - For long-running or memory-critical programs, consider using weak + For long-running or memory-critical programs, consider using weak references in singleton aspects for state that should be garbage collected. </para> <para>Finally, when using load-time weaving, the weaver can require - memory in its own right. Because the class loader never can + memory in its own right. Because the class loader never can know when it is done loading classes, the weaver can hold on - to the aspects required to weave for some time. There are + to the aspects required to weave for some time. There are strategies for minimizing this (with different trade-off's), so the time and memory required for load-time weaving will vary as load-time weaving evolves. @@ -3869,11 +3853,11 @@ aspect A { </para> <programlisting> <weaver> - <exclude within="*CGLIB*" /> + <exclude within="*CGLIB*" /> </weaver> </programlisting> </answer> - </qandaentry> + </qandaentry> </qandadiv> <qandadiv id="aj11" xreflabel="AspectJ 1.1 and eclipse.org"> @@ -3893,7 +3877,7 @@ aspect A { commercial users; the 1.1 release is imminent and will include byte-code weaving and incremental compilation; and the tool support is now well integrated with several - major IDEs. + major IDEs. </para> <para> This growth of the community and the technology means @@ -3902,7 +3886,7 @@ aspect A { development and support of AspectJ to move outside of PARC. This has already started to happen; the Eclipse AJDT plug-in and the several books in preparation are - examples. + examples. </para> <para> To encourage the growth of the AspectJ technology and @@ -3916,7 +3900,7 @@ aspect A { remain at eclipse.org, while the NetBeans, JBuilder and Emacs support will move to SourceForge.net projects. We look forward to your involvement with and - contribution to those projects. + contribution to those projects. </para> <para> We see Eclipse as an excellent new home for core @@ -3943,16 +3927,16 @@ aspect A { </qandaentry> <qandaentry> <question id="q:eclipseetc" - xreflabel="Q:What are the relationships between AspectJ, JDT, + xreflabel="Q:What are the relationships between AspectJ, JDT, Eclipse, AJDT, and IDE support generally?"> - <para>What are the relationships between AspectJ, JDT, + <para>What are the relationships between AspectJ, JDT, Eclipse, AJDT, and IDE support generally? </para> </question> <answer> <para>Eclipse is a software platform. </para> - <para>JDT is an eclipse project to support Java development. + <para>JDT is an eclipse project to support Java development. JDT has a Java compiler. </para> <para>AspectJ 1.1 is built on Eclipse/JDT's Java compiler @@ -3960,27 +3944,27 @@ aspect A { With the AspectJ distribution, you can compile and run AspectJ programs and use the AspectJ structure browser. </para> - <para>AJDT is an eclipse project to integrate AspectJ - into Eclipse/JDT so you can use Eclipse to develop + <para>AJDT is an eclipse project to integrate AspectJ + into Eclipse/JDT so you can use Eclipse to develop AspectJ programs. AJDT aims to support the full Eclipse experience - searching, compiler-error tasks, etc. AJDT will use the AspectJ Development Environment (AJDE) API's for creating IDE integrations, as well as hooking in to the model underlying the Java compiler. </para> - <para>Similarly, Sourceforge has projects integrating + <para>Similarly, Sourceforge has projects integrating AspectJ into other development environments - using the AJDE API's: + using the AJDE API's: <ulink url="http://aspectj4emacs.sourceforge.net"> - AspectJ for Emacs</ulink>, + AspectJ for Emacs</ulink>, <ulink url="http://aspectj4jbuildr.sourceforge.net"> - AspectJ for JBuilder</ulink>, and + AspectJ for JBuilder</ulink>, and <ulink url="http://aspectj4netbean.sourceforge.net"> AspectJ for NetBeans</ulink>. </para> - <para>This is the right level of separation/integration. + <para>This is the right level of separation/integration. AspectJ is available standalone, leverages an existing open-source - compliant Java compiler, and supports external projects + compliant Java compiler, and supports external projects doing IDE integrations in Eclipse, Emacs, JBuilder, and NetBeans through a common API, AJDE. </para> @@ -3998,10 +3982,10 @@ aspect A { </question> <answer> <para> - All the new features are documented in the + All the new features are documented in the <ulink url="adk15notebook/index.html"> AspectJ 5 Developer's Notebook</ulink> - and the + and the <ulink url="devguide/index.html"> AspectJ Development Environment Guide</ulink>. To summarize: @@ -4011,7 +3995,7 @@ aspect A { Java 5 support: as an extension to Java, AspectJ supports all the new language features of Java 5, including generics (parameterized types), autoboxing, covariant return types, - enhanced for-loops, enums, varargs, and of course + enhanced for-loops, enums, varargs, and of course annotations. </para></listitem> <listitem><para> @@ -4020,7 +4004,7 @@ aspect A { <itemizedlist> <listitem><para> Generic aspects: an abstract aspect can be declared - with a generic type parameter which can be used + with a generic type parameter which can be used in pointcuts and when declaring members on the aspect (but not when declaring members on other types). </para></listitem> @@ -4032,11 +4016,11 @@ aspect A { and annotations may be declared on other types in an aspect. </para></listitem> - </itemizedlist> + </itemizedlist> </para></listitem> <listitem><para> Annotation-style aspects: AspectJ 5 integrates AspectWerkz-style - aspects declared in annotations. This permits aspects to + aspects declared in annotations. This permits aspects to be written and compiled in pure-java code and woven using build-time or load-time weaving with the AspectJ weaver. (The original AspectJ language aspects are distinguished @@ -4073,7 +4057,7 @@ aspect A { <answer> <para> To use AspectJ, you can use the original code-style aspects - or the annotation-style aspects new in AspectJ 5. + or the annotation-style aspects new in AspectJ 5. </para> <para> The original code-style is a small extension of the Java language @@ -4091,7 +4075,7 @@ aspect A { aspects are written (not surprisingly) using annotations. They use the subset of the AspectJ language that works when aspects are woven after the code is compiled. - The source files are compiled with Javac, which simply saves the + The source files are compiled with Javac, which simply saves the annotations in the .class files. The resulting .class files must be woven using the AspectJ weaver, which reads the annotations from the @@ -4118,36 +4102,32 @@ aspect A { an XML file for configuration that allows deployers to declare concrete aspects using only XML. This means aspect developers can write abstract aspects, and deployers need only configure - <literal>aop.xml</literal> and run using the AspectJ weaver in Java 5. + <literal>aop.xml</literal> and run using the AspectJ weaver in Java 5. For example, to run Java 5 VM with load-time weaving, </para> -<programlisting> - <![CDATA[ +<programlisting><![CDATA[ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. -]]> - </programlisting> +]]></programlisting> <para> - To declare a concrete aspect, add a a + To declare a concrete aspect, add a a concrete-aspect XML entity to <literal>META-INF/aop.xml</literal>. - This example extends a tracing aspect to apply to + This example extends a tracing aspect to apply to every type in the application: </para> -<programlisting> - <![CDATA[ -<concrete-aspect +<programlisting><![CDATA[ +<concrete-aspect name="com.company.tracing.ConcreteTracing" extends="tracing.AbstractTracing"> - <pointcut - name="tracingScope" + <pointcut + name="tracingScope" expression="within(com.company.app..*)"/> -</concrete-aspect> -]]> - </programlisting> +</concrete-aspect> +]]></programlisting> <para> For more information, see the <ulink url="devguide/index.html"> AspectJ Development Environment Guide</ulink>. - </para> + </para> </answer> </qandaentry> </qandadiv> @@ -4164,28 +4144,28 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. <ulink url="progguide/index.html">Programming Guide</ulink>. However, current implementations do not control everything in a system, so AspectJ program semantics may be limited to code - the implementation controls. For our implementation, these - limitations are stated in + the implementation controls. For our implementation, these + limitations are stated in <ulink url="progguide/implementation.html"> Programming Guide Appendix: Implementation Notes</ulink>. - Aside from understanding the use and limitations of the - implementation, there is no need to understand the underlying + Aside from understanding the use and limitations of the + implementation, there is no need to understand the underlying technology when writing AspectJ programs. </para> <para> - The technology that implements AspectJ interests - some academic researchers and some developers + The technology that implements AspectJ interests + some academic researchers and some developers who want new features or new ways to weave. These extensions are not discussed in the documentation. Some are being developed already, others are on the drawing board (or perhaps were left off long ago), and still others haven't been considered. - If you are interested in a certain extension, + If you are interested in a certain extension, check the bug database for feature requests and the mailing list archives for any past discussions. - Then email the list to see if it's been considered. + Then email the list to see if it's been considered. For more information, see - <xref linkend="Developers"/>. + <xref linkend="Developers"/>. </para> </answer> </qandaentry> @@ -4197,10 +4177,10 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. </question> <answer> <para> - There are currently no documents describing this process in detail. + There are currently no documents describing this process in detail. You can compile programs and inspect the generated source or bytecode, or view the source code (see <xref linkend="Developers"/>). - We hope to write papers on the bytecode weaving model used in + We hope to write papers on the bytecode weaving model used in AspectJ-1.1 if we can find the time. Erik Hilsdale and Jim Hugunin did draft a paper for AOSD 2004, now available on Jim's web site: @@ -4211,28 +4191,28 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. following mailing-list reply</ulink>: </para> <para> - Each piece of advice in an aspect is associated with a pointcut. - This pointcut is stored in an attribute on the methods - corresponding to each piece of advice. - Before weaving, all of these pieces of advice are gathered + Each piece of advice in an aspect is associated with a pointcut. + This pointcut is stored in an attribute on the methods + corresponding to each piece of advice. + Before weaving, all of these pieces of advice are gathered into one large list. </para> <para> - Each .class file is woven independently. + Each .class file is woven independently. A .class file is woven by the following steps: <itemizedlist> <listitem><para> - Collect all of the joinpoint shadows in the .class file. - For every dynamic joinpoint in the AspectJ language model, - there is a corresponding static shadow of that joinpoint - in the bytecode. - For example, every method call joinpoint has an INVOKE - bytecode as its static shadow. Some joinpoints - (such as initialization) have much more + Collect all of the joinpoint shadows in the .class file. + For every dynamic joinpoint in the AspectJ language model, + there is a corresponding static shadow of that joinpoint + in the bytecode. + For example, every method call joinpoint has an INVOKE + bytecode as its static shadow. Some joinpoints + (such as initialization) have much more complicated static shadows. </para></listitem> <listitem><para> - Each piece of advice is matched to each static shadow. + Each piece of advice is matched to each static shadow. There are three results possible from this match. <itemizedlist> <listitem><para> @@ -4240,36 +4220,36 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. in which case nothing is done to the shadow </para></listitem> <listitem><para> - Always matches, + Always matches, in which case the advice is woven into this joinpoint shadow </para></listitem> <listitem><para> Sometimes matches, - in which case the advice is woven into the shadow - along with the minimal dynamic tests to determine - if any particular joinpoint in the actual running - program matches the advice. - The simplest example of sometimes matches is + in which case the advice is woven into the shadow + along with the minimal dynamic tests to determine + if any particular joinpoint in the actual running + program matches the advice. + The simplest example of sometimes matches is when the pointcut uses if(test()). - </para></listitem> + </para></listitem> </itemizedlist> </para></listitem> <listitem><para> - If any advice matched any static shadows in the .class file, - then the transformed .class file is written out, + If any advice matched any static shadows in the .class file, + then the transformed .class file is written out, otherwise it is left unchanged. </para></listitem> </itemizedlist> - See <literal>BcelClassWeaver</literal> and + See <literal>BcelClassWeaver</literal> and <literal>BcelShadow</literal> in the <literal>org.aspectj.weaver.bcel</literal> package for the two primary classes involved in this process. </para> <para> - Note: This explanation ignores the implementations of inter-type - declarations completely. - It also ignores performance optimizations such as fast-match + Note: This explanation ignores the implementations of inter-type + declarations completely. + It also ignores performance optimizations such as fast-match or pipelining that speed up the process. </para> </answer> @@ -4281,22 +4261,22 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. </para> </question> <answer> - <para>You have two choices based on how wide you want the weaving to take effect: application-server wide and application-specific weaving. - You choose between the two by loading aspect artifacts--aspects, associated types, and aop.xml--through the right classloader. - The aop.xml must be in the META-INF directory on the classpath for the chosen classloader. In either case, you modify the - startup script to specify the -javaagent:path-to/aspectjweaver.jar option to the Java virtual machine. Note that it is not - essential that all the artifacts be placed in a single jar. + <para>You have two choices based on how wide you want the weaving to take effect: application-server wide and application-specific weaving. + You choose between the two by loading aspect artifacts--aspects, associated types, and aop.xml--through the right classloader. + The aop.xml must be in the META-INF directory on the classpath for the chosen classloader. In either case, you modify the + startup script to specify the -javaagent:path-to/aspectjweaver.jar option to the Java virtual machine. Note that it is not + essential that all the artifacts be placed in a single jar. </para> - <para>For application-server wide weaving, you make aspect artifacts accessible to the server's classloader. Typically, you - achieve such access by putting these artifacts in the server's lib directory. For example, for Tomcat, you will place + <para>For application-server wide weaving, you make aspect artifacts accessible to the server's classloader. Typically, you + achieve such access by putting these artifacts in the server's lib directory. For example, for Tomcat, you will place the aspect artifacts in the TOMCAT_HOME/lib directory.</para> - <para>For application-specific weaving, you make aspect artifacts accessible to application classloader by bundling - them along with application's classes. For example, for a web application, you will place the aspect artifacts in + <para>For application-specific weaving, you make aspect artifacts accessible to application classloader by bundling + them along with application's classes. For example, for a web application, you will place the aspect artifacts in the MY_APP/WEB-INF/lib and/or MY_APP/WEB-INF/classes directory.</para> <para> We recommend that you start with application-specific weaving. - Note that you have an additional option if your application is based on the Spring framework. If you deploy in one of - the supported web servers or application servers, you can avoid modifications to the startup script. Please + Note that you have an additional option if your application is based on the Spring framework. If you deploy in one of + the supported web servers or application servers, you can avoid modifications to the startup script. Please see <ulink url="http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-aj-ltw-spring">http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-aj-ltw-spring</ulink> for more details. </para> </answer> @@ -4309,10 +4289,10 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. </question> <answer> <para> - The only time that reflection is used during run-time is when the special - thisJoinPoint object is used to discover reflective information about the + The only time that reflection is used during run-time is when the special + thisJoinPoint object is used to discover reflective information about the join point. If you don't use thisJoinPoint then no reflection will be used. - </para> + </para> </answer> </qandaentry> <qandaentry> @@ -4338,22 +4318,22 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. load-time weaving, including declaring concrete aspects in XML files and integrating with Java 5 and BEA JRocket JVM's. See <xref linkend="q:aspectj5ltw"/>. - </para> - <para>Some have asked about only weaving particular classes + </para> + <para>Some have asked about only weaving particular classes specified at run-time. - Aspects should work across an entire namespace, and problems + Aspects should work across an entire namespace, and problems will likely result from weaving - some classes but not others. Also, it's confusing to + some classes but not others. Also, it's confusing to specify crosscutting both in the aspect and in the list of runtime classes; the crosscutting specification should be in the aspect itself, where it can be processed by tools. - </para> + </para> <para>And just to state the obvious: do not use bytecode weaving, at load-time or otherwise, to modify .class files protected by license, without permission from the licensor. - </para> + </para> </answer> </qandaentry> </qandadiv> @@ -4371,10 +4351,10 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. and tools for writing AspectJ programs. </para> <para>For people who want to know how the AspectJ technology works, - the source code is the best resource, until we write some + the source code is the best resource, until we write some proper white papers (see <xref linkend="q:implementation"/>). - To get and compile the Java source code for the AspectJ + To get and compile the Java source code for the AspectJ distribution, see <xref linkend="q:buildingsource"/>. </para> @@ -4409,12 +4389,12 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. </para> </listitem> <listitem> - <para>Write bugs. Good bugs, especially with test cases, + <para>Write bugs. Good bugs, especially with test cases, are always appreciated. We especially like proposals for new <literal>XLint</literal> messages, since they are sometimes easy to implement and help users learn AspectJ, and for other implementable features - grounded in a compelling use-case. + grounded in a compelling use-case. </para> </listitem> <listitem> @@ -4425,7 +4405,7 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. </para> <para>Find them by searching open compiler bugs and picking out any which do not have test case attachments or a comment that - a test case has been written. + a test case has been written. Here is a query for open compiler bugs: <!-- ulink gacks on ampersands in url value, so quote them --> <ulink url="http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Compiler&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED"> @@ -4438,21 +4418,21 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. </listitem> <listitem> <para>Write patches to fix bugs. - If you particularly need a bug to be fixed, or if you're interested in + If you particularly need a bug to be fixed, or if you're interested in learning about the system, then get the source code and try to fix the - bug. Most likely you'll want to email aspectj-dev@eclipse.org to + bug. Most likely you'll want to email aspectj-dev@eclipse.org to declare your intentions and the approach you propose (based on having looked at the code). Mailing the list gives those experienced with the code a chance to guide you away from pitfalls. To submit the patch, attach it to - the bug. (When creating patches, do so on a per-module basis; that + the bug. (When creating patches, do so on a per-module basis; that means if fixing the bug involves changes to three modules, submit three patches.) </para> </listitem> <listitem> <para>Write patches for other reasons. - Often documentation needs to be fixed, or there may be a small new + Often documentation needs to be fixed, or there may be a small new feature you'd like to see. You can just do it and then submit it as a patch to a bug you create. As with bugs, in some cases you might want to declare your intentions on the mailing list to avoid @@ -4471,21 +4451,21 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. </para> </question> <answer> - <para>AspectJ 1.0 source code is available in an archive available + <para>AspectJ 1.0 source code is available in an archive available with the 1.0 downloads. It contains instructions for building from sources. </para> - <para>AspectJ 1.1+ source code is available through CVS using the - CVS Root <literal>dev.eclipse.org:/cvsroot/technology</literal>. - For more information on accessing the CVS tree at eclipse.org, - see the documentation from <ulink - url="http://eclipse.org">http://eclipse.org</ulink>. Find - specific instructions in the AspectJ tree at <ulink - url="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/build/readme-build-and-test-aspectj.html?rev=HEAD&content-type=text/html&cvsroot=Technology_Project"> - org.aspectj/modules/build/readme-build-and-test-aspectj.html</ulink>. - If you would like to use Ant to checkout the sources, build the - distribution, and test everything, see <ulink - url="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/build/release/build.xml?rev=HEAD&content-type=text/xml&cvsroot=Technology_Project"> + <para>AspectJ 1.1+ source code is available through CVS using the + CVS Root <literal>dev.eclipse.org:/cvsroot/technology</literal>. + For more information on accessing the CVS tree at eclipse.org, + see the documentation from <ulink + url="http://eclipse.org">http://eclipse.org</ulink>. Find + specific instructions in the AspectJ tree at <ulink + url="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/build/readme-build-and-test-aspectj.html?rev=HEAD&content-type=text/html&cvsroot=Technology_Project"> + org.aspectj/modules/build/readme-build-and-test-aspectj.html</ulink>. + If you would like to use Ant to checkout the sources, build the + distribution, and test everything, see <ulink + url="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/build/release/build.xml?rev=HEAD&content-type=text/xml&cvsroot=Technology_Project"> org.aspectj/modules/build/release/build.xml</ulink>. </para> <para> To check out the source code in Eclipse go to (<literal>File > new > Other > CVS > Checkout Projects from CVS</literal>). You'll need about 125 MB of space for the source and build. @@ -4527,7 +4507,7 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. </itemizedlist> </para> <para> - The <literal>org.aspectj.lib</literal> project is an AspectJ project so + The <literal>org.aspectj.lib</literal> project is an AspectJ project so you also have to have AJDT installed. For the latest AJDT release and download instructions visit the <ulink url="http://www.eclipse.org/ajdt/downloads/">AJDT Downloads</ulink> page. @@ -4543,15 +4523,15 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. <para> Further details: </para> - <para> + <para> You can check out the entire modules directory and build using the Ant build script <literal>modules/build/build.xml</literal>. All required libraries are included in <literal>modules/lib/</literal>, (including Ant 1.5.1 in <literal>modules/lib/ant</literal>). - If you are using Eclipse, you can check out any <literal>modules/</literal> - subdirectory as an eclipse Java project. + If you are using Eclipse, you can check out any <literal>modules/</literal> + subdirectory as an eclipse Java project. Depending on what you are trying to build, you need not check out - all modules; as of this writing, here are the modules to get + all modules; as of this writing, here are the modules to get for building the specific parts of AspectJ: </para> <para> @@ -4567,7 +4547,7 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. <listitem><para>For ajbrowser: the compiler modules, plus ajbrowser, ajdoc, taskdefs, and ajde. </para></listitem> - <listitem><para>For the AspectJ distribution, the ajbrowser modules, + <listitem><para>For the AspectJ distribution, the ajbrowser modules, plus aspectj5rt and org.aspectj.lib. </para></listitem> <listitem><para>For the test harness (or to run the release build @@ -4580,7 +4560,7 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. </itemizedlist> </para> <para> - Note that module interdependencies are recorded only in the eclipse + Note that module interdependencies are recorded only in the eclipse <literal>modules/{module}/.classpath </literal> files and may @@ -4598,9 +4578,9 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. <answer> <para>To build AspectJ, first get the source tree as described in <xref linkend="q:buildingsource"/>. Once you have - a development environment set up, copy the + a development environment set up, copy the <literal>build/sample-local.properties</literal> file - to <literal>build/local.properties</literal> and within this file point the + to <literal>build/local.properties</literal> and within this file point the <literal>java14.home</literal> and <literal>java15.home</literal> to the corresponding places on your machine. </para> @@ -4616,20 +4596,20 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. </listitem> <listitem> <para> - Navigate to the <literal>build</literal> directory within your AspectJ workspace - (to find out where your workspace is go to <literal>File > + Navigate to the <literal>build</literal> directory within your AspectJ workspace + (to find out where your workspace is go to <literal>File > Switch Workspace</literal> within Eclipse). </para> </listitem> <listitem> <para> - Run <literal>ant clean</literal> to remove the files from - previously built AspectJ versions. + Run <literal>ant clean</literal> to remove the files from + previously built AspectJ versions. </para> </listitem> <listitem> <para> - Run <literal>ant</literal> to build AspectJ. The built files are created in + Run <literal>ant</literal> to build AspectJ. The built files are created in <literal>your_eclipse_installation_directory/aspectj_development_workspace/aj-build</literal>. </para> </listitem> @@ -4639,14 +4619,14 @@ java -javaagent:aspectjweaver.jar -classpath "aspects.jar:${CLASSPATH}" .. To import a locally built AspectJ into AJDT first follow the instructions on <ulink url="http://www.eclipse.org/ajdt/faq.php#q:develop"> How do I setup an AJDT development environment in Eclipse?</ulink> - for setting up an AJDT development environment and running the + for setting up an AJDT development environment and running the correctness tests. Then: </para> <para> <itemizedlist> <listitem> <para> - Create a file <literal>aspectjlib.properties</literal> within + Create a file <literal>aspectjlib.properties</literal> within the <literal>org.aspectj.ajde</literal> project and add the following two lines <programlisting> aspectj.lib.dir=C:/eclipse/aspectj-workspace/aj-build/dist/tools/lib @@ -4657,12 +4637,12 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec </listitem> <listitem> <para> - Run the <literal>build.xml</literal> file in <literal>org.aspectj.ajde</literal> + Run the <literal>build.xml</literal> file in <literal>org.aspectj.ajde</literal> with the <literal>plugin jars</literal> target: <itemizedlist> <listitem> <para> - Right click on the <literal>build.xml</literal> file in the + Right click on the <literal>build.xml</literal> file in the <literal>org.aspectj.ajde</literal> plugin </para> </listitem> @@ -4686,17 +4666,17 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec Click <literal>Run</literal> </para> </listitem> - </itemizedlist> + </itemizedlist> </para> </listitem> <listitem> <para> - Refresh the <literal>org.aspectj.ajde, org.aspectj.runtime</literal> + Refresh the <literal>org.aspectj.ajde, org.aspectj.runtime</literal> and <literal>org.aspectj.weaver</literal> plugins. </para> </listitem> </itemizedlist> - </para> + </para> </answer> </qandaentry> <qandaentry> @@ -4707,9 +4687,9 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec </question> <answer> <para>Find the developer documentation in HTML files in the CVS tree, - inside the <literal>build</literal> and <literal>testing</literal> modules + inside the <literal>build</literal> and <literal>testing</literal> modules (i.e., in <literal>org.aspectj/modules/build/...</literal>). - Most pertinant: + Most pertinant: <itemizedlist> <listitem><para> <literal>../build/readme-build-and-test-aspectj.html</literal> @@ -4722,7 +4702,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec how to build the documentation using Ant. </para></listitem> <listitem><para><literal>../build/readme-tests-module.html</literal> - describes the all the tests + describes the all the tests in the <literal>tests</literal> module. </para></listitem> <listitem><para><literal>../build/readme-writing-compiler-tests.html</literal> @@ -4738,7 +4718,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec in the <literal>testing</literal> module. </para></listitem> </itemizedlist> - </para> + </para> </answer> </qandaentry> <qandaentry> @@ -4758,9 +4738,9 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec and the expected results are the test definitions described next. </para> - <para>For more complex bugs requiring many files, + <para>For more complex bugs requiring many files, create a zip file of a directory containing all the files - and an XML test definition file. + and an XML test definition file. The XML test definition file contains specifications for how to compile, recompile, or run the test sources. Complete documentation is available in the CVS tree @@ -4770,8 +4750,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec of the files referred to in the test definitions. </para> <para> - <programlisting> -<![CDATA[ + <programlisting><![CDATA[ <!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"> <suite> @@ -4793,7 +4772,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec <run class="pack1.Main"/> </ajc-test> -<!-- Check that compiler warning was emitted +<!-- Check that compiler warning was emitted using the following files: {testDefinitions}.xml @@ -4801,13 +4780,13 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec UsesDeprecated.java --> <ajc-test dir="two" pr="244" title="deprecated, noImportError"> - <compile options="-warn:deprecated,-noImportError" + <compile options="-warn:deprecated,-noImportError" files="UsesDeprecated.java"> <message kind="warning" line="20"/> </compile> </ajc-test> -<!-- Cooked example that uses all compiler attributes +<!-- Cooked example that uses all compiler attributes and the following files: {testDefinitions}.xml testCaseDir/ @@ -4824,7 +4803,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec AnotherRequired.class --> <ajc-test dir="testCaseDir" title="attributes test"> - <compile files="pack/Main.java,jars/injar.jar" + <compile files="pack/Main.java,jars/injar.jar" staging="true" options="-Xlint,-g:none" argfiles="debug.lst,aspects/test.lst" @@ -4843,7 +4822,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec IncCompileFix.20.java Before compiling, IncCompileFix.java is copied to a staging - directory. Before recompiling, IncCompileFix.20.java + directory. Before recompiling, IncCompileFix.20.java replaces it, so the compiler treats file as updated. --> <ajc-test dir="three" pr="622" title="incremental fix"> @@ -4856,8 +4835,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec </ajc-test> </suite> -]]> - </programlisting> +]]></programlisting> </para> </answer> </qandaentry> @@ -4873,10 +4851,10 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec described in <xref linkend="q:buildingsource"/> and then build the <literal>build-testing-drivers</literal> target: <programlisting> - cd build - ../lib/ant/bin/ant -f build.xml build-testing-drivers +cd build +../lib/ant/bin/ant -f build.xml build-testing-drivers </programlisting> - This produces + This produces <literal>../aj-build/jars/testing-drivers-all.jar</literal> which you can run as described in <literal>tests/readme-tests-module.html</literal>. @@ -4891,13 +4869,13 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec </question> <answer> <para>The AspectJ bytecode weaver has used BCEL for bytecode manipulation - since its first release. We have upgraded it extensively, to improve + since its first release. We have upgraded it extensively, to improve performance, support Java 5, etc. The BCEL developers have not incorporated our patches, so we continue to maintain our own version. - Ours has been optimized for the AspectJ weaver and battle-hardened + Ours has been optimized for the AspectJ weaver and battle-hardened over years of development and use. At some point in the future, - the AspectJ weaver might be restructured to make it easy to see - whether another bytecode package offers the same stability, + the AspectJ weaver might be restructured to make it easy to see + whether another bytecode package offers the same stability, functionality, and performance, but for now we prefer using something that we know works well. </para> @@ -4932,12 +4910,12 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec <para>How do I submit a bug report?</para> </question> <answer> - <para>You can submit a bug from + <para>You can submit a bug from <ulink url="http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ"> http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ </ulink>. If it seems to be a bug in the compiler, - please attach a small test case (source code) + please attach a small test case (source code) to reproduce the problem. For more information on writing compiler test cases, see <xref linkend="q:ajcbugs"/>. @@ -5008,7 +4986,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec <listitem> <para> Describe what you think it takes, in AspectJ terms - (concepts, syntax, and semantics) from the + (concepts, syntax, and semantics) from the <ulink url="progguide/index.html">Programming Guide</ulink>... </para> </listitem> @@ -5025,7 +5003,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec about the problem (the most common being to confuse join points and pointcuts). The code is key to clarifying your question and getting a good - response. On the mail list, someone can reply by fixing your + response. On the mail list, someone can reply by fixing your code. In bugs, the developers can reproduce the problem immediately and start analyzing the fix. The code should not be incomplete; it should run (or fail) as-is, @@ -5033,7 +5011,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec </para> <para> For the mail lists, we try to follow the conventions for open-source - discussions that help avoid "the tragedy of the commons." + discussions that help avoid "the tragedy of the commons." For example conventions, see <ulink url="http://jakarta.apache.org/site/mail.html"> http://jakarta.apache.org/site/mail.html @@ -5072,9 +5050,9 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec <para> 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 + (most importantly) clear steps for reproducing the bug. + You may submit ajbrowser bugs against the IDE component of AspectJ + via the web form <ulink url="http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ"> http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ </ulink>. @@ -5083,7 +5061,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec 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 fix for you - and incorporate it into the next release. + and incorporate it into the next release. You can submit a patch by attaching it to the bug. </para> </answer> @@ -5097,15 +5075,15 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec </question> <answer> <para> - The best compiler bug report is a reproducible test case, + The best compiler bug report is a reproducible test case, standalone code that demonstrates the problem. - Sometimes with aspects, a test case requires several + Sometimes with aspects, a test case requires several files, if not some way to capture the behavior. Here's how we recommend submitting test cases: <orderedlist> <listitem> <para> - Write the test case so that when the compiler bug + Write the test case so that when the compiler bug is fixed, the test completes normally without output (e.g., expected compiler errors are issued, or classes produced run correctly). This usually @@ -5115,14 +5093,14 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec <listitem> <para> In the bug report, briefly summarize the bug. - If it is not obvious, be sure to specify + If it is not obvious, be sure to specify the expected output/behavior (e.g., compiler error on line 32) and, if the compile should complete, the main class to run. </para> </listitem> <listitem> <para> - Submit the bugs via the web form + Submit the bugs via the web form <ulink url="http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ"> http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ </ulink>. @@ -5148,9 +5126,9 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec </para> </question> <answer> - <para>The documentation available in the distribution is the + <para>The documentation available in the distribution is the best source for language and usage questions. You can also find - selected AspectJ papers and presentations on the + selected AspectJ papers and presentations on the <ulink url="http://www.parc.com/groups/csl/projects/aspectj/index.html"> PARC AspectJ page</ulink>. For links to Aspect-oriented programming materials in general, see @@ -5214,7 +5192,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec <para>Because the code is available to all, anyone can find and fix bugs. There is no need to hope for it to be fixed in the next product release. Those who encounter the bugs - are motivated to fix them, and there are more eyeballs on + are motivated to fix them, and there are more eyeballs on the code than in closed-source, so the quality tends to be high. This can be particularly true for the AspectJ community, which tends to be highly skilled. @@ -5227,11 +5205,11 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec </para> </listitem> <listitem> - <para>For a programming language which forms the basis of + <para>For a programming language which forms the basis of an entire solution stack, open source facilitates the kind of adoption -- tool integrations and significant projects -- - that develop and prove the technology for wider adoption. This - limits delays caused by waiting for the completion of standards + that develop and prove the technology for wider adoption. This + limits delays caused by waiting for the completion of standards process or promulgation by industry leaders, and also provides the proofs necessary for such adoption. </para> @@ -5255,7 +5233,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec integrating it into IDEs, or possibly incorporating it into standard Java with Sun's blessing. </para> - <para>We currently focus on developing for the 1.1 implementation + <para>We currently focus on developing for the 1.1 implementation which improves AspectJ in key areas: rapid incremental compilation, bytecode weaving, and IDE integration. </para> @@ -5284,22 +5262,22 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec works as described in an email to the users list by Jim Hugugin: </para> <para> - The AspectJ language was designed to support weaving at many different times: - compile, load, or even run-time in the JVM. Weaving into bytecodes at both - compile and load-time will definitely be provided in a future release. This - will allow weaving at compile-time into libraries for which source code is - not available. It will also support aspect-aware class loaders that can - perform weaving at load time on arbitrary classes. One advantage of a - language like AspectJ, rather than an explicit meta-tool like jiapi, is - that it separates the specification of a crosscutting concern from any + The AspectJ language was designed to support weaving at many different times: + compile, load, or even run-time in the JVM. Weaving into bytecodes at both + compile and load-time will definitely be provided in a future release. This + will allow weaving at compile-time into libraries for which source code is + not available. It will also support aspect-aware class loaders that can + perform weaving at load time on arbitrary classes. One advantage of a + language like AspectJ, rather than an explicit meta-tool like jiapi, is + that it separates the specification of a crosscutting concern from any particular implementation strategy for weaving. </para> <para> - ...AspectJ provides a language that can cleanly - capture crosscutting concerns while preserving the static type checking, + ...AspectJ provides a language that can cleanly + capture crosscutting concerns while preserving the static type checking, modularity, and composability of Java. </para> - <para>If you have an application for using aspects and bytecode, + <para>If you have an application for using aspects and bytecode, please let the AspectJ team know of your requirements. We expect to have a demonstration classloader available in the 1.1 release or soon thereafter. @@ -5314,9 +5292,9 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec </para> </question> <answer> - <para>The AspectJ team aims to keep the implementation bug-free and - up-to-date with the Java language, - to limit AspectJ language changes to those that + <para>The AspectJ team aims to keep the implementation bug-free and + up-to-date with the Java language, + to limit AspectJ language changes to those that are carefully considered, compelling, and backwards-compatible, and to deliver those language changes only in significant releases (1.0, 1.1). </para> @@ -5406,7 +5384,7 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec </tbody> </tgroup> </table> - <para> More details for 1.0 and earlier releases are available in + <para> More details for 1.0 and earlier releases are available in <ulink url="changes.html">changes.html</ulink>. </para> </answer> @@ -5425,9 +5403,9 @@ aspectj.doc.dir=C:/eclipse/aspectj-workspace/aj-build/dist/ide/eclipse/org.aspec for <literal>RFE</literal>'s ("requests for enhancement") by <ulink url="http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&bug_severity=enhancement"> selecting severity of "enhancement"</ulink>. - + Like many open-source projects, we don't make or promise - schedules, but we do follow a pattern of issuing preview releases + schedules, but we do follow a pattern of issuing preview releases which can give observers an idea of when a particular release might be available. </para> diff --git a/docs/pdGuideDB/ajcore.xml b/docs/pdGuideDB/ajcore.xml index 3ca82849f..7207df3cc 100644 --- a/docs/pdGuideDB/ajcore.xml +++ b/docs/pdGuideDB/ajcore.xml @@ -1,26 +1,26 @@ <chapter id="ajcore" xreflabel="AspectJ Core Files"> <title>AspectJ Core Files</title> - + <sect1 id="ajcore-introduction"> <title>Introduction</title> - + <para> When the compiler terminates abnormally, either because a particular kind of message was issued or an exception was thrown, an AspectJ core file will be produced. You will find it the working directory of the compiler and it will have a name that contains - the date and time that the file was produced + the date and time that the file was produced e.g. <literal>ajcore.20060810.173655.626.txt</literal>. The file contains details of the problem such as the exception thrown as well as information about the environment such as operating system and Java version. When submitting a bug, include this file whenever it is available.</para> - + <sect2 id="configuration" xreflabel="configuration"> <title>Configuring dump files</title> - - <para> By default AspectJ will only create an <literal>ajcore</literal> file - when an unexpected exception is thrown by the weaver or an + + <para> By default AspectJ will only create an <literal>ajcore</literal> file + when an unexpected exception is thrown by the weaver or an <literal>abort</literal> message is issued. However it is possible to disable this feature or enable files to - be produced under different circumstances. The table below lists the System + be produced under different circumstances. The table below lists the System properties that can be used to configure <literal>ajcore</literal> files. </para> <informaltable> <tgroup cols="3"> @@ -52,7 +52,7 @@ </entry> <entry> Message kind for which to generate <literal>ajcore</literal> - e.g. <literal>error</literal>. + e.g. <literal>error</literal>. </entry> </row> <row> @@ -63,7 +63,7 @@ <literal>none</literal> </entry> <entry> - The directory used for ajcore files. + The directory used for ajcore files. </entry> </row> </tbody> @@ -73,7 +73,7 @@ <sect2 id="ajcore-examples" xreflabel="AJCore File Examples"> <title>AJCore File Examples</title> - + <para> Below is an extract from an <literal>ajcore</literal> file. You will see details of the 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 @@ -191,8 +191,8 @@ 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) - ]]></programlisting> - +]]> </programlisting> + </sect2> </sect1> </chapter> diff --git a/docs/pdGuideDB/ltwdump.xml b/docs/pdGuideDB/ltwdump.xml index a17ceae5b..72554d043 100644 --- a/docs/pdGuideDB/ltwdump.xml +++ b/docs/pdGuideDB/ltwdump.xml @@ -1,55 +1,55 @@ <chapter id="ltwdump" xreflabel="Dumping classes during load-time weaving"> <title>Dumping classes during load-time weaving</title> - + <sect1 id="ltwdump-introduction"> <title>Introduction</title> - - <para> - Very rarely problems may be encountered with classes that have been + + <para> + Very rarely problems may be encountered with classes that have been load-time woven. - Symptoms will include incorrect program function or a Java exception such as + Symptoms will include incorrect program function or a Java exception such as <literal>java.lang.VerifyError</literal>. - In these situations it's most helpful to include the offending class - in the bug report. When using load-time weaving the woven classes are + In these situations it's most helpful to include the offending class + in the bug report. When using load-time weaving the woven classes are in memory only so to save them to disk configure - <literal>META-INF/aop.xml</literal> to dump the classes (by default - to an <literal>_ajdump</literal> subdirectory of the current working - directory). Also if the input class file is not available + <literal>META-INF/aop.xml</literal> to dump the classes (by default + to an <literal>_ajdump</literal> subdirectory of the current working + directory). Also if the input class file is not available (e.g. it is a generated proxy or has already been instrumented by another agent) you can configure the weaver to dump the input classes as well. </para> <sect2 id="ltw-examples" xreflabel="ltwdump-configuration"> <title>Configuring bytecode dumping in load-time weaving</title> <para> - For details of how to configure byte-code dumping, see the - AspectJ Development Environment Guide section on + For details of how to configure byte-code dumping, see the + AspectJ Development Environment Guide section on <ulink url="../devguide/ltw-configuration.html#configuring-load-time-weaving-with-aopxml-files"> - Configuring Load-time Weaving</ulink>. + Configuring Load-time Weaving</ulink>. Following is a simple example. </para> </sect2> <sect2 id="ltwdump-examples" xreflabel="LTW Dump Examples"> <title>LTW Dump Examples</title> - - <para> The following <literal>META-INF/aop.xml</literal> will + + <para> The following <literal>META-INF/aop.xml</literal> will weave classes in the <literal>com.foo</literal> package (and subpackages) but not - CGLIB generated classes in the <literal>com.foo.bar</literal> package (and subpackages). + CGLIB generated classes in the <literal>com.foo.bar</literal> package (and subpackages). It will also ensure all woven byte-code is dumped both before and after weaving. </para> <programlisting><![CDATA[ - <aspectj> - <aspects> - <aspect name="ataspectj.EmptyAspect"/> - </aspects> - <weaver options="-verbose -debug"> - <dump within="com.foo.bar..*" beforeandafter="true"/> - <include within="com.foo..*"/> - <exclude within="com.foo.bar..*CGLIB*"/> - </weaver> - </aspectj> - ]]></programlisting> - +<aspectj> + <aspects> + <aspect name="ataspectj.EmptyAspect"/> + </aspects> + <weaver options="-verbose -debug"> + <dump within="com.foo.bar..*" beforeandafter="true"/> + <include within="com.foo..*"/> + <exclude within="com.foo.bar..*CGLIB*"/> + </weaver> +</aspectj> +]]></programlisting> + <para> You should see messages similar to this: </para> <programlisting><![CDATA[ @@ -59,15 +59,15 @@ [WeavingURLClassLoader] info register aspect ataspectj.EmptyAspect [WeavingURLClassLoader] debug not weaving 'com.foo.bar.Test$$EnhancerByCGLIB$$12345' [WeavingURLClassLoader] debug weaving 'com.foo.bar.Test' - ]]></programlisting> - +]]></programlisting> + <para> On disk you would find the following files: </para> <programlisting><![CDATA[ - _ajdump/_before/com/foo/bar/Test.class - _ajdump/com/foo/bar/Test.class - ]]></programlisting> - +_ajdump/_before/com/foo/bar/Test.class +_ajdump/com/foo/bar/Test.class +]]></programlisting> + </sect2> </sect1> </chapter> diff --git a/docs/pdGuideDB/messages.xml b/docs/pdGuideDB/messages.xml index 8d2a2ab97..9d2caf0b5 100644 --- a/docs/pdGuideDB/messages.xml +++ b/docs/pdGuideDB/messages.xml @@ -1,6 +1,6 @@ <chapter id="messages" xreflabel="Messages"> <title>Messages</title> - + <sect1 id="messages-introduction"> <title>Introduction</title> <para> @@ -11,47 +11,47 @@ which are hidden. However, when investigating unexpected behavior it's helpful to show them. This section describes how to configure messages, presents some problem scenarios when - compiling or doing load-time weaving, and summarizes some of the + compiling or doing load-time weaving, and summarizes some of the more relevant messages. </para> - <sect2 id="messages-introduction-config" + <sect2 id="messages-introduction-config" xreflabel="messages-configuration"> <title>Configuring Messages</title> <para> - The compiler offers <literal>-verbose</literal>, - <literal>-warning</literal>, and <literal>-XLint</literal> options - when invoked using the command-line, Ant, or embedded in an IDE. - All options are listed in the AspectJ Development Environment Guide - sections for - <ulink url="../devguide/ajc-ref.html">Ajc</ulink> and + The compiler offers <literal>-verbose</literal>, + <literal>-warning</literal>, and <literal>-XLint</literal> options + when invoked using the command-line, Ant, or embedded in an IDE. + All options are listed in the AspectJ Development Environment Guide + sections for + <ulink url="../devguide/ajc-ref.html">Ajc</ulink> and <ulink url="../devguide/antTasks-iajc.html">Ant Tasks</ulink>. - The <ulink url="../devguide/ltw.html">Load-time Weaving</ulink> + The <ulink url="../devguide/ltw.html">Load-time Weaving</ulink> section describes how to use XML configuration files and system properties to pass options to the weaver. (You can also pass options to the weaver using system properties in build- - time weaving.) + time weaving.) The <literal>-verbose</literal> option has the effect of including messages level "info", which are normally ignored. Both <literal>warning</literal> and <literal>XLint</literal> - enable you to identify specific messages to emit, but warning - messages tend to be the same provided by the underlying Eclipse - JDT (Java) compiler, while XLint messages are emitted by the + enable you to identify specific messages to emit, but warning + messages tend to be the same provided by the underlying Eclipse + JDT (Java) compiler, while XLint messages are emitted by the AspectJ compiler or weaver. Obviously, during load-time weaving only weaver messages will be emitted. Similarly, if aspects are compiled but not woven, then only compiler messages will be emitted. However, the usual case for the compiler/weaver working at build time is to emit both compiler and weaver messages. </para> - - <para> The tables below list some options, System Properties (for LTW only) and Java 5 annotations + + <para> The tables below list some options, System Properties (for LTW only) and Java 5 annotations used to control AspectJ messages. The method - of configuration depends on your environment so please refer to the relevant - documentation for - <ulink url="../devguide/ajc-ref.html">ajc</ulink>, - <ulink url="../devguide/antTasks.html">Ant</ulink> or - <ulink url="../devguide/ltw-configuration.html#weaver-options">LTW</ulink>. + of configuration depends on your environment so please refer to the relevant + documentation for + <ulink url="../devguide/ajc-ref.html">ajc</ulink>, + <ulink url="../devguide/antTasks.html">Ant</ulink> or + <ulink url="../devguide/ltw-configuration.html#weaver-options">LTW</ulink>. </para> - + <para> <informaltable> <tgroup cols="2"> @@ -105,15 +105,15 @@ </entry> <entry> In Ant tasks and LTW respectively specify the class to receive all messages. - See + See <ulink url="../devguide/antTasks-iajc.html#antTasks-iajc-options"> iajc task options</ulink> or <ulink url="../devguide/ltw-configuration.html#weaver-options"> Weaver Options</ulink>. </entry> </row> - -<!-- We need full javadoc for this API + +<!-- We need full javadoc for this API <row> <entry> <literal>org.aspectj.tools.Main.setMessageHolder(..)</literal> @@ -123,7 +123,7 @@ outside of Ant. </entry> </row> ---> +--> </tbody> </tgroup> </informaltable> @@ -144,7 +144,7 @@ <literal>aj.weaving.verbose</literal> </entry> <entry> - Show informational messages including AspectJ version and build date + Show informational messages including AspectJ version and build date (same as <literal>-verbose</literal> option). </entry> </row> @@ -162,7 +162,7 @@ <literal>org.aspectj.weaving.messages</literal> </entry> <entry> - Set this system property to enable tracing of all compiler + Set this system property to enable tracing of all compiler messages. See <xref linkend="trace-configuration"/>. </entry> </row> @@ -170,7 +170,7 @@ </tgroup> </informaltable> </para> - + <para> <informaltable> <tgroup cols="2"> @@ -194,39 +194,39 @@ </tgroup> </informaltable> </para> - - </sect2> - </sect1> + + </sect2> + </sect1> <sect1 id="messages-scenarios"> <title>Message scenarios</title> - + <sect2 id="messages-scenarios-ct"> <title>Compile-time weaving scenarios</title> <sect3 id="messages-scenarios-ct-adviceNotWoven"> <title>Advice not woven</title> <para>This means that the pointcut for the advice did not match, - and it should be debugged as described in + and it should be debugged as described in <xref linkend="pointcuts"/>.</para> </sect3> </sect2> - + <sect2 id="messages-scenarios-ltw"> <title>Load-time weaving scenarios</title> - + <para> You can use <literal>META-INF/aop.xml</literal> to control which messages are produced during LTW. The following example will produce basic informational messages about the lifecyle of the weaver in addition to any warning or error messages. </para> <programlisting><![CDATA[ - <aspectj> - <weaver options="-verbose"> - </weaver> - </aspectj> - ]]></programlisting> - - <para>The messages indicate which <literal>META-INF/aop.xml</literal> - configurations file(s) are being used. Each message is also preceeded by the +<aspectj> + <weaver options="-verbose"> + </weaver> +</aspectj> +]]></programlisting> + + <para>The messages indicate which <literal>META-INF/aop.xml</literal> + configurations file(s) are being used. Each message is also preceeded by the name of the 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. </para> @@ -238,25 +238,25 @@ [AppClassLoader@92e78c] info using configuration /C:/temp/META-INF/aop-ajc.xml [AppClassLoader@92e78c] info register aspect ExceptionHandler [AppClassLoader@92e78c] info processing reweavable type ExceptionHandler: ExceptionHandler.aj - ]]></programlisting> - +]]></programlisting> + <sect3 id="messages-scenarios-ltw-adviceNotWoven"> <title>Advice not woven</title> <para> It is often difficult to determine, especially when using load-time weaving (LTW), why advice has not been woven. Here is a quick guide to the messages to - look for. Firstly if you use the <literal>-verbose</literal> option you + look for. Firstly if you use the <literal>-verbose</literal> option you should see the following message when your aspect is registered: </para> <programlisting><![CDATA[ - info register aspect MyAspect - ]]></programlisting> +info register aspect MyAspect +]]></programlisting> - <para> Secondly if you use the <literal>-debug</literal> option you should + <para> Secondly if you use the <literal>-debug</literal> option you should see a message indicating that you class is being woven: </para> <programlisting><![CDATA[ - debug weaving 'HelloWorld' - ]]></programlisting> +debug weaving 'HelloWorld' +]]></programlisting> <para> However this does not mean that advice has actually been woven into your class; it says that the class has been passed to the weaver. To determine @@ -264,18 +264,18 @@ option which will cause a message to be issued each time a join point is woven: </para> <programlisting><![CDATA[ - weaveinfo Join point 'method-execution(void HelloWorld.main(java.lang.String[]))' ... - ]]></programlisting> - - <para>If advice is woven at this join point you should get the +weaveinfo Join point 'method-execution(void HelloWorld.main(java.lang.String[]))' ... +]]></programlisting> + + <para>If advice is woven at this join point you should get the corresponding message.</para> </sect3> </sect2> </sect1> - + <sect1 id="messages-xlint"> <title>Lint messages</title> - <para> + <para> The table below lists some useful <literal>-Xlint</literal> messages. </para> <informaltable> <tgroup cols="3"> @@ -297,8 +297,8 @@ <entry> If an aspect is not being woven, despite being registered, it could be that it has been excluded - by either an <literal>include</literal> or <literal>exclude</literal> - element in the + by either an <literal>include</literal> or <literal>exclude</literal> + element in the <literal>aspects</literal> section of <literal>META-INF/aop.xml</literal>. Enable this message to determine whether an aspect has been excluded. @@ -314,7 +314,7 @@ <entry> Issued when advice did not potentially affect any join points. This means the corresponding pointcut did not match any join - points in the program. This may be valid e.g., in library + points in the program. This may be valid e.g., in library aspects or code picking up error conditions, but often the programmer simply made a mistake in the pointcut. The best approach is to debug the pointcut. @@ -356,7 +356,7 @@ </entry> <entry> Before AspectJ 5, declare soft used to soften runtime exceptions - (unnecessarily). Since then, it does not but does issue this + (unnecessarily). Since then, it does not but does issue this warning in case the programmer did intend for the exception to be wrapped. </entry> @@ -381,5 +381,5 @@ </tgroup> </informaltable> </sect1> - + </chapter> diff --git a/docs/pdGuideDB/trace.xml b/docs/pdGuideDB/trace.xml index 21cc7d796..6ff915738 100644 --- a/docs/pdGuideDB/trace.xml +++ b/docs/pdGuideDB/trace.xml @@ -1,29 +1,29 @@ <chapter id="trace" xreflabel="Tracing"> <title>Tracing</title> - + <sect1 id="trace-introduction"> <title>Introduction</title> - - <para> + + <para> The AspectJ developers have instrumented the compiler/weaver with many "trace" messages for their own debugging use. These remain in - the production releases because tracing helps when it is hard to + the production releases because tracing helps when it is hard to isolate the problem in a test case. This sections describes how to enable tracing so you can provide trace information on bug reports. - </para> - <para> - The usual approach to opening a report on Bugzilla is to describe the symptoms of the + </para> + <para> + The usual approach to opening a report on Bugzilla is to describe the symptoms of the problem and attach a simple testcase. This allows the AspectJ team to try and reproduce the problem in an attempt to fix it as well as improve the test suite. Unfortunately it may not be possible - to produce such a testcase either because your program is too large or is commercially sensitive. Alternatively + to produce such a testcase either because your program is too large or is commercially sensitive. Alternatively the problem may relate to your specific environment where AspectJ is being used and will not be reproducible by the AspectJ team. In each of these situations you can produce a trace of the compiler when the problem occurs instead. This can then be attached to the bug report. </para> <sect2 id="trace-configuration" xreflabel="Configuring Tracing"> <title>Configuring Tracing</title> - - <para> When available (Java 5 or later) AspectJ will use the + + <para> When available (Java 5 or later) AspectJ will use the <ulink url="http://java.sun.com/j2se/1.5.0/docs/guide/logging/index.html"> java.util.logging</ulink> infrastructure configured using a <literal>logging.properties</literal> file. By default only error @@ -31,14 +31,14 @@ method entry and exit events can be obtained using the appropriate configuration. All regular compiler messages can also be logged through the infrastructure by setting the <literal>org.aspectj.weaving.messages</literal> System property. </para> - - <para> If you are running the AspectJ compiler/weaver under JDK 1.4 or earlier, + + <para> If you are running the AspectJ compiler/weaver under JDK 1.4 or earlier, AspectJ will use a simple built-in trace - infrastructure that logs to stderr. This is enabled by setting the + infrastructure that logs to stderr. This is enabled by setting the <literal>org.aspectj.weaving.tracing.enabled</literal> System property. You may also override the default behaviour or provide your own trace implementation using the <literal>org.aspectj.weaving.tracing.factory</literal> System property. </para> - + <para> The table below lists the System properties that can be used to configure tracing. </para> <informaltable> <tgroup cols="2"> @@ -73,10 +73,10 @@ </entry> <entry> Select trace infrastructure. Specify the fully qualified class name - of the <literal>org.aspectj.weaver.tools.TraceFactory</literal> + of the <literal>org.aspectj.weaver.tools.TraceFactory</literal> interface to use a custom infrastructure. Specify a value of <literal>default</literal> to force AspectJ to use it's - built-in infrastructure. + built-in infrastructure. </entry> </row> <row> @@ -97,68 +97,68 @@ <sect2 id="trace-examples" xreflabel="trace-examples"> <title>Examples</title> - + <para> Using <literal>-Dorg.aspectj.tracing.factory=default</literal> to force AspectJ to use its internal infrastructure, - <literal>-Dorg.aspectj.tracing.enabled=true</literal> to turn it on and + <literal>-Dorg.aspectj.tracing.enabled=true</literal> to turn it on and <literal>-Dorg.aspectj.tracing.messages=true</literal> to include messages running a simple HelloWorld with LTW will generate tracing to stderr. Below - is an extract from that trace with method arguments removed. + 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. </para> <programlisting><![CDATA[ -15:44:18.630 main > org.aspectj.weaver.loadtime.Aj.<init> +15:44:18.630 main > org.aspectj.weaver.loadtime.Aj.<init> 15:44:18.660 main < org.aspectj.weaver.loadtime.Aj.<init> 15:44:18.660 main > org.aspectj.weaver.loadtime.Aj.preProcess 15:44:18.660 main - org.aspectj.weaver.loadtime.Aj.preProcess 15:44:18.730 main > org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.<init> 15:44:18.730 main < org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.<init> -15:44:18.730 main > org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.initialize +15:44:18.730 main > org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.initialize 15:44:18.821 main I [AppClassLoader@92e78c] info AspectJ Weaver Version DEVELOPMENT ... 15:44:18.821 main > org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.parseDefinitions 15:44:18.821 main I [AppClassLoader@92e78c] info register classloader ... -15:44:18.821 main - org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.parseDefinitions -15:44:18.841 main - org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.parseDefinitions +15:44:18.821 main - org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.parseDefinitions +15:44:18.841 main - org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.parseDefinitions 15:44:18.841 main I [AppClassLoader@92e78c] info using configuration ... -15:44:18.891 main < org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.parseDefinitions +15:44:18.891 main < org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.parseDefinitions 15:44:19.021 main > org.aspectj.weaver.World$TypeMap.<init> 15:44:19.021 main < org.aspectj.weaver.World$TypeMap.<init> 15:44:19.021 main > org.aspectj.weaver.CrosscuttingMembersSet.<init> 15:44:19.021 main < org.aspectj.weaver.CrosscuttingMembersSet.<init> 15:44:19.021 main > org.aspectj.weaver.Lint.<init> 15:44:19.021 main < org.aspectj.weaver.Lint.<init> -15:44:19.021 main > org.aspectj.weaver.World.<init> +15:44:19.021 main > org.aspectj.weaver.World.<init> 15:44:19.111 main < org.aspectj.weaver.World.<init> -15:44:19.201 main > org.aspectj.weaver.bcel.BcelWeaver.<init> +15:44:19.201 main > org.aspectj.weaver.bcel.BcelWeaver.<init> 15:44:19.201 main < org.aspectj.weaver.bcel.BcelWeaver.<init> -15:44:19.201 main > org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.registerDefinitions -15:44:19.211 main > org.aspectj.weaver.bcel.BcelWeaver.setReweavableMode +15:44:19.201 main > org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.registerDefinitions +15:44:19.211 main > org.aspectj.weaver.bcel.BcelWeaver.setReweavableMode 15:44:19.351 main < org.aspectj.weaver.bcel.BcelWeaver.setReweavableMode -15:44:19.351 main > org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.registerAspects +15:44:19.351 main > org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.registerAspects 15:44:19.351 main I [AppClassLoader@92e78c] info register aspect Aspect -15:44:19.351 main > org.aspectj.weaver.bcel.BcelWeaver.addLibraryAspect -15:44:19.501 main - org.aspectj.weaver.bcel.BcelWorld.lookupJavaClass -15:44:19.632 main > org.aspectj.weaver.CrosscuttingMembersSet.addOrReplaceAspect -15:44:19.792 main < org.aspectj.weaver.CrosscuttingMembersSet.addOrReplaceAspect -15:44:19.792 main < org.aspectj.weaver.bcel.BcelWeaver.addLibraryAspect -15:44:19.792 main < org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.registerAspects -15:44:19.792 main < org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.registerDefinitions -15:44:19.792 main > org.aspectj.weaver.bcel.BcelWeaver.prepareForWeave +15:44:19.351 main > org.aspectj.weaver.bcel.BcelWeaver.addLibraryAspect +15:44:19.501 main - org.aspectj.weaver.bcel.BcelWorld.lookupJavaClass +15:44:19.632 main > org.aspectj.weaver.CrosscuttingMembersSet.addOrReplaceAspect +15:44:19.792 main < org.aspectj.weaver.CrosscuttingMembersSet.addOrReplaceAspect +15:44:19.792 main < org.aspectj.weaver.bcel.BcelWeaver.addLibraryAspect +15:44:19.792 main < org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.registerAspects +15:44:19.792 main < org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.registerDefinitions +15:44:19.792 main > org.aspectj.weaver.bcel.BcelWeaver.prepareForWeave 15:44:19.822 main < org.aspectj.weaver.bcel.BcelWeaver.prepareForWeave 15:44:19.822 main > org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.weaveAndDefineConcete... 15:44:19.822 main < org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.weaveAndDefineConcete... -15:44:19.822 main < org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.initialize -15:44:19.822 main > org.aspectj.weaver.tools.WeavingAdaptor.weaveClass -... - ]]></programlisting> - +15:44:19.822 main < org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.initialize +15:44:19.822 main > org.aspectj.weaver.tools.WeavingAdaptor.weaveClass +... +]]></programlisting> + <para> Alternatively when running under Java 5 the <literal>logging.properties</literal> file below could be used to configure Java Logging. The resulting - file, just containing trace for the + file, just containing trace for the <literal>org.aspectj.weaver.loadtime</literal> package, will be - written to <literal>java0.log</literal> in your <literal>user.home</literal> directory. + written to <literal>java0.log</literal> in your <literal>user.home</literal> directory. </para> <programlisting><![CDATA[ @@ -172,15 +172,15 @@ java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter java.util.logging.FileHandler.level = FINER org.aspectj.weaver.loadtime.level = FINER - ]]></programlisting> - - <para> +]]></programlisting> + + <para> By setting the System property <literal>-Dorg.aspectj.tracing.debug=true</literal> you should see a message confirming which trace infrastructure is being used. </para> <programlisting><![CDATA[ - TraceFactory.instance=org.aspectj.weaver.tools.Jdk14TraceFactory@12dacd1 - ]]></programlisting> +TraceFactory.instance=org.aspectj.weaver.tools.Jdk14TraceFactory@12dacd1 +]]></programlisting> </sect2> </sect1> </chapter> diff --git a/docs/progGuideDB/examples.xml b/docs/progGuideDB/examples.xml index e3f109e98..f0ce3808e 100644 --- a/docs/progGuideDB/examples.xml +++ b/docs/progGuideDB/examples.xml @@ -541,14 +541,14 @@ public aspect ComparablePoint { </para> <para> - The method <literal>Object.hashCode</literal> returns an + The method <literal>Object.hashCode</literal> returns an integer, suitable for use as a hash table key. It is not required - that two objects which are not equal (according to the + that two objects which are not equal (according to the <literal>equals</literal> method) return different integer results from <literal>hashCode</literal> but it can - improve performance when the integer is used as a key into a - data structure. However, any two objects which are equal - must return the same integer value from a call to + improve performance when the integer is used as a key into a + data structure. However, any two objects which are equal + must return the same integer value from a call to <literal>hashCode</literal>. Since the default implementation of <literal>Object.equals</literal> returns <literal>true</literal> only when two objects are identical, we need to redefine both @@ -851,7 +851,7 @@ aspect TraceMyClasses { </para> <programlisting><![CDATA[ - ajc -argfile tracing/tracev1.lst +ajc -argfile tracing/tracev1.lst ]]></programlisting> <para> @@ -969,7 +969,7 @@ public aspect TraceMyClasses extends Trace { </para> <programlisting><![CDATA[ - ajc -argfile tracing/tracev2.lst +ajc -argfile tracing/tracev2.lst ]]></programlisting> <para> @@ -1099,7 +1099,7 @@ abstract aspect Trace { </para> <para> - This example examines an aspect that makes Point objects into + This example examines an aspect that makes Point objects into Java beans with bound properties. </para> @@ -1190,10 +1190,10 @@ class Point { <literal>Point</literal>'s "beanness". The first thing it does is privately declare that each <literal>Point</literal> has a <literal>support</literal> field that holds reference to an - instance of <classname>PropertyChangeSupport</classname>. + instance of <classname>PropertyChangeSupport</classname>. <programlisting><![CDATA[ - private PropertyChangeSupport Point.support = new PropertyChangeSupport(this); +private PropertyChangeSupport Point.support = new PropertyChangeSupport(this); ]]></programlisting> The property change support object must be constructed with a @@ -1210,24 +1210,24 @@ class Point { which delegate the work to the property change support object: <programlisting><![CDATA[ - public void Point.addPropertyChangeListener(PropertyChangeListener listener){ - support.addPropertyChangeListener(listener); - } - public void Point.addPropertyChangeListener(String propertyName, - PropertyChangeListener listener){ +public void Point.addPropertyChangeListener(PropertyChangeListener listener){ + support.addPropertyChangeListener(listener); +} +public void Point.addPropertyChangeListener(String propertyName, + PropertyChangeListener listener){ - support.addPropertyChangeListener(propertyName, listener); - } - public void Point.removePropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - support.removePropertyChangeListener(propertyName, listener); - } - public void Point.removePropertyChangeListener(PropertyChangeListener listener) { - support.removePropertyChangeListener(listener); - } - public void Point.hasListeners(String propertyName) { - support.hasListeners(propertyName); - } + support.addPropertyChangeListener(propertyName, listener); +} +public void Point.removePropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + support.removePropertyChangeListener(propertyName, listener); +} +public void Point.removePropertyChangeListener(PropertyChangeListener listener) { + support.removePropertyChangeListener(listener); +} +public void Point.hasListeners(String propertyName) { + support.hasListeners(propertyName); +} ]]></programlisting> </para> @@ -1237,7 +1237,7 @@ class Point { <classname>Serializable</classname> interface: <programlisting><![CDATA[ - declare parents: Point implements Serializable; +declare parents: Point implements Serializable; ]]></programlisting> Implementing this interface in Java does not require any methods to @@ -1254,7 +1254,7 @@ class Point { <literal>Y</literal> properties, calls the original <literal>set</literal> method and then fires the appropriate property change event according to which set method was - called. + called. </para> <programlisting><![CDATA[ @@ -1323,33 +1323,33 @@ aspect BoundPoint { </para> <programlisting><![CDATA[ - class Demo implements PropertyChangeListener { +class Demo implements PropertyChangeListener { - static final String fileName = "test.tmp"; + static final String fileName = "test.tmp"; - public void propertyChange(PropertyChangeEvent e){ - System.out.println("Property " + e.getPropertyName() + " changed from " + - e.getOldValue() + " to " + e.getNewValue() ); - } - - public static void main(String[] args){ - Point p1 = new Point(); - p1.addPropertyChangeListener(new Demo()); - System.out.println("p1 =" + p1); - p1.setRectangular(5,2); - System.out.println("p1 =" + p1); - p1.setX( 6 ); - p1.setY( 3 ); - System.out.println("p1 =" + p1); - p1.offset(6,4); - System.out.println("p1 =" + p1); - save(p1, fileName); - Point p2 = (Point) restore(fileName); - System.out.println("Had: " + p1); - System.out.println("Got: " + p2); - } - ... + public void propertyChange(PropertyChangeEvent e){ + System.out.println("Property " + e.getPropertyName() + " changed from " + + e.getOldValue() + " to " + e.getNewValue() ); } + + public static void main(String[] args){ + Point p1 = new Point(); + p1.addPropertyChangeListener(new Demo()); + System.out.println("p1 =" + p1); + p1.setRectangular(5,2); + System.out.println("p1 =" + p1); + p1.setX( 6 ); + p1.setY( 3 ); + System.out.println("p1 =" + p1); + p1.offset(6,4); + System.out.println("p1 =" + p1); + save(p1, fileName); + Point p2 = (Point) restore(fileName); + System.out.println("Had: " + p1); + System.out.println("Got: " + p2); + } + ... +} ]]></programlisting> </sect3> @@ -1381,7 +1381,7 @@ java bean.Demo <para> This demo illustrates how the Subject/Observer design pattern can be - coded with aspects. + coded with aspects. </para> <para> @@ -1419,26 +1419,26 @@ java bean.Demo </para> <programlisting><![CDATA[ - interface Subject { - void addObserver(Observer obs); - void removeObserver(Observer obs); - Vector getObservers(); - Object getData(); - } +interface Subject { + void addObserver(Observer obs); + void removeObserver(Observer obs); + Vector getObservers(); + Object getData(); +} ]]></programlisting> - <para> + <para> The <classname>Observer</classname> interface is just as simple, with methods to set and get <classname>Subject</classname> objects, and a method to call when the subject gets updated. </para> <programlisting><![CDATA[ - interface Observer { - void setSubject(Subject s); - Subject getSubject(); - void update(); - } +interface Observer { + void setSubject(Subject s); + Subject getSubject(); + void update(); +} ]]></programlisting> <para> @@ -1449,32 +1449,32 @@ java bean.Demo </para> <programlisting><![CDATA[ - abstract aspect SubjectObserverProtocol { +abstract aspect SubjectObserverProtocol { - abstract pointcut stateChanges(Subject s); + abstract pointcut stateChanges(Subject s); - after(Subject s): stateChanges(s) { - for (int i = 0; i < s.getObservers().size(); i++) { - ((Observer)s.getObservers().elementAt(i)).update(); - } - } + after(Subject s): stateChanges(s) { + for (int i = 0; i < s.getObservers().size(); i++) { + ((Observer)s.getObservers().elementAt(i)).update(); + } + } - private Vector Subject.observers = new Vector(); - public void Subject.addObserver(Observer obs) { - observers.addElement(obs); - obs.setSubject(this); - } - public void Subject.removeObserver(Observer obs) { - observers.removeElement(obs); - obs.setSubject(null); - } - public Vector Subject.getObservers() { return observers; } + private Vector Subject.observers = new Vector(); + public void Subject.addObserver(Observer obs) { + observers.addElement(obs); + obs.setSubject(this); + } + public void Subject.removeObserver(Observer obs) { + observers.removeElement(obs); + obs.setSubject(null); + } + public Vector Subject.getObservers() { return observers; } - private Subject Observer.subject = null; - public void Observer.setSubject(Subject s) { subject = s; } - public Subject Observer.getSubject() { return subject; } + private Subject Observer.subject = null; + public void Observer.setSubject(Subject s) { subject = s; } + public Subject Observer.getSubject() { return subject; } - } +} ]]></programlisting> <para> @@ -1482,7 +1482,7 @@ java bean.Demo pointcut that extending aspects can override. It defines advice that should run after the join points of the pointcut. And it declares an inter-type field and two inter-type methods so that - each <literal>Observer</literal> can hold onto its <literal>Subject</literal>. + each <literal>Observer</literal> can hold onto its <literal>Subject</literal>. </para> </sect3> @@ -1497,28 +1497,28 @@ java bean.Demo </para> <programlisting><![CDATA[ - class Button extends java.awt.Button { - - static final Color defaultBackgroundColor = Color.gray; - static final Color defaultForegroundColor = Color.black; - static final String defaultText = "cycle color"; - - Button(Display display) { - super(); - setLabel(defaultText); - setBackground(defaultBackgroundColor); - setForeground(defaultForegroundColor); - addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - Button.this.click(); - } - }); - display.addToFrame(this); - } +class Button extends java.awt.Button { + + static final Color defaultBackgroundColor = Color.gray; + static final Color defaultForegroundColor = Color.black; + static final String defaultText = "cycle color"; + + Button(Display display) { + super(); + setLabel(defaultText); + setBackground(defaultBackgroundColor); + setForeground(defaultForegroundColor); + addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Button.this.click(); + } + }); + display.addToFrame(this); + } - public void click() {} + public void click() {} - } +} ]]></programlisting> <para> @@ -1531,24 +1531,24 @@ java bean.Demo </para> <programlisting><![CDATA[ - class ColorLabel extends Label { +class ColorLabel extends Label { - ColorLabel(Display display) { - super(); - display.addToFrame(this); - } + ColorLabel(Display display) { + super(); + display.addToFrame(this); + } - final static Color[] colors = {Color.red, Color.blue, - Color.green, Color.magenta}; - private int colorIndex = 0; - private int cycleCount = 0; - void colorCycle() { - cycleCount++; - colorIndex = (colorIndex + 1) % colors.length; - setBackground(colors[colorIndex]); - setText("" + cycleCount); - } - } + final static Color[] colors = {Color.red, Color.blue, + Color.green, Color.magenta}; + private int colorIndex = 0; + private int cycleCount = 0; + void colorCycle() { + cycleCount++; + colorIndex = (colorIndex + 1) % colors.length; + setBackground(colors[colorIndex]); + setText("" + cycleCount); + } +} ]]></programlisting> <para> @@ -1577,7 +1577,8 @@ aspect SubjectObserverProtocolImpl extends SubjectObserverProtocol { target(s) && call(void Button.click()); -}]]></programlisting> +} +]]></programlisting> <para> It does this by assuring that <classname>Button</classname> and @@ -1594,7 +1595,7 @@ aspect SubjectObserverProtocolImpl extends SubjectObserverProtocol { <sect3> <title>Compiling and Running</title> - <para> + <para> <classname>Demo</classname> is the top class that starts this demo. It instantiates a two buttons and three observers and links them together as subjects and observers. So to run the demo, go to @@ -1602,8 +1603,8 @@ aspect SubjectObserverProtocolImpl extends SubjectObserverProtocol { </para> <programlisting><![CDATA[ - ajc -argfile observer/files.lst - java observer.Demo +ajc -argfile observer/files.lst +java observer.Demo ]]></programlisting> </sect3> @@ -1803,43 +1804,43 @@ public class Customer { </para> <programlisting><![CDATA[ - abstract class Connection { +abstract class Connection { - public static final int PENDING = 0; - public static final int COMPLETE = 1; - public static final int DROPPED = 2; + public static final int PENDING = 0; + public static final int COMPLETE = 1; + public static final int DROPPED = 2; - Customer caller, receiver; - private int state = PENDING; + Customer caller, receiver; + private int state = PENDING; - Connection(Customer a, Customer b) { - this.caller = a; - this.receiver = b; - } + Connection(Customer a, Customer b) { + this.caller = a; + this.receiver = b; + } - public int getState(){ - return state; - } + public int getState(){ + return state; + } - public Customer getCaller() { return caller; } + public Customer getCaller() { return caller; } - public Customer getReceiver() { return receiver; } + public Customer getReceiver() { return receiver; } - void complete() { - state = COMPLETE; - System.out.println("connection completed"); - } + void complete() { + state = COMPLETE; + System.out.println("connection completed"); + } - void drop() { - state = DROPPED; - System.out.println("connection dropped"); - } + void drop() { + state = DROPPED; + System.out.println("connection dropped"); + } - public boolean connects(Customer c){ - return (caller == c || receiver == c); - } + public boolean connects(Customer c){ + return (caller == c || receiver == c); + } - } +} ]]></programlisting> </sect3> @@ -1854,23 +1855,23 @@ public class Customer { </para> <programlisting><![CDATA[ - class Local extends Connection { - Local(Customer a, Customer b) { - super(a, b); - System.out.println("[new local connection from " + - a + " to " + b + "]"); - } - } +class Local extends Connection { + Local(Customer a, Customer b) { + super(a, b); + System.out.println("[new local connection from " + + a + " to " + b + "]"); + } +} ]]></programlisting> <programlisting><![CDATA[ - class LongDistance extends Connection { - LongDistance(Customer a, Customer b) { - super(a, b); - System.out.println("[new long distance connection from " + - a + " to " + b + "]"); - } - } +class LongDistance extends Connection { + LongDistance(Customer a, Customer b) { + super(a, b); + System.out.println("[new long distance connection from " + + a + " to " + b + "]"); + } +} ]]></programlisting> </sect3> @@ -1913,22 +1914,22 @@ java telecom.BasicSimulation </para> <programlisting><![CDATA[ - class Timer { - long startTime, stopTime; +class Timer { + long startTime, stopTime; - public void start() { - startTime = System.currentTimeMillis(); - stopTime = startTime; - } + public void start() { + startTime = System.currentTimeMillis(); + stopTime = startTime; + } - public void stop() { - stopTime = System.currentTimeMillis(); - } + public void stop() { + stopTime = System.currentTimeMillis(); + } - public long getTime() { - return stopTime - startTime; - } - } + public long getTime() { + return stopTime - startTime; + } +} ]]></programlisting> </sect4> @@ -1963,14 +1964,14 @@ public aspect TimerLog { <para> The <classname>Timing</classname> aspect is declares an - inter-type field <literal>totalConnectTime</literal> for + inter-type field <literal>totalConnectTime</literal> for <classname>Customer</classname> to store the accumulated connection time per <classname>Customer</classname>. It also declares that - each <classname>Connection</classname> object has a timer. + each <classname>Connection</classname> object has a timer. <programlisting><![CDATA[ - public long Customer.totalConnectTime = 0; - private Timer Connection.timer = new Timer(); +public long Customer.totalConnectTime = 0; +private Timer Connection.timer = new Timer(); ]]></programlisting> Two pieces of after advice ensure that the timer is started when @@ -2029,7 +2030,7 @@ public aspect Timing { runs after <classname>Timing</classname>'s advice on the same join point. Finally, it declares inter-type methods and fields for <classname>Customer</classname> to handle the - <literal>totalCharge</literal>. + <literal>totalCharge</literal>. </para> <programlisting><![CDATA[ @@ -2097,10 +2098,10 @@ public aspect Billing { </para> <programlisting><![CDATA[ - protected void report(Customer c){ - Timing t = Timing.aspectOf(); - System.out.println(c + " spent " + t.getTotalConnectTime(c)); - } +protected void report(Customer c){ + Timing t = Timing.aspectOf(); + System.out.println(c + " spent " + t.getTotalConnectTime(c)); +} ]]></programlisting> </sect3> @@ -2115,8 +2116,8 @@ public aspect Billing { </para> <programlisting><![CDATA[ - ajc -argfile telecom/timing.lst - java telecom.TimingSimulation +ajc -argfile telecom/timing.lst +java telecom.TimingSimulation ]]></programlisting> <para> @@ -2125,8 +2126,8 @@ public aspect Billing { </para> <programlisting><![CDATA[ - ajc -argfile telecom/billing.lst - java telecom.BillingSimulation +ajc -argfile telecom/billing.lst +java telecom.BillingSimulation ]]></programlisting> </sect3> @@ -2199,8 +2200,8 @@ public aspect Billing { </para> <programlisting><![CDATA[ - public static void traceEntry(String str); - public static void traceExit(String str); +public static void traceEntry(String str); +public static void traceExit(String str); ]]></programlisting> <para> @@ -2210,7 +2211,7 @@ public aspect Billing { </para> <programlisting><![CDATA[ - Trace.traceEntry("Square.distance in " + toString()); +Trace.traceEntry("Square.distance in " + toString()); ]]></programlisting> <para> @@ -2219,8 +2220,8 @@ public aspect Billing { </para> <programlisting><![CDATA[ - public static void traceEntry(String str, Object obj); - public static void traceExit(String str, Object obj); +public static void traceEntry(String str, Object obj); +public static void traceExit(String str, Object obj); ]]></programlisting> <para> @@ -2230,7 +2231,7 @@ public aspect Billing { </para> <programlisting><![CDATA[ - Trace.traceEntry("Square.distance", this); +Trace.traceEntry("Square.distance", this); ]]></programlisting> <para> diff --git a/docs/progGuideDB/implementation.xml b/docs/progGuideDB/implementation.xml index 52da14d9c..e1fa05f2b 100644 --- a/docs/progGuideDB/implementation.xml +++ b/docs/progGuideDB/implementation.xml @@ -5,7 +5,7 @@ <sect1> <title>Compiler Notes</title> - <para> + <para> The initial implementations of AspectJ have all been compiler-based implementations. Certain elements of AspectJ's semantics are difficult to implement without making modifications @@ -25,7 +25,7 @@ </para> <programlisting><![CDATA[ - before(): get(int Point.x) { System.out.println("got x"); } +before(): get(int Point.x) { System.out.println("got x"); } ]]></programlisting> <para> @@ -36,7 +36,7 @@ compiled, whether changes were made later, etc. </para> - <para> + <para> But AspectJ implementations are permitted to deviate from this in a well-defined way -- they are permitted to advise only accesses in <emphasis>code the implementation controls</emphasis>. Each @@ -67,11 +67,11 @@ can be advised only if ajc controls the bytecode for the method or constructor body in question. The end of an exception handler is underdetermined in bytecode, - so ajc will not implement after or around advice on handler join + so ajc will not implement after or around advice on handler join points. - Similarly, ajc cannot implement around advice on initialization - or preinitialization join points. - In cases where ajc cannot implement advice, it will emit a + Similarly, ajc cannot implement around advice on initialization + or preinitialization join points. + In cases where ajc cannot implement advice, it will emit a compile-time error noting this as a compiler limitation. </para> @@ -100,35 +100,35 @@ </para> <para> When declaring members on interfaces, the implementation must - control both the interface and the top-level implementors of + control both the interface and the top-level implementors of that interface (the classes that implement the interface but do not have a superclass that implements the interface). You may weave these separately, but be aware that you will get runtime exceptions if you run the affected top-level classes - without the interface as produced by the same ajc implementation. - Any intertype declaration of an abstract method on an interface - must be specified as public, you will get a compile time error - message indicating this is a compiler limitation if you do not + without the interface as produced by the same ajc implementation. + Any intertype declaration of an abstract method on an interface + must be specified as public, you will get a compile time error + message indicating this is a compiler limitation if you do not specify public. A non-abstract method declared on an interface can use any access modifier except protected. Note that this is - different to normal Java rules where all members declared in + different to normal Java rules where all members declared in an interface are implicitly public. - Finally, note that one cannot define static fields or methods + Finally, note that one cannot define static fields or methods on interfaces. </para> <para> - When declaring methods on target types, only methods declared - public are recognizable in the bytecode, so methods must be - declared public to be overridden in any subtype or to be called + When declaring methods on target types, only methods declared + public are recognizable in the bytecode, so methods must be + declared public to be overridden in any subtype or to be called from code in a later compile using the target type as a library. </para> - + <para> Other AspectJ implementations, indeed, future versions of ajc, may define <emphasis>code the implementation controls</emphasis> more liberally or restrictively, so long as they comport with the Java language. For example, the <literal>call</literal> pointcut does - not pick out reflective calls to a method implemented in + not pick out reflective calls to a method implemented in <literal>java.lang.reflect.Method.invoke(Object, Object[])</literal>. Some suggest that the call "happens" and the call pointcut should pick it out, but the AspectJ language shouldn't anticipate what happens @@ -172,12 +172,12 @@ </para> <programlisting><![CDATA[ - class Test { - void main(String[] args) { - System.out.println(Test.class); // calls Class.forName - System.out.println(args[0] + args[1]); // calls StringBuffer.append - } - } +class Test { + void main(String[] args) { + System.out.println(Test.class); // calls Class.forName + System.out.println(args[0] + args[1]); // calls StringBuffer.append + } +} ]]></programlisting> <para>In short, the join point model of the current AspectJ @@ -217,7 +217,7 @@ </para> <programlisting><![CDATA[ - cflow(call(void foo()) || handler(java.io.IOException)) +cflow(call(void foo()) || handler(java.io.IOException)) ]]></programlisting> <para> will capture all join points in the control flow of a call to @@ -236,9 +236,9 @@ </para> <programlisting><![CDATA[ - before(): handler(java.io.IOException) && cflow(void parse()) { - System.out.println("about to handle an exception while parsing"); - } +before(): handler(java.io.IOException) && cflow(void parse()) { + System.out.println("about to handle an exception while parsing"); +} ]]></programlisting> <para> @@ -258,16 +258,16 @@ </para> <programlisting><![CDATA[ - class C { - double d = Math.sqrt(2); - } +class C { + double d = Math.sqrt(2); +} ]]></programlisting> <para> are considered part of constructors by the time AspectJ gets ahold of bytecode. That is, the assignment of d to the square root of two happens <emphasis>inside</emphasis> the default constructor of - C. + C. </para> <para> @@ -280,15 +280,15 @@ </para> <programlisting><![CDATA[ - aspect A { - C.new(Object o) {} // implicitly calls super() +aspect A { + C.new(Object o) {} // implicitly calls super() - public static void main(String[] args) { - System.out.println((new C() ).d); // prints 1.414... - System.out.println((new C(null)).d); // prints 0.0 - } + public static void main(String[] args) { + System.out.println((new C() ).d); // prints 1.414... + System.out.println((new C(null)).d); // prints 0.0 +} ]]></programlisting> - + <para> It is the job of an inter-type constructor to do all the required initialization, or to delegate to a <literal>this</literal> @@ -302,8 +302,8 @@ <para>Writing aspects in annotation-style is subject to the same bytecode limitations since the binary aspects take the same form and are woven in the same way. However, the implementation - differences (e.g., the mechanism for implementing around advice) - may be apparent at runtime. See the documentation on annotation-style + differences (e.g., the mechanism for implementing around advice) + may be apparent at runtime. See the documentation on annotation-style for more information. </para> </sect1> @@ -311,7 +311,7 @@ <title>Summary of implementation requirements</title> <para> This summarizes the requirements of our implementation of AspectJ. - For more details, see the relevant sections of this guide. + For more details, see the relevant sections of this guide. </para> <itemizedlist spacing="compact"> <listitem> @@ -343,7 +343,7 @@ <para>Implementation Caveats</para> <itemizedlist spacing="compact"> <listitem> - <para>The initialization and preinitialization join points + <para>The initialization and preinitialization join points do not support around advice</para> </listitem> <listitem> @@ -355,7 +355,7 @@ </itemizedlist> </listitem> <listitem> - <para>Declaring members on an interface in an aspect affects only + <para>Declaring members on an interface in an aspect affects only the topmost implementing classes the implementation controls.</para> </listitem> <listitem> @@ -363,7 +363,7 @@ </listitem> <listitem> <para> - Runtime <literal>ClassCastException</literal> may result + Runtime <literal>ClassCastException</literal> may result from supplying a supertype of the actual type as an argument to proceed(..) in around advice.</para> </listitem> diff --git a/docs/progGuideDB/language.xml b/docs/progGuideDB/language.xml index c666c106a..48b0fa62d 100644 --- a/docs/progGuideDB/language.xml +++ b/docs/progGuideDB/language.xml @@ -623,10 +623,10 @@ interface MyInterface { ... } </para> <programlisting> - P --------------------- +P --------------------- + \ + \ cflow of P \ - \ cflow of P - \ </programlisting> @@ -639,16 +639,16 @@ interface MyInterface { ... } </para> <programlisting> - P --------------------- + P --------------------- + \ + \ cflow of P \ - \ cflow of P + \ \ - \ - \ - Q -------------\------- +Q -------------\------- + \ \ + \ cflow of Q \ cflow(P) && cflow(Q) \ \ - \ cflow of Q \ cflow(P) && cflow(Q) - \ \ </programlisting> <para> @@ -666,10 +666,10 @@ interface MyInterface { ... } </para> <programlisting> - P && Q ------------------- - \ - \ cflow of (P && Q) - \ +P && Q ------------------- + \ + \ cflow of (P && Q) + \ </programlisting> <para> @@ -715,7 +715,7 @@ aspect A { <para> The <literal>!within(<replaceable>A</replaceable>)</literal> - pointcut above is required to avoid the <literal>printPC</literal> + pointcut above is required to avoid the <literal>printPC</literal> pointcut applying to the <literal>System.out.println</literal> call in the advice body. If this was not present a recursive call would result as the pointcut would apply to its own advice. @@ -734,9 +734,9 @@ aspect A { </para> <programlisting><![CDATA[ - pointcut setter(): target(Point) && - (call(void setX(int)) || - call(void setY(int))); +pointcut setter(): target(Point) && + (call(void setX(int)) || + call(void setY(int))); ]]></programlisting> <para> @@ -751,9 +751,9 @@ aspect A { </para> <programlisting><![CDATA[ - pointcut setter(Point p): target(p) && - (call(void setX(int)) || - call(void setY(int))); +pointcut setter(Point p): target(p) && + (call(void setX(int)) || + call(void setY(int))); ]]></programlisting> <para> @@ -774,9 +774,9 @@ aspect A { </para> <programlisting><![CDATA[ - pointcut testEquality(Point p): target(Point) && - args(p) && - call(boolean equals(Object)); +pointcut testEquality(Point p): target(Point) && + args(p) && + call(boolean equals(Object)); ]]></programlisting> <para> @@ -796,9 +796,9 @@ aspect A { </para> <programlisting><![CDATA[ - pointcut testEquality(Point p1, Point p2): target(p1) && - args(p2) && - call(boolean equals(Object)); +pointcut testEquality(Point p1, Point p2): target(p1) && + args(p2) && + call(boolean equals(Object)); ]]></programlisting> <para> @@ -828,9 +828,9 @@ pointcut setter(Point p, int newval): target(p) && following pointcut definition will result in a compilation error: <programlisting><![CDATA[ - pointcut badPointcut(Point p1, Point p2): - (target(p1) && call(void setX(int))) || - (target(p2) && call(void setY(int))); +pointcut badPointcut(Point p1, Point p2): + (target(p1) && call(void setX(int))) || + (target(p2) && call(void setY(int))); ]]></programlisting> because <literal>p1</literal> is only bound when calling @@ -856,38 +856,38 @@ pointcut setter(Point p, int newval): target(p) && </para> <programlisting><![CDATA[ - class Handle { - Partner partner = new Partner(); +class Handle { + Partner partner = new Partner(); - public void foo() { partner.foo(); } - public void bar(int x) { partner.bar(x); } + public void foo() { partner.foo(); } + public void bar(int x) { partner.bar(x); } - public static void main(String[] args) { - Handle h1 = new Handle(); - h1.foo(); - h1.bar(2); - } + public static void main(String[] args) { + Handle h1 = new Handle(); + h1.foo(); + h1.bar(2); } +} - class Partner { - boolean isAlive() { return true; } - void foo() { System.out.println("foo"); } - void bar(int x) { System.out.println("bar " + x); } - } +class Partner { + boolean isAlive() { return true; } + void foo() { System.out.println("foo"); } + void bar(int x) { System.out.println("bar " + x); } +} - aspect HandleLiveness { - before(Handle handle): target(handle) && call(public * *(..)) { - if ( handle.partner == null || !handle.partner.isAlive() ) { - throw new DeadPartnerException(); - } +aspect HandleLiveness { + before(Handle handle): target(handle) && call(public * *(..)) { + if ( handle.partner == null || !handle.partner.isAlive() ) { + throw new DeadPartnerException(); } } +} - class DeadPartnerException extends RuntimeException {} +class DeadPartnerException extends RuntimeException {} ]]></programlisting> </sect2> - + <sect2 id="pointcut-best-practice" xreflabel="pointcut-best-practice"> <title>Writing good pointcuts</title> @@ -919,15 +919,15 @@ pointcut setter(Point p, int newval): target(p) && </listitem> </itemizedlist> <para> - A well written pointcut should + A well written pointcut should try and include at least the first two types (kinded and scoping), whilst the contextual designators may be included if wishing to - match based on join point context, or bind that context for use in the advice. Supplying either just a kinded designator or - just a contextual designator will work but could affect weaving performance (time and memory used) - due to all the extra processing and analysis. - Scoping designators are very fast to match, they can very quickly dismiss groups of join points that should not be further + match based on join point context, or bind that context for use in the advice. Supplying either just a kinded designator or + just a contextual designator will work but could affect weaving performance (time and memory used) + due to all the extra processing and analysis. + Scoping designators are very fast to match, they can very quickly dismiss groups of join points that should not be further processed - that is why a good pointcut should always include one if possible. </para> - + </sect2> </sect1> @@ -945,14 +945,14 @@ pointcut setter(Point p, int newval): target(p) && </para> <programlisting><![CDATA[ - pointcut setter(Point p1, int newval): target(p1) && args(newval) - (call(void setX(int) || - call(void setY(int))); +pointcut setter(Point p1, int newval): target(p1) && args(newval) + (call(void setX(int) || + call(void setY(int))); - before(Point p1, int newval): setter(p1, newval) { - System.out.println("About to set something in " + p1 + - " to the new value " + newval); - } +before(Point p1, int newval): setter(p1, newval) { + System.out.println("About to set something in " + p1 + + " to the new value " + newval); +} ]]></programlisting> <para> @@ -961,12 +961,12 @@ pointcut setter(Point p, int newval): target(p) && </para> <programlisting><![CDATA[ - before(Point p1, int newval): target(p1) && args(newval) - (call(void setX(int)) || - call(void setY(int))) { - System.out.println("About to set something in " + p1 + - " to the new value " + newval); - } +before(Point p1, int newval): target(p1) && args(newval) + (call(void setX(int)) || + call(void setY(int))) { + System.out.println("About to set something in " + p1 + + " to the new value " + newval); +} ]]></programlisting> <para> @@ -979,9 +979,9 @@ pointcut setter(Point p, int newval): target(p) && </para> <programlisting><![CDATA[ - before(Point p, int x): target(p) && args(x) && call(void setX(int)) { - if (!p.assertX(x)) return; - } +before(Point p, int x): target(p) && args(x) && call(void setX(int)) { + if (!p.assertX(x)) return; +} ]]></programlisting> <para> @@ -991,9 +991,9 @@ pointcut setter(Point p, int newval): target(p) && </para> <programlisting><![CDATA[ - after(Point p, int x): target(p) && args(x) && call(void setX(int)) { - if (!p.assertX(x)) throw new PostConditionViolation(); - } +after(Point p, int x): target(p) && args(x) && call(void setX(int)) { + if (!p.assertX(x)) throw new PostConditionViolation(); +} ]]></programlisting> <para> @@ -1004,9 +1004,9 @@ pointcut setter(Point p, int newval): target(p) && </para> <programlisting><![CDATA[ - after(Point p) returning(int x): target(p) && call(int getX()) { - System.out.println("Returning int value " + x + " for p = " + p); - } +after(Point p) returning(int x): target(p) && call(int getX()) { + System.out.println("Returning int value " + x + " for p = " + p); +} ]]></programlisting> <para> @@ -1018,9 +1018,9 @@ pointcut setter(Point p, int newval): target(p) && </para> <programlisting><![CDATA[ - after() throwing(Exception e): target(Point) && call(void setX(int)) { - System.out.println(e); - } +after() throwing(Exception e): target(Point) && call(void setX(int)) { + System.out.println(e); +} ]]></programlisting> <para> @@ -1059,7 +1059,7 @@ void around(Point p, int x): target(p) initialized to <literal>false</literal>: <programlisting><![CDATA[ - private boolean Server.disabled = false; +private boolean Server.disabled = false; ]]></programlisting> It is declared <literal>private</literal>, which means that it is @@ -1077,7 +1077,7 @@ void around(Point p, int x): target(p) arguments that returns whatever <literal>this.x</literal> is: <programlisting><![CDATA[ - public int Point.getX() { return this.x; } +public int Point.getX() { return this.x; } ]]></programlisting> Inside the body, <literal>this</literal> is the @@ -1092,7 +1092,7 @@ void around(Point p, int x): target(p) <literal>Point</literal>: <programlisting><![CDATA[ - public Point.new(int x, int y) { this.x = x; this.y = y; } +public Point.new(int x, int y) { this.x = x; this.y = y; } ]]></programlisting> </para> @@ -1103,7 +1103,7 @@ void around(Point p, int x): target(p) to zero: <programlisting><![CDATA[ - public int Point.x = 0; +public int Point.x = 0; ]]></programlisting> Because this is publically declared, it is an error if @@ -1117,7 +1117,7 @@ void around(Point p, int x): target(p) <literal>Comparable</literal> interface: <programlisting><![CDATA[ - declare parents: Point implements Comparable; +declare parents: Point implements Comparable; ]]></programlisting> Of course, this will be an error unless <literal>Point</literal> @@ -1129,7 +1129,7 @@ void around(Point p, int x): target(p) <literal>GeometricObject</literal> class. <programlisting><![CDATA[ - declare parents: Point extends GeometricObject; +declare parents: Point extends GeometricObject; ]]></programlisting> </para> @@ -1138,8 +1138,8 @@ void around(Point p, int x): target(p) following declarations <programlisting><![CDATA[ - public String Point.name; - public void Point.setName(String name) { this.name = name; } +public String Point.name; +public void Point.setName(String name) { this.name = name; } ]]></programlisting> publicly declare that Point has both a String field @@ -1155,13 +1155,13 @@ void around(Point p, int x): target(p) interface: <programlisting><![CDATA[ - aspect A { - private interface HasName {} - declare parents: (Point || Line || Square) implements HasName; +aspect A { + private interface HasName {} + declare parents: (Point || Line || Square) implements HasName; - private String HasName.name; - public String HasName.getName() { return name; } - } + private String HasName.name; + public String HasName.getName() { return name; } +} ]]></programlisting> This declares a marker interface <literal>HasName</literal>, and also declares that any @@ -1193,7 +1193,7 @@ void around(Point p, int x): target(p) aspect makes a private inter-type declaration of a field <programlisting><![CDATA[ - private int Foo.x; +private int Foo.x; ]]></programlisting> Then code in the aspect can refer to <literal>Foo</literal>'s @@ -1230,38 +1230,38 @@ void around(Point p, int x): target(p) </para> <programlisting><![CDATA[ - class Point { - int x, y; +class Point { + int x, y; - public void setX(int x) { this.x = x; } - public void setY(int y) { this.y = y; } + public void setX(int x) { this.x = x; } + public void setY(int y) { this.y = y; } - public static void main(String[] args) { - Point p = new Point(); - p.setX(3); p.setY(333); - } - } + public static void main(String[] args) { + Point p = new Point(); + p.setX(3); p.setY(333); + } +} - aspect PointAssertions { - - private boolean Point.assertX(int x) { - return (x <= 100 && x >= 0); - } - private boolean Point.assertY(int y) { - return (y <= 100 && y >= 0); - } - - before(Point p, int x): target(p) && args(x) && call(void setX(int)) { - if (!p.assertX(x)) { - System.out.println("Illegal value for x"); return; - } - } - before(Point p, int y): target(p) && args(y) && call(void setY(int)) { - if (!p.assertY(y)) { - System.out.println("Illegal value for y"); return; - } - } - } +aspect PointAssertions { + + private boolean Point.assertX(int x) { + return (x <= 100 && x >= 0); + } + private boolean Point.assertY(int y) { + return (y <= 100 && y >= 0); + } + + before(Point p, int x): target(p) && args(x) && call(void setX(int)) { + if (!p.assertX(x)) { + System.out.println("Illegal value for x"); return; + } + } + before(Point p, int y): target(p) && args(y) && call(void setY(int)) { + if (!p.assertY(y)) { + System.out.println("Illegal value for y"); return; + } + } +} ]]></programlisting> </sect2> @@ -1290,11 +1290,11 @@ void around(Point p, int x): target(p) </para> <programlisting><![CDATA[ - aspect TraceNonStaticMethods { - before(Point p): target(p) && call(* *(..)) { - System.out.println("Entering " + thisJoinPoint + " in " + p); - } - } +aspect TraceNonStaticMethods { + before(Point p): target(p) && call(* *(..)) { + System.out.println("Entering " + thisJoinPoint + " in " + p); + } +} ]]></programlisting> <para> @@ -1304,7 +1304,7 @@ void around(Point p, int x): target(p) arguments of the join point: <programlisting><![CDATA[ - thisJoinPoint.getArgs() +thisJoinPoint.getArgs() ]]></programlisting> In addition, it holds an object consisting of all the static @@ -1312,7 +1312,7 @@ void around(Point p, int x): target(p) and static signature: <programlisting><![CDATA[ - thisJoinPoint.getStaticPart() +thisJoinPoint.getStaticPart() ]]></programlisting> If you only need the static information about the join point, you may @@ -1327,11 +1327,11 @@ void around(Point p, int x): target(p) </para> <programlisting><![CDATA[ - thisJoinPointStaticPart == thisJoinPoint.getStaticPart() +thisJoinPointStaticPart == thisJoinPoint.getStaticPart() - thisJoinPoint.getKind() == thisJoinPointStaticPart.getKind() - thisJoinPoint.getSignature() == thisJoinPointStaticPart.getSignature() - thisJoinPoint.getSourceLocation() == thisJoinPointStaticPart.getSourceLocation() +thisJoinPoint.getKind() == thisJoinPointStaticPart.getKind() +thisJoinPoint.getSignature() == thisJoinPointStaticPart.getSignature() +thisJoinPoint.getSourceLocation() == thisJoinPointStaticPart.getSourceLocation() ]]></programlisting> <para> diff --git a/docs/progGuideDB/semantics.xml b/docs/progGuideDB/semantics.xml index 23d1fb2d6..6bba37818 100644 --- a/docs/progGuideDB/semantics.xml +++ b/docs/progGuideDB/semantics.xml @@ -204,7 +204,7 @@ <literal>this</literal> expression would pick out at the join point. The target object is where control or attention is transferred to by the join point. The arguments are those - values passed for that transfer of control or attention. + values passed for that transfer of control or attention. </para> <informaltable frame="1"> @@ -216,7 +216,7 @@ <entry><emphasis role="bold">Target Object</emphasis></entry> <entry><emphasis role="bold">Arguments</emphasis></entry> </row> - </thead> + </thead> <tbody> <row> <entry>Method Call</entry> @@ -296,7 +296,7 @@ </para> <para>** There is no target object for join points associated - with static methods or fields. + with static methods or fields. </para> </sect1> @@ -485,9 +485,9 @@ <listitem> Picks out each join point where the arguments are instances of the appropriate type (or type of the identifier if using that form). A - <literal>null</literal> argument is matched iff the static type of the + <literal>null</literal> 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. + the specified args type. </listitem> </varlistentry> @@ -556,8 +556,8 @@ </para> <programlisting> - pointcut publicIntCall(int i): - call(public * *(int)) <![CDATA[&&]]> args(i); +pointcut publicIntCall(int i): + call(public * *(int)) <![CDATA[&&]]> args(i); </programlisting> <para> @@ -568,15 +568,15 @@ </para> <programlisting> - class C { - pointcut publicCall(int i): - call(public * *(int)) <![CDATA[&&]]> args(i); - } +class C { + pointcut publicCall(int i): + call(public * *(int)) <![CDATA[&&]]> args(i); +} - class D { - pointcut myPublicCall(int i): - C.publicCall(i) <![CDATA[&&]]> within(SomeType); - } +class D { + pointcut myPublicCall(int i): + C.publicCall(i) <![CDATA[&&]]> within(SomeType); +} </programlisting> <para> @@ -586,9 +586,9 @@ </para> <programlisting> - abstract aspect A { - abstract pointcut publicCall(int i); - } +abstract aspect A { + abstract pointcut publicCall(int i); +} </programlisting> <para> @@ -597,9 +597,9 @@ </para> <programlisting> - aspect B extends A { - pointcut publicCall(int i): call(public Foo.m(int)) <![CDATA[&&]]> args(i); - } +aspect B extends A { + pointcut publicCall(int i): call(public Foo.m(int)) <![CDATA[&&]]> args(i); +} </programlisting> <para> @@ -622,9 +622,9 @@ </para> <programlisting> - aspect B percflow(publicCall()) { - pointcut publicCall(): call(public Foo.m(int)); - } +aspect B percflow(publicCall()) { + pointcut publicCall(): call(public Foo.m(int)); +} </programlisting> </sect2> @@ -653,7 +653,7 @@ </para> <programlisting> - pointcut intArg(int i): args(i); +pointcut intArg(int i): args(i); </programlisting> <para> @@ -662,7 +662,7 @@ <literal>char</literal>; anything assignable to an <literal>int</literal>) is being passed as an argument. Second, though, it makes the value of that argument - available to the enclosing advice or pointcut. + available to the enclosing advice or pointcut. </para> <para> @@ -670,8 +670,8 @@ </para> <programlisting> - pointcut publicCall(int x): call(public *.*(int)) <![CDATA[&&]]> intArg(x); - pointcut intArg(int i): args(i); +pointcut publicCall(int x): call(public *.*(int)) <![CDATA[&&]]> intArg(x); +pointcut intArg(int i): args(i); </programlisting> <para> @@ -686,7 +686,7 @@ </para> <programlisting> - pointcut publicCall(): call(public *.*(..)) <![CDATA[&&]]> args(Object); +pointcut publicCall(): call(public *.*(..)) <![CDATA[&&]]> args(Object); </programlisting> <para> @@ -696,7 +696,7 @@ </para> <programlisting> - pointcut publicCall(Object o): call(public *.*(..)) <![CDATA[&&]]> args(o); +pointcut publicCall(Object o): call(public *.*(..)) <![CDATA[&&]]> args(o); </programlisting> <para> @@ -712,23 +712,23 @@ </para> <programlisting> - public class InstanceOf { +public class InstanceOf { - public static void main(String[] args) { - doInt(5); - } - - static void doInt(int i) { } + public static void main(String[] args) { + doInt(5); } - aspect IntToLong { - pointcut el(long l) : - execution(* doInt(..)) <![CDATA[&&]]> args(l); + static void doInt(int i) { } +} - before(Object o) : el(o) { - System.out.println(o.getClass()); - } +aspect IntToLong { + pointcut el(long l) : + execution(* doInt(..)) <![CDATA[&&]]> args(l); + + before(Object o) : el(o) { + System.out.println(o.getClass()); } +} </programlisting> <para> @@ -775,13 +775,13 @@ </para> <programlisting><![CDATA[ - aspect GuardedX { - static final int MAX_CHANGE = 100; - before(int newval): set(static int T.x) && args(newval) { - if (Math.abs(newval - T.x) > MAX_CHANGE) - throw new RuntimeException(); - } - } +aspect GuardedX { + static final int MAX_CHANGE = 100; + before(int newval): set(static int T.x) && args(newval) { + if (Math.abs(newval - T.x) > MAX_CHANGE) + throw new RuntimeException(); + } +} ]]></programlisting> </sect3> @@ -838,11 +838,11 @@ </para> <programlisting> - aspect NormalizeFooException { - before(FooException e): handler(FooException) <![CDATA[&&]]> args(e) { - e.normalize(); - } - } +aspect NormalizeFooException { + before(FooException e): handler(FooException) <![CDATA[&&]]> args(e) { + e.normalize(); + } +} </programlisting> </sect3> @@ -865,13 +865,13 @@ </para> <programlisting> - aspect TraceStuff { - pointcut myAdvice(): adviceexecution() <![CDATA[&&]]> within(TraceStuff); +aspect TraceStuff { + pointcut myAdvice(): adviceexecution() <![CDATA[&&]]> within(TraceStuff); - before(): call(* *(..)) <![CDATA[&&]]> !cflow(myAdvice) { - // do something - } - } + before(): call(* *(..)) <![CDATA[&&]]> !cflow(myAdvice) { + // do something + } +} </programlisting> </sect3> @@ -926,7 +926,7 @@ </para> <programlisting> - args(int, .., String) +args(int, .., String) </programlisting> <para> @@ -978,7 +978,7 @@ <literal>cflowbelow</literal> pointcuts may expose context state through enclosed <literal>this</literal>, <literal>target</literal>, and <literal>args</literal> - pointcuts. + pointcuts. </para> <para> @@ -1006,7 +1006,7 @@ class Test { aspect A { pointcut entry(int i): call(int fact(int)) <![CDATA[&&]]> args(i); pointcut writing(): call(void println(String)) <![CDATA[&&]]> ! within(A); - + before(int i): writing() <![CDATA[&&]]> cflow(entry(i)) { System.err.println("Current arg is " + i); } @@ -1079,14 +1079,14 @@ aspect A { </para> <programlisting> - if(thisJoinPoint.getKind().equals("call")) +if(thisJoinPoint.getKind().equals("call")) </programlisting> <para> - Note that the order of evaluation for pointcut expression - components at a join point is undefined. Writing <literal>if</literal> - pointcuts that have side-effects is considered bad style and may also - lead to potentially confusing or even changing behavior with regard + Note that the order of evaluation for pointcut expression + components at a join point is undefined. Writing <literal>if</literal> + pointcuts that have side-effects is considered bad style and may also + lead to potentially confusing or even changing behavior with regard to when or if the test code will run. </para> </sect3> @@ -1207,9 +1207,9 @@ aspect A { <programlisting> - class C { - public final void foo() throws ArrayOutOfBoundsException { ... } - } +class C { + public final void foo() throws ArrayOutOfBoundsException { ... } +} </programlisting> <para> @@ -1219,7 +1219,7 @@ aspect A { <programlisting> - call(public final void C.foo() throws ArrayOutOfBoundsException) +call(public final void C.foo() throws ArrayOutOfBoundsException) </programlisting> <para> @@ -1227,7 +1227,7 @@ aspect A { </para> <programlisting> - call(public final void *.*() throws ArrayOutOfBoundsException) +call(public final void *.*() throws ArrayOutOfBoundsException) </programlisting> @@ -1245,16 +1245,16 @@ aspect A { </para> <programlisting> - call(public final void *() throws ArrayOutOfBoundsException) +call(public final void *() throws ArrayOutOfBoundsException) </programlisting> <para> - The wildcard <literal>..</literal> indicates zero or more + The wildcard <literal>..</literal> indicates zero or more parameters, so </para> <programlisting> - execution(void m(..)) +execution(void m(..)) </programlisting> <para> @@ -1263,7 +1263,7 @@ aspect A { </para> <programlisting> - execution(void m(.., int)) +execution(void m(.., int)) </programlisting> <para> @@ -1280,7 +1280,7 @@ aspect A { </para> <programlisting> - withincode(!public void foo()) +withincode(!public void foo()) </programlisting> <para> @@ -1289,7 +1289,7 @@ aspect A { </para> <programlisting> - withincode(void foo()) +withincode(void foo()) </programlisting> <para> @@ -1303,7 +1303,7 @@ aspect A { </para> <programlisting> - call(int *()) +call(int *()) </programlisting> <para> @@ -1312,7 +1312,7 @@ aspect A { </para> <programlisting> - call(int get*()) +call(int get*()) </programlisting> <para> @@ -1328,7 +1328,7 @@ aspect A { </para> <programlisting> - execution(private C.new() throws ArithmeticException) +execution(private C.new() throws ArithmeticException) </programlisting> <sect3> @@ -1341,23 +1341,23 @@ aspect A { </para> <para> - When matching for pointcuts <literal>withincode</literal>, + When matching for pointcuts <literal>withincode</literal>, <literal>get</literal>, and <literal>set</literal>, the declaring type is the class that contains the declaration. </para> <para> - When matching method-call join points, the + When matching method-call join points, the declaring type is the static type used to access the method. - A common mistake is to specify a declaring type for the - <literal>call</literal> pointcut that is a subtype of the + A common mistake is to specify a declaring type for the + <literal>call</literal> pointcut that is a subtype of the originally-declaring type. For example, given the class </para> <programlisting> - class Service implements Runnable { - public void run() { ... } - } +class Service implements Runnable { + public void run() { ... } +} </programlisting> <para> @@ -1365,7 +1365,7 @@ aspect A { </para> <programlisting> - call(void Service.run()) +call(void Service.run()) </programlisting> <para> @@ -1373,49 +1373,49 @@ aspect A { </para> <programlisting> - ((Runnable) new Service()).run(); +((Runnable) new Service()).run(); </programlisting> <para> Specifying the originally-declaring type is correct, but would pick out any such call (here, calls to the <literal>run()</literal> - method of any Runnable). + method of any Runnable). In this situation, consider instead picking out the target type: </para> <programlisting> - call(void run()) && target(Service) +call(void run()) && target(Service) </programlisting> <para> - When matching method-execution join points, - if the execution pointcut method signature specifies a declaring type, - the pointcut will only match methods declared in that type, or methods + When matching method-execution join points, + if the execution pointcut 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 </para> <programlisting> - execution(public void Middle.*()) +execution(public void Middle.*()) </programlisting> <para> picks out all method executions for public methods returning void - and having no arguments that are either declared in, or inherited by, - Middle, even if those methods are overridden in a subclass of Middle. + and having no arguments that are either declared in, or inherited by, + 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: </para> <programlisting> - class Super { - protected void m() { ... } - } - class Middle extends Super { - } - class Sub extends Middle { - public void m() { ... } - } +class Super { + protected void m() { ... } +} +class Middle extends Super { +} +class Sub extends Middle { + public void m() { ... } +} </programlisting> </sect3> @@ -1430,15 +1430,15 @@ aspect A { </para> <programlisting> - pointcut throwsMathlike(): - // each call to a method with a throws clause containing at least - // one exception exception with "Math" in its name. - call(* *(..) throws *..*Math*); +pointcut throwsMathlike(): + // each call to a method with a throws clause containing at least + // one exception exception with "Math" in its name. + call(* *(..) throws *..*Math*); - pointcut doesNotThrowMathlike(): - // each call to a method with a throws clause containing no - // exceptions with "Math" in its name. - call(* *(..) throws !*..*Math*); +pointcut doesNotThrowMathlike(): + // each call to a method with a throws clause containing no + // exceptions with "Math" in its name. + call(* *(..) throws !*..*Math*); </programlisting> <para> @@ -1550,7 +1550,7 @@ aspect A { <literal>java.util.HashMap</literal> unless the aspect were in <literal>java.util</literal> or the type had been imported. - </listitem> + </listitem> </itemizedlist> <para> @@ -1569,7 +1569,7 @@ aspect A { </para> <programlisting> - call(void foo(*)) +call(void foo(*)) </programlisting> <para> @@ -1585,7 +1585,7 @@ aspect A { </para> <programlisting> - handler(java.util.*Map) +handler(java.util.*Map) </programlisting> <para> @@ -1594,7 +1594,7 @@ aspect A { </para> <programlisting> - handler(java.util.*) +handler(java.util.*) </programlisting> <para> @@ -1611,11 +1611,11 @@ aspect A { </para> <programlisting> - within(com.xerox..*) +within(com.xerox..*) </programlisting> <para> - picks out all join points where the code is in any + picks out all join points where the code is in any declaration of a type whose name begins with "<literal>com.xerox.</literal>". </para> @@ -1638,7 +1638,7 @@ aspect A { </para> <programlisting> - call(Foo.new()) +call(Foo.new()) </programlisting> <para> @@ -1647,7 +1647,7 @@ aspect A { </para> <programlisting> - call(Foo+.new()) +call(Foo+.new()) </programlisting> <para> @@ -1656,7 +1656,7 @@ aspect A { </para> <programlisting> - call(*Handler+.new()) +call(*Handler+.new()) </programlisting> <para> @@ -1689,7 +1689,7 @@ aspect A { </para> <programlisting> - staticinitialization(Foo || Bar) +staticinitialization(Foo || Bar) </programlisting> <para> @@ -1698,7 +1698,7 @@ aspect A { </para> <programlisting> - call((Foo+ <![CDATA[&&]]> ! Foo).new(..)) +call((Foo+ <![CDATA[&&]]> ! Foo).new(..)) </programlisting> <para> @@ -1716,24 +1716,24 @@ aspect A { </para> <programlisting> -MethodPattern = - [ModifiersPattern] TypePattern - [TypePattern . ] IdPattern (TypePattern | ".." , ... ) +MethodPattern = + [ModifiersPattern] TypePattern + [TypePattern . ] IdPattern (TypePattern | ".." , ... ) [ throws ThrowsPattern ] -ConstructorPattern = - [ModifiersPattern ] - [TypePattern . ] new (TypePattern | ".." , ...) +ConstructorPattern = + [ModifiersPattern ] + [TypePattern . ] new (TypePattern | ".." , ...) [ throws ThrowsPattern ] -FieldPattern = +FieldPattern = [ModifiersPattern] TypePattern [TypePattern . ] IdPattern -ThrowsPattern = +ThrowsPattern = [ ! ] TypePattern , ... -TypePattern = +TypePattern = IdPattern [ + ] [ [] ... ] | ! TypePattern | TypePattern <![CDATA[&&]]> TypePattern | TypePattern || TypePattern - | ( TypePattern ) + | ( TypePattern ) IdPattern = Sequence of characters, possibly with special * and .. wildcards ModifiersPattern = @@ -1785,7 +1785,7 @@ ModifiersPattern = <para> and where <replaceable>Formal</replaceable> refers to a variable binding like those used for method parameters, - of the form + of the form <literal><replaceable>Type</replaceable></literal> <literal><replaceable>Variable-Name</replaceable></literal>, and <replaceable>Formals</replaceable> refers to a comma-delimited @@ -1816,18 +1816,18 @@ ModifiersPattern = </para> <programlisting> - aspect A { - pointcut publicCall(): call(public Object *(..)); - after() returning (Object o): publicCall() { - System.out.println("Returned normally with " + o); - } - after() throwing (Exception e): publicCall() { - System.out.println("Threw an exception: " + e); - } - after(): publicCall(){ - System.out.println("Returned or threw an Exception"); - } - } +aspect A { + pointcut publicCall(): call(public Object *(..)); + after() returning (Object o): publicCall() { + System.out.println("Returned normally with " + o); + } + after() throwing (Exception e): publicCall() { + System.out.println("Threw an exception: " + e); + } + after(): publicCall(){ + System.out.println("Returned or threw an Exception"); + } +} </programlisting> <para> @@ -1836,9 +1836,9 @@ ModifiersPattern = </para> <programlisting> - after() returning: call(public Object *(..)) { - System.out.println("Returned normally"); - } +after() returning: call(public Object *(..)) { + System.out.println("Returned normally"); +} </programlisting> <para> @@ -1888,11 +1888,11 @@ ModifiersPattern = </para> <programlisting> - aspect A { - int around(): call(int C.foo()) { - return 3; - } - } +aspect A { + int around(): call(int C.foo()) { + return 3; + } +} </programlisting> <para> @@ -1901,7 +1901,7 @@ ModifiersPattern = </para> <programlisting> - proceed( ... ) +proceed( ... ) </programlisting> <para> @@ -1913,12 +1913,12 @@ ModifiersPattern = <programlisting> - aspect A { - int around(int i): call(int C.foo(Object, int)) <![CDATA[&&]]> args(i) { - int newi = proceed(i*2) - return newi/2; - } - } +aspect A { + int around(int i): call(int C.foo(Object, int)) <![CDATA[&&]]> args(i) { + int newi = proceed(i*2) + return newi/2; + } +} </programlisting> <para> @@ -1931,38 +1931,38 @@ ModifiersPattern = </para> <programlisting> - aspect A { - Object around(int i): call(int C.foo(Object, int)) <![CDATA[&&]]> args(i) { - Integer newi = (Integer) proceed(i*2) - return new Integer(newi.intValue() / 2); - } - } +aspect A { + Object around(int i): call(int C.foo(Object, int)) <![CDATA[&&]]> args(i) { + Integer newi = (Integer) proceed(i*2) + return new Integer(newi.intValue() / 2); + } +} </programlisting> - + <para> - Any occurence of <literal>proceed(..)</literal> within the body of around + Any occurence of <literal>proceed(..)</literal> within the body of around advice is treated as the special proceed form (even if the - aspect defines a method named <literal>proceed</literal>), unless a + aspect defines a method named <literal>proceed</literal>), unless a target other than the aspect instance is specified as the recipient of the call. - For example, in the following program the first + For example, in the following program the first call to proceed will be treated as a method call to the <literal>ICanProceed</literal> instance, whereas the second call to proceed is treated as the special proceed form. </para> <programlisting> - aspect A { - Object around(ICanProceed canProceed) : execution(* *(..)) <![CDATA[&&]]> this(canProceed) { - canProceed.proceed(); // a method call - return proceed(canProceed); // the special proceed form - } - - private Object proceed(ICanProceed canProceed) { - // this method cannot be called from inside the body of around advice in - // the aspect - } - } +aspect A { + Object around(ICanProceed canProceed) : execution(* *(..)) <![CDATA[&&]]> this(canProceed) { + canProceed.proceed(); // a method call + return proceed(canProceed); // the special proceed form + } + + private Object proceed(ICanProceed canProceed) { + // this method cannot be called from inside the body of around advice in + // the aspect + } +} </programlisting> <para> @@ -1973,11 +1973,11 @@ ModifiersPattern = </para> <programlisting> - aspect A { - after() returning (int i): call(int C.foo()) { - i = i * 2; - } - } +aspect A { + after() returning (int i): call(int C.foo()) { + i = i * 2; + } +} </programlisting> <para> @@ -1990,47 +1990,47 @@ ModifiersPattern = With <literal>proceed(..)</literal> it is possible to change the values used by less-precedent advice and the underlying join point by supplying different values for the variables. For example, this aspect replaces - the string bound to <literal>s</literal> in the named pointcut + the string bound to <literal>s</literal> in the named pointcut <literal>privateData</literal>: </para> <programlisting> - aspect A { - Object around(String s): MyPointcuts.privateData(s) { - return proceed("private data"); - } +aspect A { + Object around(String s): MyPointcuts.privateData(s) { + return proceed("private data"); } +} </programlisting> <para> - If you replace an argument to <literal>proceed(..)</literal>, you can cause + If you replace an argument to <literal>proceed(..)</literal>, you can cause a <literal>ClassCastException</literal> at runtime when the argument - refers to a supertype of the actual type and you do not supply a + refers to a supertype of the actual type and you do not supply a reference of the actual type. In the following aspect, the - around advice replaces the declared target <literal>List</literal> + around advice replaces the declared target <literal>List</literal> with an <literal>ArrayList</literal>. This is valid code at - compile-time since the types match. + compile-time since the types match. </para> <programlisting> - import java.util.*; +import java.util.*; - aspect A { - Object around(List list): call(* List+.*()) <![CDATA[&&]]> target(list) { - return proceed(new ArrayList()); - } +aspect A { + Object around(List list): call(* List+.*()) <![CDATA[&&]]> target(list) { + return proceed(new ArrayList()); } +} </programlisting> <para> But imagine a simple program where the actual target is <literal>LinkedList</literal>. In this case, the advice would cause a - <literal>ClassCastException</literal> at runtime, and + <literal>ClassCastException</literal> at runtime, and <literal>peek()</literal> is not declared in <literal>ArrayList</literal>. </para> <programlisting> - public class Test { - public static void main(String[] args) { - new LinkedList().peek(); - } +public class Test { + public static void main(String[] args) { + new LinkedList().peek(); } +} </programlisting> <para> The <literal>ClassCastException</literal> can occur even in situations @@ -2038,17 +2038,17 @@ ModifiersPattern = call <literal>size()</literal>, declared in <literal>List</literal>: </para> <programlisting> - public class Test { - public static void main(String[] args) { - new LinkedList().size(); - } +public class Test { + public static void main(String[] args) { + new LinkedList().size(); } +} </programlisting> <para> There will still be a <literal>ClassCastException</literal> because it is impossible to prove that there won't be a runtime binary-compatible change in the hierarchy of <literal>LinkedList</literal> or some - other advice on the join point that requires a + other advice on the join point that requires a <literal>LinkedList</literal>. </para> @@ -2077,22 +2077,22 @@ ModifiersPattern = </para> <programlisting> - import java.io.FileNotFoundException; +import java.io.FileNotFoundException; - class C { - int i; +class C { + int i; - int getI() { return i; } - } + int getI() { return i; } +} - aspect A { - before(): get(int C.i) { - throw new FileNotFoundException(); - } - before() throws FileNotFoundException: get(int C.i) { - throw new FileNotFoundException(); - } - } +aspect A { + before(): get(int C.i) { + throw new FileNotFoundException(); + } + before() throws FileNotFoundException: get(int C.i) { + throw new FileNotFoundException(); + } +} </programlisting> <para> @@ -2124,7 +2124,7 @@ ModifiersPattern = <varlistentry> <term>field get and set</term> <listitem> - no checked exceptions can be thrown from these join points. + no checked exceptions can be thrown from these join points. </listitem> </varlistentry> @@ -2138,7 +2138,7 @@ ModifiersPattern = <varlistentry> <term>static initializer execution</term> <listitem> - no checked exceptions can be thrown from these join points. + no checked exceptions can be thrown from these join points. </listitem> </varlistentry> @@ -2146,14 +2146,14 @@ ModifiersPattern = <term>pre-initialization and initialization</term> <listitem> any exception that is in the throws clause of - <emphasis>all</emphasis> constructors of the initialized class. + <emphasis>all</emphasis> constructors of the initialized class. </listitem> </varlistentry> <varlistentry> <term>advice execution</term> <listitem> - any exception that is in the throws clause of the advice. + any exception that is in the throws clause of the advice. </listitem> </varlistentry> @@ -2218,11 +2218,11 @@ ModifiersPattern = <para>These rules can lead to circularity, such as</para> <programlisting> - aspect A { - before(): execution(void main(String[] args)) {} - after(): execution(void main(String[] args)) {} - before(): execution(void main(String[] args)) {} - } +aspect A { + before(): execution(void main(String[] args)) {} + after(): execution(void main(String[] args)) {} + before(): execution(void main(String[] args)) {} +} </programlisting> <para>such circularities will result in errors signalled by the compiler. </para> @@ -2268,7 +2268,7 @@ ModifiersPattern = <para> Three special variables are visible within bodies of advice - and within <literal>if()</literal> pointcut expressions: + and within <literal>if()</literal> pointcut expressions: <literal>thisJoinPoint</literal>, <literal>thisJoinPointStaticPart</literal>, and <literal>thisEnclosingJoinPointStaticPart</literal>. Each is bound to @@ -2280,7 +2280,7 @@ ModifiersPattern = <programlisting> - pointcut publicCall(): call(public * *(..)); +pointcut publicCall(): call(public * *(..)); </programlisting> @@ -2372,17 +2372,17 @@ ModifiersPattern = </para> <programlisting> - interface Iface {} +interface Iface {} - aspect A { - private void Iface.m() { - System.err.println("I'm a private method on an interface"); - } - void worksOnI(Iface iface) { - // calling a private method on an interface - iface.m(); - } - } +aspect A { + private void Iface.m() { + System.err.println("I'm a private method on an interface"); + } + void worksOnI(Iface iface) { + // calling a private method on an interface + iface.m(); + } +} </programlisting> <para> @@ -2499,7 +2499,7 @@ ModifiersPattern = is illegal because it would say that a public interface has a constraint that only non-public implementors must fulfill. This would not be compatible with Java's type - system. + system. </para> </sect2> @@ -2514,13 +2514,13 @@ ModifiersPattern = </para> <programlisting> - aspect A { - private Registry otherPackage.onType.r; - public void otherPackage.onType.register(Registry r) { - r.register(this); - this.r = r; - } - } +aspect A { + private Registry otherPackage.onType.r; + public void otherPackage.onType.register(Registry r) { + r.register(this); + this.r = r; + } +} </programlisting> <para> @@ -2546,7 +2546,7 @@ ModifiersPattern = </para> <programlisting> - this.r = r +this.r = r </programlisting> <para> @@ -2614,10 +2614,10 @@ ModifiersPattern = </para> <programlisting> - aspect A { - declare parents: SomeClass implements Runnable; - public void SomeClass.run() { ... } - } +aspect A { + declare parents: SomeClass implements Runnable; + public void SomeClass.run() { ... } +} </programlisting> </sect2> @@ -2647,13 +2647,13 @@ ModifiersPattern = </para> <programlisting> - Object M O - \ / \ / - C N Q - \ / / - D P - \ / - E + Object M O + \ / \ / + C N Q + \ / / + D P + \ / + E </programlisting> <para> @@ -2661,7 +2661,7 @@ ModifiersPattern = </para> <programlisting> - Object M C O N D Q P E +Object M C O N D Q P E </programlisting> </sect2> @@ -2703,9 +2703,9 @@ ModifiersPattern = <para>For example, the aspect</para> <programlisting> - aspect A { - declare soft: Exception: execution(void main(String[] args)); - } +aspect A { + declare soft: Exception: execution(void main(String[] args)); +} </programlisting> <para>Would, at the execution join point, catch any @@ -2716,14 +2716,14 @@ ModifiersPattern = <para>This is similar to what the following advice would do</para> <programlisting> - aspect A { - void around() execution(void main(String[] args)) { - try { proceed(); } - catch (Exception e) { - throw new org.aspectj.lang.SoftException(e); - } - } +aspect A { + void around() execution(void main(String[] args)) { + try { proceed(); } + catch (Exception e) { + throw new org.aspectj.lang.SoftException(e); } + } +} </programlisting> <para>except, in addition to wrapping the exception, it also affects @@ -2735,15 +2735,15 @@ ModifiersPattern = extending concrete aspect:</para> <programlisting> - abstract aspect A { - abstract pointcut softeningPC(); +abstract aspect A { + abstract pointcut softeningPC(); - before() : softeningPC() { - Class.forName("FooClass"); // error: uncaught ClassNotFoundException - } - - declare soft : ClassNotFoundException : call(* Class.*(..)); + before() : softeningPC() { + Class.forName("FooClass"); // error: uncaught ClassNotFoundException } + + declare soft : ClassNotFoundException : call(* Class.*(..)); +} </programlisting> </sect2> @@ -2777,7 +2777,7 @@ ModifiersPattern = expressed by:</para> <programlisting> - declare precedence: *..*Security*, Logging+, *; +declare precedence: *..*Security*, Logging+, *; </programlisting> <para> @@ -2791,22 +2791,22 @@ ModifiersPattern = </para> <programlisting> - aspect Ordering { - declare precedence: CountEntry, DisallowNulls; - } - aspect DisallowNulls { - pointcut allTypeMethods(Type obj): call(* *(..)) <![CDATA[&&]]> args(obj, ..); - before(Type obj): allTypeMethods(obj) { - if (obj == null) throw new RuntimeException(); - } - } - aspect CountEntry { - pointcut allTypeMethods(Type obj): call(* *(..)) <![CDATA[&&]]> args(obj, ..); - static int count = 0; - before(): allTypeMethods(Type) { - count++; - } - } +aspect Ordering { + declare precedence: CountEntry, DisallowNulls; +} +aspect DisallowNulls { + pointcut allTypeMethods(Type obj): call(* *(..)) <![CDATA[&&]]> args(obj, ..); + before(Type obj): allTypeMethods(obj) { + if (obj == null) throw new RuntimeException(); + } +} +aspect CountEntry { + pointcut allTypeMethods(Type obj): call(* *(..)) <![CDATA[&&]]> args(obj, ..); + static int count = 0; + before(): allTypeMethods(Type) { + count++; + } +} </programlisting> <sect3> @@ -2818,7 +2818,7 @@ ModifiersPattern = </para> <programlisting> - declare precedence: A, B, A ; // error +declare precedence: A, B, A ; // error </programlisting> <para> @@ -2828,8 +2828,8 @@ ModifiersPattern = </para> <programlisting> - declare precedence: B, A; - declare precedence: A, B; +declare precedence: B, A; +declare precedence: A, B; </programlisting> <para> @@ -2848,31 +2848,31 @@ ModifiersPattern = </para> <programlisting> - abstract aspect Logging { - abstract pointcut logged(); +abstract aspect Logging { + abstract pointcut logged(); - before(): logged() { - System.err.println("thisJoinPoint: " + thisJoinPoint); - } - } + before(): logged() { + System.err.println("thisJoinPoint: " + thisJoinPoint); + } +} - abstract 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); - } +abstract 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); +} </programlisting> <para> @@ -2883,7 +2883,7 @@ ModifiersPattern = </para> <programlisting> - declare precedence: Logging, Profiling; +declare precedence: Logging, Profiling; </programlisting> <para> @@ -2891,8 +2891,8 @@ ModifiersPattern = </para> <programlisting> - declare precedence: MyLogging, MyProfiling; - declare precedence: Logging+, Profiling+; +declare precedence: MyLogging, MyProfiling; +declare precedence: Logging+, Profiling+; </programlisting> <para> @@ -2932,7 +2932,7 @@ ModifiersPattern = <para> An aspect is a crosscutting type defined by the <literal>aspect</literal> - declaration. + declaration. </para> <sect2 id="aspect-declaration" xreflabel="aspect-declaration"> @@ -2955,7 +2955,7 @@ ModifiersPattern = declarations that can can cut across other types (including those defined by other aspect declarations). </para> - </sect3> + </sect3> <sect3> <title>Aspects are not directly instantiated</title> @@ -2966,19 +2966,19 @@ ModifiersPattern = constructor taking no arguments and throwing no checked exceptions. </para> - </sect3> + </sect3> <sect3> <title>Nested aspects must be <literal>static</literal></title> - <para> + <para> Aspects may be defined either at the package level, or as a static nested aspect -- that is, a static member of a class, interface, or aspect. If it is not at the package level, the aspect <emphasis>must</emphasis> be defined with the static keyword. Local and anonymous aspects are not allowed. </para> - </sect3> + </sect3> </sect2> <sect2 id="aspect-extension" xreflabel="aspect-extension"> @@ -3041,7 +3041,7 @@ ModifiersPattern = The criteria used to determine how an aspect is instantiated is inherited from its parent aspect. If the aspect has no parent aspect, then by default the aspect is a singleton aspect. - How an aspect is instantiated controls the form of the + How an aspect is instantiated controls the form of the <literal>aspectOf(..)</literal> method defined on the concrete aspect class. </para> @@ -3103,7 +3103,7 @@ ModifiersPattern = target object of the join points picked out by <replaceable>Pointcut</replaceable>. The advice defined in A will run only at a join point where the - target object has been associated with an instance of + target object has been associated with an instance of A. </para> @@ -3156,20 +3156,20 @@ ModifiersPattern = </para> <programlisting> - public class Client - { - public static void main(String[] args) { - Client c = new Client(); - } - } +public class Client +{ + public static void main(String[] args) { + Client c = new Client(); + } +} - aspect Watchcall { - pointcut myConstructor(): execution(new(..)); +aspect Watchcall { + pointcut myConstructor(): execution(new(..)); - before(): myConstructor() { - System.err.println("Entering Constructor"); - } - } + before(): myConstructor() { + System.err.println("Entering Constructor"); + } +} </programlisting> <para> @@ -3214,16 +3214,16 @@ ModifiersPattern = </para> <programlisting> - class C { - private int i = 0; - void incI(int x) { i = i+x; } - } - privileged aspect A { - static final int MAX = 1000; - before(int x, C c): call(void C.incI(int)) <![CDATA[&&]]> target(c) <![CDATA[&&]]> args(x) { - if (c.i+x > MAX) throw new RuntimeException(); - } - } +class C { + private int i = 0; + void incI(int x) { i = i+x; } +} +privileged aspect A { + static final int MAX = 1000; + before(int x, C c): call(void C.incI(int)) <![CDATA[&&]]> target(c) <![CDATA[&&]]> args(x) { + if (c.i+x > MAX) throw new RuntimeException(); + } +} </programlisting> <para> @@ -3238,16 +3238,17 @@ ModifiersPattern = </para> <programlisting> - class C { - private int i = 0; - void foo() { } - } - privileged aspect A { - private int C.i = 999; - before(C c): call(void C.foo()) target(c) { - System.out.println(c.i); - } - } +class C { + private int i = 0; + void foo() { } +} + +privileged aspect A { + private int C.i = 999; + before(C c): call(void C.foo()) target(c) { + System.out.println(c.i); + } +} </programlisting> <para> |