Faculté informatique et communications IC, Section d'informatique, Institut d'informatique fondamentale IIF

Programming language abstractions for extensible software components

Zenger, Matthias ; Odersky, Martin (Dir.)

Thèse sciences Ecole polytechnique fédérale de Lausanne EPFL : 2004 ; no 2930.

Add to personal list
    Summary
    With the growing demand for software systems that can cope with an increasing range of information processing tasks, the reuse of code from existing systems is essential to reduce the production costs of systems as well as the time to manufacture new software applications. For this reason, component-based software development techniques gain increasing attention in industry and research. Component technology is driven by the promise of building software by composing off-the-shelf components provided by a software component industry. Therefore, component technology emphasizes the independent development and deployment of components. Even though components look like perfect reusable assets, they embody general software solutions that need to be adapted to deploymentspecific needs and therefore cannot be deployed "as is" in general. Furthermore, as architectural building blocks, components are subject to continuous change. For these reasons, it is essential that components can easily be extended by both the component manufacturer to create new versions of components and by thirdparties that have to adapt components for use in specific software systems. Since in both cases concrete changes cannot be foreseen in general, mechanisms to integrate unanticipated extensions into components and component systems are required. While today many modern programming techniques, methodologies, and languages provide means that are well suited for creating static black-box components, the design and implementation of extensible components and extensible software systems often remains a challenge. In practice, extensibility is mostly achieved through ad-hoc techniques, like the disciplined use of design patterns and component frameworks, often in conjunction with meta-programming. The use of design patterns and component frameworks requires a rigorous coding discipline and often forces programmers to write tedious "boilerplate" code by hand, which makes this approach fragile and error-prone. Meta-programming techniques on the other hand are rather code-centric and mostly source code-based. Therefore, they are often not very suitable for today's component technology practice that stresses the binary reuse of black-box components. In this thesis I argue that technical difficulties in the development of extensible software components are due to the lack of appropriate programming language abstractions. To overcome the problems, concrete programming language mechanisms are proposed to facilitate the creation of extensible software. The proposed language features are strongly typed to help the programmer extend systems safely and consistently. The first part of the thesis illustrates the vision of truly extensible software components by proposing a simple theoretical model of first-class components built on top of a conventional class-based object-oriented language. This typed model includes a small set of primitives to dynamically build, compose, and extend software components safely, while supporting features like explicit context dependencies, late composition, unanticipated component extensibility, and strong encapsulation. The second part takes some ideas from the theoretical model and applies them in the design of the programming language Keris. Keris extends Java with an expressive module system featuring extensible modules. The main contributions are: A module system that combines the benefits of classical module systems for imperative languages with the advantages of modern component-oriented formalisms. In particular, modules are reusable, generic software components that can be linked with different cooperating modules without the need for resolving context dependencies by hand. A module composition scheme based on aggregation that makes the static architecture of a system explicit, and A type-safe mechanism for extending atomic modules aswell as fully linked systems statically by replacing selected subsystems with compatible versions without needing to re-link the full system. The extensibility mechanism is non-invasive; i.e. it preserves the original version and does not require access to source code. The overall design of the language was guided by the aim to develop a pragmatic, implementable, and conservative extension of Java which supports software development according to the open/closed principle: Systems written in Keris are closed in the sense that they can be executed, but they are open for unanticipated extensions that add, refine, or replace modules or whole subsystems. The last part of the thesis finally presents a case study which compares an extensible Java compiler implemented using mainstream object-oriented language features with one that was written in Keris. It shows how in practice, extensible modules can be used to develop extensible systems safely and efficiently.
    Zusammenfassung
    Bei Software-Anwendungen, die mit ständig neuen Informationsverarbeitungsanforderungen konfrontiert sind, trägt die Wiederverwendung von Code wesentlich dazu bei, sowohl die Produktionskosten, als auch die Zeit für die Entwicklung neuer, verwandter Systeme zu reduzieren. Aus diesem Grund kommt komponentenbasierten Softwaretechnologien verstärkt Aufmerksamkeit im Entwicklungs- und Forschungsbereich zu. Komponententechnologie basiert auf der Vision, Software primär durch eine Kombination von vorgefertigten Komponenten zu erstellen, welche von einer globalen Softwarekomponentenindustrie angeboten werden. Obwohl Komponenten eigentlich als ideal wiederverwendbare Bausteine erscheinen, stellen sie dennoch allgemeine Softwarelösungen dar, die stets an anwendungsspezifische Bedürfnisse angepasst werden müssen und daher auch selten in ihrer allgemeinen Form eingesetzt werden können. Ausserdem unterliegen Softwarekomponenten, als grundlegende architekturelle Bausteine, natürlicherweise ständigen Veränderungen. Es ist daher unverzichtbar, dass Komponenten auf einfache Art und Weise, sowohl vom Hersteller, als auch von Klienten, erweitert werden können. Da in beiden Fällen die zukünftigen, konkreten Änderungen selten im Voraus absehbar sind, muss es möglich sein, auch unvorhergesehene Erweiterungen an Komponenten und Komponentensystemen vornehmen zu können. Während viele moderne Programmiertechniken und Programmiersprachen durchaus gut für die Entwicklung statischer Black-Box-Komponenten geeignet sind, bleibt die Entwicklung von erweiterbaren Komponenten und komponentenbasierten Softwaresystemen oft eine Herausforderung. In der Praxis wird Erweiterbarkeit hauptsächlich mit Hilfe von Ad-hoc-Techniken erzielt; z.B. durch eine disziplinierte Verwendung von Entwurfsmustern und Rahmenwerken, oft in Verbindung mit Meta-Programmiertechniken. Eine konsequente Verwendung von Entwurfsmustern und Rahmenwerken zwingt den Programmierer oft dazu, langweiligen und dadurch auch fehleranfälligen Anpassungscode von Hand zu schreiben. Meta-Programmierung, auf der anderen Seite, basiert meist auf Quellcode und ist damit nicht sonderlich geeignet für den Einsatz in einer auf binären Komponenten beruhenden Technologie. In dieser Dissertation wird argumentiert, dass die technischen Schwierigkeiten bei der Entwicklung von erweiterbaren Softwarekomponenten auf einen Mangel an geeigneten Abstraktionen auf der Programmiersprachenebene zurückzuführen sind. Zur Lösung des Problems werden konkrete Programmiersprachen-Mechanismen vorgeschlagen, die die Entwicklung von erweiterbarer, komponentenbasierter Software vereinfachen und damit eine sichere und konsistente Evolution von Systemen ermöglichen sollen. Im ersten Teil der Dissertation wird die Vision von flexibel erweiterbaren Softwarekomponenten an Hand eines einfachen theoretischen Modells veranschaulicht, welches Komponenten im Kontext einer konventionellen, klassenbasierten, objekt-orientierten Sprache einführt. Das typisierte Modell definiert eine kleine Menge von Primitiven mit deren Hilfe auf typsichere Art und Weise dynamisch Komponenten erzeugt, kombiniert und erweitert werden können. Im zweiten Teil werden Ideen des theoretischen Modells aufgegriffen und bei dem Entwurf der Programmiersprache Keris eingesetzt. Keris erweitert die Programmiersprache Java um ein ausdrucksstarkes Modulsystem. Diese Arbeit liefert folgende Beiträge: Ein Modulsystem, welches die Vorzüge klassischer, imperativer Modulsysteme mit den Vorteilen moderner komponentenorientierter Formalismen verbindet. Module repräsentieren wiederverwendbare, generische Softwarekomponenten, die mit anderen Modulen kombiniert werden können ohne dass Kontextabhängigkeiten von Hand aufgelöst werden müssen. Ein Prinzip zur Modulkomposition, welches auf Aggregation beruht und welches die statische Architektur eines Systems explizit macht. Ein typsicherer Mechanismus, um sowohl atomare Module, als auch voll verlinkte Systeme statisch zu erweitern, indem ausgewählte Subsysteme durch kompatible Versionen ersetzt werden, ohne dass es notwendig wird, das gesamte System erneut zu linken. Der Erweiterungsmechanismus ist nicht destruktiv; er erzeugt eine neue Version einer Softwarekomponente ohne die alte Version zu verändern und ohne auf den Quellcode der alten Version zuzugreifen. Ein Ziel des Sprachdesigns war es, eine pragmatische und implementierbare Erweiterung von Java zu konzipieren, welche es erlaubt, komponentenbasierte Software nach dem Open/Closed Prinzip zu entwickeln: Systeme die in Keris geschrieben sind, sind geschlossen, in dem Sinne, dass sie ausführbar sind; sie sind aber auch offen für zukünftige Erweiterungen, die Module oder ganze Subsysteme neu hinzufügen oder ersetzen. Im letzten Teil der Dissertation wird eine Fallstudie präsentiert, welche einen erweiterbaren Java Übersetzer, der mit gängigen, objekt-orientierten Sprachmitteln geschrieben wurde, mit einem in Keris geschriebenen Übersetzer vergleicht. Mit Hilfe dieser Fallstudie wird demonstriert, welche Möglichkeiten Keris in der Praxis bietet, erweiterbare Systeme sicher und effizient zu implementieren