Title: Checking LoD in AspectJ
1Checking LoD in AspectJ
- Show the idea, not the details.
- How can we precisely express it in a programming
language?
2An adaptive aspectLaw of Demeter Checker
(Object Form)
- aspect Check
- after() MethodCallSite
- // call ( (..))
- // check whether
- // thisJoinPoint.getTarget()
- // is a preferred supplier
- // object
3How can we capture all calls?
- pointcut MethodCallSite() scope()
- call( (..))
- BUT how to avoid checking calls in Java
libraries?
4Avoiding the Java libraries
- pointcut IgnoreCalls()
- call( java...(..))
- pointcut MethodCallSite() scope()
- call( (..))
- !IgnoreCalls()
5(No Transcript)
6AspectJ from PARC
AJ
(Demeter AspectJ)
EMETERJ
7Measuring Performance
- Traversals implemented in DemeterJ, DJ, DAJ
- Vary the size of the Object Graph
- Measure the elapsed time between start and finish
- SunBlade 100 running SunOS 5.8
8Performance Comparison
9DemeterJ and AJ Performance
10Performance Comparison
11Complex Request Interfaces
- Benefits
- Decoupling of details
- Optimization, conseq of decoupling
- Remote invocation
12Complex Request Interfaces
- We distinguish between two kinds of complex
request interfaces - Aspectual -gt advice They define code that will
be invoked implicitly. Visitor. - Normal They define code that will be invoked
explicitly. Example SQL, Traversal strategy. - Pc cri
13Complex Request Interfaces
- We distinguish between two kinds of complex
request interfaces - Normal They define code that will be invoked
explicitly. Example SQL, Traversal strategy. - Aspectual
- Advice They define code that will be invoked
implicitly. Demeter C wrapper bodies, COOL
coordinators. - Connection They define when implicit invocation
will take place. Demeter/C wrapper signatures
(e.g., wrapper -gt ,,B / all edges of a
traversal entering B /), AspectJ Pointcuts
14Selectors
- Better name for
- Pointcut designators select nodes of dynamic
call tree - Traversal strategies
- select nodes and edges of object graph or class
graph - Select nodes of dynamic call tree
15Mitchs view
- Pcd is a predicate on join points join point may
contain entire stack - For one execution
- Does not select trees
- Demeter style selector expressions are useful for
dynamic call stacks - Stacks, not trees
16- Large step semantics of lambda calculus lambda
and application - A join point is a tree
17Predefined join points
18- Spread of a selector number of different tree
nodes it selects. - Form of a selector
- Granularity
19- Selectors
- Selects set of nodes all getting the same advice
- Selects set of node tuples each tuple element
getting element dependent advice - Selects set of nodes each node getting node
dependent advice - graphs
- trees
20 21Examples of CR
S
SS1
pcd
Normal CR Invoked explicitely
Cool, Error
Connection CR for Implicit Invocation
Advice
SS2
22CRI 1 and 3 are of the same kind
Usage of CRI
S
SS1
Normal CRI to send request to S
pcd
Cool, errors
Connection CRI for Implicit Invocation
Advice CRI to send request to SS2
SS2
23LoD paper
- Karls viewgraphs
- From a talk with a different title
- Some adjustment is needed
24An adaptive aspectLaw of Demeter Checker
(Object Form)
- aspect Check
- after() Any.MethodCall
- // call ( (..))
- // check whether
- // thisJoinPoint.getTarget()
- // is a preferred supplier
- // object
25Observation
- Many AspectJ programs are adaptive (designed for
a family of Java programs) - Context Java program or its execution tree
(lexical joinpoints or dynamic join points) - Features enabling adaptiveness
- , .. (wildcards)
- cflow, (graph transitivity)
- this(s), target(s), args(a), call (),
- inheritance as wild card
- pc(Object s, Object t)
- this(s) target(t) call( f )
26AspectJ crosscutting used in Law of Demeter
checker
Dynamic call graph
cflow()
target(Object)
Connected join points
Isolated join points
27Aspects and lexical join points
- Going to the roots of the Northeastern branch of
AOP Law of Demeter. - Closing the circle Write an ultimately adaptive
program in AspectJ - Works with all Java programs
- Checks the object-form of the Law of Demeter
talk only to your friends
28Instrumentation of Java programs with Aspects
Aspect framework
Aspect Diagram
Supplier
ImmediatePartBin
TargetBinStack
ArgumentBin
Checker
LocallyConstructedBin
uses pointcuts
ReturnValueBin
Requirements
Statistics
GlobalPreferredBin
Good Separation of Concerns in Law of Demeter
Checker
29Explanation
- The bin aspects collect potential preferred
supplier objects that represent good coupling in
the context of a method body. - The Checker aspect checks each method call
whether the receiver is a preferred supplier
object. - The Statistics aspect counts events generated by
the Checker aspect.
30Law of Demeter(Join Point Form)
- JPT(ID)
- lttargetgt ID
- ltargsgt List(ID)
- ltchildrengt List(JPT)
- ltretgt ID.
- List(S) S.
31JPT(ID) lttargetgt ID ltargsgt List(ID)
ltchildrengt List(JPT) ltretgt ID. List(S) S.
E
target t2 args a1,a2
target t2 ret r1
J r1.foo1() a1.bar() t2.foo2() r3.foo2()
target null ret r3
32Generic Law of Demeter(Join Point Form)
- Definition 1 The LoD_JPF requires that for each
join point J, target(J) is a potential preferred
supplier of J. - Definition 2 The set of potential preferred
suppliers to a join point J, child to the
enclosing join point E, is the union of the
objects in the following sets
33Generic Law of Demeter(Join Point Form)
- Argument rule the args of the enclosing join
point E, including the target - Associated rule the associated values of E the
ret values of the children of E before J whose
target is the target of E or whose target is null.
34aspect LoD extends Violation pointcut
LoD_JPF() //LoD definition ArgumentRule()
AssociatedRule() pointcut ArgumentRule()
if(thisEnclosingJoinPoint.getArgs()
.contains(thisJoinPoint.getTarget()) pointcut
AssociatedRule() if(thisEnclosingJoinPoint
.hasSelfishChild(thisJoinPoint
.getTarget()))
35Pseudo Aspect
- LoD is a pseudo'' aspect because it cannot run
in the current implementation of AspectJ, which
doesn't allow declare warning to be defined on
any pointcut with an if expression.
36Join Point Form
- The pointcuts ArgumentRule and AssociatedRule
select the good'' join points. - ArgumentRule selects those join points whose
target is one of the arguments of the enclosing
join point
37Join Point Form
- AssociatedRule selects those join points whose
target is in the set of locally returned ID's,
and the ID's created in the siblings of the
current node.
38Map Dynamic Object Form (DOF) to LoD_JPF
- We use LoD_JPF pointcut to check DOF
- Dynamic join point model is mapped to JPT.
- Object is mapped to ID.
- Method invocations are mapped to JPF join points.
The enclosing join point is the parent in the
control flow.
39Map Lexical Class Form (LCF) to LoD_JPF
- We use LoD_JPF to check LCF as follows.
- Lexical join point model is mapped to JPT.
Lexical join points are nodes in the abstract
syntax tree - Class is mapped to ID.
- Join points are signatures of call sites. The
enclosing join point is the signature of the
method in which the call site resides. To run
the aspect, a suitable ordering has to be given
to the elements of children - all constructor calls, followed by local method
calls, followed by the other join points.
40AspectJ code
- In AOSD 2003 paper with David Lorenz and
Pengcheng Wu - DOF AspectJ works well. Program uses most
adaptive ingredients of AspectJ , cflow, this,
target, etc. - LCF AspectJ cannot do it. We sketch how to add
statically executable advice to AspectJ.
41package lawOfDemeter public abstract class Any
public pointcut scope() !within(lawOfDemeter.
.) !cflow(withincode( lawOfDemeter..(..)
)) public pointcut StaticInitialization()
scope() staticinitialization() public
pointcut MethodCallSite() scope() call(
(..)) public pointcut ConstructorCall()
scope() call(.new (..)) public
pointcut MethodExecution() scope()
execution( (..)) public pointcut
ConstructorExecution() scope()
execution(.new (..)) public pointcut
Execution() ConstructorExecution()
MethodExecution() public pointcut
MethodCall(Object thiz, Object target)
MethodCallSite() this(thiz)
target(target)
42Class Any continued
public pointcut SelfCall(Object thiz,
Object target) MethodCall(thiz, target)
if(thiz target) public pointcut
StaticCall() scope() call(static
(..)) public pointcut Set(Object value)
scope() set( .) args(value)
public pointcut Initialization() scope()
initialization(.new(..))
43package lawOfDemeter.objectform import
java.util. abstract class ObjectSupplier
protected boolean containsValue(Object
supplier) return targets.containsValue(suppli
er) protected void add(Object key,Object
value) targets.put(key,value)
protected void addValue(Object supplier)
add(supplier,supplier) protected void
addAll(Object suppliers) for(int i0 ilt
suppliers.length i) addValue(suppliersi
) private IdentityHashMap targets
new IdentityHashMap()
44package lawOfDemeter.objectform public aspect
Pertarget extends ObjectSupplier
pertarget(Any.Initialization()) before(Object
value) Any.Set(value) add(fieldIdentity(thi
sJoinPointStaticPart), value) public
boolean contains(Object target) return
super.containsValue(target)
Percflow.aspectOf().containsValue(target)
private String fieldIdentity(JoinPoint.StaticPart
sp) private static HashMap fieldNames
new HashMap()
45package lawOfDemeter.objectform aspect Check
private pointcut IgnoreCalls() call(
java...(..)) private pointcut
IgnoreTargets() get(static java...)
after() returning(Object o)IgnoreTargets()
ignoredTargets.put(o,o) after(Object
thiz,Object target) Any.MethodCall(thiz,
target) !IgnoreCalls() if
(!ignoredTargets.containsKey(target)
!Pertarget.aspectOf(thiz).contains(target))
System.out.println( " !! LoD Object
Violation !! " thisJoinPointStaticPart/
/ at(thisJoinPointStaticPart)//)
private IdentityHashMap ignoredTargets
new IdentityHashMap()
46package lawOfDemeter.objectform aspect Percflow
extends ObjectSupplier percflow(Any.Execution()
Any.Initialization()) before()
Any.Execution() addValue(thisJoinPoint.get
This()) addAll(thisJoinPoint.getArgs())
after() returning (Object result)
Any.SelfCall(Object,Object)
Any.StaticCall() Any.ConstructorCall()
addValue(result)
47Conclusions
- Aspects and adaptiveness must work closely
together to achieve best results. Crosscutting is
closely linked to adaptiveness. - AP is a specialization of AOP and AOP is a
specialization of AP. It goes both ways. - AspectJ is a really useful language but we are a
little concerned about how difficult it was to
debug the Law of Demeter checkers.