This document discusses using the rely-guarantee approach to reason about aspect-oriented programs. It introduces the rely-guarantee specification for a method M under advice as M sat (pre, rely, guar, post). The rely clause specifies the state transitions allowed by advice. An example shows how rely specifies that advice cannot change the coordinates of a Point object, allowing advice to change its scale. The approach makes base code specifications more robust to aspect changes by separating assumptions about advice from method specifications.
5. The Problem
Desirable!
• Addition of an aspect can change the behavior of
the base code.
6. The Problem
Desirable!
• Addition of an aspect can change the behavior of
the base code.
• Prior reasoning about the base code may no longer
be valid.
7. The Problem
Desirable!
• Addition of an aspect can change the behavior of
the base code.
• Prior reasoning about the base code may no longer
be valid.
• May be forced to reason about the entire system
again accounting for the interleaving.
8. The Problem
Desirable!
• Addition of an aspect can change the behavior of
the base code.
• Prior reasoning about the base code may no longer
be valid.
• May be forced to reason about the entire system
again accounting for the interleaving.
• Can we make base-code specifications more robust
to aspectual changes?
9. Motivation
• [Sullivan FSE’05]:
1. Separate base and crosscutting concerns.
2. Implement base concerns in an OO style ignoring
crosscutting concerns.
3. Implement the crosscutting concerns as aspects
that advise the base code directly.
4
12. Insight
• Aspect-oriented weaving and concurrent execution
present similar challenges for program analysis.
• AOP case much simpler (restricted interleaving).
13. Insight
• Aspect-oriented weaving and concurrent execution
present similar challenges for program analysis.
• AOP case much simpler (restricted interleaving).
• Well-defined join points, sequential programs,
only aspect can intercept the base-code.
14. Insight
• Aspect-oriented weaving and concurrent execution
present similar challenges for program analysis.
• AOP case much simpler (restricted interleaving).
• Well-defined join points, sequential programs,
only aspect can intercept the base-code.
• Concurrent program reasoning generally requires
knowledge of all processes.
15. Insight
• Aspect-oriented weaving and concurrent execution
present similar challenges for program analysis.
• AOP case much simpler (restricted interleaving).
• Well-defined join points, sequential programs,
only aspect can intercept the base-code.
• Concurrent program reasoning generally requires
knowledge of all processes.
• Not the case in AOP.
16. Insight
• Aspect-oriented weaving and concurrent execution
present similar challenges for program analysis.
• AOP case much simpler (restricted interleaving).
• Well-defined join points, sequential programs,
only aspect can intercept the base-code.
• Concurrent program reasoning generally requires
knowledge of all processes.
• Not the case in AOP.
• An approach known from concurrent
programming, rely-guarantee [Xu97], can be
adapted and then used to make AO programs more
analyzable.
17. Notation
the set of all variables of
σ the program
states in which each
σi , σj , ... variable has a particular
value
24. The Rely() Clause
• Identify a relation rely() that is a predicate over two
states, σa and σb.
25. The Rely() Clause
• Identify a relation rely() that is a predicate over two
states, σa and σb.
• rely() will not correspond to the actual behavior of
advice.
26. The Rely() Clause
• Identify a relation rely() that is a predicate over two
states, σa and σb.
• rely() will not correspond to the actual behavior of
advice.
• specify the kinds of behavior acceptable to m().
33. Rely-Guarantee Approach for AOP
A method M under the influence of advice satisfies
an R/G specification denoted by
34. Rely-Guarantee Approach for AOP
A method M under the influence of advice satisfies
an R/G specification denoted by
M sat (pre, rely, guar, post)
35. Rely-Guarantee Approach for AOP
A method M under the influence of advice satisfies
an R/G specification denoted by
M sat (pre, rely, guar, post)
if
36. Rely-Guarantee Approach for AOP
A method M under the influence of advice satisfies
an R/G specification denoted by
M sat (pre, rely, guar, post)
if
1) M is invoked in a state which satisfies pre, and
37. Rely-Guarantee Approach for AOP
A method M under the influence of advice satisfies
an R/G specification denoted by
M sat (pre, rely, guar, post)
if
1) M is invoked in a state which satisfies pre, and
2) all advice transitions satisfy rely,
38. Rely-Guarantee Approach for AOP
A method M under the influence of advice satisfies
an R/G specification denoted by
M sat (pre, rely, guar, post)
if
1) M is invoked in a state which satisfies pre, and
2) all advice transitions satisfy rely,
then
39. Rely-Guarantee Approach for AOP
A method M under the influence of advice satisfies
an R/G specification denoted by
M sat (pre, rely, guar, post)
if
1) M is invoked in a state which satisfies pre, and
2) all advice transitions satisfy rely,
then
3) all states prior to M being intercepted by advice
will satisfy guar, and
40. Rely-Guarantee Approach for AOP
A method M under the influence of advice satisfies
an R/G specification denoted by
M sat (pre, rely, guar, post)
if
1) M is invoked in a state which satisfies pre, and
2) all advice transitions satisfy rely,
then
3) all states prior to M being intercepted by advice
will satisfy guar, and
4) if the computation terminates, the final state will
satisfy post.
41. Rely-Guarantee Approach for AOP
A method M under the influence of advice satisfies
an R/G specification denoted by
M sat (pre, rely, guar, post)
if
1) M is invoked in a state which satisfies pre, and
2) all advice transitions satisfy rely, Pointcut
then
3) all states prior to M being intercepted by advice
will satisfy guar, and
4) if the computation terminates, the final state will
satisfy post.
42. Rely-Guarantee Approach for AOP
A method M under the influence of advice satisfies
an R/G specification denoted by
M sat (pre, rely, guar, post)
if
1) M is invoked in a state which satisfies pre, and
2) all advice transitions satisfy rely, Pointcut
then
3) all states prior to M being intercepted by advice
will satisfy guar, and for advice
pre
4) if the computation terminates, the final state will
satisfy post.
44. Rely() Example
The entire state
of C
rely(σ, σ ) ≡ (σ = σ )
45. Rely() Example
rely(σ, σ ) ≡ (σ = σ )
ble ny
ica g a
pl in !
y ap ak te
an m m sta
ds fro the
bi e
or ic s in
F v
ad ange
ch
46. Rely() Example
This is
“Harmless”[D&W
POPL’06]
rely(σ, σ ) ≡ (σ = σ )
47. 1 class Point {
2 int x, y; co
3 int s; pa
4 qu
5 public Point(int xi, int yi) mi
6 { x=xi; y=yi; s=1; } hav
7 public int getX() { return (x*s); } on
8 public int getY() { return (y*s); } ma
9
dif
10 public void move(int nx, int ny)
11 { x=nx; y=ny; }
of
12 } po
13 rel
14 aspect adjustScale { as
15 pointcut m(Point p):
16 execution(void Point.move(int,int)) cla
17 && target( p ); tha
18
ad
19 after(Point p) : m(p) {
in
20 if ((p.x < 5) && (p.y < 5)) { p.s=10; }
21 } we
22 } wi
ap
the
Figure 1. Point Class and Aspect on
po
48. 1 class Point {
2 int x, y; co
3 int s; pa
4 qu
5 public Point(int xi, int yi) mi
6 { x=xi; y=yi; s=1; } hav
7 public int getX() { return (x*s); } on
8 public int getY() { return (y*s); } ma
9
dif
10 public void move(int nx, int ny)
of
Coordinates { x=nx; y=ny; }
11
po
12 }
13 rel
14 aspect adjustScale { as
15 pointcut m(Point p):
16 execution(void Point.move(int,int)) cla
17 && target( p ); tha
18
ad
19 after(Point p) : m(p) {
in
20 if ((p.x < 5) && (p.y < 5)) { p.s=10; }
21 } we
22 } wi
ap
the
Figure 1. Point Class and Aspect on
po
49. 1 class Point {
2 int x, y; co
3 int s; pa
qu
4
5 public Point(int xi, int yi) Scaled mi
6 { x=xi; y=yi; s=1; } hav
7 public int getX() { return (x*s); } on
8 public int getY() { return (y*s); } ma
9
dif
10 public void move(int nx, int ny)
11 { x=nx; y=ny; }
of
12 } po
13 rel
14 aspect adjustScale { as
15 pointcut m(Point p):
16 execution(void Point.move(int,int)) cla
17 && target( p ); tha
18
ad
19 after(Point p) : m(p) {
in
20 if ((p.x < 5) && (p.y < 5)) { p.s=10; }
21 } we
22 } wi
ap
the
Figure 1. Point Class and Aspect on
po
50. 1 class Point {
2 int x, y; co
3 int s; pa
4 qu
5 public Point(int xi, int yi) mi
6 { x=xi; y=yi; s=1; } hav
7 public int getX() { return (x*s); } on
8 public int getY() { return (y*s); } ma
9
dif
10 public void move(int nx, int ny)
11 { x=nx; y=ny; }
of
12 } po
13 rel
14 aspect adjustScale { as
15 pointcut m(Point p):
16 execution(void Point.move(int,int)) cla
17 && target( p Too close!
); tha
18
ad
19 after(Point p) : m(p) {
in
20 if ((p.x < 5) && (p.y < 5)) { p.s=10; }
21 } we
22 } wi
ap
the
Figure 1. Point Class and Aspect on
po
51. 1 class Point {
2 int x, y; co
3 int s; pa
4 qu
5 public Point(int xi, int yi) mi
6 { x=xi; y=yi; s=1; } hav
7 public int getX() { return (x*s); } on
8 public int getY() { return (y*s); } ma
9
dif
10 public void move(int nx, int ny)
11 { x=nx; y=ny; }
of
12 } po
13 rel
14 aspect adjustScale { as
15 pointcut m(Point p):
16 execution(void Point.move(int,int)) cla
17 && target( p ); tha
18
ad
19 after(Point p) : m(p) {
in
20 if ((p.x < 5) && (p.y < 5)) { p.s=10; }
21 } we
22 } wi
Adjust ap
the
Figure 1. Point Class and Aspect on
po
52. 1 class Point {
2 int x, y; co
3 int s; pa
4 qu
5 public Point(int xi, int yi) mi
6 { x=xi; y=yi; s=1; } hav
7 public int getX() { return (x*s); } on
8 public int getY() { return (y*s); } ma
9
dif
10 public void move(int nx, int ny)
11 { x=nx; y=ny; }
of
12 } po
13 rel
14 aspect adjustScale { as
15 pointcut m(Point p):
16 execution(void Point.move(int,int)) cla
17 && target( p ); tha
18
ad
19 after(Point p) : m(p) {
in
20 if ((p.x < 5) && (p.y < 5)) { p.s=10; }
21 } we
22 } wi
ap
the
Figure 1. Point Class and Aspect on
po
53. A rely() for class Point
rely(σ, σ ) ≡ [(σ.x = σ .x) ∧ (σ.y = σ .y)]
54. A rely() for class Point
rely(σ, σ ) ≡ [(σ.x = σ .x) ∧ (σ.y = σ .y)]
55. A rely() for class Point
rely(σ, σ ) ≡ [(σ.x = σ .x) ∧ (σ.y = σ .y)]
(σ.s = σ .s)
56. A rely() for class Point
rely(σ, σ ) ≡ [(σ.x = σ .x) ∧ (σ.y = σ .y)]
• Not a fault of the reasoning approach!
57. A rely() for class Point
rely(σ, σ ) ≡ [(σ.x = σ .x) ∧ (σ.y = σ .y)]
• Not a fault of the reasoning approach!
• Must be sure not to impose stronger requirements
than necessary on aspects that might be developed
later.
58. A rely() for class Point
rely(σ, σ ) ≡ [(σ.x = σ .x) ∧ (σ.y = σ .y)]
• Not a fault of the reasoning approach!
• Must be sure not to impose stronger requirements
than necessary on aspects that might be developed
later.
• Otherwise, we may be forced to redo the task of
reasoning about the class ...
59. A rely() for class Point
rely(σ, σ ) ≡ [(σ.x = σ .x) ∧ (σ.y = σ .y)]
• Not a fault of the reasoning approach!
• Must be sure not to impose stronger requirements
than necessary on aspects that might be developed
later.
• Otherwise, we may be forced to redo the task of
reasoning about the class ...
• BUT, it is only in these cases where we must redo our
reasoning.
61. The guar() Clause
• Concurrent programs: the two processes act
symmetrically.
62. The guar() Clause
• Concurrent programs: the two processes act
symmetrically.
• AOP: base-code can’t intercept advice.
63. The guar() Clause
• Concurrent programs: the two processes act
symmetrically.
• AOP: base-code can’t intercept advice.
• guar() for AOP
64. The guar() Clause
• Concurrent programs: the two processes act
symmetrically.
• AOP: base-code can’t intercept advice.
• guar() for AOP
• The assertion is true in this case.
65. The guar() Clause
• Concurrent programs: the two processes act
symmetrically.
• AOP: base-code can’t intercept advice.
• guar() for AOP
• The assertion is true in this case.
• Aspect not available at time of construction.
66. The guar() Clause
• Concurrent programs: the two processes act
symmetrically.
• AOP: base-code can’t intercept advice.
• guar() for AOP
• The assertion is true in this case.
• Aspect not available at time of construction.
• Need to consider many possible joinpoints.
67. The guar() Clause
• Concurrent programs: the two processes act
symmetrically.
• AOP: base-code can’t intercept advice.
• guar() for AOP
• The assertion is true in this case.
• Aspect not available at time of construction.
• Need to consider many possible joinpoints.
• guar() may not be strong enough for future.
68. 9 d
public void move(int nx, int ny) o
10
11 { x=nx; y=ny; }
The Reasoning Processp
class Point {
• r
12 } 1
Do not have information
13 2 int x, y; about the value of a
Point.s s;
14 aspect int
3 adjustScale {
15 pointcut m(Point p):
4
c
16 public Point(int xi, int yi)
5 execution(void Point.move(int,int))
17 6 && target( p {);
x=xi; y=yi; s=1; }
t
18 7 public int getX() { return (x*s); } a
19 after(Point p) : getY() { return (y*s); }
8 public int m(p) { i
20 9 if ((p.x < 5) && (p.y < 5)) { p.s=10; } w
21 }
10 public void move(int nx, int ny) w
22 } 11 { x=nx; y=ny; } a
12 } t
13 Figure 1. Point Class and Aspect o
aspect adjustScale {
14 p
15 pointcut m(Point p): f
execution(void Point.move(int,int))
That is, indeed, precisely what the adjustScale aspect does.
16 (
&& target( to an
The pointcut m() corresponds p ); execution of the move()
17 o
method. The after advice specified states that if the point p is
18 a
sufficientlyafter(Point p) then the scale factor is set equal to
19
close to the origin, : m(p) { P
ten4 . 20 if ((p.x < the class Point, we see that the
Thus, if we consider just5) && (p.y < 5)) { p.s=10; } r
69. 9 d
public void move(int nx, int ny) o
10
11 { x=nx; y=ny; }
The Reasoning Processp
class Point {
• r
12 } 1
Do not have information
13 2 int x, y; about the value of a
Point.s s;
14 aspect int
3 adjustScale {
15 pointcut m(Point p):
4
c
16 public Point(int xi, int yi)
5 execution(void Point.move(int,int))
17 6 && target( p {);
x=xi; y=yi; s=1; }
t
18 7 public int getX() { return (x*s); } a
19 after(Point p) : getY() { return (y*s); }
8 public int m(p) { i
20 9 if ((p.x < 5) && (p.y < 5)) { p.s=10; } w
21 }
10 public void move(int nx, int ny) w
22 } 11 { x=nx; y=ny; } a
12 } t
13 Figure 1. Point Class and Aspect o
aspect adjustScale {
14 p
15 pointcut m(Point p): f
execution(void Point.move(int,int))
That is, indeed, precisely what the adjustScale aspect does.
16 (
&& target( to an
The pointcut m() corresponds p ); execution of the move()
17 o
method. The after advice specified states that if the point p is
18 a
sufficientlyafter(Point p) then the scale factor is set equal to
19
close to the origin, : m(p) { P
ten4 . 20 if ((p.x < the class Point, we see that the
Thus, if we consider just5) && (p.y < 5)) { p.s=10; } r
70. 9 d
public void move(int nx, int ny) o
10
11 { x=nx; y=ny; }
The Reasoning Processp
class Point {
• r
12 } 1
Do not have information
13 2 int x, y; about the value of a
Point.s s;
14 aspect int
3 adjustScale {
15 pointcut m(Point p):
4
c
16 public Point(int xi, int yi)
5 execution(void Point.move(int,int))
17 6 && target( p {);
x=xi; y=yi; s=1; }
t
18 7 public int getX() { return (x*s); } a
19 after(Point p) : getY() { return (y*s); }
8 public int m(p) { i
20 9 if ((p.x < 5) && (p.y < 5)) { p.s=10; } w
21 }
10 public void move(int nx, int ny) w
22 } 11 { x=nx; y=ny; } a
12 } t
13 Figure 1. Point Class and Aspect o
aspect adjustScale {
14 p
15 pointcut m(Point p): f
execution(void Point.move(int,int))
That is, indeed, precisely what the adjustScale aspect does.
16 (
&& target( to an
The pointcut m() corresponds p ); execution of the move()
17 o
method. The after advice specified states that if the point p is
18 a
sufficientlyafter(Point p) then the scale factor is set equal to
19
close to the origin, : m(p) { P
ten4 . 20 if ((p.x < the class Point, we see that the
Thus, if we consider just5) && (p.y < 5)) { p.s=10; } r
71. 9 d
public void move(int nx, int ny) o
10
11 { x=nx; y=ny; }
The Reasoning Processp
class Point {
• r
12 } 1
Do not have information
13 2 int x, y; about the value of a
Point.s s;
14 aspect int
3 adjustScale {
15 pointcut m(Point p):
4
c
16 public Point(int xi, int yi)
5 execution(void Point.move(int,int))
17 6 && target( p {);
x=xi; y=yi; s=1; }
t
18 7 public int getX() { return (x*s); } a
19 after(Point p) : getY() { return (y*s); }
8 public int m(p) { i
20 9 if ((p.x < 5) && (p.y < 5)) { p.s=10; } w
21 }
10 public void move(int nx, int ny) w
22 } 11 { x=nx; y=ny; } a
• History variable [Hoare78]
12 }
Figure 1. Point Class and Aspect
13
t
o
• aspect adjustScale {
Provides additional information required to
14
pointcut m(Point p):
15
p
f
establishexecution(voidof the combined system.
the behavior Point.move(int,int))
That is, indeed, precisely what the adjustScale aspect does.
16 (
&& target( to an
The pointcut m() corresponds p ); execution of the move()
17 o
method. The after advice specified states that if the point p is
18 a
sufficientlyafter(Point p) then the scale factor is set equal to
19
close to the origin, : m(p) { P
ten4 . 20 if ((p.x < the class Point, we see that the
Thus, if we consider just5) && (p.y < 5)) { p.s=10; } r
72. 4
5 public Point(int xi, int History Variable
yi)
6 { x=xi; y=yi; s=1; }
7 Consider intbehavior of Point.move(): }
public the getX() { return (x*s);
8 public int getY() { return (y*s); }
9
10 public void move(int nx, int ny)
11 { x=nx; y=ny; }
12 }
13
14 aspect What’s the value{of Point.s?
adjustScale
15 pointcut m(Point p):
16 execution(void Point.move(int,int))
17 && target( p );
18
19 after(Point p) : m(p) {
20 if ((p.x < 5) && (p.y < 5)) { p.s=1
21 }
73. 4
5 public Point(int xi, int History Variable
yi)
6 { x=xi; y=yi; s=1; }
7 Consider intbehavior of Point.move(): }
public the getX() { return (x*s);
8 public int getY() { return (y*s); }
9
10 public void move(int nx, int ny)
11 { x=nx; y=ny; }
12 }
13
14 aspect What’s the value{of Point.s?
adjustScale
15 pointcut m(Point p):
execution(void Point.move(int,int))
•
16
From the && target( p ); know that it does not
17
body of move(), we
change the value of s.
18
•
19
20
after(Point p) : m(p) {
must have been due to aspectual (i.e.,
if ((p.x < 5) && (p.y < 5)) { p.s=1
21
environmental) influence.
}
75. Post-condition of Point.move()
• Post-condition of move() will state:
• Values of x and y are equal to the values for the
corresponding arguments received.
• Value of s will be equal to whatever it was when
the final advice to execute during the execution of
move() completes.
76. Post-condition of Point.move()
• Post-condition of move() will state:
• Values of x and y are equal to the values for the
corresponding arguments received.
• Value of s will be equal to whatever it was when
the final advice to execute during the execution of
move() completes.
• Can conclude that s will be 10 or what it was at the
start of the method.
77. 1 class Point {
But
2 int x, y; condit
3 int s; particu
4 questi
5 public Point(int xi, int yi) might
6 { x=xi; y=yi; s=1; } have t
7 public int getX() { return (x*s); } on an
8 public int getY() { return (y*s); } may h
9
differe
10 public void move(int nx, int ny)
11 { x=nx; y=ny; }
of exp
12 } pointc
13 rely()
14 aspect adjustScale { as (1)
15 pointcut m(Point p): Ho
16 execution(void Point.move(int,int)) class a
17 && target( p ); that ap
18
advice
19 after(Point p) : m(p) {
in whi
20 if ((p.x < 5) && (p.y < 5)) { p.s=10; }
21 } we wi
22 } will, t
a pote
the cla
Figure 1. Point Class and Aspect one or
possib
78. 1 class Point {
But
2 int x, y; condit
3 int s; particu
4 questi
5 public Point(int xi, int yi) might
6 { x=xi; y=yi; s=1; } have t
7 public int getX() { return (x*s); } on an
8 public int getY() { return (y*s); } may h
9
differe
10 public void move(int nx, int ny)
11 { x=nx; y=ny; }
of exp
12 } pointc
13 rely()
14 aspect adjustScale { as (1)
15 pointcut m(Point p): Ho
16 execution(void Point.move(int,int)) class a
17 && target( p ); that ap
18
advice
19 after(Point p) : m(p) {
in whi
20 if ((p.x < 5) && (p.y < 5)) { p.s=10; }
21 } we wi
22 } will, t
a pote
the cla
Figure 1. Point Class and Aspect one or
possib
80. Conclusion and Future Work
• AO programmers already think implicitly about
rely(), our proposed approach makes this explicit.
81. Conclusion and Future Work
• AO programmers already think implicitly about
rely(), our proposed approach makes this explicit.
• Formally capture properties we want AO
programs to exhibit.
82. Conclusion and Future Work
• AO programmers already think implicitly about
rely(), our proposed approach makes this explicit.
• Formally capture properties we want AO
programs to exhibit.
• rely() specifies the kinds of aspectual influence
the base-code is willing to tolerate so that it
would not be adversely affected by advice.
83. Conclusion and Future Work
• AO programmers already think implicitly about
rely(), our proposed approach makes this explicit.
• Formally capture properties we want AO
programs to exhibit.
• rely() specifies the kinds of aspectual influence
the base-code is willing to tolerate so that it
would not be adversely affected by advice.
• Specifying rely().
84. Conclusion and Future Work
• AO programmers already think implicitly about
rely(), our proposed approach makes this explicit.
• Formally capture properties we want AO
programs to exhibit.
• rely() specifies the kinds of aspectual influence
the base-code is willing to tolerate so that it
would not be adversely affected by advice.
• Specifying rely().
• Formal framework, obtaining richer behavior.
85. Conclusion and Future Work
• AO programmers already think implicitly about
rely(), our proposed approach makes this explicit.
• Formally capture properties we want AO
programs to exhibit.
• rely() specifies the kinds of aspectual influence
the base-code is willing to tolerate so that it
would not be adversely affected by advice.
• Specifying rely().
• Formal framework, obtaining richer behavior.
• Multiple applicable advice.
86. Conclusion and Future Work
• AO programmers already think implicitly about
rely(), our proposed approach makes this explicit.
• Formally capture properties we want AO
programs to exhibit.
• rely() specifies the kinds of aspectual influence
the base-code is willing to tolerate so that it
would not be adversely affected by advice.
• Specifying rely().
• Formal framework, obtaining richer behavior.
• Multiple applicable advice.
• Tool-supported verification.