Lionel Seinturier
-
Nicolas Pessemier -
Thierry Coupaye
8/12/2005
Document history
AOKell is INRIA & France Telecom's implementation of the Fractal Specification. This document describes the design choices made to implement AOKell version 1.0, and the overall organization of the framework. This document is intended for framework developers that want to extend AOKell, but it can also be useful for component developers who want to understand how AOKell works.
For the remainder of this document, the reader is supposed to be familiar with the Fractal component model [1] and the basic notions of Aspect-Oriented Programming (AOP) [2].
AOKell is a framework for implementing component controllers and membranes. AOKell uses the AspectJ aspect-oriented programming language to implement controllers. Each controller is implemented as an aspect which is woven to the component. For example, a commonly encountered component such as a primitive one will be aspectized by five aspects: binding, lifecycle, naming, super, plus a special aspect which implements the Component interface. The other standard aspects existing in AOKell are: content, template and attribute. Of course, the programmer can still program his own aspect/controller.
We believe that this aspect-oriented approach for programming controllers provides several advantages:
As with Julia, the main design goal of AOKell is to implement a framework to program component controllers: we want to implement an extensible set of control objects, from which the user can freely choose and assemble the controller objects he or she wants, in order to build the membrane of a Fractal component.
AOKell is a level 3.3 implementation of the Fractal Specification (see the specifications for the meaning of compliance levels):
As this will presented in the section Aspects, the basic controllers, the Component interface and the Factory interface are implemented as aspects.
A Fractal component is associated to a membrane. The membrane provides a level of control and supervision on the component. Membranes can be decomposed into smaller units which are called controllers. A controller implements a particular functionality such as controlling the component bindings or managing the lifecycle of the component.
Several types of a membrane can be constructed depending on how controllers are grouped together. Following the Julia membrane type system, we support 13 different types of a membrane. The two most common ones are:
With AOKell, each type of a membrane is associated to a marker interface. The membrane interfaces are defined in a hierarchy. Figure 1 sums up the part of the hierarchy which corresponds to the two aforementioned types. The controller interfaces provided by each type are also mentioned. Notice that a root interface, BaseType, is defined. This interface provides the Component controller and is thus implemented by all components.
Fig 1: Membrane types.
The interfaces FlatType, PrimitiveType and CompositeType are used to type components. For example, a primitive component implements the PrimitiveType interface, which itself implements the SuperController interface, and by extension all the interfaces (BindingController, LifeCycleController, etc.) implemented by super-interfaces.
The use of the membrane types hierarchy presented in figure 1 is a design choice which is specific to the current version of AOKell. This hierarchy has been set up to factorize definitions, and to reuse as much code as possible. However, the use of this hierarchy for implementing membranes and controllers is not mandatory. As we will see in the section Aspects, aspects currently provided by AOKell use this type hierarchy but nothing prevent the programmer from implementing membranes and controllers without using it.
The hierarchy presented in figure 1 is completed with marker interfaces for parametric and template components.
A Fractal component is composed of a content and is associated to a membrane. The content is put under the control and the supervision of the membrane. A membrane can be decomposed into smaller units which are called controllers.
The purpose of this section is to present the structure set up by AOKell for a Fractal component. Two structures exist. The basic structure (see Section 3.1), called the AO (for aspect-oriented), is the one used by default by AOKell. A second structure (see Section 3.2), called JL (for Julia-like), can alternatively be used. Notice that both structure can coexist within a same application.
With AOKell, controllers are programmed as AspectJ aspects (the orange circles on Figure 2) which inject code into the content class and control its behavior. The logic of the controller is not implemented directly into the aspect but in a delegated instance which is associated to the aspect (the "controller implementations" of Figure 2). The existing aspects in AOKell will be presented with more details in the section Aspects.
Fig 2: Structure of a component.
A Fractal component owns Fractal interfaces. A Fractal interface acts as an entry point (server interface) or an exit point (client interface) for the component. A Fractal interface is associated to an InterfaceType with a name and a Java interface.
The Fractal interfaces of a component (the green circles on Figure 2) are instances which implement the Interface interface and the Java interface defined in their InterfaceType. The type of a Fractal interface is only known at runtime when newFcInstance is called to instantiate a component. This approach is very dynamic and allows creating interface and component types on the fly. Conversely, this late binding mechanism decreases type safety and prevents compile-time checks.
To sum up, the structure of a Fractal component with AOKell is composed of:
In addition to that, one needs to mention that AspectJ aspects are by default, singletons. Hence, there is also one instance per aspect for the whole application. The current version of AOKell defines 8 aspects (see Section Aspects).
This structure could be optimized by merging the controllers with the content. For that, the aspects implementing controllers could directly introduce the logic of the controllers into the content class, instead of introducing a pattern which delegates this logic to some external instances.
With this structure, the control features are directly injected into the content by the controllers. This structure is a bit different from the one defined by other implementations of the Fractal Specifications such as Julia.
With Julia, the content and the component are by default, two separated instances. The content class is then just a java.lang.Object which is not aware of the controllers. Nevertheless, if the content class implements one or several control interfaces, then this implementation is notified of any call issued on the controllers. For example, if the content class implements the BindingController interface, then whenever two components are bound, the bindFc method of the content class will be notified. By implementing the control interfaces, the programmer has then the possibility of reacting to control events. Notice that this is not a redefinition of the controllers behavior, as, in all cases, the behaviors implemented in the membrane are always executed.
The structure implemented by AOKell merges the content and the component, whereas, with Julia, the content and the component are separated.
The advantage of merging the content and the component is that the control interfaces are directly accessible at the content level. For example, with AOKell, the programmer can write the following content class.
public class ClientImpl implements PrimitiveType {
public ClientImpl() {}
public void run() {
Service s = (Service) lookupFc("s");
s.message();
}
}
ClientImpl is controlled by a primitive membrane, and the interfaces of all controllers included in this membrane are then visible. The programmer can thus call the lookupFc method which is implemented by the binding controller. The programmer does not have to implement the BindingController interface to manipulate bindings as this is the case with Julia. Instead, the programmer must tag the content class as a primitive component. This tagging takes the form of the implementation of the marker interface PrimitiveType. If the programmer wants to leave its content code free of any intrusion related to the component model, he can use an aspect which will declare the implementation (see the section Aspects for further information on this mechanism).
The previous class can then be rewritten as follows.
public aspect Conf {
declare parents:
ClientImpl implements PrimitiveType;
/*
* If needed, ClientImpl could be replaced by a regexp (e.g.
org..C*)
* to let several classes implement PrimitiveType.
*/
}
public class ClientImpl {
public ClientImpl() {}
public void run() {
Service s = (Service) lookupFc("s");
s.message();
}
}
While the structure of a Fractal component with AOKell relieves the programmer from the pain of implementing control interfaces, this structure can be problematic for reusing applications already written with Julia. In order to facilitate this, AOKell also provides a component structure which is more similar to the one of Julia where:
With the JL-structure, the previous class needs to be written as follows:
public class ClientImpl implements BindingController {
public ClientImpl() {}
public void run() {
Service s = (Service) lookupFc("s");
s.message();
}
public String[] listFc() { return new String[]{"s"}; }
public void bindFc(String itfName, Object target) {
if( itfName.equals("s") ) { s = (Service) target; }
}
public Object lookupFc(String itfName) {
if( itfName.equals("s") ) { return s; }
return null;
}
public void unbindFc(String itfName) {
if( itfName.equals("s") ) { s = null; }
}
private Service s;
}
Two structures of a Fractal component are available with AOKell: AO and JL. With the AO-structure, the control interfaces are directly injected into the content, and the programmer can use them directly. The JL-structure is similar to the one implemented by Julia, and facilitates the use of applications developed initially with Julia.
The section defines the basic notions and terms of AOP which will be reused throughout the remainder of this section. Starting from section 3.2, we present the 8 aspects which are currently available with AOKell.
The purpose of this section is not to give a thorough presentation of AOP, but just to remind the meaning of terms which will be used in the remainder of this section. These notions are illustrated with AspectJ (see the AspectJ Programming Guide for a detailed presentation of this language).
Most of the existing component controllers perform two simple things: interface injection, and method call interception. In terms of AOP, these two operations are referred to as introduction and code advising.
Introduction is a general mechanism provided by AOP languages to let the programmer inject code related to an aspect into one or several classes of an application.
The term introduction is referred to, in AspectJ, under the expression 'Inter-type declaration'. The idea is that a type (an aspect) declares code elements (fields or methods) on behalf of other types (the target classes where the introduction is to be performed). When writing an aspect, an inter-type declaration is almost similar to a member declaration, except that the name of the member is preceded by the name of the target class.
The following aspect illustrates the inter-type declaration mechanism of AspectJ.
public aspect MyAspect {
private String MyClass.name = "";
public void MyClass.setFcName( String name ) { this.name=name; }
public String MyClass.getFcName() { return name; }
declare parents: MyClass implements NamingController;
}
A field, name, and 2 methods, setFcName and getFcName, are introduced into MyClass. Notice that 'this' in the body of setFcName does not refer to the instance of the aspect, but to the instance of the target type (here MyClass). The last line of the aspect introduces an implementation relation: MyClass is now implementing NamingController.
To illustrate the usage of this aspect, one can now write the following class.
public MyClass {
public void run() {
MyClass mc = new MyClass();
mc.setFcName("foo");
NamingController nc = (NamingController) mc;
}
}
This class can be compiled by the AspectJ compiler, even though the setFcName method is not directly declared in the class, and the class does not directly implement NamingController. These code elements have been introduced into MyClass by the MyAspect aspect.
The target type of the introduction (in the example MyClass) is not necessarily a class. An interface can be used. In such a case, all the classes which implement the interface are the targets of the introduction. This is the way some members can be introduced in more than one target class.
The mechanism known under the term 'code advising' refers to the ability of defining treatments which will be applied to some selected locations, known as join points, in an application. The purpose of this mechanism is to modularize in an aspect the treatments which would be scattered in all these locations if a pure object-oriented, aspect free, language were used.
Several types of a join point exist: the two most common ones are call and execution join points. Call join points are locations where a method is called, whereas executions join points are locations where a method is executed. The AspectJ language supports several other types of a join point: set (field write), get (field read), initialization (constructor execution) preinitialization (inherited constructor execution), staticinitialization (static block execution), handler (entering in a catch block), adviceexecution (execution of an advice code), cflow (control flow).
AOP provides the notion of a pointcut which is a set of join points. This set is declared with a pattern language which includes Boolean operator and wildcards to select join points.
Given an advice code and a pointcut, the advice code can be executed before, after or around the join points picked out in the pointcut.
The following aspect illustrates the definition of a pointcut and of an advice code.
public aspect MyAspect2 {
pointcut methodUnderLifeCycleControl():
execution( * *.*(..) ) && !controllerMethods();
pointcut controllerMethods(): /* ... */;
before(): methodUnderLifeCycleControl() {
Object adviced = thisJoinPoint;
if( adviced /* is stopped .... */ )
throw new RuntimeException("Component stopped");
}
Two pointcuts are defined. The methodUnderLifeCycleControl pointcut designates the executions of 'business' methods, i.e. methods which are not control methods. Before the execution of these business methods, an exception is thrown if the component is stopped.
The details of the AspectJ syntax follow. The methodUnderLifeCycle pointcut includes all join points which are executions of any method defined in any class and which are not join points included in the controllerMethod pointcut (this last pointcut is left undefined for clarity sake). The keyword thisJoinPoint in the advice code designates the current instance of a join point. This keyword returns an instance of org.aspectj.lang.JoinPoint which is the introspection API of AspectJ.
Apart from the ALifeCycleAspect which will be presented in the next section, all the other existing aspects with AOKell only perform inter-type declarations: they introduce into components the control interface they are associated with. Six such aspects exist: ABindingController, ANamingController, ASuperController, AContentController, AAttributeController and AFactory.
These aspects rely on the membrane type hierarchy presented in the section Membrane Types to perform introductions. For example, ABindingController performs introductions on all membranes which implement the BindingType marker interface.
As said in the section Structure of a Component, these aspects do not implement directly the controller, but introduce a Delegator pattern: the introduced methods delegate the calls to an instance of a Java class. In our opinion, this kind of "best practice" for implementing controllers has several advantages:
The ALifeCycleAspect aspect is different from aspects presented in the previous section in the sense that, in addition to introducing the LifeCycleController interface for starting and stopping the components, this aspect controls the execution of the components.
The semantics of the control perform by the lifecycle controller is out of the scope of the Fractal Specifications. The idea is that the needs in terms of lifecycle may vary with the application domain (e.g. the lifecycle of a "real-time" component for embedded devices would certainly not be applicable to a business component in a CRM application). The semantics of the lifecycle controller is thus implementation dependant. With Julia for instance, method calls on a stopped component are blocked until the component is started.
With AOKell, the lifecycle controller throws a runtime exception if a call is issued on a stopped component. When a composite component is started or stopped, the operation is recursively propagated on all components contained in the composite.
In order to promote flexibility, the AOKell framework has been decomposed in several different modules called features. The purpose of this decomposition is to introduce some degrees of variability in the framework and to let developers change the implementation of these features. So far, three features exist:
Different implementations of these features are provided with AOKell. While a default implementation is provided for each feature, the developer can still choose an alternative version or provide her/his own version by configuring the properties defined in the build.properties file and recompiling AOKell.
Fractal components provide and require interfaces. These interfaces are associated with a signature (defined with a Java interface), a cardinality (singleton or collection), a contingency (mandatory or optional) and may be client (required) or server (provided). With AOKell these Fractal interfaces are Java classes which implement the Interface interface and the Java interface defined in their signature.
The fcinterface feature is concerned with the way these classes are generated. Two versions of the feature exist:
The default version of this feature is rt. The rt version is more dynamic: Fractal interface signatures can be determined at very lately, at run-time, just before instantiating the component.
With the ct version, all Fractal interfaces are defined at compile-time and the developer can not use at run-time an unforeseen interface. This version is then less flexible. However, with this version, ASM is not needed. In many cases, this simplifies the merging of AOKell with other existing framework, especially those which themselves, perform bytecode engineering or class loading. For example, this version has been used to port FROGi to AOKell.
Two dimensions exist when programming Fractal component: the business part which deals with the core functionalities provided by the component, and the control part which deals with the way components are managed.
The glue feature deals with the way these two parts are glued together. So far, only one version of this feature exists (other versions may be provided in future releases of AOKell):
As with Julia, Fractal components may be associated with a Monolog logger. When this feature is enabled, each primitive component is bound to a logger instance and a monolog-factory instance. These instances can be retrieved by calling the lookupFc method provided by the BindingController interface.
The loggable feature is concerned with whether this feature is enabled or not. Two versions of the feature exist:
Control membranes defines the way components are managed.
The membrane feature is concerned with the way membranes are implemented. Two versions of the feature exist:
The following sub-sections provide more details about the componentization of membranes. Notice that, in both cases the implementation code of controllers is similar. The difference lies in the way the membrane is constructed: a simple list of objects in the first case, and a composite component with sub-components, interfaces and bindings in the second case.
Each membrane is decomposed into a set of controllers. The purpose of this decomposition is to separate the various functionalities involved (lifecycle, binding, naming, etc.) and to make them more reusable in different types of a membrane. However, dependencies exist between controllers which prevent their reuse. For example, when considering a flat membrane which provides a component, a naming, a binding and a lifecycle controllers, the following dependencies can be found:
Several other dependencies can be defined when considering the other membrane types such as primitive and composite. Notice that these dependencies depends on the semantics chosen for each controller. A different control logic may lead to different dependencies.
In our opinion, a pure object-oriented approach is not adequate for capturing these dependencies. The best solution that could be designed would be to declare references and to provide methods for setting and unsetting these references. Yet, this solution is not satisfactory as the dependencies are tangled with the rest of the code. A better solution is to adopt a component-oriented approach and to isolate these dependencies into a software architecture. The solution implemented in AOKell is then to provide a component-oriented approach for implementing membranes:
Figure 3 illustrates this approach.
Fig 3: Componentized membranes
When designing control membranes as components, the expected benefits are the same as the ones expected when designing an application with components: to foster the reuse of components (controllers) and to facilitate the evolution of the application (the control logic) by defining explicitly existing relations between components.
Once the principle of defining the control membranes with components and bindings has been set up, all the notions and tools defined by Fractal can be reused. Among others, the Fractal API and the Fractal ADL are the two best candidates. Hence the architectures of the 13 existing membrane types in AOKell have defined with Fractal ADL. Figure 4 illustrates the architecture of the flat membrane. The Fractal ADL definition follows.
Fig 4: Architecture of the flat membrane type
<definition name="aokell.lib.membrane.flat.Flat"
extends="aokell.lib.control.component.ComponentControllerType,
aokell.lib.control.name.NameControllerType,
aokell.lib.control.lifecycle.LifeCycleControllerType,
aokell.lib.control.binding.BindingControllerType" >
<component name="Comp"
definition="aokell.lib.control.component.ComponentController"
/>
<component name="NC"
definition="aokell.lib.control.name.NameController" />
<component name="LC"
definition="aokell.lib.control.lifecycle.NonCompositeLifeCycleController" />
<component name="BC"
definition="aokell.lib.control.binding.FlatBindingController"
/>
<binding client="this.component" server="Comp.component" />
<binding client="this.name-controller" server="NC.name-controller" />
<binding client="this.lifecycle-controller"
server="LC.lifecycle-controller" />
<binding client="this.binding-controller"
server="BC.binding-controller" />
<binding client="Comp.binding-controller"
server="BC.binding-controller" />
<binding client="BC.component" server="Comp.component" />
<binding client="LC.binding-controller"
server="BC.binding-controller" />
<binding client="LC.component" server="Comp.component"
/>
<controller desc="mComposite" />
</definition>
The previous ADL piece of code defines 4 components (controllers) and 8 bindings. 4 of them are export bindings and the next 4 are normal bindings between components. In addition, the Flat component is of type mComposite.
mComposite (resp. mPrimitive) is a new controller description which is defined by AOKell for designating composite (resp. primitive) components which implement a control function.
We won't go into the details of the other 12 membranes. Their definitions can be find in the AOKell source code (see package aokell.lib.membrane).
When instantiating a component, the component factory needs to create a membrane (composite component), create the content, and then, link the content to the membrane. A factory is provided by AOKell to create membranes. This factory is implemented as an interface (membrane-factory) provided by the bootstrap component. The Java definition of this interface follows.
Fig 5: AOKell bootstrap component
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.factory.InstantiationException;
public interface MembraneFactory {
/**
* Return the membrane associated with the given controller description.
*/
public Component newFcMembrane( Object controllerDesc ) throws InstantiationException;
}
The implementation of the membrane factory relies on the generic component factory. Indeed, few differences exist between business component and control components. They both provide and require interfaces, they are bound with other components, and their architecture is defined with Fractal ADL.
In order to save execution time, the ADL definition of the membranes is compiled into Java code with the static backend provided by Fractal ADL. Indeed, parsing the ADL definition of the membrane for each newly created business component is costly whenever numerous business components, and then componentized membranes for these components, need to be created. By parsing and compiling membrane definitions once, we save a significant amount of execution time.
The rationale for defining control membranes and controllers with components and bindings is to provide a powerful mean to engineer the control dimension of the component model. The idea is that different applications will have different needs in terms of control. The functionalities needed to control embedded real-time components is certainly not the same as the one required by components for information systems. Yet, few component models tackle the issue of engineering the control dimension. AOKell addresses this issue by providing the same notions (components and bindings) for engineering the control dimension and the business dimension. The glue between these two dimensions is provided by aspects. By offering developers powerful means to program several different control membranes, we hope to promote adaptability and to ensure that applications will be better integrated within various different execution contexts.
However, as controllers are programmed as components, the issue of the control functions applied to controllers can be raised. This leads to a three-level model where M0 is the business level, M1 is the level controlling M0 and M2 is the level controlling M1 (see Figure 6).
Fig 6: Control layers
As the layering of control functions can not be infinite, we have to provide a way to stop the recursion. Basically, two solutions can be designed:
The second solution has been implemented with AOKell. The rationale for this choice is that, although we need to adapt the control policy to several application domains and execution contexts, the control of controllers is an application domain per se, and is unlikely to be subject to tremendous chances over time. Hence, although less flexible, the ad-hoc solution chosen for level M2 is also certainly more efficient than a fully open and reflective solution.
The feature mechanism provide some degrees of variability and allow the developers to customize the behavior of AOKell. The default feature configuration is: fcinterface rt, glue aspectj, loggable off, membrane component. By configuring the properties defined in the build.properties file and recompiling AOKell, the developer can choose his/her own version.
The source code of AOKell is organized in four modules:
All aspects are packaged in aokell-aspect.jar. The other modules only contain classes and interfaces. These modules can not be used independently: aokell-aspect, aokell-component and aokell-tools use classes and interfaces defined in aokell-lib. The components in aokell-component are aspectized by aspects contained in aokell-jar.
Fig 7: Package dependencies.
The AOKell code has been separated into these three jars to facilitate extensions. Extensions can take three forms: development of new aspects (controllers), development of new components, or extension of the library.
AOKell jar size occupation is 159KB (compared to 180KB for Julia 2.2): 19KB for aokell-aspect.jar, 3KB for aokell-component.jar, 102KB for aokell-lib.jar, and 35KB for aspectjrt.jar which is the standard library required to run any application compiled with AspectJ.
This section reports on the tests and the applications which are available with AOKell.
Julia is distributed with a set of 131 JUnit compliance tests. On the 131 tests, 125 run successfully with AOKell. This section comments on the 6 tests where the behavior of AOKell differs from that of Julia.
The test testParametricPrimitiveTemplate in TestComponent reports an error, because the setter method for the attribute X11 is named setWriteOnlyX11. As specified in the Fractal Specifications, AOKell expects a setter method named setX11. In our opinion, the problem lies with the test, not with AOKell.
The test testStarted in TestLifeCycleController assumes that a method call on a stopped interface hangs. This is not an issue related with the Fractal Specifications but with the semantics chosen by Julia for lifecycle controllers. AOKell chooses instead to throw an exception. This test is then not a Fractal test, but a Julia specific one.
Two tests, testCompositeSelfBindLookupUnbind and testCompositeCollectionSelfBindLookupUnbind, in TestBindingController report an error. The issue needs further investigations, but it seems that the test tries to bind a server interface to another server interface. This is not permitted with AOKell.
The test testWouldCreateNonLocalImportBinding in TestContentController fails. It seems that the test tries to bind a mandatory interface to an optional one. This is not permitted with AOKell.
The test testRemoveNotStopped in TestLifeCycleController fails because AOKell does not automatically starts components when they are added in a composite, which is what is assume by the test. As far as we understand the Fractal Specifications, this is a Julia specific behavior.
The following applications are known to run with AOKell:
Some controllers, originally developed with Julia, have also been successfully implemented with AOKell:
This initial list of applications and controllers running with AOKell is permanently under construction and we welcome any proposal for extending it.
In this section, we compare the performances of AOKell with those of Julia. 2 tests suites are used: the one known as JACBenchmark, and the performance tests of Julia.
The purpose of our benchmarks is to evaluate the overhead of running a Fractalized application with AOKell. The purpose is not to evaluate the time needed to compile an AOKell application, nor to evaluate the time taken by control operations (such as starting or stopping a component). The times we are measuring are the ones experienced by an end user who is running an "AOKellized" application.
JACBenchmark is a benchmark which we have developed for AOP applications. The benchmark has been adapted to support Fractal components. The benchmark contains a composite and two primitive components: a client and a server. The server component implements an interface with 8 different methods. Each method implements a different signature. The methods are not empty, but do not perform any interesting stuff (empty methods could distort the benchmark). A warm-up procedure is executed before taking any measures to avoid side-effects introduced by the JVM.
The client component issues one million calls on each method of the server interface (total: 8 million calls). The procedure is repeated 4 times. The result of the benchmark is the mean time of the 4 measures. The measures were taken on a 1.5GHz PC running Windows XP Pro and Sun JDK 1.5.0.
Table 1 compares the results of the current version of AOKell (1.0) to those of Julia. The performances of the two structures, AO and JL, of a component with AOKell are measured. The performances of two Julia optimization levels, NONE and MERGEALL, are also measured. The optimization level of Julia known as MERGEALL consists in merging the content, the controller and the interceptors. We have also measured the cost of the interception performed by the frameworks.
The performances of AOKell 1.0 with the AO-structure are comparable to those of Julia 2.1.1 with the optimization level NONE. The performances of AOKell 1.0 with the JL-structure are comparable to those of Julia 2.1.1 with the optimization level MERGEALL.
Notice that the performance of AOKell are the same whatever the chosen features are. Indeed, the 3 features mentionned in Section Features only impact the execution time of control functions, not the execution time of business methods. Hence, it is worth noticing that there is no cost, in terms of business method execution, in using componentized membranes compared to using membranes with plain old Java objects.
Implementation |
Time (in ms) | ||
interception | no interception | ||
Pure Java 1.5.0 | 168 | ||
AspectJ 1.2.1 | 206 | ||
AOKell 1.0 | AO | 506 | 212 |
JL | 403 | 212 | |
Julia 2.1.1 | NONE | 512 | 234 |
MERGEALL | 400 | 234 | |
JBoss AOP 1.1.1 | 1046 |
Tab 1: Cost of invoking and executing an operation (x 8,000,000).
As a matter of comparison, Table 1 gives the execution time of the same benchmark in pure Java (no Fractal components), in AspectJ 1.2.1 and in JBoss AOP 1.1.1. For these last two cases, an empty around advice has been woven on the server component. Compared to the Java version, the AOKellization of an application multiplies by 2.4 (JL) or 3 (AO) its execution time. Most of this overhead comes from the interception process which is performed by the lifecycle controller.
This document presents AOKell which is INRIA and France Telecom's implementation of the Fractal component model. This is a full Java implementation (level 3.3) of the Fractal Specifications.
The difference between AOKell and other existing implementations is that AOKell uses Aspect-Oriented Programming and the AspectJ language for implementing controllers and membranes. In our opinion, compared to other techniques such as mixins, this leads to a controller development style which is easier to understand, debug and maintain. We have shown in this document that, while providing a high level of abstraction for programming controllers as aspects, Fractal applications developed with AOKell do not suffer from runtime penalties: performances of AOKell applications are similar to those developed with Julia.
We believe that this experiment shows that AOP and AspectJ are mature tools for engineering complex applications such as the ones developed with Fractal components.
[1] E. Bruneton, T. Coupaye, M. Leclercq, V. Quema,
J.-B. Stefani. An Open Component Model and Its Support in Java. 7th
International Symposium on Component-Based Software Engineering (CBSE-7),
LNCS 3054, pp. 7-22, May 2004, Springer.
[2] G. Kiczales, J. Lamping, A. Mendhekar, C. Maeda, C.
Lopes, J.-M. Loingtier, J. Irwin. Aspect-Oriented Programming. 11th
European Conference on Object-Oriented Programming (ECOOP'97), LNCS 1241, pp.
220-242, June 1997, Springer.
Lionel Seinturier,
Nicolas Pessemier,
Thierry Coupaye.
Last modified:
11/01/2006.