Upload
jesse-dickerson
View
219
Download
2
Tags:
Embed Size (px)
Citation preview
On the Aspect Composition Issue
Eddy Truyen, Wouter Joosen, Pierre Verbaeten
Outline Overview of wrapper-based model Lasagne
Analysis of the aspect composition Issue by examples
Detailed Overview of Lasagne concepts and run-time
Lasagne applied to the aspect composition issue
Lessons learned and future work
Conclusion
Motivation for Lasagne
Support for dynamic and client-specific customization of distributed services is needed
An example: web service on the Internet Multiple clients are accessing a web service instance
simultaneously Different clients have different customization needs One client must be able to customize the web service for use
in its own context, without affecting other clients (service behavior delivered to
other clients must not be affected)
Motivation (ctd)
Customization process = context-sensitive and dynamic combination of extensions to a minimal core system Extensions can be functional (e.g. refined core service) and
non-functional (e.g. authentication, authorization)
Revisiting example: web service on the Internet Each client must be able to select a subset of extensions into
the core service, for use in its own context:
per client request, per client session without interfering with other clients
Short overview of Lasagne
A programming, deployment and run-time model that supports dynamic combination of extensions per client request
Inspired by wrapper-based design patterns Decorator and Role Object
Advantages of wrappers already support combination of extensions to a component operate at instance-level => customization of online services
Deal with disadvantages of wrappers object identity problems
Atomic Agenda
Authorization CheckWrapper
Authorization &
Access Control
Appointment System
Group Appointment
Service
SimpleAgenda core system
extensions AccessDenied
ExceptionHandler
Example
System-wide interaction refinement
High-level overview of Lasagne
Introductory terms Component-based, distributed core system
Component type =< {services}, {dependencies}> Connection supported by COTS middleware
Client request initiates collaboration between core components
Lasagne customization process consists of three phases: extension programming, deployment of extensions to a core system, and selective combination per collaboration at runtime
Agenda 1 Appointment System
Agenda 2
dependency servicecollaboration
connection
High-level overview of Lasagne
The extension programming model An extension is implemented as a layer of wrappers Wrappers are programmed in hybrid form between
Decorator and Role Object Each wrapper definition is meant for decorating a specific
minimal component type
Group App. Service
Atomic Agenda
*
<{Appointment}, {Negotiation}> <{Negotiation}, {}>
Appointment System
Agenda
High-level overview of Lasagne
Deployment of extensions to core application Declarative specification of how to integrate wrappers to a
specific core application specify fine-grained partial ordering constraints
Atomic Agenda
Authorization CheckWrapper
Authorization &
Access Control
Appointment System
Group Appointment
Service
dynamic extensible component
Simple Agenda
AccessDenied ExceptionHandler
Ordering constraints
High-level overview of Lasagne
Selective combination of extensions on a per client request
dynamic adjustment of message flow through
appropriate chain of wrappers
:Agenda
Group App. Service
Atomic Agenda
Authoriz. Check Wrapper
AccessDenied Exception Handler
:AppointmentSystem
Aspect Composition Issue
Aspect X that works correctly when composed with application A, may not work correctly in CASE 1: When X is composed with another
application B CASE 2: When other aspects are simultaneously
composed with application A
Also known as the feature interaction problem
Example of CASE 1 (cfr. [J. Brichau, “Jumping Aspects”, ADC’2000])
public class DocumentWithoutNestedCalls implements PrintableText { String[] lines; .. public void printAll() { for (int i = 0; i < lines.length; i++) System.out.println(lines[i]); }
public void printLine(int i) { System.out.println(lines[i]); }}
Example of CASE 1 (cont)public class DocumentwithNestedCalls implements PrintableText { String[] lines; .. public void printAll() { for (int i = 0; i < lines.length; i++) self.printLine(i); }
public void printLine(int i) { System.out.println(lines[i]); }
}
Example of CASE 1 (cont)/**extension_identifier counter**/public class CountingWrapper implements PrintableText { int counter; public void printAll() { counter+=(String[])self.getField("lines").length; self.PrintAll(); //call next wrapper }
public void printLine(int i) { counter++; self.printLine(i); //call next wrapper } }
Lesson Learned
Problem: CounterWrapper is not reusable It does not work correctly when wrapping
objects of class DocumentWithNestedCalls Wrapper counts twice when printAll() is
invoked Delegation is as fragile as inheritance!
Example of CASE 2 /**extension_identifier linked**/public class LinkedListWrapper implements LinkedList { Object next; public void setNext(Object x) { Object tmp = next; next = x; if (tmp!=null) ((LinkedList)x.getRole("linked")).setNext(tmp); } public Object getNext() { return next; }}
Example of CASE 2 (cont)/**extension_identifier backlinked**/public class BackLinkedListWrapper implements BackLinkedList { Object previous; public void setPrevious(Object w) { Object tmp = previous; previous = w; if (tmp != null) (Back..List)w.getRole("backlinked")).setPrevious(tmp); } public Object getPrevious() { return previous; }}
Example of CASE 2 (cont)
Problem LinkedListWrapper works well in isolation
BackLinkedListWrapper works well in isolation
BUT: Their composition does not work well in isolation
setNext(X)X
Example of CASE 2 (cont)
Problem LinkedListWrapper works well in isolation
BackLinkedListWrapper works well in isolation
BUT: Their composition does not work well in isolation
X
Backlink not updated
Example of CASE 2 (cont) Tentative Solution: Aspect on Aspect
Write a third aspect that composes the two aspects But this aspect must only be applied when the context
makes it necessary
setNext(X)X
Aspect Composition Problem!!
Example of CASE 2 (cont) Tentative Solution: Aspect on Aspect
Write a third aspect that composes the two aspects But this aspect must only be applied when the context
makes it necessary
setNext(X)X
No Aspect Composition Problem
Lesson Learned: Context is important in the Aspect
Composition Issue
Given an aspect A that is composed with a system S, there exists a set of contextual conditions CA under which the execution of the aspect A will cause an error somewhere in the system S.
Lesson Learned:Somewhere is everywhere
An error caused by A can not only occur at the joint point between A and S, but may also be at any other point in code of S or in the code of another aspect simultaneously composed with S.
General solution to the Aspect Composition Issue
First, domain-specific framework for semi-automatic specification of contextual conditions CA, to enable (semi-)automatic detection of aspect composition problems.
Second, an external mediator that evaluates contextual conditions and takes context-sensitive, semi-automated actions at all the necessary places in the system, with no invasive change in existing code.
Lasagne may contribute to the second part
Detailed Overview of Lasagne Concepts and Runtime
High-level overview of Lasagne
Selective combination of extensions on a per client request
dynamic adjustment of message flow through
appropriate chain of wrappers
:Agenda
Group App. Service
Atomic Agenda
Authoriz. Check Wrapper
AccessDenied Exception Handler
:AppointmentSystem
Lasagne Concepts
Component Identity Aggregates core instance and its wrappers into one identity Removes the spaghetti of wrapper references
Extension Identifier qualified name that uniquely identifies an extension Is used to designate wrappers as belonging to a specific
extension Composition Policy {…}
specifies the subset of extension identifiers for a specific collaboration between client and core system
A composition policy propagates with the collaboration flow
Lasagne concepts
Contextual properties e.g client-specific preferences, message flow history defined as <name, value> pairs that propagate with the
collaboration flow Interceptors
define contextual properties of collaboration select or unselect extensions. Typical selection rule:
If <condition> is satisfied within <context> then attach/discard <extension identifier> to composition policy
Variation point Extension to runtime component model Generic message dispatch mechanism
Dynamically constructs wrapper chain Interprets composition policy and ordering constraints
Component Identity
Agenda 1Appointment
SystemAgenda 2
authorization & access control
Extension Identifiers
Agenda 1 Agenda 2
authorization & access control
<“authoriz”>
<“group”>
Appointment System
Appointment System
Interceptors and Composition Policy
Agenda 1 Agenda 2
authorization & access control
<“authoriz”>
<“group”>
{ } {<“authoriz”>}
add <“authoriz”>
If client_localhost on remote subnet then attach <“authoriz”> to composition policy
{<“authoriz”>}
{<“authoriz”>}
Attach client_localhost, client_identity as contextual properties to collaboration.
Interceptor definitions
{ }
Appointment System
•Propagation of composition policy
•Propagation of contextual properties
•Variationpoint performs automatic adjustment of message flow
Underlying runtime mechanisms
Agenda 1 Agenda 2
authorization & access control
<“authoriz”>
<“group”>
{ } {<“authoriz”>}
add <“authoriz”>
{<“authoriz”>}
{<“authoriz”>}
Underlying runtime mechanisms Variation point realization
i1
component identity
i0
VariationPoint
wrapper instances
self.inspect() i3
i2
core instance
(inner i0..3).inspect()
composition policy && ordering constraints
this.inspect()
self
OOP Problems solved
Object Schizophrenia problem (web of objects have no common self) Lasagne solution: These problems is solved by redirecting self-calls
to the component identity
Passing/Stripping component references When passing a reference to a component from one client to
another client, the reference should point to the component identity Lasagne solution:
When the passing client is only using decorators => OK When the passing client is using a role => The role reference
may not be passed but must be automatically transformed to the component identity by the Lasagne run-time
OOP Problems solved (cont.)
Wrapping and Inheritance Subclass widens interface of wrapped class
Wrapper hides interface, type-transparency needed (generic wrappers [Buchi & Weck])
Lasagne solution: Is solved by using a suitable variation point implementation that dynamically skips wrappers when they do not support the currently service operation in process
Subclass overwrites existing operation of wrapped class and calls super on it
Super-calls will not be wrapped (subtle variant of the object schizophrenia problem)
Lasagne solution: Can only be solved when adopting a Lasagne philosophy: choose a Lasagne wrapper instead of subclassing and use inner-calls instead of super-calls
For both cases: according to the Lasagne philosophy it is better to choose a Lasagne wrapper then to subclass by means of inheritance.
Lasagne Applied on Aspect Composition Issue
Reminder of CASE 1public class DocumentwithNestedCalls implements PrintableText { String[] lines; .. public void printAll() { for (int i = 0; i < lines.length; i++) self.printLine(i); }
public void printLine(int i) { System.out.println(lines[i]); }
}
Solution to CASE 1 (cont)
Solution Use forwarding instead of delegation for
DocumentWithNestedCalls classes Encode this composition policy in a separate
interceptor No invasive changes in code of
CounterWrapper or DocumentWithNestedCalls classes
Solution to CASE 1 (cont)public class CounterInterceptorWithoutNestedCalls implements Interceptor { public void manipulate(Interaction i) { if (i.isMethod("print*")) { CompositionPolicy p = i.getCompositionPolicy(); p.addExtension("counter", LOCAL_OBJECT); } }}
Solution to CASE 1 (cont)public class CounterInterceptorForNestedCalls implements Interceptor { public void manipulate(Interaction i) { if (i.isMethod("print*")) { CompositionPolicy p = i.getCompositionPolicy(); CallingStack s= i.getContext().get("callingStack"); if (!( (s.peekframe(1).getObject() = self) and (s.peekframe(1).getMethod()=="printAll()V") ) ) p.addExtension("counter", LOCAL_OBJECT); else
p.removeExtension("counter", LOCAL_OBJECT); } }}
Invasive, but much simpler and more performant solution to CASE 1
public class DocumentwithNestedCalls implements PrintableText { String[] lines; .. public void printAll() { for (int i = 0; i < lines.length; i++) this.printLine(i); }
public void printLine(int i) { System.out.println(lines[i]); }
}
Lesson learned
Lasagne is only suitable for customization at the coarse-grained architectural level Too much performance overhead at object
implementation level!
We must build an efficient Lasagne implementation to be used at the object implementation level
Reminder of CASE 2 Tentative Solution: Aspect on Aspect
Write a third aspect that composes the two aspects But this aspect must only be applied when the context
makes it necessary
setNext(X)X
Aspect Composition Problem!!
/**extension_identifier doublelinked expects linked, backlinked**/public class DoubleLinkedListWrapper expects BackLinkedList, LinkedList { public void setNext(Object x) { Object tmp = self.getNext(); if (tmp!=null) ((Back…List)tmp.getRole("backlinked")).setPrevious(x); self.setNext(x); //call next wrapper } public void setPrevious(Object w) { Object tmp = getPrevious(); if (tmp!=null) ((LinkedList)tmp.getRole("linked")).setNext(w); self.setPrevious(w); //call next wrapper} }
Solution to CASE 2 (cont)
public class DoubleLinkedListInterceptor implements Interceptor { public void manipulate(Interaction i) { CompositionPolicy p = i.getCompositionPolicy(); if (i.isMethod("setNext(Object)V")) { //policy contains “linked” Object obj = ((…)self.getRole(“linked”)).getNext(); if (obj != null) { ComponentType t = obj.getComponentType(); if (t.includesInterface("BackLinkedList"))
p. addExtension("doublelinked", LOCAL_OBJECT);}
} else if (i.isMethod("setPrevious(Object)V")) { … }}
Solution to CASE 2 (cont)
Lesson learned
Lasagne is too low-level and complex for general use! Need to build higher-level tool or composition
language on top of Lasagne feedback from AOSD community
Conclusion Lasagne is meant for dynamic and context-sensitive
customization of distributed services and middleware Non-invasive Aspect-oriented Per instance Per Collaboration
Lasagne allows context-sensitive combination of extension
Simultaneously, Multiple Context-Specific Views => Lasagne could help with the aspect
composition issue
Further Information
http://www.cs.kuleuven.ac.be/~eddy/lasagne.htmlLasagne prototypes
Programming Languages with an “open” implementation
Correlate (email [email protected])Java (http://cedric.cnam.fr/caolac/jac/downloads.html, co-work with Renaud Pawlak)
middleware platformsJava RMI, Lasagne ORB, EJB
High-level overview of Lasagne
Selective combination of extensions on a per client request
dynamic adjustment of message flow through
appropriate chain of wrappers
:Agenda
Group App. Service
Atomic Agenda
Authoriz. Check Wrapper
AccessDenied Exception Handler
:AppointmentSystem
Basic Idea to support selective combination
Decorator [Gamma et al] Disjunctive chaining supports selective combination
Agenda
Decorator 1 Decorator 2
Decorator 2
Decorator 1
Spaghetti Problem Agenda
Atomic Agenda
Atomic Agenda
Appointment System
Group App. Service
AccessDenied Exception Handler
Group App. Service
AccessDenied Exception Handler
authorization & access control
Object Identity Problem
Authoriz. Check Wrapper
Authoriz. Check Wrapper
Coordination Problem Agenda
Appointment System
Atomic Agenda
Atomic Agenda
Group App. Service
AccessDenied Exception Handler
Group App. Service
AccessDenied Exception Handler
Authoriz. Check Wrapper
Authoriz. Check Wrapper
Coordination Problem Agenda
Atomic Agenda
Atomic Agenda
Appointment System
Group App. Service
AccessDenied Exception Handler
Group App. Service
AccessDenied Exception Handler
Inconsistency
Authoriz. Check Wrapper
Authoriz. Check Wrapper
Coordination Problem Agenda
Atomic Agenda
Atomic Agenda
Appointment System
Group App. Service
AccessDenied Exception Handler
Group App. Service
AccessDenied Exception Handler
Calling context must be propagated over entire
core system
Authoriz. Check Wrapper
Authoriz. Check Wrapper
Turning Spaghetti into Lasagne
Externalize wrapper composition logic from the code of core system and extensions
Clients and deployers can customize the wrapper composition logic on a per collaboration basis