Title: Session 4 Stateful Aspects in JAsCo
1Session 4Stateful Aspects in JAsCo
2Aspect-Oriented Programming
Logging in Apache Tomcat
- BAD modularity
- handled by code that is scattered over almost all
classes
Picture taken from the aspectj.org website
3Aspect-Oriented Programming
Logging in Apache Tomcat
Logging Aspect
4AOSD Terminology
- joinpoint point in the programs execution
- e.g. Executing method setX on type Y
- pointcut A set of joinpoints
- e.g. The execution of all methods which name
start with set on type Y - advice What to do at a certain pointcut
- e.g. Print a logging string before the program
continues. - weaving applying the advice to all joinpoints
defined in the pointcut declaration
5Stateful Aspects
- Natural Evolution of joinpoints
- Static
- Dynamic (e.g. cflow)
- Stateful
6Examples (1)
- Auto-save after five actions
7Examples (1) AspectJ solution
aspect Autosave private int
actions_since_last_save 0 after()
call( Application.save()) call(
Application.autosave()) actions_since_last_sa
ve0 after() call(??Command.execute()
) actions_since_last_save
if(actions_since_last_savegt4) Application.autosav
e()
8Examples (2) Safe iterator
9Examples (3) Timing Aspect
10Timing Aspect JAsCo Solution
- 1 class DynamicTimer
- 3 private VectorltTimeListenergt listeners new
VectorltTimeListenergt() - 4 private long timestampbefore,
timestampafter - 6 void addTimeListener(TimeListener aListener)
- 7 listeners.add(aListener)
- 8
- 9 void removeTimeListener(TimeListener
aListener) - 10 listeners.remove(aListener)
- 11
- 12 void notifyTimeListeners(Method method, long
time) - 13 for (TimeListener listener listeners)
- 14 listener.timeStampTaken(method,time)
- 15
- 16
- 18 hook TimeStamp
- 19 TimeStamp(timedmethod(..args))
- 20 execution(timedmethod)
- 21
- 22 before
11Timing Aspect JAsCo solution
- Timing one method
- But how to time a protocol? E.g. time between
execution of a-b-c on ComponentX.
1 connector TimeConnector 2
DynamicTimer.TimeStamp timer 3 new
DynamicTimer.TimeStamp (void ComponentX.a()) 4
timer.before() 5 timer.after() 6
12Protocol Timing Aspect?
1 class ProtocolDynamicTimer extends
DynamicTimer 2 3 boolean methodaexecuted,
methodbexecuted false 4
5 hook ProtocolMethodA 7
ProtocolMethodA(methodA(..args)) 8
execution(methodA) 9 10 before 11
timestampbefore System.currentTimeMillis()
12 methodaexecuted true 13 14
isApplicable() return !methodaexecuted 15
16 17 hook ProtocolMethodB 18
ProtocolMethodB(methodB(..args)) 19
execution(methodB) 20 21 before 22
methodbexecuted true 23 24
isApplicable() return methodaexecuted 25
26 27 hook ProtocolMethodC 28
ProtocolMethodC(methodC(..args)) 29
execution (methodC) 30 31 after 32
timestampafter System.currentTimeMillis() 3
3 notifyListeners(method,timestampafter-time
stampbefore) 34 methodaexecuted false
methodbexecuted false 35 36
isApplicable() return methodbexecuted 37
39
connector TimeConnector
DynamicTimer.ProtocolMethodA timera
new DynamicTimer. ProtocolMethodA (void
ComponentX.a()) DynamicTimer.ProtocolMethod
B timerb new DynamicTimer.
ProtocolMethodB (void ComponentX.b())
DynamicTimer.ProtocolMethodC timerc
new DynamicTimer. ProtocolMethodC (void
ComponentX.c())
13Stateful Aspects Motivation
- Protocol based aspects are rarely supported in
current AOSD approaches (apart cflow). - Result protocol checking code is scattered over
advices, poluting advice code - Is also not optimal, checks at all possible
joinpoints while only a subset is required.
14Stateful Aspects
- Allows specifying regular (DFA based) hook
triggering conditions in a hooks constructor. - Advices can be attached to any transition of the
DFA, or all of them (global). - Example Realize a more general protocol history
condition than cflow.
15Timing Example Revisited
- 1 class ProtocolDynamicTimer extends
DynamicTimer - 2
- 3 hook StatefulProtocolTimer
- 4
- 5 long timestamp
- 6
- 7 StatefulProtocolTimer(methodA(..args),metho
dB(..args),methodC(..args)) - 8 ATrans execution(methodA) gt BTrans
- 9 BTrans execution(methodB) gt CTrans
- 10 CTrans execution(methodC) gt ATrans
- 11
- 12
- 13 before ATrans()
- 14 timestampSystem.currentTimeMillis()
- 15
- 16 after CTrans()
- 17 long resultingtime System.currentTimeMi
llis() - 18 notifyListeners(calledmethod,resultingtim
e-timestamp) - 19
16Timing Example Revisited
- static connector TimingConnector
- perthread ProtocolDynamicTimer.StatefulProtoc
olTimer timer - new ProtocolDynamicTimer.StatefulProtocolTim
er( - void ComponentX.a().,
- void ComponentX.b(),
- void ComponentX.c()
- )
-
17Advanced Pointcut Features
- Explicit start transitions
- start gt XTrans
- Starting with two transitions
- start gt XTrans QTrans
- two destination transitions
- XTrans execution(methodA) gt YTrans QTrans
- no destination transition
- QTrans execution(methodB) !cflow(methodC)
18Advices
- Multiple specific advices possible, one for each
transition per before/around /after - Global advice works for all transitions
- isApplicable can also be global or specific
isApplicable() //global condition for all
transitions // returns true if advices should
be executed isApplicable XTrans() //local
condition only relevant for the transition
XTrans // returns true if advices should be
executed for the XTrans transition
19Strict Protocols
- Per default, stateful aspects are non-strict,
e.g. protocol a()-d()-b()-c() also matches timing
aspect. - When no intermediate transitions are allowed, use
the strict keyword
strict ATrans execution(methodA) gt BTrans
BTrans execution(methodB) gt CTrans CTrans
execution(methodC) gt ATrans
20Strict Protocols with Context
- Only strict with respect to a certain set of
joinpoints. E.g. timing aspect does not accept
intermediate transitions on ComponentX, on other
classes is ok though.
StatefulProtocolTimer(methodA(..args),methodB(..ar
gs),methodC(..args), context(..args))
strictexecution(context) ATrans
execution(methodA) gt BTrans BTrans
execution(methodB) gt CTrans CTrans
execution(methodC) gt ATrans
Rejects ComponentX.a() ComponentX.d() Compone
ntX.b() ComponentX.c()
static connector TimingConnector . new
ProtocolDynamicTimer.StatefulProtocolTimer( voi
d ComponentX.a()., void ComponentX.b(),
void ComponentX.c(), void ComponentX.()
)
Accepts ComponentX.a() Y.d() ComponentX.b()
ComponentX.c()
21Complement of a protocol
- Trigger advices on everything outside the
protocol COMPLEMENT
StatefulProtocolTimer(methodA(..args),methodB(..ar
gs),methodC(..args)) complement ATrans
execution(methodA) gt BTrans
BTrans execution(methodB) gt CTrans
CTrans execution(methodC) gt ATrans around
complement() throw new SecurityException(this
is not allowed on
thisJoinPoint.getClass())
22Complement with Context
- Only complement with respect to a certain set of
joinpoints.
StatefulProtocolTimer(methodA(..args),methodB(..ar
gs),methodC(..args), context(..args))
complementexecution(context) ATrans
execution(methodA) gt BTrans BTrans
execution(methodB) gt CTrans CTrans
execution(methodC) gt ATrans
d() in complement ComponentX.a() ComponentX.d(
) ComponentX.b() ComponentX.c()
static connector TimingConnector . new
ProtocolDynamicTimer.StatefulProtocolTimer( voi
d ComponentX.a()., void ComponentX.b(),
void ComponentX.c(), void ComponentX.()
)
No complement ComponentX.a() Y.d() ComponentX
.b() ComponentX.c()
23Weaving
- A DFA (Deterministic Finite Automaton) executes
the stateful aspect at run-time. - Default weaved at all possible joinpoints
defined in the pointcut. - Optionally, jumping aspect in cooperation with
run-time weaver - only weaved at next joinpoints in protocol
- overhead of reweaving vs overhead of aspect
applied at all