1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
class A {
void m() {
System.out.println("A");
}
}
class B extends A {
void m() {
System.out.println("B");
}
}
aspect IfPointcut {
after(A a, B b) returning:
execution(* foo(*,*)) &&
(args(b,a) || args(a,b)) {
System.out.println("Woven");
}
}
public class DisjunctVarBinding {
public static void foo(A a, A b) {
a.m();
b.m();
}
public static void main(String[] args) {
A a = new A();
B b = new B();
foo(b,a);
}
}
/* Example to illustrate a problem with variable
binding and (||) in pointcuts. When run, this program produces
java.lang.ClassCastException immediately after
the call to "foo".
The reason is that the instance tests inherent
in the pointcut are done separately from the
variable binding.
Decompiled, the code produced for the relevant call
to "foo" is as follows:
--------------------------------------------------
DisjunctVarBinding.foo(r5, r4);
label_0:
{
if (r5 instanceof B == false)
{
if (r4 instanceof B == false)
{
break label_0;
}
}
IfPointcut.aspectOf().ajc$afterReturning$IfPointcut$26d(r5, (B) r4);
}
--------------------------------------------------
It should however read something like this, using the instance
tests to determine the appropriate variable binding
--------------------------------------------------
DisjunctVarBinding.foo(r5,r4);
if (r4 instanceof B)
IfPointcut.aspectOf().ajc$afterReturning$IfPointcut$26d(r5, (B)r4)
else if (r5 instanceof A)
IfPointcut.aspectOf().ajc$afterReturning$IfPointcut$26d(r4,(B)r5)
--------------------------------------------------
*/
|