1 / 50

Declarative Techniques for Improving Aspect Orthogonality

Declarative Techniques for Improving Aspect Orthogonality. Karl Lieberherr. Why improve orthogonality of aspects?. Crucial for Aspect Libraries: otherwise aspects require too many modifications for reuse.

gordonv
Download Presentation

Declarative Techniques for Improving Aspect Orthogonality

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Declarative Techniques for Improving Aspect Orthogonality Karl Lieberherr PL Day 2002

  2. Why improve orthogonality of aspects? • Crucial for Aspect Libraries: otherwise aspects require too many modifications for reuse. • Danger of being too orthogonal? Not really, if the actual parameters are checked carefully for applicability: need good type systems for AOP. • Improve orthogonality by parameterization. PL Day 2002

  3. How we got to Aspect-Oriented Programming • Started simple: traversal-seeded programs: Law of Demeter dilemma. • Talk generically about points in the execution of a traversal program. • Generically means: parameterize program by an abstraction of its execution. • Some type checking when actual parameter is known. PL Day 2002

  4. interface ShapeI extends Remote { double get_x() throws RemoteException ; void set_x(int x) throws RemoteException ; double get_y() throws RemoteException ; void set_y(int y) throws RemoteException ; double get_width() throws RemoteException ; void set_width(int w) throws RemoteException ; double get_height() throws RemoteException ; void set_height(int h) throws RemoteException ; void adjustLocation() throws RemoteException ; void adjustDimensions() throws RemoteException ; } publicclass Shape implements ShapeI { protected AdjustableLocation loc; protected AdjustableDimension dim; public Shape() { loc = new AdjustableLocation(0, 0); dim = new AdjustableDimension(0, 0); } double get_x() throws RemoteException { returnloc.x(); } void set_x(int x) throws RemoteException { loc.set_x(); } double get_y() throws RemoteException { returnloc.y(); } void set_y(int y) throws RemoteException { loc.set_y(); } double get_width() throws RemoteException { returndim.width(); } void set_width(int w) throws RemoteException { dim.set_w(); } double get_height() throws RemoteException { returndim.height(); } void set_height(int h) throws RemoteException { dim.set_h(); } void adjustLocation() throws RemoteException { loc.adjust(); } void adjustDimensions() throws RemoteException { dim.adjust(); } } publicclass Shape { protecteddouble x_= 0.0, y_= 0.0; protecteddouble width_=0.0, height_=0.0; double get_x() { return x_(); } void set_x(int x) { x_ = x; } double get_y() { return y_(); } void set_y(int y) { y_ = y; } double get_width(){ return width_(); } void set_width(int w) { width_ = w; } double get_height(){ return height_(); } void set_height(int h) { height_ = h; } void adjustLocation() { x_ = longCalculation1(); y_ = longCalculation2(); } void adjustDimensions() { width_ = longCalculation3(); height_ = longCalculation4(); } } Write this coordinator Shape { selfex adjustLocation, adjustDimensions; mutex {adjustLocation, get_x, set_x, get_y, set_y}; mutex {adjustDimensions, get_width, get_height, set_width, set_height}; } class AdjustableLocation { protecteddouble x_, y_; public AdjustableLocation(double x, double y) { x_ = x; y_ = y; } synchronizeddouble get_x() { return x_; } synchronizedvoid set_x(int x) {x_ = x;} synchronizeddouble get_y() { return y_; } synchronizedvoid set_y(int y) {y_ = y;} synchronizedvoid adjust() { x_ = longCalculation1(); y_ = longCalculation2(); } } class AdjustableDimension { protecteddouble width_=0.0, height_=0.0; public AdjustableDimension(double h, double w) { height_ = h; width_ = w; } synchronizeddouble get_width() { return width_; } synchronizedvoid set_w(int w) {width_ = w;} synchronizeddouble get_height() { return height_; } synchronizedvoid set_h(int h) {height_ = h;} synchronizedvoid adjust() { width_ = longCalculation3(); height_ = longCalculation4(); } } portal Shape { double get_x() {} ; void set_x(int x) {}; double get_y() {}; void set_y(int y) {}; double get_width() {}; void set_width(int w) {}; double get_height() {}; void set_height(int h) {}; void adjustLocation() {}; void adjustDimensions() {}; } Modularization of crosscutting concerns Instead of writing this

  5. Scattering: count number of components to which color goes ordinary program aspect-oriented prog. structure-shy functionality COM1 Concern 1 object structure COM2 Concern 2 COM3 synchronization Concern 3 PL Day 2002

  6. Language for Examples: AspectJ • Xerox PARC: Gregor Kiczales et al.: lingua franca of AOP. • First version: Crista Lopes (member of Demeter group): implementing both COOL and RIDL in a general purpose AO language (early AspectJ version). • Model: join points, pointcuts, advice. PL Day 2002

  7. Pointcut set of execution points of any method, … rich set of primitive pointcuts: this, target, call, … + set operations where to enhance Advice how to enhance Visitor method sig. set of execution points of traversals specialized for traversals (nodes, edges) where to enhance Visitor method bodies how to enhance From Demeter to AspectJ Demeter (for C++ or Java) AspectJ PL Day 2002

  8. aspect Traversal { // t() //declare traversal t : // “from S” + c + “to T”; … } aspect Collecting { pointcut start() : … ; pointcut visitingT(T h): call(void t()) && target(h); before():start(){ … } before():visitingT(){ … } } class S{ HashSet collect(ClassGraph cg, String constraint){ String s = “from S” + constraint + “to T”; return (HashSet) cg.traverse(this, s, new Visitor(){ … ; public void before (Th) { … } public void start() {…}}); } } From Demeter to AspectJ Java+DJ AspectJ red = aspect name green: pointcut purple: advice PL Day 2002

  9. aspect SimpleTracing{ pointcut traced(): call(void D.update()}|| call(void D.repaint(); before():traced(){ println(“Entering:”+ thisJoinPoint);} } class Source{ HashSet collect(ClassGraph cg, String constraint){ String s = “from Source” + constraint + “to Target”; return (HashSet) cg.traverse(this, s, new Visitor(){ … ; public void before (Target h) { … } public void start() {…}}); } } refers to existing join points Demeter: defines new join points in traversal AspectJ Java+DJ red = aspect name green: pointcut purple: advice PL Day 2002

  10. Parameterization by abstraction of program execution pointcut AaB(A a1, B b1): cflow(vis_A(a1)) && vis_B(b1); pointcut vis_A(A a1): call(void t (..)) && target(a1); pointcut vis_B(B b1): … Pointcut AaB can be used with many different base programs. Parameterization is implicit. PL Day 2002

  11. A=CompilationUnit B=MetaSetRule C=Name: Verizon 24*7 app. Parameterization by abstraction of program execution pointcut AaBaC(A a1,B b1,C c1): cflow(cflow(vis_A(a1)) && vis_B(b1)) && vis_C(c1); pointcut vis_A(A a1): call(void t (..)) && target(a1); pointcut vis_B(B b1): … pointcut vis_C(C c1): … PL Day 2002

  12. usedThings = from EquationSystem through Expression to Variable Equation System EquationSystem equations Equation_List Ident * lhs Equation Variable Numerical rhs Simple args Expression_List Expression S T * op Add Compound D B PL Day 2002

  13. Adding Demeter to AspectJ • Adding more flow constructs; Demeter traversals • flow construct for object graphs: • declare traversal t = … • flow construct for class graphs: type patterns: • nodes(t): all nodes in scope of t • Adding grammar aspect … (a la JAXB) PL Day 2002

  14. Adding Demeter Traversals to AspectJ • Because the AspectJ join point model is a generalization of Demeter’s join point model, we can use the AspectJ pointcuts to express the traversal pointcuts. • However, this would expose the traversal implementation. • Extend AspectJ with two new pointcut primitives: traversal(t) and crossing(e). PL Day 2002

  15. New pointcuts • Traversal(t = from A via B to C): The set of all join points in the traversal that finds all C-objects contained in a B-object contained in an A-object. • pointcut visiting_C(C c1): traversal(t) && target(c1); • pointcut visiting_e(S s,T t): traversal(t) && && crossing(e) && this(s) && target(t); PL Day 2002

  16. Traversal(t) pointcut • picks out all join points between the start and the end of the traversal that are needed for the traversal only, i.e. the node visits and the edge visits. PL Day 2002

  17. How to define a traversal • AspectJ declare form • declare traversal t: traversal specification; • traversal specification: an automaton PL Day 2002

  18. Conclusions • AspectJ is well-aligned with Demeter. Need only a small extension to add the Demeter traversals. • Pointcuts become more verbose. Could also use traversals with visitors and extend them with AspectJ (use the args pointcut). PL Day 2002

  19. Conclusions • Adding the proposed flow constructs (to the already existing flow construct) makes aspects more orthogonal. • Otherwise they are all coupled through structural details which severely hinders reuse and the development of aspect libraries. PL Day 2002

  20. Conclusions: Flow expressions AspectJ (sets of nodes) dynamic call graphs Demeter (slices of graphs or path sets) object graphs class graphs PL Day 2002

  21. Center for Software Sciences • Work with BBN on aspects for distributed real-time embedded applications. • extending AspectJ (John Sung) • extending DJ (Pengcheng Wu with Shriram K.) • aspectual collaborations (Johan Ovlinger, Ed M.) • Extensible programming (Doug Orleans) • Work with ABB on enhancing their aspect system for Industrial IT (Theo Skotiniotis) • David Lorenz: Components PL Day 2002

  22. Looking for new opportunities • Former partners: IBM, Citibank, SAIC, Mettler-Toledo, Skyva, etc. • Looking to help apply aspect-oriented software development to industrial projects. • Graduate student support. PL Day 2002

  23. The End PL Day 2002

  24. more integration • traversal(t) && crossing(“xyz”) && this(a) && target(b) && args(v1, tS) • explanation: traversal t through edge xyz with source a and target b. The visitor is v1 and the token set is tS. tS allows us to query the state of the traversal: we can ask which strategy graph edges are currently active. PL Day 2002

  25. traversal(t) && cflow(call( * f(..)): all join points • join(traversal(t1), traversal(t2)) • traversal(t1) || traversal(t2) • traversal(t1) && !traversal(t2) • traversal(“from A to B”) && !traversal( “from A via X to B”) = from A bypassing X to B PL Day 2002

  26. cflow • is traversal the only pcd where we want nesting with advice? PL Day 2002

  27. difference between visiting(a) and this(a) and target(a) • traversal(t): target(a) = visiting(a) • this(a) where traversal was before getting to a-object PL Day 2002

  28. dynamic call graph aCompany.t() aCompany.t_domesticDivisions() 1 1 2 2 aCompany.domesticDivisions 2 aCompany.t_foreignDivisions() 1 a_d_DivisionList.t() a_f_DivisionList.t() aCompany.foreignDivisions PL Day 2002

  29. dynamic call graph a1Division.t_departments () a_d_DivisionList.t() 1 2 1 2 a1Division.departments a1Division.t () a2Division.t () aDepartmentList.t() etc. PL Day 2002

  30. From Adaptive to Aspect-Oriented Programming • Object-graphs are turned into dynamic call graphs by traversal methods produced from the class graph and a traversal specification. • As we go through dynamic call graph, we want to collect information from arguments and return values of method calls. • Exploit regularities in call graphs. PL Day 2002

  31. Motivation • Declarative techniques used in existing AOP systems • Look at a family of declarative techniques: use one uniform syntax and three different semantics. PL Day 2002

  32. Flow Expressions • D ::= [A,B] | join(D1,D2) | merge(D1,D2) • We can use them in three different graphs relevant to programming: • call trees: subset of nodes • class graphs: subset of nodes • object trees: subgraph PL Day 2002

  33. Flow Expressions and AOP • They are a basic cross-cutting construct for defining subgraphs. • merge(join([A,X],[X,C]), join([A,Y],[Y,C])) defines a subgraph of a larger graph whose ad-hoc description cuts across many nodes or edges. • succinct encapsulations of subgraphs related to some aspect. X A C Y PL Day 2002

  34. Flow expressions • are abstractions of some aspect whose ad-hoc description would cut across many nodes or edges of a graph. • define sets of join points based on connectivity in graph. • offer pointcut designator reduction (high-level pointcut designator): free programmer from details of some graph representing some aspect. PL Day 2002

  35. Definitions for Flow Expressions • D ::= [A,B] | join(D1,D2) | merge(D1,D2) • Source([A,B]) = A • Target([A,B]) = B • Source(join(D1,D2) )=Source(D1) • Target(join(D1,D2) )=Target(D2) • Source(merge(D1,D2) )=Source(D1) • Target(merge(D1,D2) )=Target(D1) PL Day 2002

  36. Well-formed Flow Expressions • D ::= [A,B] | join(D1,D2) | merge(D1,D2) • WF([A,B]) = true // well-formed • WF(join(D1,D2) )=WF(D1) && WF(D2) && Target(D1) = Source(D2) • WF(merge(D1,D2) )= WF(D1) && WF(D2) && Source(D1)=Source(D2) && Target(D1)=Target(D2) PL Day 2002

  37. Dynamic call tree • nodes are operation calls: labeled by operation name and arguments • edges: a operation calls another operation • nodes = join points PL Day 2002

  38. context-passing aspects abstract aspect CapabilityChecking { pointcut invocations(Caller c): this(c) && call(void Service.doService(String)); pointcut workPoints(Worker w): target(w) && call(void Worker.doTask(Task)); pointcut perCallerWork(Caller c, Worker w): cflow(invocations(c)) && workPoints(w); before (Caller c, Worker w): perCallerWork(c, w) { w.checkCapabilities(c); } } PL Day 2002

  39. Interpretation of traversal strategies • D ::= [A,B] | join(D1,D2) | merge(D1,D2) • A and B are pointcut designators. • [A,B]: the set of B-nodes reachable from A-nodes. • join(D1,D2): the set of Target(D2)-nodes reachable from Source(D1)-nodes following D1 and then following D2. PL Day 2002

  40. Interpretation of traversal strategies • merge(D1,D2): the union of the set of Target(D1)-nodes reachable from Source(D1)-nodes following D1 and the set of Target(D2)-nodes reachable from Source(D2)-nodes following D2. PL Day 2002

  41. t(D1) flow(A) && B t(D1) || t(D2) flow(t(D1)) && t(D2) D1 from A to B merge(D1,D2) join(D1,D2) Translation Rules PL Day 2002

  42. D [A,B] join(D1,D2) merge(D1,D2) PathSet(D) Paths(A,B) PathSet(D1).PathSet(D2) PathSet(D1) || PathSet(D2) flow expressions are called traversal strategies Demeter/C++ DJ Class graph Type patterns in AspectJ we are only interested in the set of nodes touched by the path sets -> subgraph of class graph PL Day 2002

  43. D [A,B] subgraph of O subgraph of O consisting of all paths from an A-node to a B-node, including prematurely terminated paths. flow expressions are called traversal strategies Demeter/C++ DemeterJ DJ Object tree generate traversals in AspectJ PL Day 2002

  44. D join(D1,D2) subgraph of O subgraph of O consisting of all paths following D1 and those reaching Target(D1) concatenated with all paths following D2. Object tree PL Day 2002

  45. D merge(D1,D2) subgraph of O subgraph of O consisting of all paths following D1 or following D2. Object tree PL Day 2002

  46. DJ Traversal strategy graph class graph object graph Purposes select og with sg extract node labels select cg with sg AspectJ General computation strategy call graph static call graph dynamic call graph Purposes select dcg with sycg extract node labels select scg with sycg Purposes of strategies PL Day 2002

  47. DJ + method edges Traversal strategy graph class graph object graph argument map Purposes select dcg with sg + am extract node labels Purposes of strategies PL Day 2002

  48. t(D1) flow(A) && B flow(A) flow(flow(A) && B) && C flow(flow(flow(A) && B) && C) && E (flow(flow(A) && B1) && C) || (flow(flow(A) && B2) && C) t(D1) || t(D2) flow(t(D1)) && t(D2) flow(flow(A) && B) && (flow(B) && C) = flow(flow(A) && B) && C D1 from A to B from A to * from A via B to C from A via B via C to E merge(from A via B1 to C, from A via B2 to C) merge(D1,D2) join(D1,D2) join (from A to B, from B to C) Correspondences subset(flow(B)) && flow(B) = subset(flow(B)) PL Day 2002

  49. Theme • Defining high-level artifact in terms of a low-level artifact without committing to details of low-level artifact in definition of high-level artifact. Low-level artifact is parameter to definition of high-level artifact. • Exploit structure of low-level artifact. PL Day 2002

  50. AspectJ adds • Generalizes from join points of specialized methods to join points of any method, field access, field modification, etc. • Uses set operations && and ! combined with a rich set set of primitive pointcuts. • Generalizes from a flow construct for traversals to a flow construct for arbitrary join points. PL Day 2002

More Related