Download presentation
Presentation is loading. Please wait.
Published byAldous Paul Lawson Modified over 9 years ago
1
Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?
2
An adaptive aspect: Law of Demeter Checker (Object Form) aspect Check { … after(): MethodCallSite{ // call (* *(..)); // check whether // thisJoinPoint.getTarget() // is a preferred supplier // object }
3
How can we capture all calls? pointcut MethodCallSite(): scope() && call(* *(..)); BUT: how to avoid checking calls in Java libraries?
4
Avoiding the Java libraries pointcut IgnoreCalls(): call(* java..*.*(..)); pointcut MethodCallSite(): scope() && call(* *(..)) && !IgnoreCalls();
6
AspectJ from PARC AJ J EMETERJ (Demeter AspectJ)
7
Measuring 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
8
Performance Comparison
9
DemeterJ and AJ Performance
10
Performance Comparison
11
Complex Request Interfaces Benefits –Decoupling of details –Optimization, conseq of decoupling –Remote invocation
12
Complex Request Interfaces We distinguish between two kinds of complex request interfaces –Aspectual -> 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
13
Complex 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 -> *,*,B /* all edges of a traversal entering B */ ), AspectJ Pointcuts
14
Selectors 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
15
Mitch’s 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
17
Predefined 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
Graph where node is
21
SS1 SS2 Examples of CR Normal: CR Invoked explicitely S Connection: CR for Implicit Invocation Advice Cool, Error pcd
22
SS1 SS2 Usage of CRI Normal :CRI to send request to S S Connection: CRI for Implicit Invocation Advice: CRI to send request to SS2 CRI 1 and 3 are of the same kind Cool, errors pcd
23
LoD paper Karl’s viewgraphs From a talk with a different title Some adjustment is needed
24
An adaptive aspect: Law of Demeter Checker (Object Form) aspect Check { … after(): Any.MethodCall{ // call (* *(..)); // check whether // thisJoinPoint.getTarget() // is a preferred supplier // object }
25
Observation 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 …)
26
Isolated join points AspectJ crosscutting used in Law of Demeter checker Connected join points Dynamic call graph target(Object) cflow(…)
27
Aspects 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”
28
Instrumentation of Java programs with Aspects Supplier TargetBinStack ReturnValueBin ArgumentBin GlobalPreferredBin LocallyConstructedBin ImmediatePartBin Checker Statistics Requirements: Good Separation of Concerns in Law of Demeter Checker Aspect Diagram uses pointcuts Aspect framework
29
Explanation 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.
30
Law of Demeter (Join Point Form) JPT(ID) = [ ID] List(ID) List(JPT) [ ID]. List(S) ~ {S}.
31
JPT(ID) = [ ID] List(ID) List(JPT) [ ID]. List(S) ~ {S}. J r1.foo1() a1.bar() t2.foo2() r3.foo2() E target t2 args {a1,a2} target t2 ret r1 target null ret r3
32
Generic 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:
33
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. Generic Law of Demeter (Join Point Form)
34
aspect 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())); }
35
Pseudo 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.
36
Join 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;
37
Join 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.
38
Map 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.
39
Map 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.
40
AspectJ 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.
41
package 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);
42
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(..)); } Class Any continued
43
package lawOfDemeter.objectform; import java.util.*; abstract class ObjectSupplier { protected boolean containsValue(Object supplier){ return targets.containsValue(supplier); } 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 i=0; i< suppliers.length; i++) addValue(suppliers[i]); } private IdentityHashMap targets = new IdentityHashMap(); }
44
package lawOfDemeter.objectform; public aspect Pertarget extends ObjectSupplier pertarget(Any.Initialization()) { before(Object value): Any.Set(value) { add(fieldIdentity(thisJoinPointStaticPart), 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(); }
45
package 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();}
46
package lawOfDemeter.objectform; aspect Percflow extends ObjectSupplier percflow(Any.Execution() || Any.Initialization()){ before(): Any.Execution() { addValue(thisJoinPoint.getThis()); addAll(thisJoinPoint.getArgs()); } after() returning (Object result): Any.SelfCall(Object,Object) || Any.StaticCall() || Any.ConstructorCall() { addValue(result); }
47
Conclusions 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.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.