47
Checking LoD in AspectJ • Show the idea, not the details. • How can we precisely express it in a programming language?

Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

Embed Size (px)

Citation preview

Page 1: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

Checking LoD in AspectJ

• Show the idea, not the details.

• How can we precisely express it in a programming language?

Page 2: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

An adaptive aspect:Law of Demeter Checker

(Object Form)aspect Check { … after(): MethodCallSite{ // call (* *(..)); // check whether // thisJoinPoint.getTarget() // is a preferred supplier // object}

Page 3: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

How can we capture all calls?

pointcut MethodCallSite(): scope() && call(* *(..));

BUT: how to avoid checking calls in Java libraries?

Page 4: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

Avoiding the Java libraries

pointcut IgnoreCalls(): call(* java..*.*(..));pointcut MethodCallSite(): scope() && call(* *(..)) && !IgnoreCalls();

Page 5: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?
Page 6: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

AspectJ from PARC

AJJ

EMETERJ

(Demeter AspectJ)

Page 7: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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

Page 8: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

Performance Comparison

0

5000

10000

15000

20000

5000 10000 15000 20000

Object Graph Size

Ela

pse

Tim

e (m

s)

DemeterJ

DJ

DAJ

Page 9: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

DemeterJ and AJ Performance

0

20

40

60

80

5000 10000 15000 20000

Object Graph Size

Elap

sed

Tim

e (m

s)

DemeterJ

DAJ

Page 10: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

Performance Comparison

OG Size DemeterJ DJ DAJ5000 23 3577 3210000 40 7908 4815000 55 11863 6220000 60 14905 70

Page 11: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

Complex Request Interfaces

• Benefits– Decoupling of details– Optimization, conseq of decoupling– Remote invocation

Page 12: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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

Page 13: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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

Page 14: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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

Page 15: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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

Page 16: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

• Large step semantics of lambda calculus: lambda and application

• A join point is a tree

Page 17: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

Predefined join points

Page 18: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

• Spread of a selector: number of different tree nodes it selects.

• Form of a selector

• Granularity

Page 19: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

• 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

Page 20: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

• Graph where node is

Page 21: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

SS1

SS2

Examples of CR

Normal: CR Invoked explicitely

S

Connection: CR for Implicit InvocationAdvice

Cool, Errorpcd

Page 22: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

SS1

SS2

Usage of CRI

Normal :CRI to sendrequest to S

S

Connection: CRI for Implicit InvocationAdvice: CRI to send

request to SS2

CRI 1 and 3 are of the same kind

Cool, errors

pcd

Page 23: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

LoD paper

Karl’s viewgraphs

From a talk with a different title

Some adjustment is needed

Page 24: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

An adaptive aspect:Law of Demeter Checker

(Object Form)aspect Check { … after(): Any.MethodCall{ // call (* *(..)); // check whether // thisJoinPoint.getTarget() // is a preferred supplier // object}

Page 25: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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 …)

Page 26: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

Isolated join points

AspectJ crosscutting usedin Law of Demeter checker

Connected join points

Dynamic call graph

target(Object)

cflow(…)

Page 27: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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”

Page 28: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

Instrumentation of Java programs with Aspects

Supplier

TargetBinStack

ReturnValueBin

ArgumentBin

GlobalPreferredBin

LocallyConstructedBin

ImmediatePartBin

Checker

StatisticsRequirements:

Good Separation of Concerns in Law of Demeter Checker

Aspect Diagram

uses pointcuts

Aspect framework

Page 29: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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.

Page 30: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

Law of Demeter(Join Point Form)

JPT(ID) =

[<target> ID]

<args> List(ID)

<children> List(JPT)

[<ret> ID].

List(S) ~ {S}.

Page 31: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

JPT(ID) =

[<target> ID]

<args> List(ID)

<children> List(JPT)

[<ret> ID].

List(S) ~ {S}.Jr1.foo1()a1.bar()t2.foo2()r3.foo2()

Etarget t2args {a1,a2}

target t2ret r1

target nullret r3

Page 32: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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:

Page 33: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

• 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)

Page 34: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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()));}

Page 35: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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.

Page 36: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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;

Page 37: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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.

Page 38: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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.

Page 39: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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.

Page 40: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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.

Page 41: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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);

Page 42: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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

Page 43: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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();}

Page 44: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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();}

Page 45: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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();}

Page 46: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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); }}

Page 47: Checking LoD in AspectJ Show the idea, not the details. How can we precisely express it in a programming language?

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.