* changed "Implementation Limitations" to "Implementation Notes" inside ProgGuide
* added section on bytecode limitations, headed by handler issues.
http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&keywords=info</a>
For ajc's 1.1 implementation limitations, see
- <a href="progguide/limitations.html">
- Programming Guide Appendix C, "Implementation Limitations"</a>.
+ <a href="progguide/implementation.html">
+ Programming Guide Appendix: "Implementation Notes"</a>.
</p>
</body> </html>
summarizes AspectJ syntax,
the <a href="progguide/semantics.html">Language Semantics</a>
best describes AspectJ usage, and
- <a href="progguide/limitations.html">Implementation Limitations</a> notes that
+ <a href="progguide/implementation.html">Implementation Notes</a>
+ describes how
the current version is limited to code the compiler controls.</td>
</tr>
As you learn,
use the compiler's <code>-Xlint</code> flags to catch some common
mistakes. (Understand that the
- <a href="progguide/limitations.html">current implementation</a>
+ <a href="progguide/implementation.html">current implementation</a>
is limited to code the compiler controls.)
<p>
To plan how to adopt AspectJ into a project, read the
</para>
<para>
To find out about known issues, see the
- <ulink url="progguide/limitations.html">
- AspectJ Programming Guide Appendix, "Limitations"</ulink>
+ <ulink url="progguide/implementation.html">
+ AspectJ Programming Guide Appendix, "Implementation Notes"</ulink>
and the AspectJ bugs in the database at
<ulink url="http://bugs.eclipse.org/bugs">http://bugs.eclipse.org/bugs</ulink>
(using the product <literal>AspectJ</literal>). Here are direct links to
a system, so AspectJ program semantics may be limited to code
the implementation controls. For our implementation, these
limitations are stated in
- <ulink url="progguide/limitations.html">
- Programming Guide Appendix C</ulink>.
+ <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
technology when writing AspectJ programs.
--- /dev/null
+<appendix id="implementation" xreflabel="Implementation Notes">
+
+ <title>Implementation Notes</title>
+
+<sect1>
+ <title>Compiler Notes</title>
+
+ <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
+ to the virtual machine, which a compiler-based implementation
+ cannot do. One way to deal with this problem would be to specify
+ only the behavior that is easiest to implement. We have chosen a
+ somewhat different approach, which is to specify an ideal language
+ semantics, as well as a clearly defined way in which
+ implementations are allowed to deviate from that semantics. This
+ makes it possible to develop conforming AspectJ implementations
+ today, while still making it clear what later, and presumably
+ better, implementations should do tomorrow.
+ </para>
+
+ <para>
+ According to the AspectJ language semantics, the declaration
+ </para>
+
+<programlisting><![CDATA[
+ before(): get(int Point.x) { System.out.println("got x"); }
+]]></programlisting>
+
+ <para>
+ should advise all accesses of a field of type int and name x from
+ instances of type (or subtype of) Point. It should do this
+ regardless of whether all the source code performing the access
+ was available at the time the aspect containing this advice was
+ compiled, whether changes were made later, etc.
+ </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
+ implementation is free within certain bounds to provide its own
+ definition of what it means to control code.
+ </para>
+
+ <para>
+ In the current AspectJ compiler, ajc, control of the code means
+ having bytecode for any aspects and all the code they should
+ affect available during the compile. This means that if some class
+ Client contains code with the expression <literal>new
+ Point().x</literal> (which results in a field get join point at
+ runtime), the current AspectJ compiler will fail to advise that
+ access unless Client.java or Client.class is compiled as well. It
+ also means that join points associated with code in native methods
+ (including their execution join points) cannot be advised.
+ </para>
+
+ <para>
+ Different join points have different requirements. Method and
+ constructor call join points can be advised only if ajc controls
+ the bytecode for the caller. Field reference or assignment join
+ points can be advised only if ajc controls the bytecode for the
+ "caller", the code actually making the reference or assignment.
+ Initialization join points can be advised only if ajc controls the
+ bytecode of the type being initialized, and execution join points
+ 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
+ points.
+ 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>
+
+ <para>
+ Aspects that are defined <literal>perthis</literal> or
+ <literal>pertarget</literal> also have restrictions based on
+ control of the code. In particular, at a join point where the
+ bytecode for the currently executing object is not available, an
+ aspect defined <literal>perthis</literal> of that join point will
+ not be associated. So aspects defined
+ <literal>perthis(Object)</literal> will not create aspect
+ instances for every object unless <literal>Object</literal>is part
+ of the compile. Similar restrictions apply to
+ <literal>pertarget</literal> aspects.
+ </para>
+
+ <para>
+ Inter-type declarations such as <literal>declare parents</literal>
+ also have restrictions based on control of the code. If the
+ bytecode for the target of an inter-type declaration is not
+ available, then the inter-type declaration is not made on that
+ target. So, <literal>declare parents : String implements
+ MyInterface</literal> will not work for
+ <literal>java.lang.String</literal> unless
+ <literal>java.lang.String</literal> is part of the compile.
+ </para>
+
+ <para>
+ Other AspectJ implementations, indeed, future versions of ajc, may
+ define <emphasis>code the implementation controls</emphasis> more
+ liberally or restrictively.
+ </para>
+
+ <para>
+ The important thing to remember is that core concepts of AspectJ,
+ such as the join point, are unchanged, regardless of which
+ implementation is used. During your development, you will have to
+ be aware of the limitations of the ajc compiler you're using, but
+ these limitations should not drive the design of your aspects.
+ </para>
+</sect1>
+
+<sect1>
+ <title>Bytecode Notes</title>
+
+ <para>The end of exception handlers cannot reliably be found in Java
+ bytecode. Instead of removing the handler join point entirely, the
+ current AspectJ compiler restricts what can be done with the handler
+ join point:
+ </para>
+
+ <itemizedlist>
+ <listitem>After and around advice cannot apply to handler
+ join points.</listitem>
+
+ <listitem>The control flow of a handler join point cannot be
+ detected. </listitem>
+ </itemizedlist>
+
+ <para>
+ The first of these is relatively straightforward. If any piece of
+ after advice (returning, throwing, or "finally") would normally
+ apply to a handler join point, it will not in code output by the
+ current AspectJ compiler. A compiler warning is generated whenever
+ this is detected to be the case. Before advice is allowed.
+ </para>
+
+ <para> The second is that the control flow of a handler join point
+ is not picked out. For example, the following pointcut
+ </para>
+
+<programlisting><![CDATA[
+ cflow(call(void foo()) || handler(java.io.IOException))
+]]></programlisting>
+
+ <para> will capture all join points in the control flow of a call to
+ <literal>void foo()</literal>, but it will <emphasis>not</emphasis>
+ capture those in the control flow of an
+ <literal>IOException</literal> handler. It is equivalent to
+ <literal>cflow(call(void foo()))</literal>. In general,
+ <literal>cflow(handler(<replaceable>Type</replaceable>))</literal>
+ will pick out no join points.
+ </para>
+
+ <para> This does not restrict programs from placing before advice on
+ handlers inside <emphasis>other</emphasis> control flows. This
+ advice, for example, is perfectly fine:
+ </para>
+
+<programlisting><![CDATA[
+ before(): handler(java.io.IOException) && cflow(void parse()) {
+ System.out.println("about to handle an exception while parsing");
+ }
+]]></programlisting>
+
+ <para>
+ A source-code implementation of AspectJ (such as AspectJ 1.0.6) is
+ able to detect the endpoint of a handler join point, and as such
+ will likely have fewer such restrictions.
+ </para>
+
+</sect1>
+
+</appendix>
+++ /dev/null
-<appendix id="limitations" xreflabel="Implementation Limitations">
-
- <title>Implementation Limitations</title>
-
- <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
- to the virtual machine, which a compiler-based implementation
- cannot do. One way to deal with this problem would be to specify
- only the behavior that is easiest to implement. We have chosen a
- somewhat different approach, which is to specify an ideal language
- semantics, as well as a clearly defined way in which
- implementations are allowed to deviate from that semantics. This
- makes it possible to develop conforming AspectJ implementations
- today, while still making it clear what later, and presumably
- better, implementations should do tomorrow.
- </para>
-
- <para>
- According to the AspectJ language semantics, the declaration
- </para>
-
-<programlisting><![CDATA[
- before(): get(int Point.x) { System.out.println("got x"); }
-]]></programlisting>
-
- <para>
- should advise all accesses of a field of type int and name x from
- instances of type (or subtype of) Point. It should do this
- regardless of whether all the source code performing the access
- was available at the time the aspect containing this advice was
- compiled, whether changes were made later, etc.
- </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
- implementation is free within certain bounds to provide its own
- definition of what it means to control code.
- </para>
-
- <para>
- In the current AspectJ compiler, ajc, control of the code means
- having bytecode for any aspects and all the code they should
- affect available during the compile. This means that if some class
- Client contains code with the expression <literal>new
- Point().x</literal> (which results in a field get join point at
- runtime), the current AspectJ compiler will fail to advise that
- access unless Client.java or Client.class is compiled as well. It
- also means that join points associated with code in native methods
- (including their execution join points) cannot be advised.
- </para>
-
- <para>
- Different join points have different requirements. Method and
- constructor call join points can be advised only if ajc controls
- the bytecode for the caller. Field reference or assignment join
- points can be advised only if ajc controls the bytecode for the
- "caller", the code actually making the reference or assignment.
- Initialization join points can be advised only if ajc controls the
- bytecode of the type being initialized, and execution join points
- 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
- points.
- 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>
-
- <para>
- Aspects that are defined <literal>perthis</literal> or
- <literal>pertarget</literal> also have restrictions based on
- control of the code. In particular, at a join point where the
- bytecode for the currently executing object is not available, an
- aspect defined <literal>perthis</literal> of that join point will
- not be associated. So aspects defined
- <literal>perthis(Object)</literal> will not create aspect
- instances for every object unless <literal>Object</literal>is part
- of the compile. Similar restrictions apply to
- <literal>pertarget</literal> aspects.
- </para>
-
- <para>
- Inter-type declarations such as <literal>declare parents</literal>
- also have restrictions based on control of the code. If the
- bytecode for the target of an inter-type declaration is not
- available, then the inter-type declaration is not made on that
- target. So, <literal>declare parents : String implements
- MyInterface</literal> will not work for
- <literal>java.lang.String</literal> unless
- <literal>java.lang.String</literal> is part of the compile.
- </para>
-
- <para>
- Other AspectJ implementations, indeed, future versions of ajc, may
- define <emphasis>code the implementation controls</emphasis> more
- liberally or restrictively.
- </para>
-
- <para>
- The important thing to remember is that core concepts of AspectJ,
- such as the join point, are unchanged, regardless of which
- implementation is used. During your development, you will have to
- be aware of the limitations of the ajc compiler you're using, but
- these limitations should not drive the design of your aspects.
- </para>
-
-</appendix>
It includes appendices that give a reference to the syntax of AspectJ,
a more formal description of AspectJ's semantics, and a description of
- limitations allowed by AspectJ implementations.
+ notes about the AspectJ implementation.
</para>
<para>
linkend="quick">quick reference</xref> to the language's syntax, a more
in depth coverage of its <xref linkend="semantics">semantics</xref>,
and a description of the latitude enjoyed by its <xref
- linkend="limitations">implementations</xref>.
+ linkend="implementation">implementations</xref>.
</para>
</preface>
<!ENTITY pitfalls SYSTEM "pitfalls.xml">
<!ENTITY quickreference SYSTEM "quickreference.xml">
<!ENTITY semantics SYSTEM "semantics.xml">
-<!ENTITY limitations SYSTEM "limitations.xml">
+<!ENTITY implementation SYSTEM "implementation.xml">
]>
<book>
&pitfalls;
&quickreference;
&semantics;
- &limitations;
+ &implementation;
</book>
<para> Both <literal>perthis</literal> and <literal>pertarget</literal>
aspects may be affected by code the AspectJ compiler controls, as
- discussed in the <xref linkend="limitations"/> appendix. </para>
+ discussed in the <xref linkend="implementation"/> appendix. </para>
</sect3>
<sect3>