next up previous
Next: The Reflective Architecture of Up: The Design and Implementation Previous: Introduction

  
Related Work

The development of generic mechanisms for the composition of meta-objects is still in its initial stages. OpenC++ [2] does not provide direct support for composition. MOOSTRAP [16] and MetaXa [9] (formerly known as MetaJava) support sequential composition of similar meta-objects. We say that meta-objects are similar if they implement the same interface.

Apertos [23] and CodA [14] assign aspects of base-level execution, such as sending, receiving and scheduling operations, to specialized, dissimilar meta-objects. A pre-determined set of aspects can be extended, through intrusive modification of the implementation of the meta-objects responsible for them. We consider this a primitive mechanism of composition, that fails in the general case, because the modifications are very likely to clash.

Several run-time MOPs have been designed so that, when a meta-object is requested to handle a reified operation (for example, a method invocation), it is obliged, by the design of the MOP, to return a valid result for the operation (typically the value returned by the method), as shown in Figure 1. The meta-level computation that yields the result can include or not the delivery of the operation to the base-level object.


  
Figure 1: Basic interception.
\begin{figure}{\small\begin{center}\fbox{
\begin{picture}
(210,85) (-105,-35)
...
...box(0,0)[c]{\scriptsize \result{R'}}}
\end{picture} }\end{center}}
\end{figure}

When a Client requests an operation Op from a Server object, the operation is intercepted, reified (represented as an object) and presented to a Meta-Object. It may choose to deliver a different operation Op$^\prime$ to the Server, obtaining the result R$^\prime$, that is also reified. Having delivered an operation or not, it must reply with a result R, that is unreified and returned to the Client.

This design implies that the only way to combine the behavior of meta-objects is by arranging for one meta-object, say MO1, to forward operation handling requests to another, say MO2, delegating to MO2 the responsibility for computing the result of the operation. Only after MO2 returns a result will MO1 be able to observe and/or to modify it.


  
Figure 2: Chain of Meta-Objects.
\begin{figure}{\small\begin{center}\fbox{
\begin{picture}
(210,45) (0,0)
\put...
...t(217,0){\tiny \resultbox{R$_n$ }}
}
\end{picture} }\end{center}}
\end{figure}

Given the basic interception mechanism of Figure 1, meta-objects can only be composed with a Chain of Responsibility [5, chapter 5], a sequential delegation pattern.

Given such a protocol, meta-objects are likely to be organized in a Chain of Responsibility [5, chapter 5], so that each meta-object delegates operation handling requests to its successor, as depicted in Figure 2. The last element of the chain is either the base-level object [9] or a special meta-object that delivers operations to it [16]. We argue that this design presents some serious drawbacks:

Even AspectJ [11,12], an aspect-oriented programming [8] extension of Java, lacks the possibility of introducing such an adaptor to manage conflicting weaves of aspects so that they can coexist.


next up previous
Next: The Reflective Architecture of Up: The Design and Implementation Previous: Introduction
contact the authors