Title: On the Aspect Composition Issue
1On the Aspect Composition Issue
- Eddy Truyen, Wouter Joosen, Pierre Verbaeten
2Outline
- 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
3Motivation 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)
4Motivation (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
5Short 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 gt customization of
online services - Deal with disadvantages of wrappers
- object identity problems
6Example
System-wide interaction refinement
7High-level overview of Lasagne
- Introductory terms
- Component-based, distributed core system
- Component type lt services, dependenciesgt
- 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
connection
dependency
service
8High-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
ltAppointment, Negotiationgt
ltNegotiation, gt
Appointment System
Agenda
9High-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
10High-level overview of Lasagne
- Selective combination of extensions on a per
client request
11Aspect 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
12Example of CASE 1 (cfr. J. Brichau, Jumping
Aspects, ADC2000)
public class DocumentWithoutNestedCalls
implements PrintableText String lines
.. public void printAll() for (int i 0
i lt lines.length i) System.out.println(li
nesi) public void printLine(int i)
System.out.println(linesi)
13Example of CASE 1 (cont)
public class DocumentwithNestedCalls implements
PrintableText String lines .. public
void printAll() for (int i 0 i lt
lines.length i) self.printLine(i)
public void printLine(int i)
System.out.println(linesi)
14Example 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
15Lesson 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!
-
16Example 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
17Example 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
18Example of CASE 2 (cont)
- Problem
- LinkedListWrapper works well in isolation
- BackLinkedListWrapper works well in isolation
- BUT Their composition does not work well in
isolation
19Example of CASE 2 (cont)
- Problem
- LinkedListWrapper works well in isolation
- BackLinkedListWrapper works well in isolation
- BUT Their composition does not work well in
isolation
20Example 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
21Example 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
No Aspect Composition Problem
22Lesson 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.
23Lesson LearnedSomewhere 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.
24General 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
25Detailed Overview of Lasagne Concepts and Runtime
26High-level overview of Lasagne
- Selective combination of extensions on a per
client request
27Lasagne 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
28Lasagne concepts
- Contextual properties
- e.g client-specific preferences, message flow
history - defined as ltname, valuegt pairs that propagate
with the collaboration flow - Interceptors
- define contextual properties of collaboration
- select or unselect extensions. Typical selection
rule - If ltconditiongt is satisfied within ltcontextgt then
attach/discard ltextension identifiergt to
composition policy - Variation point
- Extension to runtime component model
- Generic message dispatch mechanism
- Dynamically constructs wrapper chain
- Interprets composition policy and ordering
constraints
29Component Identity
30Extension Identifiers
ltgroupgt
ltauthorizgt
31Interceptors and Composition Policy
ltauthorizgt
ltgroupgt
ltauthorizgt
ltauthorizgt
ltauthorizgt
Interceptor definitions
Attach client_localhost, client_identity as
contextual properties to collaboration.
If client_localhost on remote subnet then attach
ltauthorizgt to composition policy
32Underlying runtime mechanisms
ltauthorizgt
ltgroupgt
ltauthorizgt
ltauthorizgt
ltauthorizgt
- Propagation of composition policy
- Propagation of contextual properties
- Variationpoint performs automatic adjustment
of message flow
33Underlying runtime mechanisms
- Variation point realization
self
34OOP 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
gt OK - When the passing client is using a role gt The
role reference may not be passed but must be
automatically transformed to the component
identity by the Lasagne run-time
35OOP 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.
36Lasagne Applied on Aspect Composition Issue
37Reminder of CASE 1
public class DocumentwithNestedCalls implements
PrintableText String lines .. public
void printAll() for (int i 0 i lt
lines.length i) self.printLine(i)
public void printLine(int i)
System.out.println(linesi)
38Solution 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
39Solution 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)
40Solution 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("callingSta
ck") if (!( (s.peekframe(1).getObject()
self) and (s.peekframe(1).getMethod()
"printAll()V") ) )
p.addExtension("counter", LOCAL_OBJECT)
else p.removeExtension("counter",
LOCAL_OBJECT)
41Invasive, 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 lt
lines.length i) this.printLine(i)
public void printLine(int i)
System.out.println(linesi)
42Lesson 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
43Reminder 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
44Solution to CASE 2 (cont)
/extension_identifier doublelinked expects
linked, backlinked/ public class
DoubleLinkedListWrapper expects
BackLinkedList, LinkedList public void
setNext(Object x) Object tmp
self.getNext() if (tmp!null)
((BackList)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
45Solution 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("setPre
vious(Object)V"))
46Lesson 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
47Conclusion
- 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
- gt Lasagne could help with the aspect composition
issue
48Further Information
- http//www.cs.kuleuven.ac.be/eddy/lasagne.html
- Lasagne prototypes
- Programming Languages with an open
implementation - Correlate (email eddy_at_cs.kuleuven.ac.be)
- Java (http//cedric.cnam.fr/caolac/jac/downloads.h
tml, co-work with Renaud Pawlak) - middleware platforms
- Java RMI, Lasagne ORB, EJB
49High-level overview of Lasagne
- Selective combination of extensions on a per
client request
50Basic Idea to support selective combination
- Decorator Gamma et al
- Disjunctive chaining supports selective
combination
51Spaghetti Problem
52Coordination Problem
53Coordination Problem
54Coordination Problem
55Turning 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