Title: The AspectJ Programming Language Part I: Pointcut Declaration
1The AspectJ Programming LanguagePart I Pointcut
Declaration
- CS 5382
- Spring 2009
- The AspectJ Programming Guide, available from
- http//www.eclipse.org/aspectj/doc/released/proggu
ide/index.html
2Outline
- Basic syntax
- Pointcut declaration
- Pointcut designators
- Method/constructor call and execution call,
execution - Field access get, set
- Exposing context this, target, and args
- Control-flow based cflow, cflowbelow
- Lexical-structure based within, withincode
- Initialization staticinitialization,
initialization - Others if, handler
3Basics of AspectJ
- 1 overlay onto Java
- join points - points in the execution of Java
programs - 4 small additions to Java
- pointcuts
- primitive pointcuts - pick out sets of join
points and values at those points - user-defined pointcuts - named collections of
join points and values - advice
- additional action to take at join points in a
pointcut - introduction
- additional fields/methods/constructors for
classes - aspect
- Unit of modular crosscutting implementation,
consisting of advice, introduction, field,
constructor and method declarations
4Example Figure Editor
class Line implements FigureElement private
Point p1, p2 Point getP1() return p1
Point getP2() return p2 void setP1(Point
p) p1 p void setP2(Point p) p2 p
class Point implements FigureElement
private int x 0, y 0 int getX() return
x int getY() return y void setX(int
x) this.x x void setY(int y) this.y
y
display must be updated when objects move
5Move Tracking
- Collection of figure elements
- that change periodically
- must monitor changes to refresh the display as
needed - collection can be complex
- hierarchical
- asynchronous events
6Identifier Pattern
IdPattern IdChars IdPattern
IdPattern IdPattern .. IdPattern IdChars
IdChar IdChars IdChar IdChar a Java
identifier character
. Example getX get edu.utep.cs.Line edu.
utep..Pt
7Semantics
Matches IdPattern, IdChars -gt Boolean Matches(,
x) x does not contain . Matches(p, x) (x
p) and p in IdChars Matches(y z, x) (\exists
x1, x2 (x x1 x2) and Matches(y,
x1) and Matches(z, x2)) Matches(y .. z, x)
Example Matches(getP, getP1) Matches(edu..L
ine, edu.utep.Line) Matches(edu..Line,
edu.utep.cs.Line) Matches(edu..Pt,
edu.utep.cs.Point) Matches(edu..Pt, edu.Point)
8Type Patterns
TypePattern IdPattern IdPattern
TypePattern ! TypePattern TypePattern
TypePattern TypePattern TypePattern (
TypePattern ) Example Point FigureElement (e
du.. !edu..Point) org.. Q. How to
formalize the meaning of this?
9Signature Patterns
Signature MethodPattern ConstructorPattern M
ethodPattern ModifiersOpt TypePattern
TypeDotOpt IdPattern ( FormalsOpt )
ThrowsOpt ConstructorPattern ModifiersOpt
TypeDotOpt new ( FormalsOpt ) ThrowsOpt Modifiers
Opt Modifiers TypeDotOpt TypePattern
. FormalsOpt Formals Formals Formal
Formals , Formal Formal ..
TypePattern ThrowsOpt ThrowsPattern ThrowsPa
ttern
10Signature Patterns (Cont.)
Example void Point.setX(int)
set(..) public Point.new() new(int, int)
throws IllegalArgumentException Questions What
should be the syntax of ThrowsPattern? What
would be the semantics of these patterns?
11Join Points
key points in dynamic call graph
a Line
dispatch
method call join points
method execution join points
- Several kinds of join points
- method constructor call join points
- method constructor execution join points
- field get set join points
- exception handler execution join points
12Pointcut Constructs
Names certain join points
each time a Line executes a void
setP1(Point) or void setP2(Point) method
13Pointcut Declarations
AspectMemberDecl PointCutDeclaration
PointCutDeclaration ModifiersOpt pointcut
Id ( Formals ) ModifiersOpt pointcut Id (
Formals ) PointCut ModifiersOpt
Modifiers Modifiers abstract public
Example protected abstract pointcut
moves() public pointcut moves() call (void
set(..))
14Pointcut Designators
pointcut moves() execution(void
Line.setP1(Point)) execution(void
Line.setP2(Point))
- primitive pointcut designator, such as
- - call, execution - this, target
- - get, set - within, withincode
- - (static)initialization - cflow, flowbelow
15Pointcut Syntax
Pointcut call ( Signature ) execution (
Signature ) initialization (ConstructorPattern
) staticinitialization ( TypePattern ) get
( FieldPattern ) set ( FieldPattern )
handler ( TypePattern ) within ( TypePattern
) withincode ( Signature ) cflow ( PointCut
) cflowbelow ( PointCut )
16Pointcut Syntax (Cont. )
if ( Expression ) this ( TypePatternOrVar
) target ( TypePatternOrVar ) args (
TypePatternOrVarList ) PointCut PointCut
PointCut PointCut ! PointCut Id (
TypePatternOrVarList ) TypePatternOrVar
TypePattern Id TypePatternOrVarList
TypePatternOrVar .. TypePatternOrVarList ,
TypePatternOrVar TypePatternOrVarList , ..
17Call and Execution Pointcuts
call ( Signature ) execution ( Signature
) Method or constructor call join points (at
call site) Method or constructor execution joint
points (at callee site) call(void
Point.setX(int)) execution(public
Point.new()) Q Difference between call and
execution?
18Call vs. Execution Pointcuts
a Line
dispatch
method call join points
method execution join points
Difference in terms of this and target Difference
on the semantics of method invocation
19Call vs. Execution
class MyPoint extends Point int getX()
return super.getX() aspect ShowAccess
before() call(int getX()) ltagt
before() execution(int getX()) ltbgt
dynamic dispatch?
code ltagt runs
once new MyPoint().getX()
code ltbgt runs twice
20Call vs. Execution (Cont.)
class MyPoint extends Point MyPoint()
... aspect ShowAccesses before()
call(new()) ltagt before()
execution(new()) ltbgt
remember the implicit super call here!
code ltagt runs
once new MyPoint()
code ltbgt runs twice
21Example - Simple Tracking
aspect TrackMoves private static boolean flag
false public static boolean testAndClear()
boolean result flag flag false
return result pointcut moves()
execution(void Line.setP1(Point))
execution(void Line.setP2(Point)) after()
moves() flag true
22Example Multi-Class Aspect
Can cut across multiple classes
pointcut moves() execution(void
Line.setP1(Point)) execution(void
Line.setP2(Point)) execution(void
Point.setX(int)) execution(void
Point.setY(int))
23Exercise
- Write an aspect to keep track of the number of
accesses (calls to accessors) made to
FigureElement objects.
class Line implements FigureElement private
Point p1, p2 Point getP1() return p1
Point getP2() return p2 void setP1(Point
p) p1 p void setP2(Point p) p2 p
class Point implements FigureElement
private int x 0, y 0 int getX() return
x int getY() return y void setX(int
x) this.x x void setY(int y) this.y
y
24Field Get and Set Pointcuts
get ( FieldPattern ) set ( FieldPattern
) FieldPattern ModifiersOpt TypePattern
TypeDotOpt IdPattern Field reference or
assignment join points get(int
Point.x) set(Point Line.p)
25Example Tracing Revisited
aspect TrackMoves private static boolean flag
false public static boolean testAndClear()
boolean result flag flag false
return result pointcut moves()
set(Point Line.p1) set(Point Line.p2)
after() moves() flag true
26Using Context in Advice
- Pointcut can explicitly expose certain values
- Advice can use value
typed variable in place of type name
any join pointwhere this is a FigureElement
pointcut moves(FigureElement figElt)
this(figElt) (execution(void
Line.setP1(Point)) execution(void
Line.setP2(Point)) execution(void
Point.setX(int)) execution(void
Point.setY(int))) after(FigureElement fe)
moves(fe) ltfe is bound to the figure
elementgt
27Parameters
of user-defined pointcut designator
- Variable bound in user-defined pointcut
designator - Variable in place of type name in pointcut
designator - Pulls corresponding value out of join points
- Makes value accessible on pointcut
pointcut parameters
pointcut moves(Line l) this(l)
(execution(void Line.setP1(Point))
execution(void Line.setP2(Point)))
after(Line line) moves(line) ltline is
bound to the linegt
variable in place of type name
28Parameters
of advice
- Variable bound in advice
- Variable in place of type name in pointcut
designator - Pulls corresponding value out of join points
- Makes value accessible within advice
pointcut moves(Line l) this(l)
(execution(void Line.setP1(Point))
execution(void Line.setP2(Point)))
after(Line line) moves(line) ltline is
bound to the linegt
typed variable in placeof type name
advice parameters
29Parameters
- Value is pulled
- Right to left across left side
right side - From pointcut designator to user-defined pointcut
designator - From pointcut to advice
pointcut moves(Line l) this(l)
(execution(void Line.setP1(Point))
execution(void Line.setP2(Point))) after(Line
line) moves(line) ltline is bound to the
linegt
30this
Primitive pointcut designator
- this ( TypePatternOrVar )
- TypePatternOrVar TypePattern Id
- Any join point at which
- currently executing object (this) is the
specified or - variables type
- Force the joint point to be matched only when
found in a particular class - Provide access to the object where the joint
point is found - this(Point)
- this(Line)
- this(figElem)
31An idiom for
getting object in a polymorphic pointcut
- this (SuperTypeNameOrVar)
- Does further restrict the join points
- Does pick up the currently executing object (this)
pointcut moves(FigureElement figElt)
this(figElt) (execution(void
setP1(Point)) execution(void
setP2(Point)) execution(void setX(int))
execution(void setY(int)))
after(FigureElement fe) moves(fe) ltfe is
bound to the figure elementgt
32Context and Multiple Classes
aspect MoveTracking private static Set movees
new HashSet() public static Set getMovees()
Set result movees movees new
HashSet() return result pointcut
moves(FigureElement figElt) this(figElt)
(execution(void Line.setP1(Point))
execution(void Line.setP2(Point))
execution(void Point.setX(int))
execution(void Point.setY(int)))
after(FigureElement fe) moves(fe)
movees.add(fe)
33target
Primitive pointcut designator
- target ( TypePatternVar )
- Any join point at which
- target (of call, execution, get, set) is the
specified or - variables type
- - Provide access to the object where the joint
point occurs - Narrow the scope of call, execution, get, and
set. - target(ptr) execution(int Point.getX())
- target(Point) execution(int getX())
34Context Sensitive Aspects
aspect MoveTracking List movers new
LinkedList() List movees new LinkedList()
// pointcut lineMoveCall(Line ln)
target(ln) call(void Line.set(Point))
pointcut pointMoveCall(Point ptr)
target(ptr) call(void Point.set(int))
pointcut moveCall(Object mover, FigureElement
movee) this(mover) (lineMoveCall(movee)
pointMoveCall(movee)) after(Object mover,
FigureElement movee) moveCall(mover,
movee) movers.add(mover)
movees.add(movee)
35args
Primitive pointcut designator
- args ( TypePatternOrVarList )
- Provide arguments sent to the joint point as
parameters - Limiting the matching on specific call or
execution - args(x) call(void Point.setX(int))
- args(int) call(void Point.setX(..))
36Exercise
- Write an aspect to keep track of the number of
setX and setY method executions with negative
argument values.
class Point implements FigureElement private
int x 0, y 0 int getX() return x
int getY() return y void setX(int x)
this.x x void setY(int y) this.y y
37Exercise
- Extend the aspect of the previous exercise to
also keep track of callers for each Point object.
38Exercise (Take-Home)
- Write an aspect to keep track of the number of
accesses (calls to accessors) and the callers for
each FigureElement object.
class Line implements FigureElement private
Point p1, p2 Point getP1() return p1
Point getP2() return p2 void setP1(Point
p) p1 p void setP2(Point p) p2 p
class Point implements FigureElement
private int x 0, y 0 int getX() return
x int getY() return y void setX(int
x) this.x x void setY(int y) this.y
y
39Control-Flow Based Pointcuts
- To capture joint points based on the control flow
of joint points captured by another pointcut,
e.g., - All joint points after execution(void
Point.setX(int)) - Two built-in designators
- cflow
- cflowbelow
40cflow
Primitive pointcut designator
- cflow ( JointPoint )
- All joint points within the dynamic control flow
of any joint points - specified by Pointcut, including those designated
by Pointcut. - cflowbelow ( JointPoint )
- All joint points within the dynamic control flow
of any joint points - specified by Pointcut, excluding those designated
by Pointcut. - cflow(call( Line.changeP1(int,int)))
- cflowbelow(call( Line.changeP1(int,int)))
41Example
- class Line
- private Point p1
- public void changeP1(int x, int y)
- p1.setX(x)
- p1.setY(y)
-
- // other fields and methods here
-
- cflow(call(void Line.changeP1(int,int)))
- cflowbelow(call(void Line.changeP1(int,int)))
42Example
setX()
changeP1()
return
setY()
return
return
Captured by cflowbelow(call( Line.changeP1(int,in
t)))
Captured by cflow(call( Line.changeP1(int,int)))
43Exercise
Define a pointcut to denote all non-recursive
calls to the factorial method. public static
long factorial(int n) return n lt 0 ? 1 n
factorial(n 1)
44Context Sensitive Aspects
aspect MovementTracking private static
Set moved new HashSet() public static Set
getMoved() Set result moved
moved new HashSet() return result
pointcut movement(FigureElement figElt)
this(figElt) (execution(void
Line.setP1(Point)) execution(void
Line.setP2(Point)) execution(void
Point.setX(int)) execution(void
Point.setY(int))) pointcut topLevelMovement(Fi
gureElement figElt) movement(figElt)
!cflowbelow(movement(FigureElement))
after(FigureElement fe) topLevelMove(fe)
moved.add(fe)
45Lexical-Structure Based Pointcuts
- To capture join points occurring inside a lexical
scope of specified classes, apsects, and methods - Two built-in designators
- within
- withincode
46within
Primitive pointcut designator
- within ( TypePattern )
- All joint points within the body of specified
classes and aspects, - as well as any nested classes.
- withincode ( Signature )
- All joint points inside lexical scopes of methods
and constructors, - Including any local classes in them.
- within(Point)
- within(FigureElement)
- withincode( Point.set(..))
47Example Fine-Grained Protection
class Point implement FigureElement private
int x 0, y 0 int getX() return x
int getY() return y void setX(int nv)
primitiveSetX(nv) void setY(int nv)
primitiveSetY(nv) void primitiveSetX(int x)
this.x x void primitiveSetY(int y)
this.y y aspect
PrimitiveSetterEnforcement pointcut
illegalSet(Point ptr) !(withincode(void
Point.primitiveSetX(int)) withincode(void
Point.primitiveSetY(int))) target(ptr)
((set(int Point.x) set(int
Point.y))) before(Point ptr)
illegalSet(ptr) throw new Error("Illegal
primitive setter call on ptr)
48Exercise Avoiding Infinite Loops
Complete the following aspect to print before
and after messages on every method call except
for those made inside the aspect itself.
aspect NoInfiniteLoopAspect pointcut
allCalls() _____________________________________
before() allCalls()
System.out.println(before ) after()
allCalls() System.out.println(
after)
Q Difference between cflow() and within()?
49Conditional Check Pointcut
- if ( Expression )
- All joint points where the given condition holds.
- if(Sytem.currentTimeMilis() gt triggerTime)
- If(aPoint.getX() gt 100)
50Exception Handler Execution
- handler ( TypePattern )
- Executions of exception handlers for the
specified exception types.
try p1.setX(-100) catch (InvalidCoordinateEx
ception e) System.out.println(Invalid
coordinate value!) handler(InvalidCoordinate
Exception)
51Class Initialization
- staticinitialization ( TypePattern )
- Loading of classes including the initialization
of the static portions
import java.util. class PointExtent extends
Point public static Set extent static
extent new HashSet() staticinitializatio
n(PointExtent)
52Object Initialization
- initialization ( ConstructorPattern )
- Initialization of an object starting from the
return of a parent classs - constructor until the end of the first called
constructor.
class ColoredPoint extends Point private
Color color public ColoredPoint(Color c)
color c public ColoredPoint()
this(Color.BLUE) initialization(ColoredPoi
nt.new())
How does this differ from constructor call and
execution joint points?
53Exercise
- Write an aspect to keep track of (store)
PointExtent instances - in the order of creation in the static field
extent. - (Hint HashSet doesnt maintain the insertion
order but - LinkedHashSet does maintain the order.)
import java.util. class PointExtent extends
Point public static Set extent new
HashSet()
54Review Wildcarding in Pointcuts
is wild card, and .. is multi-part wild card
this(Point) this(graphics.geom.Point) this(graphic
s.geom.) any type in graphics.geom this(graphics.
.) any type in any sub-package of
graphics call(void Point.setX(int)) call(public
Point.(..)) any public method on
Point call(public ...(..)) any public method
on any type call(void getX()) call(void
getY()) call(void get()) any
getter call(Point.new(int, int)) call(new(..))
any constructor
55Property-Based Crosscutting
package edu.utep.cs3360 public class C2
public int bar1() A.doSomething()
public int bar2() A.doSomething()
package edu.utep.cs3360 public class C1
public void foo() A.doSomething()
Package edu.utep.cs3360 public class C3
public String m1() A.doSomething()
- Crosscuts of methods with a common property
- public/private, return a certain value, in a
particular package - Logging, debugging, profiling
- log on entry to every public method
56Property-Based (Cont.)
aspect PublicErrorLogging static Log log
new Log() pointcut publicInterface ()
call(public edu.utep...(..)) static
after() throwing (Error e) publicInterface()
log.write(e)
neatly captures public interface of mypackage
- Consider code maintenance
- another programmer adds a public method,
- i.e. extends public interface this code will
still work - another programmer reads this code
- whats really going on is explicit