From c0ef7c724322530a361686fade5607ed0577bb87 Mon Sep 17 00:00:00 2001 From: wisberg Date: Thu, 5 Oct 2006 17:01:58 +0000 Subject: bug 159390 Documenting long-known runtime ClassCastException from proceed --- docs/progGuideDB/implementation.xml | 16 ++++++++ docs/progGuideDB/semantics.xml | 75 ++++++++++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 5 deletions(-) (limited to 'docs/progGuideDB') diff --git a/docs/progGuideDB/implementation.xml b/docs/progGuideDB/implementation.xml index f83e7dd8c..52da14d9c 100644 --- a/docs/progGuideDB/implementation.xml +++ b/docs/progGuideDB/implementation.xml @@ -297,6 +297,16 @@ + + Annotation-style Notes + 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 + for more information. + + Summary of implementation requirements @@ -351,6 +361,12 @@ cflow and cflowbelow pointcuts work within a single thread. + + + Runtime ClassCastException may result + from supplying a supertype of the actual type as an argument + to proceed(..) in around advice. + diff --git a/docs/progGuideDB/semantics.xml b/docs/progGuideDB/semantics.xml index 6c2fb173a..fd282faec 100644 --- a/docs/progGuideDB/semantics.xml +++ b/docs/progGuideDB/semantics.xml @@ -1938,11 +1938,11 @@ ModifiersPattern = } } - - - Any occurence of proceed(..) within the body of - around advice is treated as the special proceed form (even if the - aspect defines a method named proceed) unless a + + + Any occurence of proceed(..) within the body of around + advice is treated as the special proceed form (even if the + aspect defines a method named proceed), unless a target other than the aspect instance is specified as the recipient of the call. For example, in the following program the first @@ -1986,6 +1986,71 @@ ModifiersPattern = parameters or return values of join points can be done by using around advice. + + With proceed(..) 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 s in the named pointcut + privateData: + + + + aspect A { + Object around(String s): MyPointcuts.privateData(s) { + return proceed("private data"); + } + } + + + If you replace an argument to proceed(..), you can cause + a ClassCastException at runtime when the argument + 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 List + with an ArrayList. This is valid code at + compile-time since the types match. + + + import java.util.*; + + aspect A { + Object around(List list): call(* List+.*()) target(list) { + return proceed(new ArrayList()); + } + } + + + But imagine a simple program where the actual target is + LinkedList. In this case, the advice would cause a + ClassCastException at runtime, and + peek() is not declared in ArrayList. + + + public class Test { + public static void main(String[] args) { + new LinkedList().peek(); + } + } + + + The ClassCastException can occur even in situations + where it appears to be unnecessary, e.g., if the program is changed to + call size(), declared in List: + + + public class Test { + public static void main(String[] args) { + new LinkedList().size(); + } + } + + + There will still be a ClassCastException because + it is impossible to prove that there won't be a runtime binary-compatible + change in the hierarchy of LinkedList or some + other advice on the join point that requires a + LinkedList. + Advice modifiers -- cgit v1.2.3