Composing Active Objects

Composing Active Objects is a research project funded initially for two years by the Swiss National Science Foundation (SNSF # 21-40610.94).

Increasingly, modern software systems are required to be open systems. Traditional software development techniques do not cope well with the needs of open systems, and in particular with rapidly changing requirements. Object-oriented languages and techniques offer some help in that they allow one to view an application as a flexible composition of properly encapsulated software components, i.e., objects. Object-oriented languages, however, (i) generally fail to provide a systematic view of concurrent behaviour, and (ii) provide only limited mechanisms for specifying and composing software components. This project aims to develop a new model for object-oriented software composition that cleanly integrates active objects and components, and demonstrate the practical value of the model by applying it to existing component sets.

Keywords: open systems development; object-orientation; active objects; software components; composition; frameworks.

Summary

Present-day applications are increasingly required to be open systems in terms of topology (distributed systems), platform (heterogeneous hardware and software) and evolution (rapidly changing requirements). Object-oriented programming languages, tools and methods address some of the needs of open systems development, but ultimately they only offer limited support for viewing applications as flexible configurations of adaptable and reusable software components. There are many reasons for this, but the basic problem is that object-oriented approaches have traditionally emphasized programming over composition, and objects over components. As a consequence, object-oriented programming does not inherently provide any means to view open applications as flexible compositions of existing components.

To provide a "complete solution" to the problem of open systems development is a massive research undertaking, dealing with methodological issues, development tools and environments, software classification and retrieval, and project management tactics and strategy. This proposal addresses a more refined goal, which is to explore solutions for the core software composition technology. The related issues will be studied in subsequent projects.

Specifically, this project will develop

State of the art and related work

The first proposal for a formal model of active objects was Hewitt's actor model [8][1]. This model has served as the foundation for long list of actor languages and concurrent object-oriented languages, but has had limited success as a basis for reasoning about the properties of programs. More recently, there has been growing interest in the use of so-called process calculi (loosely based on the l-calculus) as more theoretically tractable basis for modelling active objects, since the development of Milner's CCS [15] and the pi calculus [16]. Semantics for object-oriented languages in terms of CCS and the pi calculus have been studied by Walker [22] and Papathomas [18][18]. More recently, Jones [11] has used the pi calculus to give an operational semantics to pobl (pronounced "pobble"), a formal specification language for concurrent object-based programs.

Until now, no research has yet been done into using process calculi as a basis for modelling general software components, but there has been significant work by Milner [17] and Sangiorgi [21] on modelling functions as processes. Since functions can be seen as the simplest possible interpretation for all kinds of abstractions (in fact, standard denotational semantics for programming languages essentially interprets all language constructs as kinds of functions over a semantic domain), an integration of functions and processes arguably provides a good starting point for modelling both components and active objects within a common framework. There has also been interesting foundational work by Dami [6][7] on lN, an object calculus that starts with the lambda calculus, but replaces variables by communication using names, considerably simplifying the modelling of object-oriented features.

Software composition in a typed framework should ideally address both type-checking of object interactions (i.e., verifying that only valid messages are sent to objects), and of component compositions (i.e., verifying that only suitable arguments are bound to the formal parameters of software components). There is a vast literature on type models for object-oriented languages, starting with the work by Cardelli [4]. None of this work addresses type-checking of object protocols (i.e., to cope with the fact that objects' services may not be uniformly available), and none addresses type-checking of the inheritance interface (i.e., to check that modifications introduced in a subclass are actually valid with respect to the superclass). The first issue is partially addressed by the process calculus community, notably in the work by Brinksma [3], and the latter is beginning to be addressed in the object-oriented language community (see, for example, Lamping [13]).

Object-oriented languages typically provide only very limited notions of software components, and these are closely tied to the granularity of objects. Classes are software components, for example, but their granularity is identical to that of objects. Composition is similarly tightly-coupled to objects, so that inheritance is often the only mechanism provided for composing software. A few languages, notably Emerald [20], Jigsaw [2], and CLOS [12], provide more flexible means to define abstractions over the object space, and provide more fine-grained control over the composition of objects from parts, but none provides a systematic view of active objects (although Emerald is intended for distributed programming). A particular problem in concurrent object-oriented languages is the inheritance anomaly [14], namely that encapsulation of concurrent behaviour must often be violated in order to reuse the implementation in subclasses (i.e., implementation details cannot be abstracted). This problem is in large part due to the emphasis on inheritance over and above more general and flexible composition mechanisms in such languages: features visible to subclasses when inheritance is used are typically determined by the language design rather than being explicitly controlled by the programmer, so inheritance can severely limit the ability to precisely define the right level of encapsulation of software components.

Software libraries have existed since the early days of computer programming. Object-oriented techniques add the notion of a framework [9] as a systematic means to organize components (object classes) that have been designed to work together. Technically, a framework consists of abstract classes, from which application classes are derived by inheritance. All applications built with a particular framework therefore are based on the same sets of object interactions. Current research on frameworks focuses on principles for iteratively developing frameworks over time [5] and on techniques for documenting reusable design patterns at a level above frameworks [10].

Software development environments for object-oriented systems exist both as research prototypes and as commercial products. Much current research both in academia and in industry is focused on various aspects of open distributed processing (ODP). There is an on-going joint effort by ISO and ITU to develop standards for ODP, and the Object Management Group (OMG) has over the past few years developed standards for exporting application services within open systems. Vendors are now producing applications and tools that are based on these standards.

Various high-level tools exist that allow developers to graphically compose user interfaces, database interfaces, or other parts of their applications using graphical and direct manipulation techniques, but (i) these tools are typically specialized for addressing only a very limited domain of composition, and (ii) component-engineering, the development of the components that can later be composed, is still a black art, and few tools exist to support this activity.

References

Contributions to the field by the applicants

Hybrid [10] was an early attempt at designing a general-purpose programming language for developing open systems, based on the integration of active objects with other object-oriented language features (namely, classes, multiple inheritance, genericity and strong-typing). Hybrid fell short in addressing its goals to a large extent because of the over-emphasis on classes and inheritance as the principle means for defining and composing software components. The lack of a commonly-accepted formal foundation for attributing semantics to concurrent object-based language features was also a source of ambiguity and subsequent difficulty in the language specification. This led to work on the development of an object calculus [8] to be used as a semantic target for evaluating language design options [5][13][14]. The object calculus was a first attempt to address both active objects and software components within a process calculus setting. A straightforward implementation of the operational semantics of the object calculus led to a simple tool for experimenting with object models and prototyping language features.

In parallel with this work, some attempts were made to develop a new kind of type system for active objects that would allow one to express "plug-compatibility" in terms of the protocols required by objects' message-passing interfaces [7][12]. Whereas traditional type systems assume that all messages are understood at all times, this approach allows one to express non-uniform service availability. This is important even in sequential environments, for objects that require special initialization and cleanup methods to be called. Here too, ideas from process calculi turned out to be useful in developing both a new type model and algorithms for checking type compatibility [12]. This work, as well as work on the object calculus, was partially carried out within the FNS project 20-33703.92, "Active and Multimedia Objects."

CHASSIS is an on-going project of the Swiss Priority Programme in Informatics, in the area of secure and reliable systems, which addresses the construction of flexible, open and secure information systems from both new and existing application and database components [11]. The language-specific part of CHASSIS focuses on support for interoperability between applications developed on heterogeneous software platforms. CHASSIS provides a so-called cell framework for encapsulating applications and managing the interchange of information (both data and objects) between them. Although CHASSIS addresses mainly large-grained components, i.e., applications, the approach is also valid for more fine-grained software composition.

ITHACA is an on-going Esprit project to produce a complete object-oriented application development environment [1][2][4]. One of the original aspects of the ITHACA environment is the support for visual composition of applications from pre-fabricated components. Whereas most visual programming environments concentrate on a particular composition domain, such as user interface development, or restrict themselves to a particular paradigm for computation, such as dataflow, Vista, the visual composition tool of ITHACA provides generalized support for software composition by factoring out the composition model in use [6]. The composition model determines the kind of interfaces that may be associated with components, and determines which interfaces are plug-compatible. Associated information determines how components and their interfaces are visualized, and precisely how bindings between components should be realized at by the tool during a composition session. The computational behaviour of components, on the other hand, is properly encapsulated within the components, and is hidden both from the user and the tool.

Component-oriented software development has been proposed as an approach for developing open systems [9], and a number of the technological issues [3][16] and methodological issues [15] have been studied in discussed in some detail.

References

Research Plan

The Object Model

Object-oriented applications can be viewed dynamically as a collections of communicating and collaborating objects, or statically as compositions of software components. In most object-oriented languages, the granularity of software components is not very different from that of objects, since classes and inheritance are the principle mechanisms provided for specifying and composing components, consequently the difference between the two views is typically hard to detect. For open systems development, however, the separation is extremely important, since applications may need to be reconfigured frequently to meet changing requirements. Decoupling components from objects is important (i) to permit the development of components whose granularity may differ significantly from that of objects, and (ii) to permit the specification of compositional interfaces that may differ from that provided by objects or those built into the inheritance rules of the programming language.

We propose to develop an object model incorporating both active objects as message passing, run-time entities, and components as static, high-order values. The semantics of object model will be defined as a thin layer on top of a process calculus incorporating both processes and functions (most likely Sangiorgi's higher-order pi calculus, or a dialect). The object model will determine the properties and behavioural structure of objects viewed as processes. Whereas the raw processes of a process calculus may exhibit no regularity or discipline of behaviour, objects obey fairly strict rules of interaction and provide services according to these rules. The object model will provide a framework that defines what kinds of abstractions (components) are of interest, and how objects can be built up from these abstractions. An important part of the object model will be a type system that defines plug compatibility both for objects and components.

The object model will be realized by a concrete syntax and an executable abstract machine, thus allowing it to be used as a target for a programming language translator.

The Composition Language

The composition language will provide syntactic sugar on top of the object model, providing language features more suitable for programming. (Similarly, a modern functional programming language can be seen as syntactic sugar on top of a lambda calculus: one would not wish to program directly in the lambda calculus, though useful programming features can be defined by straightforward mappings down to the level of the calculus.) The implementation of the composition language will also provide some mechanisms for wrapping and binding components written in other programming languages, thus permitting its use as a high level composition tool for existing component sets.

The first version of the composition language will focus on proof-of-concept and experimentation, and will not be used as a test-bed for developing new compiler technology. On the contrary, compiler-development technology will be selected that will allow a flexible but usable prototype of the language to be developed as quickly as possible, and thus permit the language itself to evolve as a consequence of positive and negative experiments.

The Component Laboratory

The validation of the approach will be carried out by experimenting with the development of flexible, open systems based largely on available software components. The development of large component libraries is clearly outside the scope of the project, and is even counter-productive. Instead, existing and available component libraries will be collected and used as a basis for experiments. Some binding components will have to be developed to permit the composition language to be applied to the existing component sets. Since the results of experiments will feed back into the evolution of the composition language, the "path of least resistance" will be chosen, and initial experiments will be selected to minimize the development effort required. As positive results are achieved, more ambitious experiments will be attempted.

At this point, it is not possible to say which application domains should be targeted, but it is clear that the most dramatic results would be obtained in areas characterized by ill-defined and rapidly changing requirements. In such cases, a component-oriented approach is arguably a necessity, since traditional software engineering methods do not cope well with changing requirements. Candidate domains include areas as diverse as banking, insurance, process control and monitoring, parallel systems, CASE tools and hypermedia systems. The domains in which experiments will be performed will depend on the availability of components sets, and possibly on the interest of potential collaborators (yet to be determined).

The component laboratory will also address the use of high-level graphical tools for application composition and re-configuration. The development of a purpose-built visual composition tool falls outside the scope of this project, but a number of available tools exist as commercial products and as academic prototypes. We plan to experiment with the use of selected tools as front-ends for software composition, particularly with respect to the goal of dealing with changing requirements. Again, bindings will need to be established between the various tools and the composition language, so a "path of least resistance" approach will be used.

Work plan

First year