aspect-oriented programming workshop icse'98 - Semantic Scholar

32 downloads 0 Views 3MB Size Report
Cristina Lopes, Gail Murphy, and Gregor Kiczales .... Clarke and J. Murphy. ...... [3] Craig Thompson, Ted Linden and Bob Filman, “Thoughts on OMA-NG: The ...
PROCEEDINGS OF THE

ASPECT-ORIENTED PROGRAMMING WORKSHOP AT

ICSE’98 Organizers: Cristina Lopes, Gail Murphy, and Gregor Kiczales

http://www.parc.xerox.com/aop/icse98

Includes an overview of the workshop the position papers.

The overview of the workshop was published in Proceedings of the 20 th International Conference on Software Engineering, Volume II, April 1998, Kyoto, Japan. IEEE Computer Society.

The position papers are copyrighted by their authors. All rights are reserved.

Workshop on Aspect-Oriented Programming Cristina Videira Lopes Gregor Kiczales Xerox Palo Alto Research Center 3333 Coyote Hill Rd. Palo Alto, CA 94304, USA +1 (650) 812-4498 {lopes, gregor}@parc.xerox.com

Gail Murphy University of British Columbia Dept. of Computer Science Vancouver Canada [email protected]

ABSTRACT This is a preview of the workshop on Aspect-Oriented Programming at ICSE 98. It includes an overview of the position papers. The workshop takes place on Monday, April the 20th 1998. Keywords Aspect, component, code tangling, aspect weaving. 1 STATEMENT OF WORK Mechanisms for defining and composing abstractions are essential elements of programming languages. They allow programs to be composed up from smaller units, and they support design styles that proceed by decomposing a system into smaller and smaller sub-systems. The abstraction mechanisms of most current programming languages – subroutines, procedures, functions, objects, classes, modules and APIs – can all be thought of as fitting into a generalized procedure call model. The design style they support is one of breaking a system down into parameterized components that can be called upon to perform a function. But many systems have properties that don’t align with the system’s functional components. Failure handling, persistence, communication, replication, coordination, memory management, real-time constraints, and many others, are aspects of a system’s behavior that tend to cut-across groups of functional components. While they can be thought about and analyzed relatively separately from the basic functionality, programming them using current component-oriented languages tends to result in these aspects being spread throughout the code. The source code becomes a tangled mess of instructions for different purposes.

Arthur Lee Korea University Dept. of Computer Science Seoul 136-701 Korea +82-2-3290-3196 [email protected]

This “tangling” phenomenon is at the heart of much needless complexity in existing software systems. It increases the dependencies between the functional components. It distracts from what the components are supposed to do. It introduces numerous opportunities for programming errors. It makes the functional components less reusable. In short, it makes the source code difficult to develop, understand and evolve. A number of researchers have begun working on approaches to this problem that allow programmers to express each of a system's aspects of concern in a separate and natural form, and then automatically combine those separate descriptions into a final executable form using automatic tools. These approaches have been called AspectOriented Programming (AOP). The purpose of this workshop is to bring together researchers and practitioners working on a wide range of AOP techniques, including languages, tools, frameworks, programming styles, etc. 2 SUBMITTED PAPERS This section presents an overview of the position papers received until the elaboration of this summary. “Formalizing adaptability aspects”, M. Aksit and B. Tekinerdogen. This paper studies the sorting and the adaptability aspects and their object-oriented implementations. It is shown that transforming aspects into the object-oriented model results in loss of information. Because of the mismatch between the aspect and the object-oriented models, aspect weaving and language transformation operations are generally ill conditioned. In the object-oriented implementation some of the aspects are not separable. Performance is also taken into account. The performance aspect can be added by weaving the performance, adaptability and sorting aspects together. Weaving and the transformation operation are expressed in the object-oriented model. The authors suggest the presented formalism is suitable for expressing various aspects, and can be a basis to defining aspectoriented analysis and design models.

“Quality of service – aspects of distributed programs”, C. Becker and K. Geihs. This paper shows an aspect-oriented approach for QoS integration in CORBA. By using enhanced IDL and its target language (i.e. C++) as aspect languages for QoS, the conceptual changes to the original CORBA are kept small. The presented system does not need an explicit weaver or specialized languages for aspects, but still provides a clear separation of concerns and this an aspect-oriented view on QoS. The goal of this work is to reduce the complexity of distributed systems and to show that aspect-oriented programming is an appropriate paradigm for the integration of non-functional aspects such as QoS. “Interactions between objects: an aspect of object-oriented languages”, L. Berger, A. M. Dery and M. Fornarino. The authors argue that object interactions should be viewed as an extensible aspect of object-oriented languages. The paper proposes an aspect language called IL (Interaction Language) to describe the interactions between objects. The aspect approach, when possible, gives a higher level of specification better adapted to the developers. Viewing interactions between objects in terms of an aspect of objectoriented languages allows a separation between interaction language and the component language. “Developing a tool to support the application of aspectoriented programming principles to the design phase”, S. Clarke and J. Murphy. Integrating the technical functionality and the business functionality of a system, both at the design and the coding level, increases the complexity of the design models or the code. This paper presents a tool that applies AOP techniques at the design level. The current version of the tool supports the creation of an aspect program in a graphical manner, from the design model. The authors now consider a more flexible mechanism to support the design of an aspect’s semantics. “Injecting ilities”, R. Filman. This paper discusses the use of AOP technology to impose system-wide properties on distributed systems. Tools such as CORBA have enabled programmers to code the specification of objects and methods; but elements such as security or reliability are still the responsibility of the application programmer, and likely to be done incorrectly or incompletely. The work in this paper is aspect-oriented in that it separates the tasks of creating the actual domain application from the code that produces security, reliability, and such ilities. “Mixin composition strategies for the modular implementation of aspect weaving”, Y. Roudier and Y. Ichisugi. EPP (the Extensible Preprocessor) was designed to introduce new language constructs by the mere addition of plug-in modules that can also define new syntax and macros. The relation of EPP and AOP is two-fold. First, the EPP kit has been programmed using the Ld-2 language, which introduces AOP constructs: system mixins. Second, the authors

suggest that EPP could be used to program aspect-oriented weavers in a modular way. “Extending aspect-oriented programming in order to flexibly support workflows”, R. Schmidt and U. Assmann. The authors describe a dilemma in designing architectures for workflow support. Approaches based on virtual machines are flexible in adapting to workflow changes, but suffer in terms of performance. Architectures that directly implement workflows offer good performance, but are inflexible in adapting to workflow changes. The paper suggests that combining AOP and the decomposition of workflow aspects allows an escape from this dilemma. “Assessing aspect-oriented programming and design”, R. Walker, E. Baniassad and G. Murphy. This paper reports on an experiment designed for assessing the claims of AOP. The authors obtained data comparing the use of an AOP language vs. an OO language. The experiment highlighted the usefulness of being able to easily express and understand synchronization code. It is noted that the users of the AOP language AspectJ were able to complete debugging tasks with fewer instances of semantic analysis which seemed to lead directly to less switching between files, and ultimately to quicker completion times. The authors conclude that there are times at which it is useful for synchronization code to be embedded in the core functionality, but that at times work can be speeded considerably when synchronization code is separated from the rest. “An abstract view of computational reflection”, T. Watanabe. This paper presents a formal definition of computational reflection using abstract rewriting systems. The author uses the notion of an abstract implementation between abstract rewriting systems that realizes the “meta” relation introduced informally by B. C. Smith. The definition is independent from any particular computation models and can capture important concepts of computational reflection. The paper relates to AOP in that the whole motivation in building a reflective system is to make its base level computation perform effectively by observing and/or altering itself at the meta level. 3 INFORMATION AND QUESTIONS For more information, contact the workshop’s organization at [email protected], or see the workshop’s home page (http://www.parc.xerox.com/aop/icse98). We look forward for a productive and fun workshop!

Formalizing adaptability aspects Mehmet Aksit and Bedir Tekinerdogan University of Twente Department of Computer Science P.O. Box 217 7500 AE Enschede, The Netherlands e-mail: {aksit, bedir}@cs.utwente.nl

1. Definitions In [Kiczales et al. 97], aspects are defined as properties that affect the performance or semantics of the components in systemic ways. Systemic characteristic of aspects implies that they can be considered as concepts. The term performance is a special case of the general term quality. Other quality examples are adaptability and reusability. From this point of view, aspects are concepts which affect the quality and/or semantics of software components. We define the term software component as a programming language abstraction. Examples of software components are procedures, data structures and objects. Programming languages are vehicles to express abstract executable mechanisms. An aspect language is a language whose abstractions can directly represent one or more aspects. A trivial aspect is an aspect, which can be directly represented by a software component. This means that an aspect can show up as a software component (or can become trivial) if a suitable programming language can be designed for that aspect. Aspect weaving1 is a cross product among two or more aspects, and software components. An aspect weaving process can be defined as MXAà

R

Here M is a model,

A

is an aspect,

X

is the weaving operator, à is the transformation process and

R

is the

result. Structure preserving weaving is a weaving process without ill transformations. An ill transformation is a transformation, which has one or more of the following problems: not expressible aspects, non-separable aspects, non-composable aspects, and scattered aspects. In non-expressible aspects, the result of a transformation becomes less expressive than before. In non-separable aspects, aspects are tangled and therefore cannot be individually used and extended. In non-composable aspects, although explicitly desired, a transformation cannot compose semantics of aspects together. In scattered aspects, one or more aspects are scattered over different software components or aspects.

1

An aspect weaving process is a cross product operation, whereas component composition is generally attaching components together.

2. Example Problem: Adaptable Sorter Sorting is the process of arranging items in order. Different kinds of sorting algorithms have been defined in the literature such as card sort, swap sort, bubble sort, select sort, quick sort, etc. The suitability of a sorting algorithm generally depends on the context of the application, sorting criterion, data structure, etc. A sorting algorithm can be defined as

S = (CF, RN, RW, CR),

sorting, RW is the accessing (read-write) operation, and

CR

where CF is the control-flow, RN is the range of

is the sorting criterion.

Adaptability can be defined as A = (FX, AD), where FX represents the fixed concerns, and

AD

represents the

adaptable concerns. Adaptable sorter is defined as AS = S X A = (CF, RN, RW, CR) X (FX, AD). Here, adaptable sorter (AS) represents a list of all combinations of sorting and adaptability aspects. For example, the element ( CF.FX) means that the control-flow of the sorting algorithm is fixed, and (CR.AD) means that the sorting criterion is adaptable. The next concern is coupling

CP,

which defines relations between the elements of the adaptable sorter. All

possible couplings between the elements of the adaptable sorter is defined as:

CPAS = (AS)

2

For example, ((CF.FX).(CR.AD)) is the coupling between the fixed control flow and the adaptable comparison criterion. Object-oriented modeling of the sorter means mapping its elements into object-oriented language abstractions. For example, fixed elements can be implemented using statements and adaptable elements are either classes or objects. The coupled fixed elements can be in-lined together, and the coupling between adaptable and fixed elements can be implemented using message passing or inheritance.

2.1. Object-oriented implementation of the adaptable sorter The adaptable sorter has been defined as: AS = S X A

= (CF, RN, RW, CR) X (FX, AD).  CF.FX CF.AD    RN.FX RN.AD  AS =  RW.FX RW.AD   CR.FX CR.AD 

It is assumed that the following elements of the adaptable sorter are of our interest: AS1 =

((CF.FX), ( RN.AD), (RW.AD), (CR.AD))

Now we will define the couplings between these elements: CPAS1 = (AS)

2

= ((CF,FX), ( RN.AD), (RW.AD), (CR.AD))2

 (CF.FX).(CF.FX) (CF.FX).(RN.AD) (CF.FX).(RW.AD) (CF.FX).(CR.AD)    (RN.AD).(CF.FX) (RN.AD).(RN.AD) (RN.AD).(RW.AD) (RN.AD).(CR.AD)  CPAS1 =  (RW.AD).(CF.FX) (RW.AD).(RN.AD) (RW.AD).(RW.AD) (RW.AD).(CR.AD)   (CR.AD).(CF.FX) (CR.AD).(RN.AD) (CR.AD).(RW.AD) (CR.AD).(CR.AD) 

The elements coupled with themselves, can be neglected. Further, it is assumed that couplings are symmetric. This results in the following simplified matrix:   (RN.AD).(CF.FX) CPAS1 =  (RW.AD).(CF.FX) (RW.AD).(RN.AD)  (CR.AD).(C F.FX) (CR.AD).(R N.AD) (CR.AD).(R W.AD) 

-  - -  -

The following implementation knowledge is available: Possible control-flow algorithms are CF =

((CARD SORT), (SWAP SORT), (BUBBLE SORT), (SELECT SORT), (QUICK SORT), ..)

The fixed elements and couplings among them can be implemented as methods and in lining, respectively. The adaptable elements are classes (or objects). The couplings among fixed and adaptable elements are message passing or inheritance. Let us assume that the element

CF

is selected as the bubble sort algorithm. The couplings among the fixed

elements are in lined. The couplings among the fixed and adaptable elements are implemented as inheritance relations. This results in the following implementation of the sorting algorithm: collection::sort temp: Element; i,j,length : Integer; length:=self.range; "Range" for i:=1 to length-1 do for j:=length downto i+1 do if self.compare( self.get(i), self.get(j)) then begin temp:= self.get(i); self.put(self.get(i), self.get(j); "Update" self.put(self.get(j), temp); end; end; end; end;

"Compare" "Indexing

Figure. Implementation of the sorting algorithm The range, sorting criterion, read and write concerns are implemented by the methods range, compare, get and put, respectively. A self call allows the subclasses to specialize the corresponding method. In this implementation, the couplings ((RW.AD).(RN.AD)),((CR.AD).(RN.AD)), ((CR.AD).(RW.AD)) are not shown in the algorithm. If message passing is used as an implementation of couplings among fixed and adaptable elements, then self calls have to be replaced by message sends to the corresponding objects. Of course, a

mixture of inheritance and message passing couplings can be used. If all the elements are fixed, then the implementation is a single algorithm without inheritance or message passing.

3. Discussions and Conclusions In this paper we have considered the sorting and adaptability aspects and their object-oriented implementations. It is shown that transforming aspects into the object-oriented model results in loss of information. Because of the mismatch between the aspect and object-oriented models, aspect weaving and language transformation operations are generally ill conditioned. In the object-oriented implementation, some of the aspects are not separable. For example, after defining the sorting algorithm as shown in the figure, it is not possible to change couplings from inheritance to message passing implementations unless the whole algorithm is rewritten. Obviously, there are other important aspects such as performance. The performance aspect can be added to the sorter by weaving the performance, adaptability and sorting aspects together. This will generate many additional combinations. The performance of an implementation can be improved by using the following 3 criteria: implementing the efficient alternative, by run-time dispatching or by prioritization. In case most efficient alternative is selected, then all the elements of the sorter must be fixed and in lined. This will of course reduce the adaptability of the sorter. In the criterion run-time dispatching, the performance affecting alternatives must be made adaptable, and a decision-maker must select the most efficient one. The prioritization approach requires a real-time language and operating system to control the executions based on priorities. Obviously, many of the alternatives conflict with each other. During the mapping process, the most appropriate alternatives must be selected based on the requirements and the design context. Due to space limitation, we will not discuss performance aspects in this paper. In this paper we have formulated the sorting and adaptability aspects. We have expressed the weaving and the transformation operation into the object-oriented model. We think the presented formalism is suitable in expressing various aspects, and can be a basis to define aspect-oriented analysis and design methods.

References Kiczales et al. 97 G. Kiczales, J. Lamping, A. Mendhekar, C. Maeda, C. Lopes, J-M. Loingtier and J. Irwin, Aspect-Oriented Programming, ECOOP’97 Conference proceedings, LNCS 1241, June 1997, pp. 220 – 242.

Quality of Service - Aspects of Distributed Programs Christian Beckery Kurt Geihs University of Frankfurt/Main Computer Science Department (beckerjgeihs)@informatik.uni-frankfurt.de February 20, 1998 Keywords:

Aspect Oriented Programming, QoS, Object-Oriented Middleware, CORBA

Abstract

Modelling and implementing distributed systems leads often to the same problems. By ignoring partial failures, dynamic changes in bandwiths, security issues etc. object-orientation provides a very well suited abstraction. But when actually dealing with the aspects arising from the distribution, former clear designs loose their elegance. Little or none support is provided by current implementations. Quality of Service (QoS) handling provides mechanisms to integrate the handling of distribution aspects separated from the service implementation. We will motivate QoS as aspects of distributed programs. By extending OMG IDL we provide QoS integration in object-oriented middleware in a generic manner such that the service itself is little a ected.

1 Introduction Quality of Service (QoS) addresses the non-functional issues of services in distributed processing systems. QoS concerns originate from distribution e ects such as transmission errors, dynamic bandwidth

uctuation, overload situations, partial failures, etc. Obviously, these issues reduce the amount of distribution transparency that can be achieved in a distributed system. Nevertheless, QoS management for distributed applications has received more and more attention since new application requirements related to e.g. multimedia or fault tolerance demand an explicit handling of QoS issues. The object model is a popular conceptual base model for the design and implementation of distributed systems. Object-oriented middleware such as CORBA is available that supports the construction and operation of distributed object systems. Distribution transparency is one of the major design goals. However, the management of QoS has not been an issue in the initial development of such systems. Only lately there is a growing interest in integrating QoS in e.g. CORBA platforms. QoS concerns the non-functional issues of a service. It refers to performance attributes that are in general not explicitly visible in the service interface. Instead, client and server need orthogonal means to specify and manage QoS as part of their service association. We argue that QoS should be seen as an aspect in the sense of Aspect-Oriented Programming (AOP). Thus, it should be speci ed in an appropriate language. We  This work has been funded by the DFG under SFB 403 y Robert Mayer Str. 11-15, 60325 Frankfurt/Main, Germany,

1

Tel.: (+49)69 -798-23975 Fax: -22643

2 QOS AS ASPECTS OF DISTRIBUTED PROGRAMS

2

will show that this can be done together (but separately) with the application speci cation, and can be integrated into the application implementation by means of a QoS integration framework. In this paper we will discuss QoS as an aspect of distributed programs, and we will show how CORBA can be extended by QoS management. This includes IDL enhancements and a general QoS framework which supports the integration of QoS categories into CORBA applications.

2 QoS as Aspects of Distributed Programs Figure 1 illustrates our view of QoS in client-server systems. A service o ers a functional interface to clients. Additionally, QoS guarantees may be provided such that the client can rely on certain qualities when the service is performed. In general, many di erent QoS categories can be distinguished in distributed systems, e.g. real-time constraints, system availability, or sound quality. QoS management requires QoS handling operations at the client and the server, e.g. to monitor the status or negotiate QoS guarantees. The middleware, e.g. the ORB, must support these operations. The QoS together with the service functionality form the contract between client and service. While existing QoS approaches tend to mix these concerns and to restrict themselves to the handling of a single QoS category, we aim at an open architecture that is capable of supporting many QoS categories in a generic way. QoS 1

QoS 2

...

QoS n

Client

Functional Interface

QoS-Aspects

Service

Contract

g. 1 QoS and functional interface

To distinguish the di erent meanings of QoS let us give some terminology de nitions. A QoS category denotes a class of QoS, such as fault tolerance or real time. A QoS characteristic identi es a speci c QoS in a QoS category, such as a replica group in fault tolerance. A speci c QoS consists of a QoS interface with QoS related operations availiable to a client and a QoS attribute which contains the QoS parameters specifying the state of that speci c QoS. These de nitions might suggest, that QoS can be modelled in abstractions like classes in object-oriented programming. However, it turns out that the integration of QoS in existing programming languages or interface de nition languages cannot be encapsulated completely. QoS is a pervasive element of the client, service, and middleware programs. An example are replica groups. A speci c QoS for replica groups contains a QoS attribute containing the QoS parameters - here: a list of computers where replicas should be running - and a QoS interface with QoS related operations, e.g. group manipulations etc. The user of such a speci c QoS expects simple reuse, e.g. by inheriting the service implementation from the QoS implementation. Unfortunately this is not possible since a replica QoS must consist of a state transferring operation to keep newly started replicas in virtual synchronity. Similar examples can be found for other speci c QoS as well. The abstractions provided by object-oriented programming are not sucient to encapsulate QoS. Therefore QoS is an aspect in the sense of AOP[5].

3 QIDL

3

Though QoS management can not be encapsulated entirely, we believe that object-oriented principles can help in integrating QoS. The operations visible to clients of a QoS enabled service can be encapsulated in the QoS interface. The state of a QoS is described by the QoS attribute. The aspect QoS is therefore modelled by its interface description without regarding its implementation. The assignment to services is done by an integration into the interface de nition language (IDL). Instead of using an AspecWeaverTM we generate QoS elements in a framework by the IDL compiler1 . The aspect language for QoS is IDL for the QoS de nition and the implementation language for the QoS implementation.

3 QIDL Enhancing CORBA for QoS management should not violate the underlying design principles. A key concept in CORBA is the separation between interfaces and their implementation by using an interface de nition language. We extend OMG IDL by QoS de nitions and call the resulting interface de nition language QIDL. Therefore QoS implementations are separated from their interface (QoS interface and QoS attribute). The QoS de nitions are designed under respect to a broad variety of di erent QoS. The QIDL compiler can assist the user in implementing QoS enabled services. Thus we do not have to introduce new languages or weaving tools. In the following, we give a brief description of QIDL and its mapping to implementation languages like C++. More detailed information can be found in [2].

3.1 QoS De nitions in QIDL A QoS de nition in QIDL allows the speci cation of a speci c QoS attribute and interface. Both are de ned by a newly introduced syntactical construct. These QoS constructs support inheritance. Inheritance of QoS allows generalization/specialization relationships in distinct QoS categories, e.g. a state machine QoS with voting is a specialization of a replica group QoS. The implementor of a speci c QoS can rely on already implemented features by using implementation inheritance provided by the implementation language. "qos" QoSname [ ":" baseQoS { "," baseQoS } ] "{" { simple-type-spec QoSParam ";" } interface "{" { operation-decl ";" } "}" ";" "}" ";"

g. 2 QIDL QoS de nition

Figure 2 shows the de nition of speci c QoS in QIDL. The qos keyword introduces the QoS de nition. After the colon a set of names can refer to a base QoS which this speci c QoS inherits from. The QoS de nition is bound to an identi er. The QoS de nition contains two parts. The rst part describes the QoS parameters which may have any IDL type, even a user de ned one, since a simple-type-spec may refer to a user de ned type. The second part is the QoS interface which contains the operations of a QoS visible at its interface. 1

Which in fact implicitly weaves the QoS with the other generated elements of the interfaces

3 QIDL

4

An important question is, which elements in the system QoS can be assigned to. There are several possible elements[11] a QoS can be assigned to. We restrict QoS assignment to interfaces. Finer granularity, e.g. operations or parameters, may con ict when using di erent QoS, like replica groups and best e ort communication. Assigning QoS to modules is unnecessary coarse and may be too restrictive. An interface may provide more than one QoS. But only one QoS at a time is allowed. This QoS is negotiated between client and service. Our system MAQS[1] supports adaptive clients which use negotiation and adaption as a respone to a changing service quality during the service association. Changing the QoS agreement during runtime is also done by a negotiation procedure.

3.2 QIDL Mapping Interfaces de ned in IDL are translated to an implementation language by an IDL compiler. This should be done for QoS de nitions as well. Currently we only support a QIDL to C++ mapping. The mapping of QoS de nitions is kept consistent to the mapping of structs and interfaces in IDL. QIDL-definition (QoS, interface assignement)

generates

Stub

QoS-Skel delegates

Mediator

Skeleton

QoS-Impl

inherits

Implementation Client side

Service side

g. 3 generated entities

Figure 3 shows the generated entities for a speci c QoS de nition and the assignment to a service. Note that the situation in the gure re ects only one speci c QoS. On the client side a mediator is generated which is a delegate of the stub object. The mediator realizes the QoS handling above the ORB on client side. Each speci c QoS provides its own mediator which is loaded upon negotiation agreement. The mediator is generated as a skeleton with all operations of the speci c QoS interface. Additionally it contains a generic calling interface to pass the requests to the functional service interface to the ORB. On the service side a QoS skeleton and the corresponding implementation is generated. The QoS skeleton is the C++ mapping of the QoS interface. The QoS implementation is a skeleton of the implementation to be completed by the QoS implementor. The service implementor can reuse this speci c QoS implementation by using implementation inheritance. A speci c QoS can be used with little or none adaption e ort. All functionalities which must be implemented by the service implementor, such as a state transfer method, are kept as virtual functions and must be well documented by the QoS implementor. The core framework contains a simple protocol which must be implemented by every QoS enabled service. Therefore a client can use a CORBA narrow2 on a service to test if it is QoS enabled. The negotiation is generic in the sense that CORBA::Any types are exchanged and the corresponding speci c QoS is 2

a typesave downcast to an interface

4 RELATED WORK

5

determined by checking the type of the exchanged speci c QoS attribute. The client o ers a QoS attribute lled with the desired parameters to the service which replies with the best possible QoS. The client can accept this o ering and QoS enabled communication begins. On QoS changes a renegotiation is done in a similar way. To provide dynamic extensions of clients and hierachical QoS handling a layer between the ORB and the transport system is integrated in our runtime system. In a paper about MAQS[1] we give an overview about our system.

4 Related Work Isolating aspects of distributed computing has been done before. D[4] provides a framework for distributed programming based on an implementation language with aspect languages for thread coordination and remote access strategies. By isolating the aspects remote access and coordination and supporting them by suitable languages (RIDL, COOL) many applications in distributed programming can be modelled. But QoS still does not t in these aspects since RIDL deals with remotely executed methods and copying mechanisms of parameters rather than with timeliness of execution, group communication mechanisms etc. COOL does not provide any help in the sense of coordination since only local coordination of threads is supported. QuO[13] provides a framework for generic QoS integration in CORBA by Aspect Oriented Programming. Three aspect languages are introduced for resources, structures, and contracts. The runtime system is supported by a set of delegates between the objects and the ORB. The aspect languages expose part of the internal behaviour of objects to the IDL level which is a contradiction to the CORBA design principles of separating interface and implementation. Besides that, the speci c aspect languages of QuO introduce additional complexity. Many other approaches to QoS integration in CORBA exist. Most of them are restricted to one QoS category, like real time or fault tolerance. TAO[10] identi es the requirements for real time CORBA and its implementation, whereas ELEKTRA[6] provides fault tolerance by adding group communication to CORBA.

5 Conclusion We have shown an aspect-oriented approach for QoS integration in CORBA. In constrast to other non generic systems we provide a general, aspect-oriented view on QoS. By using enhanced IDL and its target language (i.e. C++) as aspect languages for QoS, we keep the conceptual changes to the original CORBA small. Therefore our system does not need an explicit weaver or specialized languages for aspects but still provides a clear separation of concerns and thus an aspect-oriented view on QoS. We hope to reduce the complexity of the system and to show that Aspect Oriented Programming is an appropriate paradigm for the integration of non-functional aspects such as QoS.

6 Acknowledgements We thank Kay Romer and Douglas C. Schmidt for stimulating discussions and comments.

REFERENCES

6

References [1] C. Becker, K. Geihs \MAQS - Management for Adaptive QoS-enabled Services" IEEE Workshop on Middleware for Distributed Real-Time Systems and Services, December 1997, San Francisco [2] C. Becker, K. Geihs \Enhancing IDL by generic QoS de nitions" submitted to International Workshop on QoS, May 1998, Napa [3] S. Frlund, J. Koistinen \Quality of Service Speci cation in Distributed Object Systems Design," HP Technical Report, HPL-98-10 [4] C. V. Lopes, G. Kiczales \D: A Language Framework for Distributed Programming," PARC Technical report, February 97, SPL97-010 P9710047 [5] G. Kiczales et. al. \Aspect-Oriented Programming," PARC Technical Report, February 97, SPL97-008 P9710042 [6] S. Ma eis, \Adding Group Communication and Fault-Tolerance to CORBA" Proceedings of the USENIX Conference on Object-Oriented Technologies, June 1995. [7] Object Management Group, Control and Management of Audio/Video Streams, OMG RFP Submission, OMG RFP Submission, telecom/97-05-07, May 1997. [8] Object Management Group, The Common Object Request Broker: Architecture and Speci cation (Revision 2.0), Object Management Group, Framingham, MA, March 1995. [9] K. Romer, A. Puder, MICO, http://www.vsb.cs.uni-frankfurt.de/~mico [10] D. C. Schmidt, D. L. Levine, S. Mungee , \The Design of the TAO Real-Time Object Request Broker" Computer Communications Journal, Summer 1997. [11] D. C. Waddington, G. Coulson, D. Hutchinson, \Specifying QoS for Multimedia Communications within Distributed Programming Environments," Multimedia Telecommunications and Applications, Springer LNCS 1185, pp. 75-101, 1996 [12] J. Waldo, G. Wyant, A. Wollrath, S. Kendall, \A Note on Distributed Computing," Sun Microsystems Laboratories, Inc. Technical Report 94-29, 1994. [13] J. A. Zinky, D. E. Bakken, R. E. Schanitz, \Architectural Support for Quality of Service for CORBA Objects," Theory and Practice of Object Systems, John Wiley, New York, April 1997.

Interactions between objects : an aspect of object-oriented languages L. Berger I3S - CNRS UPRESA 6070 ESSI, 930 Rte des Colles BP 145 06903 Sophia-Antipolis, France 04 92 96 50 66 [email protected]

A.M. Dery I3S - CNRS UPRESA 6070 ESSI, 930 Rte des Colles BP 145 06903 Sophia-Antipolis, France 04 92 96 51 62 [email protected]

ABSTRACT This paper is based on our experience of integrating the interactions to several object-oriented languages and on our conclusion: interactions should be viewed as an “extensible” aspect of object-oriented languages.

M. Fornarino I3S - CNRS UPRESA 6070 ESSI, 930 Rte des Colles BP 145 06903 Sophia-Antipolis, France 04 92 96 51 61 [email protected]

Our experience with integration of interactions to objectoriented languages has shown that the expressiveness required for the interactions can vary according to the component languages and the target applications. When the language integrates concurrent or distributed paradigms, the interaction expression implies to deal with concurrent behavior or distributed communication. When the applications need more static checking, an analysis or control of the global interaction graph is essential. In the first implementations, we defined a reflexive architecture in order to give the way to a programmer to adapt the tool to its specific applications. Today, we think that this approach lives a good way to allow the implementation and evolution of Aspect Weavers1 . Although the aspect approach, when it is possible, gives a higher level of specification better adapted to the final developers. So, we propose to customize the interaction language both using directly aspects on the IL language and indirectly to adjust the Aspect Weavers to the programmer needs.

KEYWORDS aspects, object, meta-programming, interaction, synchronization 1 INTRODUCTION It is now well known that it is not easy to manage the interactions between objects in conventional object-oriented languages [Rum92, Bos94]. The interactions are tangled in the code of the objects, specializing classes, sending messages to other objects in the code of methods or referencing interacting objects by specific attributes. The consequence is that the semantic of the objects participating to an interaction is modified and the application maintainability and extensibility are harder.

This paper is based on our experience of integrating interactions to different object-oriented languages and on our conclusion : interactions should be viewed as an “extensible” aspect of object-oriented languages. The paper is organized as follows. The next section provides a short description of IL and illustrates its integration in several environments. Section 3 presents our proposal solution as Interaction Aspect Weaver. This solution is essentially based upon meta programming to facilitate the future integration of new aspects. The last section presents some aspects to extend the basic IL such as a synchronization aspect to synchronize interactions in a concurrent environment. Then we conclude.

So different works have proposed some extensions to objectoriented languages to take into account this lack of abstraction [Neu91, Hol92, AF93, Pin93, Frø94]. We did the same [DFP95, DDF96, BDFJ97]. But, today, we argue that interactions are conceptually independent of any object-oriented language and match exactly the definition of an aspect described in [KLM 97] : A SPECTS tend not to be units of the system’s functional decomposition, but rather to be properties that affect the performance or semantics of the components in systemic ways.

2 INTERACTIONS : THE IL LANGUAGE This section briefly presents the IL language through a simple example : a Smalltalk version (Figure 1) and an IL version (Figure 2). A more complete description of IL can be found in [Ber97a]. We conclude this section with remarks on our different experimentations for integrating interactions to object-oriented languages.

So, we propose a language, called IL (Interaction Language) to describe the interactions between objects. This language allows to specify interactions between objects referring to the objects only through their interface (list of methods). IL is an aspect language for object-oriented languages. So, whatever the object-oriented component language may be, classes and behaviors of objects are written in the component language without having to deal explicitly with interactions.

1 Aspect

1

Weaver is a trademark of Xerox Corporation

2.1 Example: a Diary Manager in Smalltalk without IL

2.2 Short description of IL

A diary manager handles the association between shared diaries and personal diaries. When a rendezvous is added to a shared diary the participants of this rendezvous (reunion) are notified and their personal diaries are updated.

With IL, the interactions are specified outside of the objects, using only their interface. The methods in the component language describe the intrinsic behavior of objects without taking care of future participations in interactions.

Figure 1 shows an implementation part of this specification using Smalltalk 2 .

The description of interactions in IL is based on the expression of interaction rules. An interaction rule describes, for a given message, the set of partial ordered messages corresponding to its effective execution. This description uses the sending message operator (noted .), two reactive operators (; and // respectively for synchronous and asynchronous sending), and a conditional operator.

We have colored the background of the code in grey when the code applies to interactions between objects. 2 The SharedDiary object has also methods to manage the list of persons who share the diary

Object subclass: #Diary instanceVariableNames: ’aRdVList ’ classVariableNames: ” poolDictionaries: ” category: ’Diaries’! !Diary methodsFor: ’adding’! addRdV: aRdV ”Add a Rendezvous to a diary” aRdVList add: aRdV! modifyRdV: aRdV new: aNewRdV ”Modify a Rendezvous to a diary” aRdVList del: aRdV aRdVList add: aNewRdV! removeRdV: aRdV ”Remove a Rendezvous to a diary” aRdVList del: aRdV! ! Diary subclass: #SharedDiary instanceVariableNames: ’anDiaryList’ classVariableNames: ” poolDictionaries: ” category: ’Diaries’! !SharedDiary methodsFor: ’adding’! addRdV: aRdV ”Add a Rendezvous to a shared diary” (anDiaryList collectDiaryOf: (aRdV affectedTo)) do: [:each | each addRdV: aRdV]

The interaction rules are described in interaction managers. An interaction manager allows to specify the state and behaviors (for example the cardinality [OMG95, Mul97, Rat97] and the delayed execution) fitted to the designed interaction. An interaction manager can be specialized adding or completing interaction rules and participating objects. In the IL language, an interaction manager can be statically declared between given objects. But, most of the time, the interactions between objects have to be dynamically established or destroyed. A given object (instance) interacts with different objects during the execution. So dynamically adding or removing interaction managers is essential and the resulting language must offer such a functionality. 2.3 A shared diary manager in IL We show in Figure 2 the code of the diary manager presented in section 2.1 using IL. This manager describes the interactions between a shared diary SD, a personal diary PD and its owner P. Three rules specify the consequences of a message sending on a shared diary. For example, when a message addRdV is received by a shared diary, the RdV is concurrently added to the shared and personal diaries and then the owner is notified, if needed.

(aRdV affectedTo) do: [:each | each notify: ”Rendezvous added”] ˆsuper addRdV: aRdV! removeRdV: aRdV ”Remove a Rendezvous to a shared diary” (anDiaryList collectDiaryOf: (aRdV affectedTo)) do: [:each | each removeRdV: aRdV] (aRdV affectedTo) do: [:each | each notify: ”Rendezvous removed”] ˆsuper removeRdV: aRdV! ...

!

!

RainbowDiary := SharedDiary new. SchoolDiary := SharedDiary new. LaurentDiary := Diary new ownedBy: Laurent. SchoolDiary addDiary: LaurentDiary. ...

Figure 1: An implementation of shared diaries in Smalltalk

The use of IL separates the basic functionalities of objects and interactions and then greatly decreases the level of code tangling. Subclassing the Diary class is not needed to obtain shared diaries. A shared diary is just a diary interacting with other diaries. So the code is easier to extend and to reuse. 2.4 An Integrated Environment for IL IL allows to describe interactions independently of the component language. A programming environment which allows the description and the edition of interaction rules and managers is provided with the IL language. This environment is developed in Smalltalk and includes at present time two generators, one for Corba and C++, another one for Smalltalk. This tool is an interaction editor and also allows the application designing by means of “interaction” scenarii. Interaction managers are then consequently generated in IL. In the

Object subclass: #Diary instanceVariableNames: ’aRdVList ’ classVariableNames: ” poolDictionaries: ” category: ’Diaries’! !Diary methodsFor: ’adding’! addRdV: aRdV ”Add a Rendezvous to a diary” aRdVList add: aRdV! modifyRdV: aRdV new: aNewRdV ”Modify a Rendezvous to a diary” aRdVList del: aRdV aRdVList add: aNewRdV! removeRdV: aRdV ”Remove a Rendezvous to a diary” aRdVList del: aRdV! ! manager ConsistencyDi ( Diary SD, Diary PD, Person P ) { SD.addRdV ( aRdV ) SD.addRdV ( aRdV ) // if aRdV.affectedTo ( P ) then PD.addRdV ( aRdV ) ; P.notify ( ”Rendezvous added” ) endif, SD.modifyRdV:new ( aRdV, aNewRdV ) SD.modifyRdV:new ( aRdV, aNewRdV ) // if aRdV.affectedTo ( P ) then PD.modifyRdV:new ( aRdV, aNewRdV ) ; P.notify ( ”Rendezvous modified” ) endif, SD.removeRdV ( aRdV ) SD.removeRdV ( aRdV ) // if aRdV.affectedTo ( P ) then PD.removeRdV ( aRdV ) ; P.notify ( ”Rendezvous removed” ) endif } ConsistencyDi ( SchoolDiary : Diary, LaurentDiary : Diary, Laurent : Person);

Figure 2: A shared diary implementation in Smalltalk and IL same time, a set of class skeletons is deduced. These skeletons help the design of an application and are used during the code generation to check the existence of classes involved in the interactions. 2.5 Experimentation with Component languages Some experimentations have been done to integrate the interaction language to several object-oriented languages : Smalltalk [Bec97, Ber97b], Clos [ABB 89, DFP95], Open C++ [Chi95, CH97], Corba-C++ [ORB92, Nac97], CorbaOpen C++. At the present time we are interested in component languages that integrate network management such as Java RMI [SUN96], Corba-Smalltalk and Corba-SmalltalkC++. Our aim is to see the impact of a distributed environment to the architecture and the possible consequences on the aspect language (see sections 3 and 4). According to the component language, the resulting language deals with simple interactions between objects, concurrency or communication between remote objects. For example, when the resulting language, such as our first implementation in Clos, does not manage concurrency the operator // is equivalent to ;, otherwise the example using the interactions is, without change, concurrent. We can also note that no assumption is done concerning the physical location of objects in IL. So, when a component lan-

guage is coupled with a distributed language, the interaction aspect weaver has to take into account the object location. In Corba, for example, it must generate the IDL (Interface Description Language) of the remote objects from the interaction managers described with IL. In order to hide that some objects in the interaction managers are local or remote, the weaver has to handle the physical locality of the objects at the message execution time. So, according to the kind of component language, the interaction aspect weaver has to deal with different paradigms. In answer to this extensibility problem, we will detail in the next section the proposed architecture of an interaction aspect weaver. The following section will deal with this problem in term of aspects when the considered paradigms are weaver implementation dependent. 3 INTERACTION ASPECT WEAVER For each experimentation, we have developed an aspect weaver. Those weavers have common features. They generate in the component language first class objects for the interaction rules and interaction managers described in IL. They add code to glue the component objects and the generated objects and they install a set of units which manage the interactions. We can consider this set as a runtime library. The principal common characteristic of all the weavers is the redefinition of the execution of a message to manage interactions. So, in the resulting language, it is necessary to catch the messages and to determine if the messages are concerned by interactions. In this case, the interaction rules concerning this message at this time are selected, and the new behavior of the message is executed. A specific unit is responsible for each step of this message execution. Each of these units has a specific behavior according to the component language and the target resulting language features. Each unit has to be easily extensible and substituted without altering the global behavior. The chosen solution is to associate a meta-object to each interacting object and to introduce these units in each metaobject. So, we developed all our weavers using an open object-oriented language. The description of the meta-object given in the following section is a guideline for interaction aspect weaver implementation. 3.1 Meta Architecture Figure 3 shows the architecture of a meta-object with its units and their collaboration to manage the new message execution. Catching Message Unit The sending message semantic is changed because when a message involves at least an interaction rule, this or these rules are executed instead of the message itself. So we need a catching message mechanism to modify the sending message

execution message to an interaction rule is recursively sent to its operators. So a new operator can easily be added. We can see in the Figure 3 that the execution unit can contain other units, for example, to manage remote calls in a language that does not provide them at base level. The implementation of these four units is complicated when the weaver has to mask the network management or to handle the concurrency. In such a case the evolution and maintainability of the meta-object is complex. The next section presents the advantage of the introduction of an aspect language to describe concurrency interactions and the future works under consideration in term of aspects. 4 ASPECT ON THE INTERACTION ASPECT LANGUAGE

Figure 3: An overview of the meta architecture

behavior semantic. Several mechanisms for catching messages in open object-oriented languages exist. For the catching message unit, in Open C++, we have used the method wrapper ([Bra96] gives an example of method wrapper in Smalltalk). In Corba, we gain, with the Orbix version, the filters mechanism [Orb96, Nac97] that is suitable to catch the sending message between hosts. We had the choice between the techniques presented by Ducasse in [Duc97] in the Smalltalk environment and we take advantages of dynamic subclassing and compilation. Selection Unit This unit manages the effective interaction rules. It contains the list of all effective interaction rules in concern with the object managed by the meta-object. This list is evolutionary because the interaction rules can be included or removed dynamically, at runtime. This unit determines, when a message is received and caught, which interaction rules among the effective rules must be executed. Merging Unit When the set of interaction rules to execute for one sending message is fixed by the Selection Unit, the Merging Unit must merge these rules before their execution. Indeed each rule can contain the ask of the execution of the interacting message but the interacting message must be executed only one time. So we need to merge these rules to avoid extra execution of the interacting message. The merging algorithm is based on the operator semantics. Execution Unit The role of the Execution Unit is to manage the execution of the interaction rule resulting from the merging realized by the Merging Unit. Interaction rules and operators are first class objects which know how they execute themselves. An

The current behavior of resulting languages are not completely satisfying in some points : the network management, the synchronization of the interactions and the checking of the global interaction graph are not well integrated yet. The AOP [KLM 97] can solve in part these problems. We have completed the interaction language features to the synchronized interactions due to an aspect language. We are now studying the advantages to use aspects to simplify the weaver implementation in case of distributed implementation and to introduce explicitly properties on interactions for checking the global consistency at runtime. 4.1 Interactions Synchronization : an aspect of IL The problem of synchronization occurs when the interactions are an aspect of a concurrent or a distributed objectoriented language. We need then to express self exclusive or mutual exclusive interaction rules in an interaction manager to avoid cycle or reentrance. To extend IL with exclusion instructions is not a good solution because such an information is not used in a sequential language and transforms the code of interactions in a tangled code with synchronization. So interaction synchronization is typically an aspect for IL. After a first study of this solution, a language such as the coordinators of Cool [VLL94] seems to be a good applicant. The synchronization program refers to the interaction program by its interaction managers and interacting messages to designate a rule in this manager. For example, coordinator DiaryManagerCoord : ConsistencyDi { mutexclusive { SD.addRdV ( aRdV ), SD.removeRdV ( aRdV ) }; }

specifies that the two rules cannot be executed concurrently. We also need sometimes to consider an interaction as an atomic transaction and more generally to declare a set of interacting messages in an atomic transaction. Let see the shared diary example with the following behavior : the ask for a modification or an addition of a rendezvous requires

the acceptance of all the persons involved in the rendezvous before the effective updating of the shared diary. This example can be directly implemented in an interaction manager between all the persons and the shared diary by asynchronous sending messages managing a two phase commit. In fact, this solution is not a satisfactory answer because it is too closely related to the implementation and too far from a specification language as IL. We have chosen to introduce the keyword atomic (associated to a rule or a set of rules) in the synchronization aspect language. It is more declarative and then it fits better the philosophy of IL.

rate the syntax of our language and it is easier to check properties on the interactions. But, the objective of such a language is always to be integrated in others languages. So, due to our experimentation in the interaction weaver implementation, we are today able to propose an architecture based on meta programming to implement Weavers. Separating the interaction language from an object-oriented language leads us to tackle other points such as distribution or concurrency. Our current idea is that these features don’t have to be integrated in IL, and are in fact aspects on the IL language or as to be used to implement the Weavers.

4.2 Future Works around aspects on aspect

In conclusion, we think that the IL language and its programming environment are a good way to investigate and to help the programmers in a new type of programming : interaction-oriented programming. Moreover, it seems to us that the interaction-oriented programming allows to fear the component oriented programming in an interesting and promising manner.

Interactions between remote objects The problem of the network management is the complexity of the library associated to the weaver. The network management is tangled in the code of meta-object and the extension and maintainability is then difficult. Moreover the user has no explicit information concerning the network behavior and cannot control it nor customize it. So we think that the distribution management for the interactions must be an aspect. In such a case, our study concerns essentially to determine two points : which kind of language is required to express distribution for interactions and if this aspect must be associated with the interaction language, the component language, the resulting language or the Interaction Aspect Weaver design. Interactions Graph The last point concerns control on the complete interactions graph. It should be probably resolved by an aspect but the difficulties are to find the well adapted properties we want to express (no cycle or limited loops, detection of synchronization points, multiple calls to a same message in an interaction rule resulting from the merging, reducing a list of interaction calls, etc) and to check on this graph and the consequences of the kind of the component language (concurrent or distributed) on this set of properties. The originality of our approach is that we can propose a basic interaction aspect that can be extended with other aspects, such as coordinator language, according to the nature of the component language or the target applications. The programmer can customize the interaction language according to the component language and the target features of the resulting language. 5 CONCLUSION In our first works on the interactions, we were interested in proposing the “ideal” architecture to integrate interactions in your “preferred” languages. Doing so, we were language dependent and it was difficult to determine which features were required by the object-oriented language and which were required by the interactions themselves. The new vision of interactions between objects in term of an aspect of objectoriented languages allows a separation between interaction language and component languages. So, we are free to elabo-

REFERENCES [ABB 89] G. Attardi, C. Bonini, M.R. Boscotrecase, T. Flagella, and M. Gaspari. Metalevel programming in CLOS. In S. Cook, editor, Proceedings of ECOOP’89, pages 243–256, Nottingham, July 1989. Cambridge University Press. [AF93]

G. Agha and S. Frølund. A Language Framework for Multi-Object Coordination. In Proc. Of European Conf. On Object-Oriented Programming ’93, number 707 in LNCS, pages 347–360, July 1993.

[BDFJ97]

L. Berger, A-M. Dery, M. Fornarino, and O. Jautzy. Contribution : Interaction and Communication Models. In ECOOP’97 Workshop Reader. Springer Verlag, 1997.

[Bec97]

K. Beck. Smalltalk, Best Practice Patterns. Prentice Hall, 1997. ISBN- 0-13-476904-x.

[Ber97a]

L. Berger. et d’un de Coordination entre Objets Distants. Rapport de recherche I3S, RR-97-24, 1997.

[Ber97b]

J-M. Bernelas. Rapport de stage ESSI seconde October 1997.

[Bos94]

J. Bosch. Relations as first-class entities in layom. Not Yet Published. Available on http: //www.pt.hk-r.se/~bosch, 1994.

[Bra96]

J. Brant. Method Wrappers. Smalltalk goody, 1996. http://st-www.cs.uiuc. edu/users/brant/Applications/ MethodWrappers.html.

[CH97]

B .Cazaux and T. Haquet. FLO++ entre objets distants, April 1997. Rapport de projet de fin

[Orb96]

Orbix 2 Programming and Reference Guide, Iona Technologies Ltd, 1996. http://www. iona.com.

[Chi95]

S. Chiba. A Metaobject Protocol for C++. In the ACM Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA), pages 285–299, October 1995.

[Pin93]

[DDF96]

A-M. Dery, S. Ducasse, and M. Fornarino. Object and Dependency Oriented Programming in FLO. In ISMIS’96 : International Symposium on Methodologies for Intelligent Systems. LNAI, June 1996.

X. Pintado. Gluons: a support for software component cooperation. In Shojiro Nishio and Akinori Yonezawa, editors, First International Symposium on Object Technologies, volume 742 of Lecture Notes in Computer Science, pages 43–60, 1993.

[Rat97]

Objectory Process 4.1 : Your UML Process, Rational Corp., 1997. http://www. rational.com.

[Rum92]

J. Rumbaugh. Horsing around with associations. Journal of Object Oriented Programming, 4(6):20–29, February 1992.

[SUN96]

SUN. http://www.javasoft.com: 80/products/jdk/1.1/docs/guide/ rmi/index.html, “Remote Method Invocation Tutorial”, 1996.

[VLL94]

C. Videira-Lopes and K. Lieberherr. Abstracting Process-to-Function Relations in Concurrent Object-Oriented Applications. In European Conference on Object-Oriented Programming, pages 81–89, Bologna, Italy, 1994.

[DFP95]

S. Ducasse, M. Fornarino, and A-M. Pinna. A Reflective Model for First Class Relationships. In Proceedings of OOPSLA’95, pages 265–280, 1995.

[Duc97]

S. Ducasse. Des Techniques de de l’Envoi de Messages en Smalltalk. In L’objet, o Smalltalk en France : de l’art et de la pratique. Hermes 1997.

[Frø94]

S. Frølund. Constraint-Based Synchronization of Distributed Activities. PhD thesis, University of Illinois at Urbana-Champaign, 1994.

[Hol92]

I. M. Holland. Specifying reusable components using Contracts. In O. Lehrmann Madsen, editor, Proceedings of ECOOP’92, volume 615 of Lecture Notes in Computer Science, pages 287– 308, Utrecht, June 1992. Springer-Verlag.

[KLM 97] G. Kiczales, J. Lamping, A Mendhekar, C. Maeda, C lopes, J-M. Loingtier, and J. Irwin. Aspect-Oriented Programming. In Proceeding of ECOOP’97, Xerox PARC, Palo Alto, CA, June 1997. Springer-Verlag. [Mul97]

P.A. Muller. rolles, 1997.

objet avec UML. Ey-

[Nac97]

A. Nacciu. Dependencies within a distributed object system - a CORBA approach, July 1997.

[Neu91]

C. Neusius. Synchronizing Actions. In Proc. Of European Conf. On Object-Oriented Programming ’91, number 512 in LNCS, pages 118– 132, July 1991.

[OMG95]

“Relationship Service Specification”, Part 9 of CorbaServices Doc. Number 95.3.31, 1995. http://www.omg.org/library/ corbserv.htm.

[ORB92]

“The common Object Request Broker : Architecture and Specifications”, Object Management Group and X/Open, 1992.

Developing a Tool to support the Application of Aspect-Oriented Programming Principles to the Design Phase Siobhan Clarke, John Murphy School of Computer Applications, Dublin City University, Ireland. Contact: [email protected] Abstract: Integrating system, technical functionality with the business functionality of a system, both at the design and the coding level, increases the complexity of the design models or the code, and thereby makes them more difficult to understand and maintain. Research into aspect-oriented programming [Kiczales97] has shown that programs can be written to support the business functionality without including distribution support in the code, where separate programs (called “aspect programs”) cater for the distribution requirements. We introduce here a tool which applies the AOP techniques at the design level, leaving design models simpler and easier to understand.

1. Introduction The design concepts corresponding to a component language and a component program at the implementation level, are a component design language and a component design respectively. The component design is specified in the component design language and the component design is the design specification of the component program. In AOP, the component language’s explicit constructs constrain the definition of the aspect language because the aspect program must coordinate with those constructs. Since we are working with a design language, we translate this to the aspect language being constrained by the constructs of the design language so that the aspect program may be generated based on the component design. There are two distinct “tasks” which a design tool needs to support and which would probably be performed by different people: 1. Specification of Aspect Language: This task is one which is likely to be performed infrequently by a skilled individual who understands the semantics of the design language and the specific technical area the aspect in question supports. In the tool, we currently simply expose a graphical representation of the component design language meta-model to the creator of the aspect language, allowing the selection of those constructs of the design language with which an aspect program will coordinate. The designer of the aspect language records the relevant syntax of the aspect language without attaching meaning to those constructs. Extensions to this approach under discussion are supporting the aspect language designer model the technical aspect in a manner similar to modeling the functional component.

1

2. Aspect Program Creation: A more frequent task, this allows the application designer specify how the technical aspect supported by the aspect language applies to the particular functional component. Here, the tool assists the creator of the aspect program to work with the component design in defining the actual component design elements which are affected by the aspect.

2. Specification of an Aspect Language The specification of an aspect language is based on the explicit language constructs which are available to the designer of the functional component. (We have not yet considered the case where join points are implicit in the functional components.) When using our tool to define an aspect language, a representation of the constructs in the meta-model are presented to the aspect language designer. The aspect language designer may then select the design language construct for which an aspect language construct is required, and specify what that aspect language construct is. The tool maintains the specification of the aspect language in a collection of objects which have responsibility for reifying the list of aspect language constructs defined in the aspect language and the rules defined for each. APIs to the collection of objects provide clients such as the tool component responsible for graphically guiding a designer through the creation of an aspect program, with those construct names and rules. These rules will be the basis for the different options which will be available when using the aspect language to define the cross-cutting functionality of a functional design. We are currently working on support for the aspect designer to design the aspect’s semantics behind the aspect language.

3. Using Aspect Language to create an Aspect Program Aspect languages are designed to describe functionality which "cross cuts" all the objects in a program which handles the system functionality. There is no dependency on the nature of the actual functionality handled by the program. The two main parts to the process of creating an aspect program are supporting the designer select the functional design elements affected by the aspect and secondly, generation of the aspect program. 3.1. Applying Aspect Keywords to Functional Specification There may be many different aspect languages which have been designed to cater for different kinds of system functionality. The designer selects an aspect language from a list of available ones. The objective of the designer performing this task is to select the functional specification elements for which the aspect functionality is required. The set of functional elements eligible for selection is dependent on the aspect language construct rules. For example, if an aspect language construct deals with operations, then the designer is presented with the list of operations to choose from.

2

The tool makes use of an API to the appropriate aspect language object to obtain the list of aspect language constructs available, and presents this list to the designer. 3.2. Building the Aspect Program The aspect program is generated based on the syntax of the particular aspect language and the designer’s selection of associated design elements. Once the aspect program is generated, and on generation of the component program from the component design, we have both the required inputs to an AspectWeaver such as those discussed within the AOP team. The component design models do not contain any non-functional elements. The aspect program is maintained entirely separately. This clear separation of concerns reduces the complexity and thereby makes the design easier to work with.

4. Current position of work The focus of the current version of the tool was supporting the designer to create an aspect program in a graphical manner, from the design model. Specification of the aspect language was focussed on what was required to achieve that end. Currently, we are focussing on a more flexible mechanism to support the design of an aspect’s semantics. We feel this mechanism should be similar to the process of designing a functional component, with similar facilities for describing an aspect’s behaviour.

References: [Kiczales97]

Gregor Kiczales, John Lamping, Anurag Mendhekar, Chris Maeda, Cristina Lopes, Jean-Marc Loingtier, John Irwin "Aspect-Oriented Programming", ECOOP, (1997)

3

Injecting Ilities Robert E. Filman* Microelectronics and Computer Technology Corporation 3500 West Balcones Center Drive Austin, Texas 78759-6509 [email protected] This paper discusses the use of aspect-oriented programming technology to impose desirable system-wide properties on distributed systems.

Overcoming Complexity in Distributed Computing The goal of the Microelectronics and Computer Technology Corporation's (MCC) Object Infrastructure Project (OIP) is to simplify the development and evolution of distributed, object-oriented applications. OIP is designing and implementing an architecture where ility-providing program elements (injectors) can be automatically wrapped around application components. The task of specifying the appropriate injectors is separate from the actual component coding. Traditionally, software application development has been a monolithic process. An organization building a software system presumed to know how it wanted that system to behave. The requirements for that behavior would flow down to the construction of the underlying modules. Since the modules were being built specifically for the system in question, it was “straightforward” to get their developers to obey the rules and conform to defined standards. To the extent that the system used an externally provided component such as a GUI or database, the behavior of that component would be ascertained and the use of that component within the architecture of the system shaped to match the external component's actual behavior. Software development has gotten more complex. Technologies such as CORBA and HTTP provide the glue for building applications from distributed components. But understanding the nuances of multiple components and varieties of glue can is itself an intellectual challenge. We can't expect a single application programmer to become expert in the intricacies of many components, even if the application needs to use them all. Similarly, components impose their own constraints on their usage. We want to develop systems from components but don’t want the artifacts of a particular component manufacturer to permeate our designs, rendering us eternally dependent on the whims, demands and destiny of that vendor. We want components that obey our policies—not to have to distort our systems to match the policies of the components. And we want ways to federate existing systems while still maintaining overarching rules and procedures. *

This paper describes work performed at MCC while the author was on assignment from Lockheed Martin Missiles and Space. LMMS contact information: Advanced Technology Center; Lockheed Martin Missiles and Space; 3251 Hanover Street O/H1-43 B/255; Palo Alto, California 94304. Email: [email protected].

1

Injecting Ilities

03/30/98

Distributed systems introduce additional complexity. Developing a distributed system is in itself a more difficult task because distributed systems imply nondeterministism(and non-determinism is complex), distribution introduces many additional kinds of failures, distribution is naturally less secure, and distribution’s inherent decentralization is inconvenient to manage. Distributed computing can be made simpler by making it look more like conventional programming and by providing and automatically invoking correct implementations of distributed and concurrent algorithms.

Requirements System development (ought to) follow from requirements. What kinds of requirements are there? In [1], I proposed dividing requirements into four classes based on the "tractability" of achieving the requirement: functional requirements that exhibit the primary semantic behavior of a system and are typically locally realized, systematic requirements that can be achieved by "doing the right thing" consistently throughout the program, combinatoric requirements that are computationally intractable expressions of overall system behavior (for example, guarantees of real-time behavior or limits on storage footprint) and aesthetic requirements that express non-computable qualities of the system (about which even wise men may differ.) The first of these is well supported by the conventional development process ("The requirements say that a dialog box appears at this time with the choices…") and the last two are difficult to automate in any case. Aspect-oriented programming gives us a handle on systematic requirements. Always doing the right thing is hard for a single coder, no less a gaggle of hackers. Computers, on the other hand, can be programmed to be tediously consistent. (Compilers are programs that are tediously consistent in transforming other programs.) What kinds of systematic requirements exist? Our applications should exhibit reliability, security, scalability, extensibility, manageability, maintainability, interoperability, composability, evolvability, survivability, affordability, understandability, and agility. (I've omitted a few.) Let us label these qualities ilities. The keen reader is likely to ask, “So what exactly do you mean by, say, reliability?” Reliability requirements differ for different applications and are likely to change over the lifetime of the application. The reliability requirement maps to executing specific algorithms that need to be invoked systematically throughout the application. Some ilities are consequently manifestations of properly defined and implemented requirements. The open scientific question is thus (given the fuzzy definition of an ility) "Which ilities can be achieved by systematic actions, and what are the actions needed to achieve those ilities?"

Controlling communication The OIP project is pursuing the thesis that certain interesting ilities (security, reliability, manageability, quality of service) can be achieved by proper manipulation of the communications between components and the significant events of a component’s lifecycle. We are currently creating a set of tools to realize the transformation from specified ilities to controlled communications, a reference architecture (set of rules defining component interactions) and set of frameworks (realizations of that architecture in particular environments) to demonstrate this thesis. A key observation of this work is that communication is not confined to the “actual text of a message” (for example, the procedure be-

2

Injecting Ilities

03/30/98

ing called and its arguments) but also allows arbitrary additional annotation—we pr esume to control both sides of the communication act. Our efforts are aspect-oriented programming [2] in that we are separating the tasks of creating the actual domain application from the code that produces security, reliability, and such ilities. Our efforts can also be seen as an instance of the perpetual effort in computer science to raise the “level” of supporting substrates. Tools such as CORBA have enabled programmers to code to the specification of objects and methods. But realizing elements such as security or reliability are still the responsibility of the application programmer, and likely to be done incorrectly or incompletely by most such programmers. (A programmer expert in the workings of a satellite flight control system or medical database is unlikely to also be expert in security and replication algorithms.) This effort can thus be seen as a way to produce the “next generation” of CORBA-like systems [3], where the application programmer no more worries about how to achieve security than she does about mapping the location of a mouse click to a window’s button.

Applied ilities Let us consider, for each of our target ilities, how communication and lifecycle control can be used to affect or realize that ility, and the limits of that realization.

Security Security (at least in a software sense) is primarily a combination of access control, intrusion detection, authentication, and encryption. Controlling the communication process allows us to encrypt communications, reliably send user authentication from client to server (and pass it along to dependent requests) and check the access rights of requests, all independent of the actual application code. (However, depending on where the encryption happens in the communication process, we may only be able to encrypt the message data, not its headers.) Watching communications provides a locus for detecting intrusion events [4] (though not, of course, specifying the actual algorithms for recognizing an intrusion.) These mechanisms can all be imposed on a component-based system by controlling its communications. (Such mechanisms cannot, however, prevent subverting a system’s personnel, tapping communication lines, brute-force cracking of encryption codes, or components that cheat by opening their own socket connections.)

Manageability The International Standards Organization has defined five elements to manageability: performance measurement, accounting, failure analysis, intrusion detection, and configuration management. The first four of these can be implemented by generating events in relevant circumstances and directing those events to the appropriate recipients. To the extent that the semantics of these events can be tied to communication acts (e.g., each time a service is called, a micro-payment for that service is processed, or the trace of inter-component messages is sent to a system’s debugger) then they can be realized through external communication controls. To the extent that the interesting actions happen completely within the application components (e.g., payment is due proportional to the number of records accessed by a database service or debugging wholly within a component) then this technique will prove inadequate.

3

Injecting Ilities

03/30/98

Configuration management is partially an issue of object lifecycle. Communication control can be used to dynamically determine if appropriate configurations are in use and to automatically update stale configurations.

Reliability Our primary experiments in supporting reliability have centered on using replication for reliability [5]. Replication algorithms typically need to send copies of messages to replicants, but our work has also revealed that message replication is insufficient for practical replication. Rather, the application needs to be written to express its operations in symbolic terms, not in terms of addresses in a specific replicant’s address space. Similarly, I believe transaction management would (practically) yield to communication control only if the managed objects provide the necessary primitives (locking and rollback.) These points illustrate the limitations of pure communication control in the presence of monolithic compents, even given the existence well-defined algorithms.

Quality of service By quality of service I mean to encompass a variety of requirements for getting things done within time constraints. The real-time community recognizes two varieties of realtime systems, hard real-time and soft real-time. Hard real-time systems have tasks that must be completed at particular deadlines, or else the system is incorrect. Soft real-time systems seek to allocate resources so as to accomplish the most important things. To achieve hard real-time systems, one can either reserve resources and plan consumption or use an anytime algorithm. Aside from that latter, somewhat esoteric choice, hard real-time requires cooperation throughout the processing chain (for example, in the underlying network), for the promise of particular service can be abrogated in too many places. That is, you can’t get hard real-time unless you build your entire system with that in mind. It’s a combinatoric requirement. (Doug Schmidt's work on Real-Time CORBA ORBs [6] illustrates this point: commercial ORBs, built without constant realtime mindfulness, conceal FIFO queues and exhibit anti–real-time behavior.) Soft real-time quality of service is amenable to several communication control tactics. These include calling the underlying system’s quality of service primitives, using side-door mechanisms to efficiently transport large quantities of data (e.g., opening a socket to send a movie, thereby avoiding CORBA coding and decoding), using queue control to identify the most worthwhile thing to do next [7] and by choosing among multiple ways of problem solving. All of these except the last are well within the scope of communication control, and if the application supplies the alternative problem solving methods (either by replicating the problem solving sites or providing genuinely different algorithms) the communication control mechanism can learn (based on historical timing data and communications with other clients) the most efficient problem solvers.

Implementation A few remarks on OIP implementation are worth mentioning. The underlying computational model is to wrap components with a sequence of injectors. Systems like CORBA and Java RMI support a stub/skeleton proxy mechanism for distributed communication. (In fact, several commercial ORBs include the ability to specify some userdefined filters on communications. Such filters are required by the yet-to-becomecommercially-available CORBA security service.) OIP injectors are individuated by

4

Injecting Ilities

03/30/98

proxy/method and can, with the appropriate access controls, be changed for a particular proxy. Injectors can both read and write not only the application program arguments, but also the annotations associated with the message. Thus, the annotation mechanism supports communications among injectors. Annotations can be understood to be the procedure-call analog of mail headers. Certain headers have common meanings ("From" and "To") while others are more specialized to particular programs ("X-Sun-Charset"). Our experience with OIP has suggested an initial set of common annotations (including session identification, request priority, sending and due dates, version and configuration, answer futures, cyber wallet, public key, sender identification and conversational thread.) Thus, a request can be identified as having a specific priority and injectors can change their actions based on that priority (for example, to queue incoming requests and execute the highest priority request next, as was done in [7].) Security concerns about the use of injectors can be reduced by requiring an injector to declare which annotations it reads and writes (and enforcing that declaration). We may be more willing to use a plug-in injector obtained from a random site if we know that all it does is read the sending and due dates of messages than if it claims to alter sender identification and message text. (The former could be used to support an adaptive real-time mechanism such as the one described in [8].) OIP also supports chaining of annotations through called threads. Thus a routine called with a priority of X will make calls at priority X (unless the thread explicitly changes the priority). Selection of which initial injectors to use for which methods of which classes is done by a compiler that takes a language of injector specifications and builds the appropriate default structures for the run-time system. This language provides a level of indirection between desired ilities and their implementations, and allows the successive refinement of policies through an organization. This use of a separate specification language for creating filters parallels the work at BBN on QoS [9], where an IDL-like Quality Description Language is woven with IDL to affect system performance. I also note that Videira Lopes and Kiczales also apply communication control to distribution for the aspects of synchronization and distribution [10].

Concluding remarks I have argued that high-level, desirable system-level properties can be achieved in a component-based system by systematically controlling the inter-component communications and component lifecycle. Our initial experiments have lent credence to this hypothesis, subject to the caveats that some algorithms (e.g., transactions) require cooperation on the part of the application, and that our desire for system-level properties (e.g., security) must be kept within the range of definable mechanisms. Our work continues on developing the mechanisms to automate this process and testing our thesis.

Acknowledgments The ideas expressed in this paper have emerged from the work of the MCC Object Infrastructure Project, particularly Stu Barrett, Carol Burt, Deborah Cobb, Tw Cook, Phillip Foster, Diana Lee, Barry Leiner, Ted Linden, David Milgram, Gabor Seymour, Doug Stuart and Craig Thompson. Some of these ideas have been expressed in refer-

5

Injecting Ilities

03/30/98

ence [1]. My thanks to Tw Cook, Diana Lee, Ted Linden, Dave Milgram and Tom Shields for comments on the drafts of this paper.

References [1] Robert E. Filman, "Achieving Ilities," Workshop on Compositional Software Architectures, Monterey, California, Jan. 1998. http://www.objs.com/workshops/ws9801/papers/paper046.doc [2] Gregor Kiczales, John Lamping, Anurag Mendhekar, Chris Maeda, Cristina Lopes, JeanMarc Loingtier, and John Irwin “Aspect-Oriented Programming, ” Xerox PARC Technical Report, February 97, SPL97-008 P9710042. http://www.parc.xerox.com/spl/projects/aop/tr-aop.htm [3] Craig Thompson, Ted Linden and Bob Filman, “Thoughts on OMA-NG: The Next Generation Object Management Architecture,” Presented at the OMG Technical Meeting, Dublin, Ireland, September, 1997. http://www.mcc.com/projects/oip/next_oma.html [4] Robert Filman and Ted Linden, “Communicating Security Agents,” The Fifth IEEEWorkshops on Enabling Technologies: Infrastructure for Collaborative Enterprises--International Workshop on Enterprise Security, Stanford, California, June 1996, pp. 86-91. [5] Stu Barrett and Phillip Foster, “Turning Java Components into CORBA Components with Replication,” OMG-DARPA-MCC Workshop on Compositional Software Architectures, Monterey, California, Jan. 1998. http://www.objs.com/workshops/ws9801/papers/paper067.doc [6] Douglas C. Schmidt, Rajeev Bector, David L. Levine, Sumedh Mungee, and Gurur Parulkar, "An ORB Endsystem Architecture for Statically Scheduled Real-time Applications," Proc. IEEE Workshop on Middleware for Distributed Real-time Systems and Services, San Francisco, Dec. 1997, pp. 52-60. [7] Diana Lee and Robert Filman, “Verification of Compositional Software Architectures,” OMG-DARPA-MCC Workshop on Compositional Software Architectures, Monterey, California, Jan. 1998. http://www.objs.com/workshops/ws9801/papers/paper096.html [8] M. Gergeleit, E. Nett, and M. Mock, "Supporting Adaptive Real-Time Behavior in CORBA," Proc. IEEE Workshop on Middleware for Distributed Real-time Systems and Services, San Francisco, Dec. 1997, pp. 61-67. [9] Richard Schantz, David Bakken, David Karr, Joseph Loyall, and John Zinky, "Distributed Objects with Quality of Service: An Organizing Architecture for Integrated System Properties," OMG-DARPA-MCC Workshop on Compositional Software Architectures, Monterey, California, Jan. 1998. http://www.objs.com/workshops/ws9801/papers/paper099.doc [10] Cristina Videira Lopes, and Gregor Kiczales, "D: A Language Framework For Distributed Programming," Xerox PARC Technical report, February 97, SPL97-010 P9710047. http://www.parc.xerox.com/spl/projects/aop/tr-d.htm

6

Operation-Level Composition: A Case in (Join) Point Harold Ossher Peri Tarr IBM T.J. Watson Research Center P.O. Box 704 Yorktown Heights, NY 10598 {ossher, tarr}@watson.ibm.com

1.

Introduction

Our work on subject-oriented programming [1, 2] has focused on two central issues that we believe to be at the core of research in the domain of “aspect-oriented'” software development: • Facilitating the identification and description ofcross-cutting concerns in a software system— i.e., those aspects that affect more than one unit of functionality in the system, given some definition of “units of functionality” (objects, modules, functions, etc.). • Facilitating the identification and integration ofjoin points in the system. Join points are the locations in systems that are affected by one or morecross-cutting concerns. The process of integrating join points involves describinghow a cross-cutting concern affects code at one or more join points. The integration process is referred to ascomposition or weaving. The set of possible join points includes all locations in all system components, which we call statement-level join points to indicate that they can occur in any part of code. Subject-oriented programming, however, is predicated on the belief that a significant majority of join points of concern in software development are those represented byoperations, and that the majority of cross-cutting issues that are of concern to developers are those involving capabilities that affect multiple operations. Additionally, we believe that a focus on operation-level joining isespecially appropriate in an object-oriented context, because it adds the power of composition naturally within the object-oriented paradigm. Operation join points do not necessarily imply specification (or coding) of all aspects as functions. We believe that many of the kinds of capabilities for which aspect-oriented programming might be used, which might at first appear non-functional, do, in fact, involve functional aspects and operation join points. However, there are undoubtedly cases in which nonfunctional specification of aspects, in different notations, is appropriate. Even in such cases, operation join points are often appropriate. The remainder of this position paper explores the broad utility of functional aspects and operation join points, and discusses several issues that affect the feasibility of supporting general statementlevel join points.

2.

The Prevalence of Operation Join Points

Many kinds of cross-cutting concerns affect the definition of collections of operations that span multiple units of functionality. For example, many objects might support aprint capability. The particular way in which this capability works in a given system might depend on one or more system requirements, such as “all print operations will send mail to the system administrator if they cannot complete successfully.”Cross-cutting concerns that affect the behavior of groups of operations typically require the use of operation join points— e.g., to add a check for success after the invocation of each print operation, and to send mail as appropriate. In our experience, a wide range of cross-cutting concerns that affect a system are, in fact, correctly described using operation join points, even when, at first glance, it is not obvious that this would be the case. This phenomenon arises because cross-cutting concerns very often are specified in terms of how they affect existing object behaviors (when they define new behaviors, they can be said to involve operation join points trivially), which makes them amenable to implementation via operation join points. Some examples of these kinds ofcross-cutting concerns, and their description in terms of operation join points, are presented in the following paragraphs. Persistence: Persistence tends to be a pervasive property of data in systems; thus, it would be appropriate to develop a “persistence aspect” that implements the persistence capability independently of any particular objects and compose this capability into those objects that are to become persistent. In deciding how to compose the persistence aspect with the objects to which it will apply, we note that retrieval of persistent objects from a database occurs upon object access, and update of persistent objects occurs upon object creation or modification. Thus, the necessary join points are operations: the “update” part of the persistence aspect affects the constructor and set methods of persistent objects, while the “retrieve” part affectsget methods. Error detection and handling, and fault tolerance : Some forms of error detection are intrinsic to the definition of a type of object; for example, it is always wrong to attempt to pop an item from an empty stack. Such “well-formedness” definitions are usually built into a type. Other kinds of errors, however, are context-specific— their presence depends on the requirements of the particular application in which the types are used. For example, a set of generic, reusable components (e.g., lists, stacks, sets) used in a compiler have considerably looser error handling and fault tolerance requirements than the same components used in a safety-critical system. In such cases, it is desirable to describe the error detection and handling behaviors as one or more separate aspects. Some of the most common kinds of non-intrinsic error handling mechanisms we have seen are those represented as pre- and post-conditions on modify methods. The join points in such cases are operations: pre- and post-condition checks, error-catching methods, and error-handling methods can all be joined to the methods that can cause or encounter the error conditions. There are other cases where one really needs to add additional error checks within existing code; in these cases operation join points are not sufficient (unless one is willing to duplicate code by replacing a function with a copy to which the additional checks have been added). Logging, tracing, and metrics-gathering: Where and when logging, tracing, or metricsgathering activities occur is frequently dependent on application-wide decisions that are determined, for example, by development phase or local policies. Ideally, code to perform these activities would be modeled as an aspect and composed selectively into the relevant parts of an application. All of these activities are usually associated with operations (e.g., to log entry into, and exit from, an operation) and could be composed using operation join points.

Caching behavior: It is often desirable to consider the issue of caching intermediate results in a complex computation as an aspect separate from the algorithm itself. In particular, an algorithm written without caching might need to be modified to include caching upon observation of inadequate performance. In the important case where the computation traverses a network of objects, processing each node to compute some value(s), operation join points are natural. The “process” operation in the algorithmic aspect just performs the computation. The caching aspect of this same operation maintains a cache of the computed value(s), probably in the node itself. It either returns the cached value or invokes the algorithmic aspect, depending on the currency of the cache. Clearly, the composition in this case must give the caching aspect control. Other common cross-cutting issues that affect many applications include serializability, atomicity, replication, security and visualization. We believe that support for these and many other features turn out to be well represented using operation join points. Clearly, functional aspects and operation join points are required and useful for describing and integrating a wide range of important cross-cutting concerns in software systems. For this reason, the subject-oriented programming paradigm supports “aspect-oriented programming” based on functional aspects and operation join points. Part of our ongoing research includes the exploration and validation of the variety of functional and non-functional aspects to which operation-level joining applies.

3.

On General, Statement-Level Join Points

A key element of subject-oriented programming is flexible, domain-independent, generic points at which composition is to occur, and specify the details of the composition desired. It is important that rules continue to work even as the inputs evolve, within reason. Weexcluded statement-level join points for several reasons: • We have not yet found convincing evidence that the additional power resulting from such join points is of general use, particularly in light of the concomitant increase in complexity. This is particularly true in light of the broad spectrum of circumstances under which operation join points appear to be applicable. • The tractability of the problem of defining general-purpose statement-level weavers is questionable. Even stable references to join points in rules present serious problems in the light of evolving inputs. • We are extremely concerned about the degree of unpredictability that results from statement-level weaving. Changing a statement in a piece of code changes both the dataand control-flow properties of that code; any guarantees that might have been made about the code are negated. In fact, much work in the area of software analysis and testing has attempted to identify the impact of changes to code, in an attempt to identify new errors and to help select test cases whose results have been invalidated by the changes. Unfortunately, data- and control-flow analyses are inherently exponential, further suggesting the difficulty involved in understanding the effects of statement-level composition. • One of the significant contributions of object-oriented software development was to make changes additive rather than invasive (see, for example, [3]). This is a particularly important property because of the well-documented, extremely adverse effects on software systems of invasive changes. The notion of general statement-level joins represents invasive software change, violating the additive-changes principle.

In light of these concerns, we do not believe that conclusive evidence yet exists to suggest that the additional power provided by arbitrary statement-level joiningis of sufficiently broad and practical use to justify its potential disadvantages. Indeed, the work on aspect-oriented programming we are aware of has concentrated on weaving in specific domains, and in each case the kinds of join points, though not always operations, are carefully circumscribed. Further research is required to characterize systematically the circumstances under which statement-level joining may be practical and justified, despite its drawbacks.

4.

Conclusion

We believe that the ability to describe capabilities associated with concerns that cut across multiple parts of a system and to specify how those capabilities affect the system, without having to physically intersperse the code that realizes such capabilities, is an extremely important part of support for programming-in-the-large. Used correctly, this capability, which defines aspectoriented programming, can reduce the complexity and improve the maintainability of a system considerably. Identifying the points at which a cross-cutting concern affects a system is an important part of aspect-oriented programming. While the set of potential “join points” is large and could, potentially, include every statement and expression within a system, our research suggests that focusing on operation-level joining can successfully address many common composition needs, for both functional and non-functional aspects. Further, we believe that general statement-level joining raises numerous technical and methodological concerns that may render it intractable, infeasible, or undesirable in the general case. Further work is needed to test and extend this conclusion. Subject-oriented programming is an approach to aspect-oriented programming that is based on operation-level joining. Subject-oriented programming thus avoids the problems inherent in general statement-level joining, while providing the ability to describe many kinds of crosscutting concerns separately and to compose cross-cutting capabilities into object-oriented programs. It also preserves and extends many of the desirable features of the object-oriented paradigm. The choice of join points has made it possible to develop a general-purpose, domainindependent compositor, which is central to our tool support[4].

5.

Bibliography

[1] William Harrison and Harold Ossher. Subject-oriented programming (a critique of pure objects). In Proceedings of the Conference on Object-Oriented Programming: Systems, Languages, and Applications, pages 411–428, Washington, D.C., September 1993. ACM. [2] Harold Ossher, William Harrison, Frank Budinsky, and Ian Simmonds. Subject-oriented programming: Supporting decentralized development of objects. InProceedings of the 7th IBM Conference on Object-Oriented Technology, Santa Clara, CA, July 1994, IBM. Available as Research Report RC 20004, IBM T.J. Watson Research Center, Yorktown Heights, NY, March 1995. [3] John Vlissides. Subject-Oriented Design. InC++ Report, February 1998. [4] http://www.research.ibm.com/sop

Mixin Composition Strategies for the Modular Implementation of Aspect Weaving The EPP preprocessor and its module description language Ld-2 Aspect Oriented Programming workshop at ICSE'98, April 20th, 1998, Kyoto 1

2

Yves ROUDIER , Yuuji ICHISUGI

froudier,[email protected]

1 STA Fellow - Electrotechnical Laboratory, 2 Electrotechnical Laboratory Computer Science Division 1-1-4 Umezono, Tsukuba, Ibaraki 305 JAPAN

EPP (the Extensible Preprocessor) is an extensible language preprocessor; it was designed to introduce new language constructs by the mere addition of plugin modules that can also de ne new syntaxes and macro de nitions. The relation of EPP to AOP is twofold. First, the EPP kit has been programmed using the Ld-2 language which introduces aspect-oriented constructs: system mixins. Second, we suggest that EPP could be used to program aspect-oriented weavers in a modular fashion. We describe here the new Java version of EPP. We also discuss the constructs needed for providing additional capabilities regarding the composition of extension modules that could serve in writing weavers. Abstract:

1

get these problems and thus shed a new light on possible solutions. However, this approach delegates many problems to the aspect weaver which has to gather aspectual code, process it according to aspect descriptions and generate the nal program. If the size of a system becomes quite large, complexity will also increase. Aspects seem to be somehow domain dependent: if the system grows, it is rather likely that more aspects will be needed to describe it. For now, we can only think of rather simple aspects, but there could be a need for more complex ones as well (although not as complex as the systems they will help to describe). Decomposing the aspect weaver into smaller composable units would both simplify the task of programming a weaver and allow to reuse parts of the aspect description. But to date, a very limited number of tools has been developped that could readily address, in a generic manner, the de nition of weavers with such kind of modular units.

Issues in AOP

The traditional approach to software programming has been to modelize a problem by de ning independent components, be it under the form of objects or functions. Global interactions between components and with the program environment arise, but only implicitly, from their local calls: this is a major drawback when this global interaction (or other mechanisms involving parts of several components) is the most important de nition in the software, especially if it must be ne-tuned. For instance, parallel or reactive systems often exhibit these characteristics. Re ective systems are good at solving some of these issues but do not seem so well adapted for dealing with composition problems or syntactic issues in a simple manner. These problems get worse when the size of the system grows. The programmer needs to isolate parts of its components in relation with others (untangling). Moreover, introducing speci c syntax is very important, would it only be because many formalisms and formal systems have already been developed and could improve the quality of programs.

2

The

module

description

language Ld-2

We rst introduce an object-oriented language, Ld2 (Language for di erential description) [IHT+ 96, RI97b]. Ld-2 provides a mechanism, system mixin,

Aspectual approaches (e.g. [LK97]) directly tar1

mixins are similar to mixins but the unit of inheritance is not a class but the whole program. The second program in Fig.1 uses the system mixin feature and has the same meaning as the rst one; however, its structure is much more modular. The keyword SystemMixin de nes a system mixin, that is, a fragment of the program. All system mixins are composed into a complete program before starting up. The expression original(d) is similar to the method invocation to the super class in traditional object-oriented languages. When the method m is called, the fragment of method m de ned in B will be called. If the fragment evaluates original(d), the next fragment de ned in A will be called. If there are subclasses of class Foo, the extension of method m will be propagated to all of them.

which enables the program to be split according to di erent points of view into small reusable modules.

2.1 System Mixins The rst program in Fig.1 de nes a method named m which contains nested if statements. This method is written in a traditional style, in other words, in a \monolithic" way. When a programmer wants to add a new else-if clause to this method, the only way to do so is to edit the source code. By using the inheritance mechanism, some editing can be avoided, but this changes the name of the class where the method belongs. It is indeed impossible to extend the behavior of the method without de ning a new subclass. If at some other place in the program, there exists the de nition class Bar extends Foo f1 1 1g or the de nition new Foo(), all Foo occurrences have to be changed to the name of the subclass.

2.2 An AO layout in Ld-2

class Foo { void m(String d){ if (d.equals("B")){ doB(); } else if (d.equals("A")){ doA(); } else { doDefault(); } } SystemMixin Skeleton { class Foo { define implement void m(String d){ doDefault(); } } } SystemMixin A { class Foo { extend void m(String d){ if (d.equals("A")) { doA();} else { original(d);} } } } SystemMixin B { class Foo { extend void m(String d){ if (d.equals("B")) { doB();} else { original(d);} } } }

Figure 1: Method de nitions with and without system mixins. Ld-2 solves this problem by introducing system mixins. Bracha [BC90] showed the exibility and reusability of mixin-based inheritance. System 2

Among other styles, system mixins allow programming \by di erence", a form of aspect-oriented programming. Intuitively, the API of the application should be de ned as a description of small components. The base object-oriented language is very well adapted for expressing these matters. Classes should remain the common reference, especially for teamwork. After this rst description has been written, cross-cutting concepts can be introduced by other system mixins. Classes or parts of classes are distributed among system mixins, then programmed. A system mixin thus roughly corresponds to an aspect or to part of an aspect (either if it is complex or for reuse reasons, in a mixin style). The choice of classes or parts to be added to a mixin is equivalent to chosing join points in other approaches (decided inside of the aspect weaver). Of course, each system mixin can introduce new join points by de ning new classes, which could be regarded as de ning aspects of aspects. We generally nd it preferable to de ne a kind of abstract system mixin containing all these classes de nitions (but only class de nitions). All other system mixins simply introduce additional aspects. As usual in object-related designs, this double de nition of components interface and crosscutting system mixins should probably follow an iterative design (and should in fact already take place in the requirements speci cation). The nal composition depends on the order of speci cation of system mixins, mostly decided for dependency reasons, but can also be a deliberate choice of the

Name AutoSplitFiles defmacro EmbedCopyright enum OptParam UserOp Math assert noassert SystemMixin Symbol BackQuote

Function Splits multiple public classes in one le to multiple les. Macro de nition with the same style as #de ne . Embedding a message into all class les. Constant integer de nition. Optional actual parameters. Operators for user de ned data types. Using java.lang.Math with easier way. Assert macro. Translates assert macros to null statements. Supporting programming-by-di erence. Same as lisp's symbols. Same as lisp's back quote macros. Table 1: Plugins currently provided.

programmer to select features from a special system mixin.

just before starting up the program. 3

2.3 Related constructs

A generic extensible preprocessor kit: EPP

Flavors and CLOS [Ste90] provide before and after daemon methods that are related to the system mixins because they can add extra behavior to existing methods without changing their class name and method name. However, daemon methods are a more restricted mechanism than system mixins. For example, it is impossible to add multiple before (or after) daemon to one method. Objective-C has a notion of \category". Using categories, the programmer can add new methods to the existing class hierarchy. A third party programmer can add methods to existing class libraries even if their source code has not been supplied. However, it is impossible to extend existing methods without subclassing. Some design patterns [GHJV93] which enhance extensibility o er an analogy to system mixins. For example, decorators are units of extension and multiple decorators can be composed simultaneously. However, applying the Decorator pattern requires explicit method delegation which is not required by the system mixin construct. In addition, the Decorator pattern requires a xed interface for decorators. Therefore, exibility is worse than system mixins. Of course the comparison is dicult because decorators are just patterns and not language constructs. Decorators also de ne the way they can be dynamically composed during the execution of the program. As opposed to this design, the con guration of the system mixin list is xed

To implement new languages or extend existing ones, pre-processors or translators are often used rather than native compilers (e.g. many tools for C/C++). The merits of this style of implementation are its simplicity and high portability; moreover, preprocessors o er a form of re exivity since the introduced extensions are ultimately described in the extended language. We argue that the interest for such tools is symptomatic of their power of description of (admittedly often simple) abstractions of the code, and sometimes the possibility to deal, at least partly, with tangling issues. Syntactic issues are especially often adressed and preprocessors clearly help increase programs declarativeness.

3.1 Preprocessing tools The Java language [GJG96] has recently become very popular among programmers but lacks facilities for language extension o ered by many other object-oriented languages. For instance, C++ provides at least a macro pre-processor and has operator overloading and template facilities; Smalltalk and CLOS [Ste90] have closures and metaclass facilities. These features extending language constructs and operators supplement the class mechanism which extends data types. Many extensions have been proposed for the Java language and often implemented as pre3

processors. Although there are potentially many useful language extension systems, extensions are often exclusive: it is generally impossible to merge several language extensions or eliminate harmful features from the extended system. Systems with a meta-object protocol (MOP) such as CLOS [KdRB91], MPC++ [Ish94], OpenC++ [Chi95], EC++ [C+ 97] or JTRANS [KK97] have solved this problem. These systems allow the implementation of language extensions as modules that can be selected by the users. Yet, extensibility of syntax is slightly restricted in these systems; composition of extensions is often not the main interest of these systems either.

#epp "enum" public class EnumTest { enum {RED, GREEN, BLUE} enum { MALE, FEMALE, } public static void main(String argv[]){ System.out.println(EnumTest.RED); } }

Figure 2: A program using a enum plugin. /* Generated by EPP 1.0beta3 (by lisp-epp1.0beta3) */

3.2 EPP: the preprocessor kit

public class EnumTest public static final public static final public static final public static final public static final

The Extensible PreProcessor kit, EPP, is a generic extensible preprocessor: it provides an application framework for writing preprocessor type language extension systems. EPP basic behavior is to transform a Java source code into the same program. By using the hooks provided by EPP recursive descent style parser the extension programmer can extend this basic behavior: he can introduce new features, possibly associated with new syntax without editing the existing source code of EPP. Because all grammar rules are de ned in a modular way, it is also possible to remove some original grammar rules from standard Java. Once the parsed program has been transformed into a tree, the pre-processor programmers can easily manipulate it from their program. The usefulness of such kind of tool has already been proven by Lisps and adapted to C++ by various systems like Sage++ [B+ 94], MPC++ [Ish94] or OpenC++ [Chi95]. EPP enables preprocessor programmers to write extensions as separate modules that are nally composed to form a complete preprocessor. We call these extension modules plugins. High composability of EPP plugins can be realized thanks to the module description language Ld-2 and the system mixin feature. The inheritance mechanism of object-oriented languages makes it easy to implement extensible applications because all methods of objects can be considered as hooks for extensions. In addition to the traditional inheritance mechanism, system mixins encourage the development of extensible and modular software. The rst prototype of EPP (lisp-epp) was written in Common Lisp [Ste90]. Using this system, several plugins have been implemented in-

}

{ int int int int int

RED = 0; GREEN = 1; BLUE = 2; MALE = 0; FEMALE = 1;

public static void main(String argv[]){ System.out.println(EnumTest.RED); }

Figure 3: The translated program. cluding a simple parallel language: Tiny DataParallel Java [IR97] and a reactive programming extension [RI97a]. The source code of lisp-epp is now re-written in \Java extended by EPP" itself. The bootstapped byte-code is available on any platform where Java is supported. Plugins also work on any platform, therefore they can circulate and be used as casually as class libraries written in Java. Although the current target of pre-processing is only Java, the architecture of EPP is applicable to pre-processors for other programming languages.

3.3 An Example of an EPP plugin The user of the pre-processor can specify an EPP plugin at the top of his Java source les. The plugin will be dynamically loaded by EPP before starting the pre-processing. Fig. 2 is a simple example program using an EPP plugin that de nes an enum macro. Fig. 3 is the translated program. Each element of the enum declaration is expanded into static nal eld declarations. The plugin is a Java class le written in \Java extended by EPP". Fig. 4 shows how the source 4

code of the enum plugin looks like. The source code makes use of four plugins (see Table 1 which explains the function of each plugin). The source code consists of two parts: the de nition of the extended syntax and the de nition of the macro expansion function. The rst part will add a \patch" to the recursive descent parser in order to add a new grammar rule of enum declaration. The second one de nes a function which translates an enum declaration into a static nal eld declaration.

#epp #epp #epp #epp

package enum; import epp.*; SystemMixin enum { class Epp {

3.4 Parser design

extend Tree classBodyDeclarationTop() { if (lookahead() == :enum) { matchAny(); TreeVec tvec = new TreeVec(); match(:"{"); while (true){ if (lookahead() == :"}") break; tvec.add(identifier()); if (lookahead() == :"}") break; match(:","); } matchAny(); return new Tree(:enum, tvec); } else { return original(); } }

Code generation is not the only part of EPP written in Ld-2. The parser itself is basically written in a recursive descent style [ASU87], using the system mixin feature. Each function which parses a non-terminal consists of nested if-then-else branched by the value of a look-aheaded token. The plugin programmer can add new else-if clauses to the methods in order to add new operators or new statements. As shown in gure 4, it is possible to manipulate the abstract syntax tree of the program without special problems. The nal parser is composed of the original parser plus several patches in the order chosen for the composition of system mixins. 4

"Symbol" "SystemMixin" "AutoSplitFiles" "BackQuote"

Beyond system mixins: an

}

architecture for the weaver

}

extend void initMacroTable() { original(); defineMacro(:enum, new EnumMacro()); }

class EnumMacro extends Macro { public Tree call(Tree tree){ Tree[] args = tree.args(); int c = 0; TreeVec top = (TreeVec)Dynamic.get(:beginningOfClassBody); for (int i = 0; i < args.length; i++){ top.add( `(decl (modifiers (id public) (id static) (id final)) (id int) (vardecls (varInit ,(args[i]) ,(new LiteralTree(:int, Integer.toString(c++)))))) ); } return `(emptyClassBodyDeclaration); } }

From their primary objectives, most aspects seem to be domain dependent. Most probably, aspects can be grouped in families from which basic bricks could be extracted for describing their common points. Aspects are also fairly specialized, hence avoiding combinatory explosion should also be a concern of weaver programmers. Our position is that these basic bricks should not be classes but system-wide mixins (used in an AOP fashion or not). As a side e ect, using mixins is a good way to preserve alternative designs for weavers, and potentially to ne-tune aspect implementations at run-time. For these reasons, we will essentially focus on the use of system-wide mixins for designing weavers.

Figure 4: The source code of enum plugin.

5

We have experimented with Ld-2 system mixins rst in the Lods compiler kit [IHT+ 96] and more recently for programming EPP extension plugins and have found them a very suitable and simple tool for improving program organization. However, they provide only a limited form of compositionality. The standard composition rule of mixins is a simple, additive fusion of constructs in the order explicitly determined by the programmer (system mixin dependencies). Of course, each system mixin can itself de ne additional classes which can be extended by other system mixins: this slightly enhances the model compositionality and could permit to program aspects of system mixins (themselves aspects or parts of aspects). Improving composition capabilities should enhance the reusability of system mixins. Moreover, de ning a general architecture of aspects is very desirable: it would document the weaver and could keep knowledge about good or bad designs (for performance improvement or compatibility for instance: e.g. which aspects should not be used together ?).

mixins and explicitly conveying the composition description. The purpose of this approach should be to expose all connections between components of a weaver, which we feel is especially important if we adopt a mixin-based solution. Similar approaches have been undertaken like pattern languages [KC97] which can be used to de ne relations between di erent patterns; semantic nets are another example of such composition model. In EPP, plugins must be assembled in a determined order which is speci ed in a setup list; this list can be seen as a set of precedence relations between the di erent plugins. Other relations are most probably interesting: policy for merging several plugins (addition, replacement, partial replacement, etc.), contracts to ensure the delivery of information between system mixins (in a data owdriven fashion), logical assertions, and so on. Relations are probably not only two-party but more probably multi-party: think for instance of how to combine several overlapping system mixins to form an aspect. It is possible to use relations to represent possible or unacceptable design alternatives, especially in a mixin approach as we noted; the programmer could be able to select among a set of mixin strategies to implement his plugins (aspects descriptions). Introducing such complex relations would probably also mean adding an interface to system mixins for connecting related types of relations. Since extended plugins can be very general, these interfaces should also be parametric on the relations in input: this would permit the most abstract de nition to be possible. For instance, if an information is expected by a plugin, it could be parameterized to o er pattern-like generative properties. Component litterature should probably be reread with aspects in mind instead of direct composition of components. The granularity of extended plugins certainly in uences their reuse, but in this approach, their composability essentially depends on the kind of relations that they can support and establish with other extended plugins. That way, building an aspectual weaver would be nearly transformed into merely connecting them with relations. A relational approach is probably more dicult to design than a re nement one (that we can program now with existing tools), but would surely bring important bene ts for code organization. As a side note, it might well be possible to use

4.1 Successive re nement approach A rst approach to introducing more compositionality in our design is to build a weaver as the successive application of smaller weavers, that is by applying a re nement process: the original program (possibly written using several languages) is transformed into simpler forms by the repeted application of simple transformations. In this approach, the nal program is the result of a series of rewritings. This approach can be re ective if the process applied at each step is the same: see for instance compile-time MOPs with an recursive generation of meta-objects. The speci cation of the di erent re nements is quite simple in itself, especially in a meta-object architecture where each meta-object is a modular unit. However, global interactions of several mixins/aspect descriptions is not explicitable (except maybe by introducing group re ection, but which might then result in di erent implementations) and the composite architecture is not directly visible or even representable in a detailed way, apart from the succesive weavers applied.

4.2 Relational approach This is why we are currently studying the introduction of a notion of relation connecting system 6

that the aspect language has to take the method listing plugin's output and use it to replace the parameter in the guard plugin: for every method listed, a new guard would be produced (in the absence of a speci cation, the default behavior being to preserve the method service untouched). The input and output arrows do not have the same meaning as the other ones, since they in fact represent les that are used as input/ouput by run-time components (run-time meaning weaver run-time, not nal program run-time). The usefulness of a relational model depends probably on what relations are expressible and easy to understand at the same time (and on what kind is not).

this approach with the previous one. The former approach could be an especially easy way to implement aspects able to survive weaving and providing run-time adaptations as suggested in [MJV+ 97].

4.3 Example sketch In parallel object-oriented languages, guards are good instances of aspects. They can either be implemented as an usual extension for active object languages (possibly using re exive techniques); or guards in themselves can be a program describing the synchronization of all components of the system, separately from the program, in relation with objects decomposition (for a more concrete example, have a look at [LK97]). Many kinds of guards can be described: the term essentially speci es the protection of a routine by some test, but it is possible to specify that restrictions be incrementally added (e.g. [Fro92]) or to de ne guards conditions exclusively expressed on synchronizations variables, etc. De ning an aspect language for each of these di erent guards is possible but clearly restrictive. Moreover it is not informative as to what are the possibilities for implementing guards. On the contrary, it is rather natural to construct more basic modules for describing all possible guard languages, like for instance: -

5

Visualization

and

docu-

mentation issues

An important purpose of modularizing the weaver description is to be able to represent and document aspects interactions. Using diagrams and providing a visual interface for assembling them into a weaver is important in this respect. Many examples (e.g. JavaBeans for components assembly and event dispatch description, KLIEG [STST97] for describing behavioural patterns, ...) show the interest of visual environments for component assembly. In an aspect-oriented approach, visual tools could be developped for programming aspects (user-oriented) or for coordinating aspect descriptions in the weaver (for advanced users and for user documentation). In relation with the study of relations, we intend to provide an environment for composing system mixins with a graphical interface close to Fig. 5. For instance, in EPP, instead of writing the plugin setup by hand, the user would be able to graphically build it as a graph of precendence relations between plugins. Is a graphical description really enough if we want to deal with libraries of elementary components for aspect description (especially, what about the size of such libraries) ? Textual documentation is a very important part of software. Can documentation or speci cation (think of assertions for instance) be considered as aspects ? For instance, literate programming [Knu92] relies on separate de nition of documentation through a kind of anchoring technique which allows to write pseudo-code and to reference other parts of a \program". Its intent is however notably di erent from AOP, since it is presented as

, de ning how to relate some piece of code with any method; - synchronization variables, providing a declarative framework for de ning synchronization variables; - condition restriction, de ning how to check that conditions are increasingly strengthened; - etc. methods listing

These modules correspond to di erent choices of implementation for guards, but they cannot be combined in an arbitrary manner; they are also more general than a direct implementation of a speci c type of guard since no commitment to a complete combination of their di erent features is done by default. A guard aspect would provide a language for associating the e ective service of a method request with conditions: such an aspect language could, among other possible solutions, depend on modules like method listing and synchronization variable. Fig. 5 represents a possible con guration where we would de ne the synchronization variables based guard with a parameter concerning the method it controls. A relation would be de ned to express 7

Figure 5: Synchronization variable based guard: relational graph of plugins composition \the combination of documentation and source together in a fashion suited for reading by human beings", but should there be a special organization for aspects or aspect-weaving documentation ? How to document aspects, and more speci cally the integration of aspects ? To be able to use an aspect correctly, it should be available with lots of informations. The weaver part may need a documentation close to that of patterns (which seem to share many similarities) while an aspect could sometimes be documented by a formal model. 6

process or a relational design. We plan to experiment with our environment (especially the second approach), especially to test the interest of the graphical tool for reuse. We expect from these experiments a better insight on common characteristics of aspects which might help design speci c mixins and relations, maybe for adressing speci c families of problems. References [ASU87]

Conclusion

[B+ 94]

We described the extensible pre-processor kit EPP, a generic extensible preprocessor for Java, and its module description language Ld-2 which provides an aspect-oriented construct: system mixins. EPP is extensible through plugin modules written in Ld2; among other things, these plugins can introduce new grammar rules in the original language. We have already used EPP for writing several language extensions and think that aspect weaving implementations could be treated as preprocessing extension composition issues. Part of our design philosophy is: developing a tool simple enough for being used by the average programmer yet unrestrictive enough to be extended in many ways. We are currently working on the extension of system mixin composition capabilities and the possibility of a visual support environment for composing them. We suggested that aspect descriptions be composed to form a weaver from system-wide mixin building blocks and described two major approaches to their composition: a re nement-based

[BC90] [C+ 97]

8

A.V. Aho, R. Sethi, and J.D. Ullmann. Compilers: Principles, Techniques and Tools. Addison-Wesley Publishing company, 1987. F. Bodin et al. Sage++: A Class Library for Building Fortran and C++ Restructuring Tools. In Proc. of Object-Oriented Numerics Confs., Oregon, April 1994. G. Bracha and W. Cook. Mixin-based Inheritance. In Proc. of ECOOP/OOPSLA'90, 1990. D. Caromel et al. Europa Parallel C++ version 2.1. In Future Directions for Parallel C++, June 1997. http://www.dcs.kcl.ac.uk/Future Directions/.

[Chi95]

S. Chiba. A Metaobject Protocol for C++. In Proceedings of OOPSLA'95, volume 30(10) of ACM Sigplan Notices, pages 285{299, Austin, Texas, October 1995. ACM Press.

[Fro92]

Svend Frolund. Inheritance of synchronization constraints in concurrent objectoriented programming languages. In O. Lehrmann Madsen, editor, Proceedings of the ECOOP'92, volume 615 of Lecture Notes in Computer Science, pages 185{196,

[MJV+ 97] Frank Matthijs, Wouter Joosen, Bart Vanhaute, Bert Robben, and Pierre Verbaeten. Aspects should not die. In ECOOP'97 workshop on aspect-oriented programming, 1997. [RI97a] Yves Roudier and Yuuji Ichisugi. Integrating data-parallel and reactive constructs into java. In proceedings of the 2nd FranceJapan Workshop on Object-Based Parallel and Distributed Computing (OBPDC'97), Toulouse, France, October 1997. [RI97b] Yves Roudier and Yuuji Ichisugi. Java data-parallel programming using an extensible preprocessor. In proceedings of SWOPP'97 (Summer united WOrkshops on Parallel, distributed and cooperative Processing), Kumamoto, Japan, pages 85{ 90, June 1997. [Ste90] G.L. Steele. Common Lisp the Language, 2nd edition. Digital Press, 1990. [STST97] Etsuya Shibayama, Masashi Toyoda, Buntarou Shizuki, and Shin Takahashi. Visual Abstractions for Object-Based Parallel Computing. In proceedings of the 2nd France-Japan Workshop on ObjectBased Parallel and Distributed Computing (OBPDC'97), Toulouse, France, October 1997.

Utrecht, the Netherlands, July 1992. European Conference on Object-Oriented Programming, Springer-Verlag. [GHJV93] Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design patterns: Abstraction and reuse in object-oriented designs. In O. Nierstrasz, editor, Proceedings of ECOOP'93, Berlin, 1993. SpringerVerlag. [GJG96] J. Gosling, B. Joy, and Steele. G. The Java Language Speci cation. Java Series. Sun Microsystems, 1996. + [IHT 96] Yuuji ICHISUGI, Satoshi HIRANO, Hitoshi TANUMA, Kuniyasu SUZAKI, and Michiharu TSUKAMOTO. Compiler Widgets | Reusable and Extensible Parts of Language System | (in Japanese). In The 11th workshop of object oriented computing WOOC'96, Japan Society of Software Science and Technology, March 1996. [IR97] Yuuji Ichisugi and Yves Roudier. The extensible java preprocessor kit and a tiny data-parallel java. In Yutaka Ishikawa, Rodney R. Oldehoeft, John V. W. Reynders, and Marydell Tholburn, editors, proceedings of ISCOPE'97 (International Scienti c Computing in Object-Oriented Parallel Environments Conference), December 8 - 11, 1997, Marina del Rey, California, USA., number 1343 in LNCS, pages 153{ 160. Springer-Verlag, 1997. [Ish94] Y. Ishikawa. Meta-level Architecture for Extendable C++, Draft Document. Technical Report Technical Report TR-94024, Real World Computing Partnership, 1994. [KC97] Norman L. Kerth and Ward Cunningham. Using patterns to improve our architectural vision. IEEE Software, pages 53{59, January/February 1997. [KdRB91] Gregor Kiczales, Jim des Rivieres, and Dan Bobrow. The Art of the Meta Object Protocol. MIT Press, 1991. [KK97] A. Kumeta and M. Komuro. MetaProgramming Framework for Java. In The 12th workshop of object oriented computing WOOC'97, Japan Society of Software Science and Technology, March 1997. [Knu92] Donald E. Knuth. Literate Programming. Technical report, Stanford University Center for the Study of Languages and Information, Leland Stanford Junior University, 1992. [LK97] Cristina Videira Lopes and Gregor Kiczales. D: A Language Framework for Distributed Programming. Technical Report SPL97-010 P9710047, Xerox PARC, February 97.

9

Extending Aspect-Oriented-Programming In Order To Flexibly Support Workflows R. Schmidt, U. Assmann, Forschungszentrum Informatik (FZI) and Universität Karlsruhe email: [email protected], [email protected]

The problem Aspect-Oriented Programming [KILL97], [Kicz97] has been used to introduce a new unit of modularity for the systemic, non-functional concerns of applications such as error-handling, synchronization, etc. The aspect decompositions of the problem domain have been identified as being of importance [Berg97], but have not been further developed yet. Furthermore, although aspect-oriented-programming separates the design, specification and implementation of different aspects, it still follows the classical software design cycle. Therefore it is not possible to change an implementation without running through the complete design cycle. Frequent changes to implementations are necessary in many application domains, such as workflow processing. Workflows are an important means for supporting process-based cooperations such as business processes, software development etc. They are formally defined by a workflow model which can be separated into socalled workflow-aspects, representing discretemodelling domains [Jabl95]. One important workflow aspect is the functional aspect, describing the workflow’s decomposition into sub-workflows. It should not be confused with the functional aspect in Aspect-Oriented Programming. Other aspects are thecontrol aspect, responsible for directing the execution of workflows, thedata aspect, covering the data exchange between sub-workflows, the operational aspect, describing the operations performed in the sub-workflows; and the organizational aspect, representing the relationship to the organizational structure of the enterprise. These aspects are necessary to execute a workflow and are called imperative aspects. There are also workflow aspects, whose specification is not necessary to execute the workflow, but increase the quality of it’s execution. These workflow aspects are called optional aspects. One example is the persistence aspect, covering the persistence of workflow data. The development of software architectures for supporting workflows is driven by the requirement to flexibly adapt to workflow changes. Since business processes often have to be changed due to market requirements, the workflows implementing the business processes have to be changed, also. Traditional software development, and even object-oriented methods have failed to fulfill this requirement. Using this “direct” approach, the workflow aspects are not dealt with separately, but tangled in the implementation. If, for example, the control flow in an workflow has to be adapted, all participating objects have to be changed, because the control flow is embedded in each of them. To overcome the deficiencies of the direct implementation, workflow-management-systems (wfms) [Jabl95] have been developed. They allow the definition, execution and monitoring of workflows with both human and machine-based actors. Basically, wfms represent a virtual machine. A formal model of the workflow is interpreted, executed and supervised by a so-called workflow-engine. The virtual machine approach allows the easyadaption of workflow changes by changing the workflow model represented in the wfms. This is possible, because the different aspects of the workflow are not firmly connected through the virtual machine. For example, because the control aspect is kept separate from the single workflow operations, it is possible to rearrange flexibly the single workflow operations to reflect workflow changes. However, the flexibility gained by interpreting the workflow is paid for dearly in the form or reduced performance which is further diminished by the centralized workflow engine, which hampers the enterprise-wide use of wfms. Many approaches to create new wfms-architectures try to circumvent these deficiencies. Some try to apply new processing models, such as an event-based one, or they attempt to go way back to the direct implementation, to achieve higher performance. Event-based support for workflows has already been proposed by [ChRa90]. According to this approach, workflows are transformed into event-dependencies. 1

Although this approach seems promising, one has to realize, that the problem of distributing workflow execution has not been solved by replacing it by the problem of distributed processing of event dependencies. An approach which reverts back to direct workflow support is Meteor2 [DKMS96]. Meteor2 avoids central bottlenecks by distributing the processing of workflows to task-managers which supervise the execution of the parts of the workflow called tasks. Task-managers are activated by their predecessor task managers and activate consecutive task-managers upon the fulfillment of certain conditions. Task-managers are created by “compiling” the task’s definition. Therefore, in order to adapt to workflow changes, old task managers have to be replaced by new ones, reflecting the changes. This approach creates a number of problems. First, generating a new version of the task-manager requires completely running through the software development process. Second, exchanging the task-managers means a great amount of effort, especially if this has to be done system that is running. It is questionable, whether or not all task-managers can be replaced at once, therefore mechanisms are required which enable the coexistence of old and new versions. Third, changes have to be coordinated, for example, if task-managers participate in different workflows. In summary, if one reverts to direct workflow support, more and more of the deficiencies of this approach appear. Therefore, designing architectures for workflow support creates a dilemma. Approaches based on virtual machines are flexible in adapting to workflow changes, but suffer in terms of performance. Architectures that directly implement workflows offer good performance, but are inflexible in adapting to workflow changes. Existing approaches fall in-between the two extremes when trying to find a solution, but never identifying the main reason for the dilemma, which is the fact that the aspects in the “direct” workflow implementation are tangled togehter making it impossible to treat them separately.

Position Our thesis is, that combining Aspect-Oriented Programming and the decomposition of workflows into different workflow aspects allows an escape from this dilemma. However, in order to fully solve the problem of flexibly and effectively supporting workflows, Aspect-Oriented Programming has to be extended with ideas found in component-based technologies such as JavaBeans [Beans] or ActiveX/DCOM [Chap96]. Our vision is to fuse Aspect-Oriented Programming and component-oriented systems by paying special attention to domain-specific aspect-oriented models, such as workflow models, in order to obtain the best of both worlds.

Workflow model

Aspect specifications

Aspect implementations

Aspect weaver

Workflow application

Figure 1: Workflow-support through aspect-oriented-programming

2

A first step towards realizing this vision is made by viewing the decomposition of workflows into workflow aspects, as an decomposition of the problem domain into different aspects, as proposed by [Berg97]. Starting with the workflow model, theaspect specifications are made. The aspect specifications are the basis for the implementation aspect implementations. These implementations, whichstill are not compiled, are combined by the aspect weaver to an workflow application. It is important to note that in the workflow application, the aspects are no longer dealt with separatly. Supporting workflows in this way, allows one to benefit from the many advantages of Aspect-Oriented Programming. Workflow changes can be adopted much easier, because the aspects are dealt with separately. However, the whole software development cycle still has to be run through, because it is not possible to exchange parts of the workflow application, to represent changes in the workflow. Aspect-Oriented Programming maintains the separation of aspects until the aspect-weaver combines the different aspect implementations. However, in the workflow application the aspects are tangled together again. The exchange or modification of aspect implementations in workflow applications is possible with the mechanisms found in component-based frameworks such as Enterprise JavaBeans [Beans] or ActiveX/DCOM [Chap96]. The term “component” used in this context should not be confused with the components and connectors found in architecture definition languages [Medv97]. Component-based frameworks aim at enabling the cooperation of independently developed software-units, called components, even across computer and network boundaries. Furthermore, they want to enable the independent evolution of components. Architecture definition languages [Med97] and architectural styles are description models and aim at the structural description of software systems. They try to give a more abstract view of software systems than object-oriented methods do,for example, [GaSh93] and allow analyses with broader view. The scope of component-based frameworks is the single component, whereas architecture definition languages take the whole system into consideration. Two concepts in component-based frameworks can be used to exchange aspect-implementations even in the application: The first concept is that of strong interfaces that completelyhide the implementation and the implementation model of the aspect from other aspects (In ActiveX/DCOM for example, interfaces are defined at the binary level, although more comfortable language adaptations exist). Therefore, one aspect implementation can be replaced by another one, as long as the same interface is supported. The second concept is implicit interface invocation. In a component-based framework, the component supporting an interface is never directly addressed. This would imply that the user of the component has to know the identity and the location of a component. Therefore, the user of a component onlyspecifies the interface required and the component-based framework returns a reference to a component providing the interface. This reference may be a component but also an representative, such as a proxy. The user of the component does not see any difference. The information about the interfaces and the location of a component implements is stored in a registry or repository and not in the components themselves. An application built from aspects implemented as components differs from applications built with Aspect-Oriented Programming. The aspects implemented as components do not address one another directly, but address each other using the indirection mechanisms described above. Therefore, it is possible to exchange aspect implementations flexibly and even to relocate them to another computer using implicit invocation. The components composing the application, may not form a single executable, but can be distributed across different computers.

3

Aspectspecification Aspectimplementation

selection

Components

Pre-fabricated Components

Component weaver Weaving information Implementation

Component-based framework Easy exchange of aspect implementations

Figure 2: Component-based Aspect-weaving Extending Aspect-Oriented Programming with the concepts of component-based frameworks changes Aspect-Oriented Programming in the following manner (seeFigure 2). The different aspects of the applications are not directly combined by the aspect-weaver, but are first compiled into aspect-specific components, containing the implementation ofonly one aspect. Then the aspect-specific-components are combined with an so-called component-weaver. Also pre-fabricated components can be used, which are selected using the aspect specification. The use of pre-fabricated components makes it necessary, for weaving information to be provided for the component-weaver, because these components are generic and contain no information about how to connect with the other components. Finally, the component-weaver creates an implementation consisting of the aspect-specific components, glued together as made possible by component-based frameworks. Therefore, components can easily be replaced to reflect aspect changes. Central to this concept is the component-weaver, which has to work differently from the aspect weaver because components do not allow access to their implementations details, such as their source code. The component-weaver uses two mechanisms: Introspection allows one to gain knowledge about the component’s interfaces without knowing its implementation. For example, Java Beans provides two mechanisms for introspection, reflection and the BeanInfo class.Reflection allows to know about all methods of a component without further programming. The BeanInfo class gives complex information about a Bean component, but has to be implemented explicitly.Specialization allows a component to be changed without access to its implementation. Specialization in Java Beans is supported by property sheets and customizers. Property sheets offer a simple specialization mechanism which sets the parameters of the Bean. Complex specializations can be done by customizers. Both introspection and specialization are used by the component weaver to combine the aspect implementations. The introspection mechanisms give the component weaver information about the connection points of the component, that means, how other component implementations can be connected to the component. The specialization mechanisms are used to connect one component to another component.

4

Combining the beneficial portions of other approaches results in our overall approach which extends AspectOriented Programming. It is illustrated in Figure 3). The different workflow-aspects from the workflow model are implemented as components which contain introspection and specialization mechanisms, allowing them to be used with a component weaver. Not all aspects have to be implemented from scratch, because generic workflow functionality may also be introduced by adding pre-fabricated components. They may be selected from a component repository or even a component market, using the specification of the workflow model. The aspect-specific components are put into the component-weaver, which combines them into a component-based workflow application. Therefore, components can even be replaced in the implementation without running through the whole edit-compile cycle, as would be necessary in standard Aspect-Oriented Programming. If, for example, the control flow of the workflow changes, one or several components reflecting these changes may be introduced into the application. Work flow model

Work flow Aspectspecification Aspectimplementation

selection

Components

Pre-fabricated Components

Component weaver Weaving information Work flow Application

Figure 3: Using Component-weaving for workflow support At first glance the architecture presented here offers the distributed, non-interpretative processing of workflows. It provides an escape from the dilemma of workflow architecture because it combines the performance of the direct workflow support with the flexibility of the virtual machine approach. There is no centralized interpretation of a workflow model and workflow changes can be easily integrated by exchanging components. Under closer scrutiny, the architecture demonstrates that aspect decompositions of the problem domain are a valuable extension of Aspect-Oriented Programming. Through the aspect decomposition of the problem domain, additional aspects can be separated, which were tangled before. Furthermore, the domain presented here, workflow support, shows that there is a need to introduce mechanism for system evolution into AspectOriented Programming, because the flexible support of changes is necessary to effectively support applications in many domains, not only in workflow support. However, this is only possible, if the separation of aspects is maintained, not only in the implementation phase, but also in the applications. Not only Aspect-Oriented Programming can profit from the extensions presented in this paper. AspectOriented Programming can give valuable hints about how to organize applications in modern componentbased frameworks such as ActiveX/DCOM or JavaBeans, which are playing an increasingly important role in application development. Application development for component-oriented systems should start with an aspect-separated domain model, such as an workflow model. Ideally components should only implement 5

functionality belonging to one aspect of an application, and applications should be composed of aspectseparated components. By applying the concept of Aspect-Oriented Programming, there is a much better chance that components become truly reusable, because they only have to fulfill the requirements of one aspect and not the requirements of several aspects. Component-oriented systems built in an aspect-separated manner can then be expected to become more flexible, because changes which concern only one aspect, will only influence the implementations of one aspect.

References [AAAM97]

G. Alonso, D. Agrawal, A. El Abbadi, C. Mohan: Functionality and Limitations of Current Workflow Management Systems. To appear in IEEE Expert (Special Issue on Cooperative Information Systems), 1997.

[AsSc97]

U. Aßmann, R. Schmidt: Towards a Model For Composed Extensible Components. Workshop Foundations of Component-Based Systems, Proceedings, Zurich, Switzerland September 26, 1997

[Berg97]

L. Bergmans: Aspects of AOP: Scalability and application to domain modelling. TRESE project, University of Twente & STEX. http://www.parc.xerox.com/spl/projects/aop/aop-meetingpps/bergmans.html

[Beans]

Javasoft: Java Beans Specification 1.0 A. http://splash.javasoft.com/beans/-beans.100A.pdf

[Chap96]

D. Chappell: Understanding ActiveX and OLE. Microsoft Press. Redmond 1996

[ChRa90]

P.K. Chrysanthis, K. Ramamritham: ACTA: A Framework for Specifying and Reasoning about Transaction Structure and Behaviour, Proc. ACM SIGMOD International Conference on the Management of Data, Atlantic City, NJ, S. 194-203, Mai 1990

[CiSc96]

O. Ciupke, R. Schmidt: Components As Context-Independent Units of Software. WCOP 96, Linz 1996. Special Issues in Object-Oriented Programming. Workshop Reader of the 10th European Conference on Object-Oriented Programming ECOOP96. Dpunkt.verlag, Verlag 1996

[GaSh93]

D. Garlan, M. Shaw. An Introduction to Software Architecture: Advances in Software Engineering and Knowledge Engineering, volume I. World Scientific Publishing, 1993

[GeHS95]

D. Georgakopoulos, M. Hornick, A. Sheth: An Overview of Workflow Management: From Process Modelling to Workflow Automation Infrastructure. In Distributed and Parallel Databases, Kluwer Academic Publishers, September 1995. Jablonski, S.: Workflow-Management-Systeme. International Thomson Computer Press. Bonn 1995

[Jabl95] [Kicz96]

G. Kiczales: Aspect-oriented programming. ACM Computing Surveys, 28(4), Dec. 1996.

[KILL97]

G. Kiczales, J. Irwin, J. Lamping, J.M. Loingtier, C. V. Lopes, C. Maeda, a. Mendhekar: AspectOriented Programming. Position Paper from the Xerox Parc Aspect-Oriented Programming Project.

[LoWa95]

P.C. Lockemann, H. D. Walter: Object-Oriented Protocol Hierarchies for Distributed Workflow Systems. In [PaTo95].

[Medv97]

N. Medvidovic. A Classification and Comparision Framework for Software Architecture Despcription Languages. Technical Report. UCI-ICS-97-02, University of Californica, Irvine, January 1997 R. Pareschi, M. Tokoro: TAPOS Theory And Practice of Object Systems. John Wiley, New York. Volume 1(1) SPECIAL ISSUE: 1995 European Conference of Object Oriented Programming

[PaTo95] [Schm97]

6

R. Schmidt: Component-based systems, composite applications and workflow-management. Workshop Foundations of Component-Based Systems, Proceedings, Zurich, Switzerland September 26, 1997

Assessing Aspect-Oriented Programming and Design Robert J. Walker, Elisa L. A. Baniassad, Gail C. Murphy walker, bani, murphy @cs.ubc.ca Department of Computer Science University of British Columbia Vancouver, BC V6T 1Z4 March 6, 1998

Abstract

to investigate such characteristics of aspect-oriented development as the creation and ease of debugging programs built with aspect-oriented design and programming. The experiments investigate aspect-oriented design and programming as represented in AspectJ , an aspect-oriented variant of Java developed at Xerox PARC. In conducting software engineering experiments, we are constrained by four factors: the pool of potential participants available to us is very small, the amount of time each participant can devote to an experiment is very short, especially in comparison to typical development times of even tiny applications, the cost of running and analyzing experiments is high, and since the evaluation of an aspect-oriented approach is complex, some precision of measurement needs to be forfeited in favor of realism[3]. As a result, our “experiments” were set up as semi-controlled empirical studies rather than statistically valid experiments. This report describes the results of a pilot study and the first experiment. The pre-study was used to test our experiment design in the context of investigating whether aspect-oriented programming eases the creation of correct program. The first experiment studied the ease of debugging such a program. The two experiments which have yet to begin are designed to investigate the ease of change of an existing program and the ease of design and implementation of a new program.

Aspect-oriented programming is a new software design and implementation technique proposed by researchers at Xerox PARC. This project is assessing the claims of aspect-oriented programming to improve the software development cycle for particular kinds of applications. The project is divided into three experiments, the first of which has been completed. These experiments have been designed to investigate, separately, such characteristics of aspect-oriented development as the creation of new aspect-oriented programs and ease of debugging aspect-oriented programs.

1

Introduction

Two of the most important and most difficult questions one can ask about a new design or programming approach are whether the approach is useful and whether the approach is usable. One way to evaluate these questions is to make the design or programming approach immediately accessible to the greater community and to simply see whether the approach sinks or swims. Although ultimately the goal is to positively affect the greater community through the adoption of the approach, this strategy has many pitfalls: useful techniques that are not quite usable can be lost, and usable techniques that are not particularly useful can mask the adoption of other, perhaps more powerful, techniques. Aspect-oriented programming is a new software design and implementation technique proposed by researchers at Xerox PARC[2]. This technique is in its infancy. The aspect-oriented approach claims to make it easier to reason about, develop and maintain certain kinds of application code while maintaining highly efficient code. To better understand the usefulness and usability of the aspect-oriented approach, we are currently conducting three experiments. These experiments are designed

2 Pilot Study Before designing our set of experiments, it was necessary to understand how difficult a problem we could realistically ask a participant to tackle in a period of no more than four hours. We also used this pilot study to determine better methods of training and questioning our participants. The experimental question approached in the pilot study was AspectJ is a trademark of Xerox Corporation. Java is a registered trademark of Sun Microsystems.

Submission to 1998 International Workshop on Software Engineering

1

2.2 Results

whether, in the context of AspectJ, the combination of JCore for component programming and COOL as a synchronization aspect language eases the creation of multi-threaded programs compared to programming in the Java object-oriented language. The basis of this experiment was to select a small programming problem with concurrency, and then have several Javaknowledgeable programmers attempt to produce a solution to the problem, some working in Java, others in AspectJ. Since we were working within a small community from which to draw participants we ranked the participants and chose the least qualified for this pilot study. We held the following questions in mind while watching and annotating the video-tapes of the sessions:

None of the six participants in the experiment were able to produce a solution to the programming problem in the time provided, although two came close (one Java, one AspectJ). We analyzed this pilot study to learn how to conduct subsequent studies; for this reason we did not go to great lengths to guarantee the abilities of our participants. In addition, the difficulty of the task was greater than we had expected: aside from the basic point of encoding the necessary synchronization, the means for completing the non-synchronized aspects of the program, the semantics of the problem domain, and the functionality of the existing code (written by someone else) needed to be understood first. One and a half hours was unreasonably short. The following lessons are among those we were able to take away from this pilot study: Can programmers working with an aspect-oriented language produce a “correct” program in less time than proParticipant training with and set-up of the programming grammers working with an object-oriented language? environment is necessary. It is impossible to test usefulDo programs produced with an aspect-oriented programness when usability is at a minimum. To address this, we ming language have fewer bugs than programs created modified our experiment design by ensuring that all parwith an object-oriented programming language? ticipants were given a thorough lesson on how to use the environment.

2.1 Format

All participants must be given lengthy exposure to the synchronization mechanisms provided by the language they are given to use. After this exposure they should be tested to ensure they know the information necessary to perform the experiment task. Subtle differences in synchronization constructs can be a great hindrance to someone attempting to use a language in which they have not frequently programmed synchronization, even if they are otherwise familiar with synchronization concepts. In the first experiment we ensured that all participants spent the same amount of time reading the synchronization documentation, and asked them to describe the basic concepts necessary for completion of the experiment task.

A pilot study session proceeded in stages. First, we required that the experimental participant review materials on concurrent programming. If the participant was to use AspectJ, the experimenter would introduce the concepts of aspect-oriented programming and provide the participant with an opportunity to become familiar with AspectJ; otherwise, they were given material describing Java synchronization usage [1]. Participants using AspectJ were required to examine an example piece of code to ensure that they were familiar with the syntax of the language. Finally, the participants were told the problem, provided a programming environment, were given 1.5 hours to complete the assigned task, and were asked to think aloud while we video-taped their progress. Twice during each session, the invigilator asked the participant a set of questions. The programming problem chosen for the experiment was a simple version of a non-audio karaoke machine in which text at the bottom of a small window scrolls from right to left and a ball bounces straight up and down above the text. The problem was to synchronize the ball and the text such that the ball would bounce on the start of each word. The text or the ball could be paused to permit this to happen. The participants were provided with a skeleton program from which to begin that contained the basic functionality to make the ball bounce and the text scroll. Six participants took part in the experiment, three used Java to program their solution and three were given AspectJ.

An interesting observation was that, among the participants, only the two near-successful ones pursued a course of action expressing a separation of concerns: get the code to work without synchronization first, then add the synchronization.

2.3 Participants’ Comments In general the participants that used AspectJ liked the method even though they were unable to complete the problem. We asked each of the AspectJ participants if they had any comments about aspect-oriented programming in general. “Well, [it was] just the way I imagined that [aspectoriented programming] would be used in a specific program. I thought it was really cool, because I could

Correct here is used to mean a program that meets the specification given for the program.

2

concentrate on what I was doing now, on the functionality that it would have by itself, as opposed to how to synch it up with the other object.”

chosen. One advantage of choosing a non-standard problem like karaoke was that the participants could not simply provide a ’textbook’ solution.

“Ultimately, I guess the idea is that the objects could be separated so you could change how the coordination was done without messing with the objects. I always like that, changing one little thing without touching what’s going on in the other place. It has a really elegant nature to it.”

Code Skeleton

To focus the participants’ efforts on concurrency we provided them with a code skeleton from which to start programming. This code skeleton lacked any synchronization and also lacked some of the functionality necessary so as to allow the participant some flexibility in pursuing a solution. In retrospect it is 2.4 Pilot Study Critique clear we did not provide a sufficient overview of the existing code or sufficient time for the participant to review the code Problems involving concurrency are hard to solve. One inter- and ask questions. A specific period of time for review and pretation of the results of this experiment is that the support questions might have mitigated problems arising from a lack for concurrency in AspectJ did not ease the difficulty of the of understanding of the given code skeleton. programming problem sufficiently such that it could be solved with the aspect-oriented approach when it could not be solved with the object-oriented (Java) approach. This result is not surParticipant Selection prising in that aspect-oriented programming is meant to ease the expression of the solution to the problem rather than to nec- Since this was seen as a pilot study and we had a limited numessarily help the software engineer design the solution. From ber of potential participants we put the programmers with less the participants comments, it appears that many of them had experience in this study. All participants were asked prior to difficulty framing an appropriate solution in the time available. selection whether they were familiar with the concepts of conThe participant who made the most progress on the problem currency and Java; however, since the aim of this pilot study was a participant using the aspect-oriented approach. Only a was mainly to gain experiment design information, stress was few small changes were necessary to the coordinator code pro- not placed on the screening of participants. We relied on induced by this participant to produce a solution to the problem: terviewing and questioning of the participants on these topics the changes were all of the same nature — an attempt to coor- rather than on a specific pre-test. dinate on objects rather than classes. More than one participant also spent a significant amount of the experiment time trying to understand syntax errors, both from Java and AspectJ. The latter have since been clarified via Running Time improvements in the AspectJ weaver. The participants were given 1.5 hours to program a solution to the given problem. Given that no participant was able to solve the problem, it is clear that either the problem was too complex, or insufficient time was provided to the participants. We 3 Experiment 1: Ease of Debugging had thought that 1.5 hours to solve the problem from a given code base would be reasonable given that the initial solution The intent of this experiment was to learn whether the separawas coded, from scratch, in just over 2 hours; however, this did tion of concerns provided in aspect-oriented programming ennot include the many hours spent discussing the semantics of hanced users ability to find and fix functionality errors (bugs) the karaoke machine synchronization during the design of the present in a multi-threaded program. In terms of AspectJ, the pilot study. question was whether the combination of JCore for the compoThis problem could be mitigated in two ways. First, addi- nent programming and COOL as a synchronization aspect lantional dry-runs could be held to try and gauge if the experimen- guage eased the debugging of multi-threaded programs, comtal running time is reasonable. Second, the experimental pro- pared to the ability to debug the same program written in Java. cedure could have called for giving participants as much time A 600 line, multi-threaded, program was created, and as they needed up to some (reasonably) large maximum such as three synchronization bugs were introduced. Then, pairs of 3 hours. However, given that only two of the six participants programmers, knowledgeable in multi-threaded programming were pursuing approaches likely to be successful, it is unclear techniques and object-oriented programming, attempted to fix that additional time alone would necessarily lead to more con- the three bugs. Three of the pairs worked with AspectJ, three sistent (and interpretable) results. Alternatively, a more stan- with Java. The solutions to the program were compared in the dard problem based on readers and writers might have been following ways: 3

Can programmers working with an aspect-oriented proThe experiment consisted of six pairs of participants, three gramming language debug a multi-threaded program in worked with Java and the others with AspectJ. All of the pairs less time than programmers working in an object-oriented were given time to train to familiarize themselves with the lanlanguage? guages they were to be using; 1.5 hours were allowed each pair to code their solution. Each of the pairs were to be asked for reAre programmers debugging an aspect-oriented program- ports of their progress either after they had coded each of the ming language able to more quickly and easily identify solutions, or at 1/2 hour intervals, whichever came first. the cause of a bug in a multi-threaded program than in one written in an object-oriented language?

3.2 Results 3.1 Format

In each the AspectJ and Java groups, all of the pairs of participants were able to find and correct all three of the bugs. We examined the performance of the pairs by comparing the time it took them to fix each of the bugs, how many times they built and ran the program, how many times they examined the semantics of the core functionality of the program, if they mixed synchronization and core functionality issues, if they searched for a synchronization solution by modifying the core functionality, and also the number of times the pairs changed the file they were examining while reaching their solution. We first discuss each data element in isolation, and then correlate and summarize the results.

The program provided to the participants was a simple digital library consisting of 6 classes, 3 of which required coordination. The library had two main actors: readers and libraries. The readers would make requests to libraries for a particular book. Libraries would search within their internal repositories for the book, and also ask remote libraries to do the same. Each reader could query one library, and each library could directly query at least one other. Three synchronization bugs were inserted into the code. The participants worked in pairs . In each pair, one participant had control of the computer with the programming problem, and the other had access to a report describing the symptoms of the bugs, and on-line documentation. They were then asked to fix each bug in turn, The bugs were cascading, meaning that the symptoms of the first hid the symptoms of the second, and the second hid those of the third. In the first bug only one reader would make a request and then they system would halt. The participants had to remove a per-class self-exclusive coordination on the run() method of the Reader class so that more than one reader could run. In the second problem, two readers would make requests and then the system would deadlock. The participants were required to determine that the deadlock occurred when two libraries each tried to do a remote-search on the other at the same time. They then had to remove a per-object self-exclusive coordination on the remoteSearch() method of the Library class so that the system would no longer deadlock. The third bug was that more than one reader was able to check out the same book from the same library. For this problem, the participants had to add a per-object self-exclusive coordination on the checkOut() method of the Library class so that only one reader could check out a book at a particular library at a time. To compare Java with AspectJ, a pair of synchronization lock classes were built which were identical in functionality with the woven output from AspectJ source code. This allowed the true aspect-oriented properties of COOL, as opposed to its library-like functionality, to be compared with non-aspectoriented Java code.

Time The completion times for each of the three bugs are shown in Figure 1. The largest difference in completion times was with respect to the first bug; the AspectJ teams clearly repaired the bug faster than the Java ones. For the second and third bugs, there was a smaller difference. When examining the time information in isolation we are unable to draw any definite conclusions. The quicker AspectJ time in the first bug could be attributed to any number of factors, and could imply that COOL is an easier language to quickly understand, or that the bug was more obvious when using COOL than Java. In the data correlation section the distribution of completion times is discussed with relation to the amount of programming understanding necessary to complete the programming task.

AspectJ

Bug 1

Java

Bug 2

Bug 3 1

5

10

15

20

25

30

minutes

Participants were graduate students in computer science, and an undergraduate in computer engineering.

Figure 1: Completion times 4

35

40

Switching Between Files

Builds

We were interested in determining if, for bugs where more semantic analysis was being performed on the code, users had to switch between files more using AspectJ because of the need for context of the synchronization code. For this reason, we recorded the number of times the pairs switched the file they were examining. Figure 2 shows that the AspectJ pairs made fewer file switches than the Java group for bug 1, more for bug 2 and slightly less for bug 3.

For the first and third bugs, there was only one build per bug with the exception of one Java pair for the first bug, who built and executed five times, and one Java pair in the third bug, who built and executed twice. There was no direct correlation between builds and instances of semantic analysis; however, there was a slight correlation between the number of builds performed and the number of file switches. Mixing Concurrency and Functionality Issues

AspectJ

Bug 1

In each of the AspectJ and Java groups, one group attempted to solve the synchronization bug with a change to the core functionality of the code.

Java

Bug 2 Bug 3

Granularity Analysis 0

1

2

3

4

5

6

7

8

Since AspectJ synchronization is fixed at a method-level granularity, users of Java have an opportunity to think about the granularity of locks that AspectJ users do not. To collect the Figure 2: Number of file switches instances of this we noted when the users attempted to move locks around within a method, hence implementing a finer granularity of locking than the original method granularity. Instances of Semantic Analysis Only one Java pair investigated locking granularity in the first bug, one in the second, and two in the third. None of the AsThe histograms shown in Figure 3 highlight the difference in pectJ participants questioned the synchronization granularity number of instances of semantic analysis over the nine sesimposed by COOL. sions. To determine the number of instances of semantic analysis we recorded the number of times participants said something to the effect of “let’s find out what this does...”. This in- Correlation of Data dicates that the Java pairs spent more time analyzing the actual behavior of the code than the AspectJ pairs did. In the AspectJ When examined in isolation, the increase in number of file session with the most instances of semantic analysis, the group switches made by the AspectJ pairs versus the less significant members openly disagreed as to how much semantic analysis increase for the Java pairs from the first to the second bug may was necessary to solve the second bug: be explained by the fact that the Java groups had done extensive initial file investigation in solving the first bug. A: ...we know it’s in the COOL file... However, the AspectJ group spent less time performing seB: But we have to know what they do before changmantic analysis than the Java group did. This could explain ing anything. why the times for the Java pairs never caught up to those of the AspectJ group. The Java group’s general lack of regard for the granularity of locks removes this as an explanation for the extra time spent. One other point must be clarified regarding AspectJ Bug 1 time: Both the AspectJ and Java pairs spent relatively equal Java time in building and executing their program. The additional time for weaving AspectJ was negligible. Bug 2 The number of instances of semantic analysis somewhat explain the number of file switches made by the AspectJ pairs. In Bug 3 the second bug (the bug with the highest average of semantic 0 1 2 3 4 5 6 7 8 analysis instances) the most file switching occurred. We beinstances of analysis lieve that there were less file switches by AspectJ pairs than Java pairs on bug 2 because less semantic analysis was performed to solve the bug. Figure 3: Instances of semantic analysis file switches

5

Participants’ Thoughts

gramming versus object-oriented programming. We noted that users of the aspect-oriented programming language AspectJ We asked the AspectJ users what they thought about the sep- were able to complete debugging tasks with fewer instances of aration of the synchronization code from the rest of the core. semantic analysis which seemed to lead directly to less switchTwo of the three groups were enthusiastic and noted that they ing between files, indirectly to fewer builds, and ultimately to did not want the code for the coordination in-line: quicker completion times. We used a pilot study to gather a set of guidelines about the I’d much rather have it separated like this. I really design of further studies, and used those guidelines in designwould. ... I would rather not look at the details ing the first main experiment. The ability of one participant to come close to an appropriate solution with a coordinator It meant that since [the problems] were just synchrodemonstrates it is possible to learn the approach quickly and nization problems we just had to look at the parts apply it. that were related to synchronization. We could have The first experiment highlighted the usefulness of being able spent lots of time looking at the non-synchronization to easily express and understand synchronization code. We parts, at one point we did look briefly, but it was learned that there are times at which it is useful for synchroclear there was nothing about synchronization in that nization code to be embedded in the core functionality, but that code, and the only way to deal with synchronization at times work can be speeded considerably (as in bug 1) when was to look in the COOL files. synchronization code is separated from the rest. The other group felt that COOL provided a handy way of summarizing coordination of and between methods, but were unhappy with the actual separating out of the coordination 5 Acknowledgments code. We would like to thank the Xerox Embedded Computation Area group for their comments on the experiment concepts and the use of the AspectJ weaver, the anonymous participants who took part in the sessions, and Robert Rekrutiak and Paul Nalos for their work on experiment setup. Funding provided by Xerox Corporation and a UBC GraduThey would have opted instead for the COOL code to have ate Fellowship. been inserted in pertinent places throughout the code so that the user could see in once glance both the coordination and the method at the same time. Interestingly, this pair (the third As- References pectJ pair) switched less between files in total than any of the Java pairs. [1] K. Arnold and J. Gosling. The JavaTM Programming LanWe asked the Java groups how they mentally separated guage. Addison-Wesley, 1996. the synchronization code from the core code. One participant noted that when looking at Java synchronization code [2] G. Kiczales, J. Lamping, A. Mendhekar, C. Maeda, C. Lopes, and J. Irwin. Aspect-oriented programming. In they made no algorithmic differentiation between the synchroECOOP ’97 - Object-Oriented Programming. 11th Euronization code and the core code. They continued by dispean Conference Proceedings. Jyvaskyla, Finland, pages cussing the need for some abstraction of the synchronization 220–242, June 1997. that was higher level than the locking available through Java. ”Some way of specifying that you have certain constraints be- [3] Joseph E. McGrath. Methodology matters: Doing retween methods within classes or objects, instead of using this search in the behavioral and social sciences. In Ronald M. scheme”. They noted that this shortcut for locking would save Baecker, Jonathan S. Grudin, William A. S. Buxton, and both five lines of code and save you looking at the code itself. Saul Greenberg, editors, Readings in Human-Computer We admit that this is speculative since the Java people had no Interaction: Toward the Year 2000, pages 152–169. Morexperience with the real separation. gan Kaufmann, San Francisco, 2nd edition, 1995. The only place I can see there could be an advantage is if you know that you have some modules you are working with that are tested and you are sure you can limit the bugs to synchronization issues in which case you don’t really have to understand the code.

4

Summary

With the first of our three experiments, we were able to obtain interesting indications about the use of aspect-oriented pro6