Machine-level Composition of Modularized Crosscutting Concerns Hans Schippers Universiteit Antwerpen 20 november 2008
Special Thanks To... Michael Haupt Robert Hirschfeld Software Architecture Group Hasso Plattner Institute, University of Potsdam (close to Lindenstube...)
Agenda Context Modularization Crosscutting Concerns A Dedicated Machine Model Object-based + Delegation Support for Modularization Mechanisms Language Mappings j : Object-Oriented Programming ij : Inter-Type Declarations aj : Pointcut-and-Advice AOP cj : Context-Oriented Programming Future Work
Modularization Divide and Conquer Organize a Software System in Manageable Modules Each Module its own Responsibilities => Which Modules? => How to Decompose the System?
Employee Management System Task 1 Find Out Employee-Boss Relationships Sales Research Financial Support
Employee Management System Task 2 Calculate Salaries ? Sales Research Financial Support
Employee Management System Task 2 Calculate Salaries Research Monthly Hourly Bonus
Employee Management System Task 1 Find Out Employee-Boss Relationships ? Research Monthly Hourly Bonus
Dominant Decomposition: Organizational Hard to calculate salary... Easy to find out supervisor  relationships... Employee Research ResearchManager Sales SalesManager Financial FinancialManager Support SupportManager
Dominant Decomposition: Payroll Easy to  calculate salary... Hard to find out supervisor relationships... Employee HourlyWage MonthlyWage Research Regular Sales SalesManager RegularManager Secretary Labourer ResearchManager
Crosscutting Concerns source: http://www.ercim.org/publication/Ercim_News/enw58/van_deursen1.jpg  Column: Module Each Color: Task
Modularizing Crosscutting Concerns MDSOC  approaches  deal with the  modularization of  crosscutting concerns . tangling / scattering extra module (e.g., aspect, layer, ...) modularized code  (e.g., advice, ...) join points Now somehow  make all modules work together...
State-of-the-Art: Weaving... Source Code Level [EAOP] Byte Code Level [AspectJ, Steamloom] ----- Application Level [EAOP, AspectJ] Machine Level [Steamloom]
I've Got Troubles, Oh-Oh Ik Heb Zorgen Manageability: Lose Track of Modules Performance: Residual Code Modules may be active depending on dynamic conditions Elegance: Modularized Code --> OO Code Conceptual: Join Points Misrepresented as Shadows We Need a Dedicated (Virtual) Machine
Core Mechanisms a different look at join points at each join point, decisions are drawn which functionality  to execute? depends on context (current object, message sent/received, methods on stack, ...) very much like  polymorphic dispatch running application ≈ sequence of late binding events a join point is a locus of late binding like virtual methods:  virtual join points
A Dedicated Machine Model core concepts: objects and delegation  [ECOOP 07] each application object, internally, consists of two a proxy (a mere  placeholder ) and the actual object other application objects only directly see the proxy access to properties only via messages classes and instances classes are also represented by objects, also have a proxy instances reference the proxy only delegation ensures correct binding of  self self object actual-object foo = ( ... ) bar = 23 delegate instance-of-C actual-instance-of-C v = 23 C actual-C m = ( ... ) m
Basic Modularization Operations // CaesarJ-like pseudo code class C { void f() { ... } void g() { ... } void h() { ... } } class A { before(): execution(void C.f()) { ... } after(): execution(void C.g()) { ... } void  around(): execution(void C.h()) { ... proceed(); ... } } ... deploy(new A()); ... actual-C f = ( ... ) g = ( ... ) h = ( ... ) C instance-of-C actual-instance-of-C A-proxy f = ( ...;  resend  ) g = (  resend;  ... ) h = ( ...;  resend;  ... ) f
Instance-Local Deployment // CaesarJ-like pseudo code class C { void f() { ... } void g() { ... } void h() { ... } } class A { before(): execution(void C.f()) { ... } after(): execution(void C.g()) { ... } void  around(): execution(void C.h()) { ... proceed(); ... } } ... deploy(new A(), instance-of-C); ... actual-C f = ( ... ) g = ( ... ) h = ( ... ) C instance-of-C actual-instance-of-C A-proxy f = ( ...;  resend  ) g = (  resend;  ... ) h = ( ...;  resend;  ... )
Thread-Local Deployment // CaesarJ-like pseudo code class C { void f() { ... } void g() { ... } void h() { ... } } class A { before(): execution(void C.f()) { ... } after(): execution(void C.g()) { ... } void  around(): execution(void C.h()) { ... proceed(); ... } } // in thread T1 ... deploy(new A()) { ... } ... actual-C f = ( ... ) g = ( ... ) h = ( ... ) C instance-of-C actual-instance-of-C A-proxy f = ( ...;  resend  ) g = (  resend;  ... ) h = ( ...;  resend;  ... ) the delegate of  C  is a function  of the thread T1 others
cflow: Continuous Weaving // CaesarJ-like pseudo code class C { void f() { ... } void g() { ... f(); ... } } class A { before(): execution(void C.f()) && cflow(execution(void C.g())) { ... } } ... deploy(new A()); ... actual-C f = ( ... ) g = ( ... f(); ... ) C instance-of-C actual-instance-of-C // in thread T1 ... instance-of-C.g(); ... T1 others A-cw-proxy g = (  act-cflow;  resend;  deact-cflow  ) A-proxy f = ( ...; resend ) f g
Introduction // CaesarJ-like pseudo code class C { int x; void f() { ... } } class A { int C.y; void C.g() { ... } before(): execution(void C.f()) { ... } } ... deploy(new A()); ... actual-C f = ( ... ) C instance1-of-C actual-instance1-of-C x = 23 ... instance1-of-C.y ... instance2-of-C actual-instance2-of-C x = 42 A-int-proxy y = ( /* add y field to instance */; self y ) g = ( /* imp. of introduced method */ ) y A-int1-proxy y = 0
Agenda Context Modularization Crosscutting Concerns A Dedicated Machine Model Object-based + Delegation Support for Modularization Mechanisms Language Mappings j : Object-Oriented Programming ij : Inter-Type Declarations aj : Pointcut-and-Advice AOP cj : Context-Oriented Programming Future Work
j  – Object-Oriented Programming  [Skipper04] class Subject  ext Object   { Integer attr Observer obs void doSomething(Object x) { this.attr := 25 } void changed(Object x) { this.obs.update(this) } void setObserver(Observer x) { this.obs := x } } class Observer ext Object { void update(Subject x) { out.println(x.attr) } } class Main ext Object { Subject s Observer o void main(Main x) { x.s := new Subject; x.o := new Observer; x.s.setObserver(x.o); x.s.doSomething(null); x.s.changed(null) } }
j  Prepared Heap Subject_prototype attr obs Subject_proxy Subject doSomething  = (...) changed = (...) setObserver = (...) Main_prototype s o Main_proxy Main main  = (...) Observer_prototype Observer_proxy Observer update  = (...) Object proxy Object
j  Class Instantiation doSomething Subject_prototype attr obs Subject_proxy Subject doSomething  = (...) changed = (...) setObserver = (...) Main_prototype s o Main_proxy Main main  = (...) Observer_prototype Observer_proxy Observer update  = (...) Object proxy Object subject_inst attr obs subj_inst_proxy
ij  – Inter-Type Declarations  [Skipper04] class Observer ext Object { void update(Subject x) { out.println(x.attr) } Subject <--  Observer obs Subject <-- void changed(Object x) { this.obs.update(this) } Subject <--  void setObserver(Observer x) { this.obs := x } } class Subject  ext Object   { Integer attr void doSomething(Object x) { this.attr := 25 } } class Main ext Object { Subject s Observer o void main(Main x) { x.s := new Subject; x.o := new Observer; x.s.setObserver(x.o); x.s.doSomething(null); x.s.changed(null) } }
ij  Prepared Heap Subject_proto attr Subject_proxy Subject doSomething  = (...) Main_proto s o Main_proxy Main main  = (...) Observer_proto Observer_proxy Observer update  = (...) Object proxy Object intr_proxy 1 changed = (...) setObserver = (...) obs=(... self obs)
ij  Class Instantiation obs Subject_proto attr Subject_proxy Subject doSomething  = (...) Main_proto s o Main_proxy Main main  = (...) Observer_proto Observer_proxy Observer update  = (...) Object proxy Object intr_proxy 1 changed = (...) setObserver = (...) obs=(... self obs) subject_inst attr subj_inst_proxy intr_proxy2 obs
aj  – Pointcut and Advice AOP  [Skipper04] class Subject ext Object { Integer attr void changed(Object x) { out.println(this.attr) } } aspect Observer  { bool changed before set (Integer Subject.attr) { this.changed := v.neq(r.attr) } after set (Integer Subject.attr) { if (this.changed){ r.changed(null) } else { null } } } class Main ext Object { Subject s void main(Main x) { x.s := new Subject; x.s.attr := 25; } }
aj  Prepared Heap setAttr attr Subject_proto attr Subject_proxy Subject setAttr = (... self attr ...) changed = (...) Main_proto s Main_proxy Main main  = (...) Observer_Asp changed Object Object_proxy obs_proxy_1 setAttr = (... resend) obs_proxy_2 setAttr = (resend; ...) subject_inst attr obs subj_inst_proxy
cj  – Context-Oriented Programming class Subject  ext Object   { Integer attr void Subject.setAttr(Integer x){ this.attr := x } void Subject.changed(Object x){ out.println(this.attr)} } layer Observer  { bool changed void Subject.setAttr(Integer x)  { thislayer.changed := x.neq(this.attr); proceed(x); if(thislayer.changed) { this.changed(null) } else { null }} } class Main ext Object { Subject s void main(Main x) { x.s := new Subject; x.s.setAttr(12); withlayer(Observer)  { x.s.setAttr(25) } } }
cj  Prepared Heap attr setAttr Subject_proto attr Subject_proxy Subject setAttr = (... self attr ...) changed = (...) Main_proto s Main_proxy Main main  = (...) Observer_Lyr changed Object Object_proxy subject_inst attr obs subj_inst_proxy obs_proxy_1 setAttr = (... resend; ...)
Prototypical Implementation COLA Framework  [Piumarta  et al. ]
Experimental Implementation Implementation Substrate: VM Instructions (define-class ...) (create-instance ...) (create-proxy ...) (insert-proxy ...) (define-method ...) (send ...) (resend ...) Compiler for  *j  languages towards this substrate Transform PEG AST Languages executable on top of the substrate
Onward! (Listen up, OOPSLA!) Additional Join Points (Pointcuts) history-based logic-based call (?) Different Kinds of Advice asynchronous Formally Prove Language Mappings Correctness actor systems; “formal VM” Production Quality VM caching garbage collection maxine Dynamic Composition
Summary Dedicated Machine Model Object-based + Delegation Support for Modularization Mechanisms Unifying Delegation-based Semantics j : Object-Oriented Programming ij : Inter-Type Declarations aj : Pointcut-and-Advice AOP cj : Context-Oriented Programming Prototypical Implementation Thank You - Questions?

Machine-level Composition of Modularized Crosscutting Concerns

  • 1.
    Machine-level Composition ofModularized Crosscutting Concerns Hans Schippers Universiteit Antwerpen 20 november 2008
  • 2.
    Special Thanks To...Michael Haupt Robert Hirschfeld Software Architecture Group Hasso Plattner Institute, University of Potsdam (close to Lindenstube...)
  • 3.
    Agenda Context ModularizationCrosscutting Concerns A Dedicated Machine Model Object-based + Delegation Support for Modularization Mechanisms Language Mappings j : Object-Oriented Programming ij : Inter-Type Declarations aj : Pointcut-and-Advice AOP cj : Context-Oriented Programming Future Work
  • 4.
    Modularization Divide andConquer Organize a Software System in Manageable Modules Each Module its own Responsibilities => Which Modules? => How to Decompose the System?
  • 5.
    Employee Management SystemTask 1 Find Out Employee-Boss Relationships Sales Research Financial Support
  • 6.
    Employee Management SystemTask 2 Calculate Salaries ? Sales Research Financial Support
  • 7.
    Employee Management SystemTask 2 Calculate Salaries Research Monthly Hourly Bonus
  • 8.
    Employee Management SystemTask 1 Find Out Employee-Boss Relationships ? Research Monthly Hourly Bonus
  • 9.
    Dominant Decomposition: OrganizationalHard to calculate salary... Easy to find out supervisor relationships... Employee Research ResearchManager Sales SalesManager Financial FinancialManager Support SupportManager
  • 10.
    Dominant Decomposition: PayrollEasy to calculate salary... Hard to find out supervisor relationships... Employee HourlyWage MonthlyWage Research Regular Sales SalesManager RegularManager Secretary Labourer ResearchManager
  • 11.
    Crosscutting Concerns source:http://www.ercim.org/publication/Ercim_News/enw58/van_deursen1.jpg Column: Module Each Color: Task
  • 12.
    Modularizing Crosscutting ConcernsMDSOC approaches deal with the modularization of crosscutting concerns . tangling / scattering extra module (e.g., aspect, layer, ...) modularized code (e.g., advice, ...) join points Now somehow make all modules work together...
  • 13.
    State-of-the-Art: Weaving... SourceCode Level [EAOP] Byte Code Level [AspectJ, Steamloom] ----- Application Level [EAOP, AspectJ] Machine Level [Steamloom]
  • 14.
    I've Got Troubles,Oh-Oh Ik Heb Zorgen Manageability: Lose Track of Modules Performance: Residual Code Modules may be active depending on dynamic conditions Elegance: Modularized Code --> OO Code Conceptual: Join Points Misrepresented as Shadows We Need a Dedicated (Virtual) Machine
  • 15.
    Core Mechanisms adifferent look at join points at each join point, decisions are drawn which functionality to execute? depends on context (current object, message sent/received, methods on stack, ...) very much like polymorphic dispatch running application ≈ sequence of late binding events a join point is a locus of late binding like virtual methods: virtual join points
  • 16.
    A Dedicated MachineModel core concepts: objects and delegation [ECOOP 07] each application object, internally, consists of two a proxy (a mere placeholder ) and the actual object other application objects only directly see the proxy access to properties only via messages classes and instances classes are also represented by objects, also have a proxy instances reference the proxy only delegation ensures correct binding of self self object actual-object foo = ( ... ) bar = 23 delegate instance-of-C actual-instance-of-C v = 23 C actual-C m = ( ... ) m
  • 17.
    Basic Modularization Operations// CaesarJ-like pseudo code class C { void f() { ... } void g() { ... } void h() { ... } } class A { before(): execution(void C.f()) { ... } after(): execution(void C.g()) { ... } void around(): execution(void C.h()) { ... proceed(); ... } } ... deploy(new A()); ... actual-C f = ( ... ) g = ( ... ) h = ( ... ) C instance-of-C actual-instance-of-C A-proxy f = ( ...; resend ) g = ( resend; ... ) h = ( ...; resend; ... ) f
  • 18.
    Instance-Local Deployment //CaesarJ-like pseudo code class C { void f() { ... } void g() { ... } void h() { ... } } class A { before(): execution(void C.f()) { ... } after(): execution(void C.g()) { ... } void around(): execution(void C.h()) { ... proceed(); ... } } ... deploy(new A(), instance-of-C); ... actual-C f = ( ... ) g = ( ... ) h = ( ... ) C instance-of-C actual-instance-of-C A-proxy f = ( ...; resend ) g = ( resend; ... ) h = ( ...; resend; ... )
  • 19.
    Thread-Local Deployment //CaesarJ-like pseudo code class C { void f() { ... } void g() { ... } void h() { ... } } class A { before(): execution(void C.f()) { ... } after(): execution(void C.g()) { ... } void around(): execution(void C.h()) { ... proceed(); ... } } // in thread T1 ... deploy(new A()) { ... } ... actual-C f = ( ... ) g = ( ... ) h = ( ... ) C instance-of-C actual-instance-of-C A-proxy f = ( ...; resend ) g = ( resend; ... ) h = ( ...; resend; ... ) the delegate of C is a function of the thread T1 others
  • 20.
    cflow: Continuous Weaving// CaesarJ-like pseudo code class C { void f() { ... } void g() { ... f(); ... } } class A { before(): execution(void C.f()) && cflow(execution(void C.g())) { ... } } ... deploy(new A()); ... actual-C f = ( ... ) g = ( ... f(); ... ) C instance-of-C actual-instance-of-C // in thread T1 ... instance-of-C.g(); ... T1 others A-cw-proxy g = ( act-cflow; resend; deact-cflow ) A-proxy f = ( ...; resend ) f g
  • 21.
    Introduction // CaesarJ-likepseudo code class C { int x; void f() { ... } } class A { int C.y; void C.g() { ... } before(): execution(void C.f()) { ... } } ... deploy(new A()); ... actual-C f = ( ... ) C instance1-of-C actual-instance1-of-C x = 23 ... instance1-of-C.y ... instance2-of-C actual-instance2-of-C x = 42 A-int-proxy y = ( /* add y field to instance */; self y ) g = ( /* imp. of introduced method */ ) y A-int1-proxy y = 0
  • 22.
    Agenda Context ModularizationCrosscutting Concerns A Dedicated Machine Model Object-based + Delegation Support for Modularization Mechanisms Language Mappings j : Object-Oriented Programming ij : Inter-Type Declarations aj : Pointcut-and-Advice AOP cj : Context-Oriented Programming Future Work
  • 23.
    j –Object-Oriented Programming [Skipper04] class Subject ext Object { Integer attr Observer obs void doSomething(Object x) { this.attr := 25 } void changed(Object x) { this.obs.update(this) } void setObserver(Observer x) { this.obs := x } } class Observer ext Object { void update(Subject x) { out.println(x.attr) } } class Main ext Object { Subject s Observer o void main(Main x) { x.s := new Subject; x.o := new Observer; x.s.setObserver(x.o); x.s.doSomething(null); x.s.changed(null) } }
  • 24.
    j PreparedHeap Subject_prototype attr obs Subject_proxy Subject doSomething = (...) changed = (...) setObserver = (...) Main_prototype s o Main_proxy Main main = (...) Observer_prototype Observer_proxy Observer update = (...) Object proxy Object
  • 25.
    j ClassInstantiation doSomething Subject_prototype attr obs Subject_proxy Subject doSomething = (...) changed = (...) setObserver = (...) Main_prototype s o Main_proxy Main main = (...) Observer_prototype Observer_proxy Observer update = (...) Object proxy Object subject_inst attr obs subj_inst_proxy
  • 26.
    ij –Inter-Type Declarations [Skipper04] class Observer ext Object { void update(Subject x) { out.println(x.attr) } Subject <-- Observer obs Subject <-- void changed(Object x) { this.obs.update(this) } Subject <-- void setObserver(Observer x) { this.obs := x } } class Subject ext Object { Integer attr void doSomething(Object x) { this.attr := 25 } } class Main ext Object { Subject s Observer o void main(Main x) { x.s := new Subject; x.o := new Observer; x.s.setObserver(x.o); x.s.doSomething(null); x.s.changed(null) } }
  • 27.
    ij PreparedHeap Subject_proto attr Subject_proxy Subject doSomething = (...) Main_proto s o Main_proxy Main main = (...) Observer_proto Observer_proxy Observer update = (...) Object proxy Object intr_proxy 1 changed = (...) setObserver = (...) obs=(... self obs)
  • 28.
    ij ClassInstantiation obs Subject_proto attr Subject_proxy Subject doSomething = (...) Main_proto s o Main_proxy Main main = (...) Observer_proto Observer_proxy Observer update = (...) Object proxy Object intr_proxy 1 changed = (...) setObserver = (...) obs=(... self obs) subject_inst attr subj_inst_proxy intr_proxy2 obs
  • 29.
    aj –Pointcut and Advice AOP [Skipper04] class Subject ext Object { Integer attr void changed(Object x) { out.println(this.attr) } } aspect Observer { bool changed before set (Integer Subject.attr) { this.changed := v.neq(r.attr) } after set (Integer Subject.attr) { if (this.changed){ r.changed(null) } else { null } } } class Main ext Object { Subject s void main(Main x) { x.s := new Subject; x.s.attr := 25; } }
  • 30.
    aj PreparedHeap setAttr attr Subject_proto attr Subject_proxy Subject setAttr = (... self attr ...) changed = (...) Main_proto s Main_proxy Main main = (...) Observer_Asp changed Object Object_proxy obs_proxy_1 setAttr = (... resend) obs_proxy_2 setAttr = (resend; ...) subject_inst attr obs subj_inst_proxy
  • 31.
    cj –Context-Oriented Programming class Subject ext Object { Integer attr void Subject.setAttr(Integer x){ this.attr := x } void Subject.changed(Object x){ out.println(this.attr)} } layer Observer { bool changed void Subject.setAttr(Integer x) { thislayer.changed := x.neq(this.attr); proceed(x); if(thislayer.changed) { this.changed(null) } else { null }} } class Main ext Object { Subject s void main(Main x) { x.s := new Subject; x.s.setAttr(12); withlayer(Observer) { x.s.setAttr(25) } } }
  • 32.
    cj PreparedHeap attr setAttr Subject_proto attr Subject_proxy Subject setAttr = (... self attr ...) changed = (...) Main_proto s Main_proxy Main main = (...) Observer_Lyr changed Object Object_proxy subject_inst attr obs subj_inst_proxy obs_proxy_1 setAttr = (... resend; ...)
  • 33.
    Prototypical Implementation COLAFramework [Piumarta et al. ]
  • 34.
    Experimental Implementation ImplementationSubstrate: VM Instructions (define-class ...) (create-instance ...) (create-proxy ...) (insert-proxy ...) (define-method ...) (send ...) (resend ...) Compiler for *j languages towards this substrate Transform PEG AST Languages executable on top of the substrate
  • 35.
    Onward! (Listen up,OOPSLA!) Additional Join Points (Pointcuts) history-based logic-based call (?) Different Kinds of Advice asynchronous Formally Prove Language Mappings Correctness actor systems; “formal VM” Production Quality VM caching garbage collection maxine Dynamic Composition
  • 36.
    Summary Dedicated MachineModel Object-based + Delegation Support for Modularization Mechanisms Unifying Delegation-based Semantics j : Object-Oriented Programming ij : Inter-Type Declarations aj : Pointcut-and-Advice AOP cj : Context-Oriented Programming Prototypical Implementation Thank You - Questions?