Download presentation
Presentation is loading. Please wait.
Published byAttila Mészáros Modified over 5 years ago
1
Declarative Techniques for Improving Aspect Orthogonality
Karl Lieberherr 4/15/2019 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. 4/15/2019 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. 4/15/2019 PL Day 2002
4
crosscutting concerns
public class 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 { return loc.x(); } void set_x(int x) throws RemoteException { loc.set_x(); } double get_y() throws RemoteException { return loc.y(); } void set_y(int y) throws RemoteException { loc.set_y(); } double get_width() throws RemoteException { return dim.width(); } void set_width(int w) throws RemoteException { dim.set_w(); } double get_height() throws RemoteException { return dim.height(); } void set_height(int h) throws RemoteException { dim.set_h(); } void adjustLocation() throws RemoteException { loc.adjust(); void adjustDimensions() throws RemoteException { dim.adjust(); class AdjustableLocation { protected double x_, y_; public AdjustableLocation(double x, double y) { x_ = x; y_ = y; synchronized double get_x() { return x_; } synchronized void set_x(int x) {x_ = x;} synchronized double get_y() { return y_; } synchronized void set_y(int y) {y_ = y;} synchronized void adjust() { x_ = longCalculation1(); y_ = longCalculation2(); class AdjustableDimension { protected double width_=0.0, height_=0.0; public AdjustableDimension(double h, double w) { height_ = h; width_ = w; synchronized double get_width() { return width_; } synchronized void set_w(int w) {width_ = w;} synchronized double get_height() { return height_; } synchronized void set_h(int h) {height_ = h;} width_ = longCalculation3(); height_ = longCalculation4(); 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 ; Modularization of crosscutting concerns public class Shape { protected double x_= 0.0, y_= 0.0; protected double 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(); 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}; 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() {}; Write this 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 avoid tangled programs AOP COM3 synchronization Concern 3 4/15/2019 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. 4/15/2019 PL Day 2002
7
Visitor method sig. Visitor method bodies Pointcut Advice
From Demeter to AspectJ Demeter (for C++ or Java) AspectJ Visitor method sig. set of execution points of traversals specialized for traversals (nodes, edges) where to enhance Visitor method bodies how to enhance 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 4/15/2019 PL Day 2002
8
Java+DJ AspectJ From Demeter to AspectJ red = aspect name
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 (T h) { … } public void start() {…}}); } 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(){ … } green: pointcut purple: advice 4/15/2019 PL Day 2002
9
AspectJ Java+DJ refers to existing Demeter: defines new join points
join points in traversal AspectJ Java+DJ red = aspect name 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() {…}}); } green: pointcut purple: advice 4/15/2019 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. 4/15/2019 PL Day 2002
11
Parameterization by abstraction of program execution
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): … 4/15/2019 PL Day 2002
12
Equation System EquationSystem equations Equation_List Ident * lhs
usedThings = from EquationSystem through Expression to Variable Equation System EquationSystem equations Equation_List Ident * lhs Equation Variable Numerical rhs Simple args Expression Expression_List S T * op Add Compound D B 4/15/2019 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) 4/15/2019 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). 4/15/2019 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); 4/15/2019 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. 4/15/2019 PL Day 2002
17
How to define a traversal
AspectJ declare form declare traversal t: traversal specification; traversal specification: an automaton 4/15/2019 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). 4/15/2019 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. 4/15/2019 PL Day 2002
20
Conclusions: Flow expressions
Demeter (slices of graphs or path sets) object graphs class graphs AspectJ (sets of nodes) dynamic call graphs 4/15/2019 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 4/15/2019 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. 4/15/2019 PL Day 2002
23
The End 4/15/2019 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. 4/15/2019 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 4/15/2019 PL Day 2002
26
cflow is traversal the only pcd where we want nesting with advice?
4/15/2019 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 4/15/2019 PL Day 2002
28
aCompany.t_domesticDivisions()
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 4/15/2019 PL Day 2002
29
a1Division.t_departments () a_d_DivisionList.t()
dynamic call graph a1Division.t_departments () a_d_DivisionList.t() 1 2 1 2 a1Division.departments a1Division.t () a2Division.t () aDepartmentList.t() etc. 4/15/2019 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. 4/15/2019 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. 4/15/2019 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 4/15/2019 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 4/15/2019 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. 4/15/2019 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) 4/15/2019 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) 4/15/2019 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 4/15/2019 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); } 4/15/2019 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. 4/15/2019 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. 4/15/2019 PL Day 2002
41
Translation Rules D1 from A to B merge(D1,D2) join(D1,D2) t(D1)
flow(A) && B t(D1) || t(D2) flow(t(D1)) && t(D2) 4/15/2019 PL Day 2002
42
Class graph D [A,B] join(D1,D2) merge(D1,D2) PathSet(D) Paths(A,B)
flow expressions are called traversal strategies Demeter/C++ DJ Class graph Type patterns in AspectJ D [A,B] join(D1,D2) merge(D1,D2) PathSet(D) Paths(A,B) PathSet(D1).PathSet(D2) PathSet(D1) || PathSet(D2) we are only interested in the set of nodes touched by the path sets -> subgraph of class graph 4/15/2019 PL Day 2002
43
Object tree D [A,B] subgraph of O
flow expressions are called traversal strategies Demeter/C++ DemeterJ DJ Object tree generate traversals in AspectJ 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. 4/15/2019 PL Day 2002
44
Object tree 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. 4/15/2019 PL Day 2002
45
Object tree D merge(D1,D2) subgraph of O
subgraph of O consisting of all paths following D1 or following D2. 4/15/2019 PL Day 2002
46
Purposes of strategies
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 4/15/2019 PL Day 2002
47
Purposes of strategies
DJ + method edges Traversal strategy graph class graph object graph argument map Purposes select dcg with sg + am extract node labels 4/15/2019 PL Day 2002
48
Correspondences subset(flow(B)) && flow(B) = subset(flow(B)) 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) 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 subset(flow(B)) && flow(B) = subset(flow(B)) 4/15/2019 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. 4/15/2019 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. 4/15/2019 PL Day 2002
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.