Location Transparency and Transactions as First-Class Concepts in Object-Oriented Programming Languages

192  Download (0)

Full text

(1)

S

KATHOLIEKE UNIVERSITEIT LEUVEN

FACULTEIT INGENIEURSWETENSCHAPPEN

DEPARTEMENT COMPUTERWETENSCHAPPEN

AFDELING INFORMATICA

Celestijnenlaan 200 A — B-3001 Leuven

Location Transparency and Transactions

as First-Class Concepts

in Object-Oriented Programming Languages

Promotor :

Prof. Dr. ir. E. STEEGMANS

Proefschrift voorgedragen tot het behalen van het doctoraat in de ingenieurswetenschappen door

Jeroen BOYDENS

(2)

S

DEPARTEMENT COMPUTERWETENSCHAPPEN

AFDELING INFORMATICA

Celestijnenlaan 200 A — B-3001 Leuven

Location Transparency and Transactions

as First-Class Concepts

in Object-Oriented Programming Languages

Jury :

Prof. Dr. ir. P. Van Houtte, voorzitter Prof. Dr. ir. E.Steegmans, promotor Prof. Dr. ir. W. Joosen

Prof. Dr. J. Calu (K.H.B.O.) Prof. Dr. ir. Y. Berbers Prof. Dr. P. De Causmaecker

Proefschrift voorgedragen tot het behalen van het doctoraat in de ingenieurswetenschappen door

Jeroen BOYDENS

U.D.C. 681.3∗D15, 681.3∗D2, 681.3∗D33

(3)

c

Katholieke Universiteit Leuven – Faculteit Ingenieurswetenschappen

Arenbergkasteel, B-3001 Heverlee (Belgium)

Alle rechten voorbehouden. Niets uit deze uitgave mag worden vermenigvuldigd

en/of openbaar gemaakt worden door middel van druk, fotocopie, microfilm,

elektronisch of op welke andere wijze ook zonder voorafgaande schriftelijke

toe-stemming van de uitgever.

All rights reserved. No part of the publication may be reproduced in any form

by print, photoprint, microfilm or any other means without written permission

from the publisher.

D/2008/7515/48

(4)

Software systems are becoming ever more complex. This leads to longer

devel-opment cycles, which increases costs. Adding high level concepts with clear and

uniform semantics is one way to speed up development. They hide the complexity

of the underlying low level constructs, allowing developers to use these concepts

in a clear and unambiguous way.

The first part of this dissertation provides concepts for location transparency

in distributed object-oriented applications. A mutability concept is proposed to

tackle synchronization problems in specific scenarios. To provide a transparent

so-lution for both local and remote parameter passing schemes, a caching framework

is suggested.

The second part provides concepts to integrate transactional behavior into

object-oriented programming languages. Basic transactional concepts are

ex-tended to provide compensating transactional behavior. In addition, transactional

locking levels are introduced to fine-tune concurrency control. Finally,

transac-tional method execution is extended with retry semantics. These extensions serve

as building blocks of long running transactional behavior and closed nested

trans-actional behavior. These advanced transaction types allow developers to create

clear and correct software solutions.

All concepts have been applied successfully to medium-size case studies. These

experiments show significant reduction in the lines of code for object-oriented

ap-plications. This dissertation also introduces a new graphical notation for

reason-ing about transactional behavior. This notation supports the extended concepts

and the advanced transaction types.

(5)

Voorwoord

Doctoreren es vele lez'n en vele schriv'n. Doctoreren es vele schriv'n (Frank Devos)

Dit proefschrift is het startpunt van een nieuwe richting in mijn loopbaan. In het begin van deze tekst wil ik graag mijn dank betuigen aan alle mensen die mij gedurende de laatste vijf jaar hierin direct of indirect hebben bijgestaan. In eerste instantie wil ik mijn promotor professor Eric Steegmans bedanken. De gesprekken tijdens vergaderingen waren steeds inspirerend en richtinggevend. De regelmaat waarmee ze terugkeerden, confronteerden me met de voortgang van mijn werk. De motivatie en de appreciatie bezorgden me de moed om mijn onderzoek tot een goed einde af te werken. Ik wens elke doctorandus zo'n promotor toe.

De overige leden van de begeleidingscommissie, professor Wouter Joosen en professor Johan Calu, alsook de overige juryleden, professoren Yolande Berbers, Patrick De Causmaecker en Paul Van Houtte, ben ik dankbaar om mijn werk aan hun kritische blik te onderwerpen.

De directie en de collega's van de Katholieke Hogeschool Brugge-Oostende departement IW&T dank ik voor hun steun en sympathie. Zonder de onvoor-waardelijke toestemming van mijn gewezen departementshoofd Egide Degroote

en de steun van mijn toenmalig afdelingshoofd Eric Debrabandere was dit onder-zoek niet opgestart. Het combineren van een onderwijsactiviteit en het voeren van een doctoraatsonderzoek is niet vanzelfsprekend. Daarom wil ik de collega's van de groep informatica bedanken voor hun collegialiteit en de interesse die ze toonden voor mijn onderzoek.

Mijn collega's van de onderzoeksgroep SOM (Softwareontwikkelingsmethodo-logie) aan de K.U.Leuven bezorgden me een aangename werksfeer: Pieter Be-kaert, Sven De Labey, Geert Delanote, Frank Devos, Nele Smeets, Koen Vander-kimpen, Marko van Dooren. De discussies die we hadden, onder andere over ons onderzoek, waren steeds boeiend en dynamisch. Aanvankelijk had ik in de groep vooral contact met mijn streekgenoten Frank en Geert. Nele verkoos te verhuizen naar een softwarebedrijf. Frank, Pieter en Marko zijn ondertussen gepromoveerd, maar bewaren het contact met de groep. Geert werkt momenteel zijn onderzoek verder af, ik wens hem hierbij alle moed. Marko was bereid mijn publicaties te

(6)

zen terwijl zijn eigen publicaties explosief toenamen. Ondanks onze verschillende levenservaring vond ik in Sven een aangename sparringpartner.

Tenslotte dank ik mijn familie en vrienden. De blijk van interesse door me regelmatig te vragen hoe het nu was met mijn doctoraat en te pogen te begrijpen waar ik net mee bezig was, dreven mij vooruit. Mijn schoonzus Marie-Pierre dank ik voor het nalezen van deze tekst. Het moet een hels karwei geweest zijn voor een niet-informaticus. Maar bovenal gaat mijn dank naar mijn vrouw Caat en mijn kinderen Jonathan en Laura. Jullie gaven me de ruimte en vooral de tijd om te werken aan dit onderzoek. Caatje, zonder de liefde en de motivatie die je in al die jaren gaf, was dit werk niet geworden tot wat het nu is.

(7)

Aan mijn liefste Caatje, Jonathan en Laura.

(8)
(9)

Contents

1 Introduction 1

1.1 Background . . . 1

1.1.1 Programming Languages in General . . . 2

1.1.2 Object-Oriented Programming . . . 3

1.1.3 Model Driven Architecture . . . 4

1.1.4 Aspect-Oriented Programming . . . 6

1.1.5 Extreme Programming and Test Driven Development . . . 7

1.1.6 Transaction Processing . . . 7

1.1.7 Enterprise Programming . . . 8

1.2 Goals . . . 9

1.3 Approach . . . 9

1.4 Overview of the Dissertation . . . 10

2 Local-Remote Transparency Concepts 13 2.1 Introduction . . . 14

2.1.1 Parameter Passing for Local Methods . . . 14

2.1.2 The Transparency Problem . . . 14

2.1.3 Mutability of Objects . . . 15

2.2 Problem Scenarios . . . 16

2.2.1 Overview of Problem Scenarios . . . 16

2.2.2 Immutable Local Object Passed to a Local Method . . . 17

2.2.3 Immutable Local Object Passed to a Remote Method . . . 18

2.2.4 Mutable Local Object Passed to a Local Method . . . 21

2.2.5 Mutable Local Object Passed to a Remote Method . . . 22

2.2.6 Immutable Remote Object Passed to a Local Method . . . 24

2.2.7 Immutable Remote Object Passed to a Remote Method . . 25

2.2.8 Mutable Remote Object Passed to a Local Method . . . 28

2.2.9 Mutable Remote Object Passed To a Remote Method . . . 30

2.3 Solution to the Transparency Problem . . . 32

2.3.1 Scope Settings . . . 32

2.3.2 Make all Objects Remotely Available . . . 33 i

(10)

2.3.3 Objects Live Only in One Place . . . 33

2.3.4 Distributed Transactions . . . 34

2.3.5 Observer Pattern . . . 34

2.3.6 Caching Strategy . . . 35

2.4 The Mutability Concept . . . 36

2.5 Multi-Threaded Testing . . . 38

2.6 Conclusion and Future Work . . . 39

3 Transactions as First-Class Concepts 41 3.1 Introduction . . . 42

3.2 Denition of Transactions . . . 43

3.2.1 Transactions in the Database World . . . 43

3.2.2 Transactions used as Concept in Object Oriented Program-ming Languages . . . 44

3.3 Introducing Transactions . . . 44

3.3.1 Problem Statement . . . 45

3.3.2 Defensive Programming . . . 46

3.3.3 Nominal programming . . . 46

3.3.4 Manual Use of the Transaction Class . . . 47

3.4 Methods with Transactional Behavior . . . 50

3.4.1 Explicitly Providing Aborting Behavior . . . 50

3.4.2 Default Aborting Behavior . . . 51

3.4.3 Manual Request of Transactional Behavior . . . 53

3.5 Further Semantics of Transactional Methods . . . 54

3.5.1 Semantics Illustrated Using Principal Cases . . . 55

3.5.2 Evaluation Using the Case Study . . . 62

3.6 Transactional Concept Implementation . . . 64

3.6.1 Transactional Method . . . 64

3.6.2 Transactional Method Translation Scheme . . . 65

3.6.3 Operator -> Translation Scheme . . . 66

3.7 Testing non-Deterministic Methods . . . 68

3.8 Related Work . . . 69

3.9 Conclusion . . . 70

4 Extended Concepts for Transactions 71 4.1 Graphical Notation for Transactions . . . 71

4.2 Compensating Transactions . . . 75

4.2.1 Denition of a Compensating Transaction . . . 75

4.2.2 Mapping Compensating Transactions to Object-Oriented Programming Languages . . . 78

4.2.3 Idempotent Compensating Transactions . . . 82

4.3 Transaction Locking Levels . . . 83

(11)

CONTENTS iii

4.3.2 Dierent Locking Levels on Transactional Methods . . . 83

4.3.3 Transactional Methods Requesting Locking Levels . . . 84

4.3.4 Introducing Concepts for Locking Levels . . . 85

4.3.5 Multi-Threading in Object-Oriented Programming Lan-guages . . . 86

4.3.6 Locking Implementation . . . 87

4.3.7 Avoid Deadlocks Using Timestamps . . . 87

4.4 Retry Semantics for Transactions . . . 88

4.4.1 Introducing Retry Semantics for Transactions . . . 88

4.4.2 Graphical Notation for Retry Semantics . . . 89

4.4.3 Mapping of Retry Semantics for Transactions to Object-Oriented Programming Languages . . . 92

4.4.4 Abstraction of Control . . . 93

4.4.5 Retry Semantics in Eiel . . . 96

4.5 Conclusion and Future Work . . . 97

5 Concepts for Advanced Transaction Types 99 5.1 Long Running Transactions . . . 100

5.1.1 Denition of a Long Running Transaction . . . 100

5.1.2 Mapping Long Running Transactions to Object-Oriented Programming Languages . . . 105

5.1.3 Long Running Transactional Method Translation Scheme . 107 5.2 Nested Transactions . . . 108

5.2.1 Denition of a Nested Transaction . . . 108

5.2.2 Open Nested Transactions . . . 108

5.2.3 Closed Nested Transactions . . . 109

5.2.4 Mapping Nested Transactions to Object-Oriented Pro-gramming Languages . . . 112

5.2.5 Closed Nested Transactional Method Translation Scheme . 113 5.3 Retry Semantics for Advanced Transaction Types . . . 113

5.3.1 Retry Semantics for Long Running Transactions . . . 114

5.3.2 Retry Semantics for Nested Transactions . . . 116

5.4 Combining Advanced Transaction types . . . 118

5.4.1 Combining Nested Transaction Types . . . 118

5.4.2 Combining Long Running and Nested Transaction Types . 122 5.5 Based on a Case Study . . . 122

5.6 Conclusion . . . 123

6 Conclusion 125 6.1 Summary of Contributions . . . 125

6.2 Directions for Future Work . . . 129

(12)
(13)

List of Figures

2.1 Immutable Local Object Passed to a Local Method . . . 18

2.2 Immutable Local Object Passed to a Remote Method . . . 19

2.3 Technical Details of an Immutable Local Object Passed to a Remote Method . . . 20

2.4 Mutable Local Object Passed to a Local Method . . . 21

2.5 Mutable Local Object Passed to a Remote Method . . . 22

2.6 Technical Details of a Mutable Local Object Passed to a Remote Method . . . 23

2.7 Immutable Remote Object Passed to a Local Method . . . 24

2.8 Immutable Remote Object Passed to a Remote Method . . . 26

2.9 Technical Details of an Immutable Remote Object Passed to a Remote Method . . . 27

2.10 Mutable Remote Object Passed to a Local Method . . . 28

2.11 Mutable Remote Object Passed to a Remote Method . . . 30

2.12 Technical Details of a Mutable Remote Object Passed to a Remote Method . . . 31

2.13 Distributed Application . . . 35

2.14 Interception at Server Side . . . 37

2.15 Deployment Pattern . . . 38

2.16 Smart References . . . 39

3.1 ValueState Class . . . 55

3.2 Nested Methods . . . 58

3.3 Composition of Objects . . . 59

3.4 Overriding Methods in Subclasses . . . 60

3.5 State Diagram for Transactional Methods . . . 67

4.1 Graphical Notation for Transactions . . . 72

4.2 Use of the Transactional Notation . . . 73

4.3 Compensational Transactions . . . 77

4.4 State Diagram for Compensational Methods . . . 81 v

(14)

4.5 Graphical Notation for Retry Semantics for Transactions . . . 90 4.6 Transaction Retrying . . . 91 5.1 Long Running Transaction as a Sequence of Small Transactions . . 102 5.2 Small Transaction (left) Aborting Long Running Transaction . . . 103 5.3 Small Transaction (middle) Aborting Long Running Transaction . 104 5.4 Small Transaction (right) Aborting Long Running Transaction . . 105 5.5 Closed Nested Transaction . . . 110 5.6 Child Transaction (left) Aborting Closed Nested Transaction . . . 110 5.7 Child Transaction (middle) Aborting Closed Nested Transaction . 111 5.8 Small Transaction (left) Aborting Long Running Transaction with

Retry Semantics . . . 115 5.9 Small Transaction (Middle) Aborting Long Running Transaction

with Retry Semantics . . . 116 5.10 Child Transaction (left) Aborting Closed Nested Transaction with

Retry Semantics . . . 117 5.11 Child Transaction (middle) Aborting Closed Nested Transaction

with Retry Semantics . . . 118 5.12 Child Aborting in a Nested-Nested Transaction . . . 120

(15)

Chapter 1

Introduction

If we knew what it was we were doing, it would not be called research, would it? Albert Einstein

Section 1.1 starts with topics of software engineering in general and back-ground information to trace the status of the present understanding of the do-main. Next, section 1.2 enumerates the goals of our research and Section 1.3 pro-vides the used approach. Finally, Section 1.4 gives an overview of the remainder of this dissertation.

1.1 Background

This section starts with an overview of evolutions in software development pro-cesses and current trends in object-oriented programming languages. This section includes several publications of the authors that are not an integral part of the contributions of this research. These papers were written in studying aspects of software engineering that are relevant for the work. Section 1.1.2 includes publications of the authors in the general area of software engineering. Fur-thermore, Section 1.1.3 enlightens experiments and publications in the domain of Model Driven Architecture. Section 1.1.4 includes a paper discussing dier-ences between an aspect-oriented and an object-oriented implementation of a specic case study. Section 1.1.5 shows publications of the authors in eXtreme Programming, more specically Test Driven Development. Finally, Section 1.1.6 and Section 1.1.7 illustrate background on enterprise programming and transac-tion processing.

(16)

1.1.1 Programming Languages in General

In our research we mainly focus on the world of object-oriented programming languages, like Java and C#. In this world, changes are coming from various directions. On one hand, new technologies and paradigms are proposed that shed a whole new light on the entire process of software development. Examples include Agile Methods, eXtreme Programming (XP) and Test Driven Develop-ment (TDD). Moreover, with Model Driven Architecture (MDA) the developDevelop-ment process itself is lifted to a higher level of abstraction. Initially MDA focused on vertical markets, but this paradigm has recently shifted its focus towards a more horizontal, widespread application in dierent software domains. Next to tech-nologies altering the entire software development process, several techtech-nologies are focusing on improving specic parts of this development cycle. The imple-mentation phase, for instance, is greatly impacted by new technologies such as Aspect-Oriented Programming, declarative programming, and annotation-based programming. The success of these technologies clearly originates from the fail-ure of mainstream programming languages to provide developers with powerful language abstractions. Consider annotations, a concept often applied in enter-prise systems to enable persistency or distribution. Before annotations were introduced, these challenges needed to be tackled using verbose and technical framework interactions. But now, developers simply provide the necessary infor-mation in annotations, leaving the implementation of technical interactions to an annotation pre-processor. What all these changes have in common is that they search to increase the quality of the software product, while at the same time reducing the eort required to build it.

This work focuses on the underlying common denominator of all these changes, namely the programming language. When they were introduced, lan-guages like Java and C# were marketed as manageable object-oriented program-ming languages with a reduced number of concepts. They needed to serve as a counterpart to programming languages which were gradually becoming more complex. To have some idea, consider for instance the number of keywords dened in those languages. Consider COBOL, the general business oriented pro-gramming language of which there is a new standard coming up in 2008, in its ANSI-74 standard that language contained 305 keywords. The ANSI-85 standard added another 52 keywords, or to quote Edsger Dijkstra on COBOL (the Dutch computer Scientist who won the Turing Award in 1972.):

The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal oense.

On the other hand, both Java and C# contained approximately 50 keywords when they were introduced. These languages inherited most of their keywords from their common ancestor C++. This reduction with a factor of 10 of the number of keywords, was possible because of the advantages of object-oriented

(17)

1.1. BACKGROUND 3 programming. Advantages like encapsulation, inheritance and polymorphism form solid pillars in object-oriented programming. These advantages help devel-opers express their intent in an unambiguous way. This way, a large number of concepts is now translated using a reduced number of keywords, which brings new developers quicker up to speed. However, even though they initially stressed a clean and simple programming model, relatively young languages like Java and C# are already growing. For example, generics is now integrated in both languages, giving new potentials for developers to express their intent.

Whether the integration of generics in Java is done well, is out of scope of this dissertation. In our opinion Java developers have to be very careful when using generics, because the languages designers opted for not changing the virtual machine, hereby forcing compatibility issues with legacy code on the developers. Moreover, we experience that history seems to repeat itself: instead of solidly integrating closures into Java, we note they seem to be dropped as a feature from the next release because of ongoing arguing about their proposed syntax.

In this dissertation, we use a principle that already has proven its value in the evolution of programming languages. The principle species that we search for good styles to deal with low level constructs and integrate these styles as high level concepts in programming languages. A sample of the application of this principle is the integration of iteration statements in current programming languages. Namely, as a replacement for the diculty to track goto-statement constructs, high level concepts like the while-statement are now used. Another more recent example of this principle is the replacement of the use of function pointers in structural programming languages to dynamically bind method exe-cution, by the clean use of method overriding in object oriented languages. These samples show that the application of this principle eternalizes the solid high level concepts into programming languages.

It is our perception that the current number of concepts, integrated in object-oriented programming languages like Java and C#, is by far too low. As a consequence, we see the number of application libraries and frameworks largely explode. Although these libraries and frameworks oer great functionality in spe-cic problem domains, they miss the support compilers could provide by validat-ing their correct usage. By addvalidat-ing new concepts to object-oriented programmvalidat-ing languages, we aim to raise their expressive power. To that extent, we have con-ducted two experiments. First, we have evaluated the use of language concepts for realizing location-transparency in distributed object-oriented programs. Second, we have evaluated the integration of new language concepts for using transactions as rst-class concepts in object-oriented programming languages.

1.1.2 Object-Oriented Programming

Advantages of Object-Oriented Programming

(18)

and polymorphism, are already well known. Using these concepts leads to nu-merous advantages. First of all, modeling real world objects as software objects leads to clear and less complex program structures. Next, separating internal functioning of objects from their external interface, makes it easy to make minor changes to the internal implementation in view of maintenance, without aecting the clients. Finally, re-using existing classes through inheritance and composi-tion, enables developers to extend existing solutions to provide new ones.

We note a positive trend in current object-oriented programming languages like Java and C#. New language features such as generics, annotations and closures increase their expressiveness. However, the way some of these extensions have been integrated in Java and C# is the subject of many discussions. It is our perception that learning to use and implementing these new features is not always straightforward, however it is primordial to good software development. Although not further mentioned in this dissertation, several seminars [18, 24] were organized by us during this research, to stress on the importance of these new features.

Design Patterns

Inspired by the work of Alexander C. [31], described in his books on environ-mental structures, patterns form a rock solid base to discover and implement proper solutions. Patterns identify and document key ideas that distinguish good solutions from a poor solution. Hence, a thorough knowledge of the seman-tics of existing software design patterns like the famous Gang of Four patterns book [48], is essential for every respected software developer. Explaining solu-tions to fellow developers and project management using such a common pattern language [4, 28, 51, 76, 103], moves the focus away from implementation issues to-wards a more conceptual level. And only at this conceptual level are sustainable solutions constructed.

Although we reckon the value of design patterns and general framework so-lutions, in our vision they illustrate the shortcomings of the underlying pro-gramming languages. We see that application-specic patterns and frameworks indirectly state the need for domain specic-languages. These languages apply the principle of Section 1.1.1; they eternalize good styles as high level concepts in programming languages. We use this advantage and apply the principle through-out this dissertation.

1.1.3 Model Driven Architecture

As modern software is becoming ever more complex, the urge to move the level of abstraction higher up is becoming increasingly more prominent. As in tra-ditional engineering, software is developed using models (schemes) to reduce the gap between product vision and product implementation. The various goals of

(19)

1.1. BACKGROUND 5 these models are to detect errors and omissions in an early design stage, to com-municate with stakeholders and to drive implementation.

Model Driven Architecture (MDA) [47, 70, 82, 113] is one of the modern soft-ware development process evolutions. Hence during the doctoral training pro-gram numerous experiments were conducted. MDA starts by sketching one or more computation independent business models (also known as domain models). Various viewpoints, such as a distributed computing viewpoint or an information viewpoint, can be used to focus on dierent concerns of the business at stake. The next step is to create a computational model. This model, referred to as the PIM, is still platform independent. In a PIM, a software system is modeled of-fering solutions for the requirements stated in the business model. In a following stage, the PIM is transformed into one or more platform specic models (PSM), each focusing on a specic implementation technology. PSM's can be oriented towards the data tier, the business tier, the presentation tier, etc. Finally, the code is generated from the dierent PSM's. It is evident that this whole process cannot be performed fully automatically, but that it is steered with parameters and extra behavioral models at dierent levels of abstraction.

MDA makes use of widely accepted and well-rewarded technologies. Mod-els can be created using the Unied Modeling Language (UML)[14, 45, 71, 102]. These models can be augmented with principles of design by contract (DBC) [81, 83], using the Object Constraint Language (OCL) [113] to drive parts of the be-havior. General design patterns and business specic patterns can be used in the generation steps [4, 28, 31, 48, 71, 76, 103]. Authors of MDA claim that a unique feature about MDA is its exibility to make structural changes to the software while it is under development. Such changes are made eective by altering the Platform Independent Model. The ultimate goal of the MDA paradigm then, is to translate these changes to lower levels such as the PSM and the code level, without nullifying previous work of the developers. Such changes inevitably occur because business models evolve, additional requirements appear and misunder-standings in the design stage occur. To enable such round-trips to the design stage, a specialized MDA tool-set is required, and a large number of these tools has already been developed. These tools generate new software releases without loosing previously ne-tuned information.

A research paper [20] was published with the title Model Driven Architecture: The next abstraction level in programming. This paper explains the Model Driven Architecture as a paradigm that supports change in software. The paper argues that MDA is the next logical step in the evolution of techniques and methods for software development. Moreover, the necessity of MDA in an ever evolving software industry is explained. The paper sketches a series of clear advantages of MDA over more traditional approaches of software development, as they are practiced today.

(20)

We published and presented some of our insights in the principles and the application of Model Driven Architecture at the rst European Conference on the Use of Modern Information and Communication Technologies in 2004 [20]. At the same time, four Erasmus master students conducted several experiments to evaluate the use and possibilities of MDA. In 2005 [21], this research was nalized with a comparison between MDA and other modern development processes, such as XP. The results of these publications are left out of this dissertation, the experiments were conducted to get acquainted with the problem domain.

1.1.4 Aspect-Oriented Programming

As indicated in Section 1.1.2, object-oriented programming is an established strategy and design patterns are taking a leading role when structuring soft-ware systems. It is tedious to create complete separation of concerns, espe-cially when multiple inheritance is not supported. Aspect-Oriented program-ming [1, 33, 41, 42, 44, 54, 61, 62, 66, 67, 68, 69, 89, 90, 92] claims to be a solution to this problem, by weaving extra code in the application. This weav-ing can be done statically by insertweav-ing extra code in the source le before it is compiled, or it can be done dynamically by inserting byte code in compiled pro-grams. A problem with this aspect-oriented solution is that there are very little restrictions on the weaving of aspect code. Aspect-Oriented programming allows to modify the behavior of the original code without warning clients depending on that code. We know this domain is still in evolution. We did not follow recent developments in aspect-oriented programming.

During this research a case study was developed to illustrate the location transparency concepts of Chapter 2. We were tempted to use an aspect-oriented solution and confronted this solution to an object-oriented solution. The con-clusions of this confrontation were presented and published in 2006 at the Soft-ware Engineering and Application conference of the Virtual Multi Conference on Computer Science and Information Systems in Portugal [22]. For this specic case study the paper showed an object-oriented solution using well-known de-sign patterns, resulting in a disciplined way of working. However, contrary to the aspect-oriented solution, the object-oriented solution forced developers to do some repetitive work. The conclusions in this paper were based on the state of the art of aspect-oriented programming in 2005. In [54] J. Hannemann and G. Kiczales propose aspect implementations of a number of the GoF [48] design pat-terns to show improvements in code. By means of Java and AspectJ they claim to take the advantages of using design patterns into aspect-oriented programming. Although the conclusions of this comparative study are not included in this dissertation, we apply the lessons learned from it. In addition, we use aspect-oriented programming together with annotation features in this dissertation, as a toolkit to implement new concepts in an object-oriented programming language like Java.

(21)

1.1. BACKGROUND 7

1.1.5 Extreme Programming and Test Driven

Develop-ment

The eXtreme Programming (XP) [7, 99] software development process oers many advantages that are not found in other development processes. By far the most important advantages are, on one hand, the adaptability of development in case of changing requirements and, on the other hand, the continuous availability of a deliverable product. Both these characteristics are often required in software projects. Customers change their requirements as the software evolves because they could not clearly explain their problem domain, or because they came up with new ideas for added functionality. Moreover, the XP strategy gives cus-tomers the feeling that the product is really growing in accordance to their needs. Prototypes that are released during the development process give customers a product for early experiments. These customers are also able to steer the overall development by assigning specic priorities to dierent features of the end prod-uct. Hence, because customers participate continuously during development, the risk of failing software projects is reduced by making use of XP.

An article by the authors appeared in a reviewed journal on .Net technology in 2005 [26]. The article describes the essential parts of an XP process, followed by a SWOT (Strengths, Weaknesses, Opportunities and Threats) analysis to imple-ment the process successfully. This dissertation does not focus on XP; it merely applies one of its key principles, namely Test Driven Development (TDD). Hence, during the development of the dierent case studies, and during the evaluation of the concepts introduced in this work, the TDD approach is used to qualify the dynamic behavior of the proposed solutions. Present research in this direction is the base for future research directions of the authors [15, 16, 17, 19], but a detailed discussion of these research results is outside the scope of this dissertation.

1.1.6 Transaction Processing

Database management systems and associated transaction management systems are probably the rst large scale applications ever made. At the moment these systems were introduced, they had a remarkable impact on industrial eciency. Tasks that required mentally exhausting work were supported by database-based software, such as accountancy, inventory management, production planning and the like. The core properties of transactions as atomicity, consistency, isolation and durability took a major role in software systems.

These software systems still take a leading role in industry and are not ex-pected to ever become redundant. On the contrary, we expect them to further integrate in current software practices. Years ago, Jim Gray [52] predicted that operating systems better replace the underlying le system with a database man-agement system. Hereby preventing to loose any information in case of a system crash, this way allowing a system to be halted immediately. The state-of-the art

(22)

database recovery mechanisms could recover all previously committed work. This idea is still under evaluation in current operating systems. Moreover, because of their ability to nd specic information in a vast amount of data, databases outperform the le-system.

More recently, research communities are looking at the isolation property of database transactions to provide new concurrency mechanisms [57, 58, 59, 65, 101]. Consequently, ideas as software transactional memory to back a concur-rency mechanism, are proposed by M. Herlihy in [60]and N. Shavit in [105].

Although this section shows the importance of transactions in dierent soft-ware domains, we noted their integration as concepts to provide transactional behavior in object-oriented programming languages is non-existent. In this text we propose language concepts to enhance methods with transactional behavior. Our work primarily focuses on atomicity properties of transactions, therefore transaction behavior takes a leading role in the topics covered in Chapters 3-5 of this dissertation.

1.1.7 Enterprise Programming

Since network became available in the late eighties, concepts to split work on dierent runtime environments were introduced. Remote procedure calls allowed programs, created using structural programming techniques, to be split across multiple central processing units.

Currently, this idea of splitting work across multiple machines is still in use in object-oriented programming languages by technologies as Java RMI (Re-mote Method Invocation) [40] and .Net Remoting [80, 84, 95]. Moreover, enter-prise frameworks like JEE (Java Enterenter-prise Edition) [38, 79, 97] and .Net Ser-vices [32, 88] still use the same underlying mechanisms to communicate across runtime boundaries. Even current Service Oriented Architectures, using web services to compose applications based on numerous available components, use an underlying protocol comparable to the remoting infrastructures. Enterprise frameworks currently use annotations to describe remote relations. Some on-going research projects study the integration of these relations as concepts in object-oriented programming languages [36].

The discrepancy between the semantics for passing arguments to local and remote runtime environments is the core research domain of Chapter 2.

(23)

1.2. GOALS 9

1.2 Goals

The goals of this dissertation are fourfold:

Design language concepts for transparent local and remote object interac-tions.

Current technology allows developers to pass objects to operations in re-mote environments. A dierent semantics is used when passing these ob-jects to local operations. Therefore developers currently have to be con-cerned whether their application will be deployed in a distributed environ-ment or not. The rst objective of this dissertation is to provide concepts to enable developers to pass mutable objects to both local and remote methods in a fully transparent way.

Dene language concepts for transactional behavior.

Current state of the art for using transactions is by means of library classes and code annotation. The second goal of this dissertation is to evaluate if language concepts can be used to get transactional behavior as rst-class concepts into object-oriented programming languages. By making use of the atomicity and the isolation property of transactions, this goal avoids the need for boilerplate code currently used to handle exceptional cases.

Support for advanced transactional types.

Basic concepts supporting transactions in programming languages still lead to considerable amounts of handwritten code in working out more complex types of transactions. The third goal of our work is to support more ad-vanced kinds of transactions by means of developer-friendly and simple language concepts so as to strategically implement complex designs more easily.

Provide a graphical notation to reason about transactional behavior. In the same way software engineers need graphical notations to express the ow of method calls, they must be able to visualize the state of running transactions in reasoning abut complex software systems. The notation must specify shapes to illustrate transactional types and transactional in-stances at specic moments in time.

1.3 Approach

In this dissertation, we search for good styles to deal with low level constructs. Instead of using library classes or code annotation to use the constructs, we eval-uate whether we are able to integrate their usage as high-level language concepts. By adding new concepts to object-oriented programming languages like Java and

(24)

C#, we aim to raise their expressive power. When explaining language features we refer to Java as our reference language, but the concepts are also applicable to C#.

In our search for new language concepts we took the following approach: 1. A case study was developed using current object-oriented language

con-cepts. This case study was developed both in Java and in C#. Test suites for every feature of the case study were added. They act as a safety net so future changes to the code will not modify the behavior of the application. 2. The code was scanned for recurring patterns, implementing specic aspects repeatedly. Those patterns were translated into language concepts. A formal denition of the introduced concepts does not make part of our re-search. Instead, by using the language concepts in the previously developed case study, their applicability was veried.

3. The case study was rewritten using the new language concepts. Transla-tion schemes were provided to translate the high level concepts into regular Java code. This way, new concepts were introduced, and these concepts were translated into currently available language constructs. To verify the proposed semantics and to quantify the reliability of the introduced con-cepts, we reused the test suites of the original case study.

An alternative approach could have been to change the compiler, as such that it supports the new concepts, and translates these new concepts in byte code constructs. We opted to translate our language concepts to regular Java.

1.4 Overview of the Dissertation

This dissertation contains 6 chapters. In addition to this introduction, the dis-sertation is organized in the following chapters:

In Chapter 2 we focus on the disparity among the mechanisms for local and remote parameter passing. We introduce concepts to transparently invoke local and remote methods. The chapter starts with a detailed classication of method invocation semantics so as to create a list of problems that occur in Java's pa-rameter passing strategy. As it turns out, most of these problems arise as a result of Java's choice to pass local parameters and remote parameters in a dierent way, leading to transparency problems. We propose a number of solutions to support this transparency. Finally, we present a transparent framework to pass mutable objects to remote operations, in the same way as they are passed to local operations.

Chapter 3 proposes transactions as rst-class concepts in object-oriented pro-gramming languages, without the need for a transaction management system.

(25)

1.4. OVERVIEW OF THE DISSERTATION 11 We show how this approach allows to realize atomicity and isolation, important database transactional properties that keep systems in a consistent execution state. The concept of transactional behavior is added to methods, this way en-hancing the expressiveness of the programming language.

Chapter 4 starts with the introduction of a graphical notation to discuss ex-tended concepts for transactions and advanced transaction types. Using our graphical notation we introduce compensational behavior of transactional meth-ods. Next, transaction locking levels are dened to relax the transaction isolation level and nally, transactional methods are extended with retry semantics.

Chapter 5 uses the concepts of Chapter 4 to dene advanced transaction types. In this chapter, concepts for long running advanced transaction types and nested advanced transaction types are proposed.

Finally, we conclude this dissertation in Chapter 6 with an overview and sum-mary of our contributions, together with directions for future research.

(26)
(27)

Chapter 2

Local-Remote Transparency

Concepts

The essence of knowledge is having it, to apply it; not having it, to confess your ignorance. Confucius

A developer should not experience concern on whether his application will be deployed in a distributed runtime environment or not. However, because of the disparity among the mechanisms for local and remote parameter passing, he has to be cautious. Mechanisms for local parameters pass parameters by value or by reference, depending on their type. But current remoting infrastructures use value semantics (realized by serialization) to pass all parameters from a local method to a remote method, hence creating transparency problems.

In this chapter we analyze the transparency diculties in a number of scenarios. We propose a language concept to model the mutability of objects. We evaluate its use in a case study. Before solving the transparency problem, we present a detailed classication of all possible method invocation semantics. Next, several solutions will be considered to provide this transparency. Finally, we propose a transparent framework to pass mutable objects to remote operations, in the same way as they are passed to local operations. This framework solution will use an introduced mutability concept and the framework will be implemented and validated using tests in a multi-threaded environment.

The key insights of this chapter are published as a reviewed research paper in the proceedings of the second European Conference on the Use of Modern Information and Communication Technologies in 2006 [23].

(28)

2.1 Introduction

In this Section, we start by explaining parameter passing strategies in local en-vironments. Next, we identify the transparency problem when using parameter passing in a distributed environment. Finally, we will discuss the mutability of the objects, the underlying transparency problem.

2.1.1 Parameter Passing for Local Methods

In the Java programming environment, the JVM (Java Virtual Machine) uses call-by-value as the only parameter passing strategy. When delivering primitive typed parameters to local methods, the parameter's value is copied onto the stack. The callee copies this value from the stack into its own address space. This way, the callee gets a copy of the original primitive type variable. However, when delivering reference typed parameters, the parameter's reference is copied onto the stack. This way, the callee gets a copy of the original reference and is thus referencing the same object as the caller. This reference passing mechanism is known as aliasing. Because of aliasing, both the caller and the callee can change the same referenced object.

In this dissertation the rst type of parameters, where the actual value is copied, is called value parameter. The second type of parameters, where the reference is copied, is called reference parameter.

The .Net programming environment contains three dierent parameter pass-ing strategies. For each parameter the developer species how it should be passed. In C# parameters can be passed as in-parameters, as out-parameters and as ref-parameters. In the Unied Modeling Language [14] the C# ref-parameters are called in-out-parameters. A C# in-parameter is the equivalent of a call-by-value parameter in the Java environment. Hence, aliasing of reference typed parameters is also present in the VES (Virtual Execution System) for .Net.

Mind that struct parameters in C#, which is the .Net version of a compound value type similar to expanded classes in Eiel [2, 81], are passed as primitive typed parameters. In case of a struct parameter passed to a method, the content of the compound value type is copied onto the stack and the callee copies this content from the stack into its own address space. In terms of this dissertation, only reference typed parameters are considered, since aliasing does not occur for structs.

2.1.2 The Transparency Problem

This chapter concentrates on problems appearing in situations where parameters are passed to remote methods. The transparency problems are caused by the underlying remote parameter passing strategy that diers from the local param-eter passing strategy. Namely, aliasing of reference typed paramparam-eters in

(29)

non-2.1. INTRODUCTION 15 distributed environments is dissimilar to aliasing in distributed environments. These problems occur both in Java Enterprise Edition(JEE) [13, 79, 106], where Remote Method Invocation over Internet Inter-Orb Protocol(RMI-IIOP) [38] is used, as in .Net [32, 84] , where .Net Remoting [80, 95] is used. From now on we will use the term virtual machine to denote both the Java Virtual Machine and the C# Virtual Execution System.

The boundary of the execution environment is crossed when passing param-eters to operations on remote objects. The virtual machine uses a serialization mechanism to pass parameters across these boundaries. In case of value param-eters, the local execution environment serializes these values into a byte-stream and sends the stream to the remote execution environment. The remote execu-tion environment de-serializes the stream into a new value in the remote program space. This is still comparable to the call-by-value strategy for local method calls. However, in case of reference parameters, a dierent strategy is used. Because references are only eective in their own execution environment, the virtual ma-chine serializes the referenced object instead of the reference. At the remote side, the byte-stream is de-serialized and a new version of the object is created in the remote program space.

In most situations, the remote parameter passing mechanism is working ne. Only some minor performance degradation can be found when the parameter that is passed to the remote method is immutable. However, when this parameter is mutable, as is mostly the case, a dierent version of the parameter is used in local and remote program space. This is not quite the equivalent of the local-calling scheme, since in the local scheme we are actually referring to the same object. In the remote scheme we are referring to two completely dierent objects that, additionally, reside in dierent program spaces. In this scheme, the remote callee is using a new object with the same initial state as the caller's object. In Section 2.2, a number of problem situations will be identied. These are situations in which performance degradation is noted, and one situation in which dirty data can exist.

When implementing applications, the developer should focus on the func-tional requirements of the application. Yet, passing parameters to local methods or to remote methods is implemented in dierent ways. Thus local-remote trans-parency is required since developers should not worry whether their applications will be distributed or not.

2.1.3 Mutability of Objects

The problems caused by serialization, as explained in Section 2.1.2, depend on the nature of the object passed as a parameter. One kind of objects is mutable, another is immutable. Immutable objects include those objects (1) that never change during their entire lifetime, (2) that remain unchanged during the

(30)

execu-tion of the remote method, (3) and those objects for which any changes made to the original object can be ignored by the remote method.

Immutable objects may be replicated as many times as necessary, as synchro-nization issues between dierent instances will never occur. However, mutable objects, whose state changes during the execution of the operations, are causing trouble. In the following sections, we will provide a mechanism to inform the developer whether or not he is using outdated data.

Mind that a common way to protect data across machine boundary is by using distributed transactions. Inside such a transaction the data is locked temporarily. The heavy machinery of transactions, and the discussion of isolation levels to solve locking, is overkill for this problem. In this chapter we want to provide a lightweight solution for preventing synchronization issues.

2.2 Problem Scenarios

The number of possible interactions between two objects dramatically increases when remoteness enters the picture. Now, both the invocation target as well as the method argument may contain references to remote objects. This does not only complicate invocation semantics, but it may also lead to synchronization problems. Therefore, before solving the transparency problem, we needed to have a detailed classication of all possible method invocation semantics. This classication takes into account remoteness and mutability, and serves as a basis for explaining some interesting problems that occur when distributing object-oriented applications. Section 2.3 will then propose solutions to the problems that were discovered after making this classication.

In this Section we illustrate the transparency problem using a series of sce-narios. The Java language is used in the samples, but as stated in Section 2.1.2, the problems are also observed in C# on .Net.

2.2.1 Overview of Problem Scenarios

Consider all possible scenarios, as shown in Table 2.1. The top part of this table considers local objects passed as parameter. In the bottom part, remote objects are passed. Inside each part of this table, four rows specify the consequences if a mutable or an immutable object is passed to a local or a remote method. The last column of the table shows in which section problems are noted.

(31)

2.2. PROBLEM SCENARIOS 17 Object

Locality MutabilityObject Operation Section Problem

1 local immutable local call 2.2.2

2 local immutable remote call 2.2.3

3 local mutable local call 2.2.4

4 local mutable remote call 2.2.5 out-of-sync

5 remote immutable local call 2.2.6

6 remote immutable remote call 2.2.7 degradation

7 remote mutable local call 2.2.8

8 remote mutable remote call 2.2.9 degradation Table 2.1: Parameter passing scenarios

The eect of passing value parameters in a local environment is the same as in a distributed environment. In the local environment the values are copied onto the stack, and the receiving method copies these values from the stack into its own address space. In the distributed environment, the same behavior is noted, but instead of the values being copied onto and from the stack, these values are now serialized, pushed over the network and de-serialized. Since the transparency problem only arises with reference parameters, only scenarios with this kind of parameters are considered.

Each of the following sections illustrates a scenario with a graphical represen-tation. The left hand side of these graphical representations shows a local runtime environment, the right hand side the corresponding remote environment. Next, a short explanation is given on how the parameters are passed and extra clari-cation is provided in cases where problems arise. Finally, sample code is shown illustrating the specic scenario in Java.

2.2.2 Immutable Local Object Passed to a Local Method

Graphical Representation

Figure 2.1 shows an immutable local object that is passed as an argument to a local method. In this illustration, the immutable object is of type X and is named x. It is passed as an actual parameter to a method f, called on an object y of type Y, in the same address space. The call considered in this scenario is: y.f(x).

(32)

x : X Network Local-side Remote-side Immutable y : Y y.f( x ) reference

Figure 2.1: Immutable Local Object Passed to a Local Method Explanation

This is the most simple scenario of using a reference parameter, included for completeness. The parameter x passed to the method f, will be accessed by f using aliasing. Hence, f gets a copy of the reference and accesses the correct value of this immutable object.

Sample Java Code

The sample in Algorithm 1 shows a local immutable object amount passed to a method withdraw of an object myAccount in the same address space as amount. During the method execution of withdraw, a copy of the reference amount is used to access the immutable Money-object.

Algorithm 1 Sample code y.f(x)

// x

Money amount = new Money(100.0); // y

Account myAccount = new Account("Jonathan"); // call

myAccount.withdraw( amount );

2.2.3 Immutable Local Object Passed to a Remote Method

Graphical Representation

Figure 2.2 shows an immutable local object that is passed as an argument to a remote method. In this illustration, the immutable object is of type X and is named x. It is passed as a parameter to a method f, called on an object ry of type RemoteObjectStubY, in the local address space. The reference ry is actually

(33)

2.2. PROBLEM SCENARIOS 19 a remote stub to the object y of type Y, living in a remote address space. The call considered in this scenario is: ry.f(x).

x : X Network Local Remote Immutable y : Y : RemoteObjectSkeletonY ry : RemoteObjectStubY ry.f( x ) serialization

Figure 2.2: Immutable Local Object Passed to a Remote Method Explanation

This is the basic form of remote method invocation. The remote stub ry passes the parameter x to the actual method f of the remote object y. The actual execution of f is carried out in a remote address space on a copy of x. But since x is immutable, the values in this copy of x are correct.

Figure 2.3, shows the technical details of how a local object x with stateαis

serialized into a byte-stream by the local stub ry of the remote object y. The corresponding skeleton in the remote runtime environment de-serializes the byte-stream into a new object x with stateα0in the remote address space. The remote

(34)

x : X Immutable y : Y : RemoteObjectSkeletonY ry : RemoteObjectStubY 01001010 01101111 01101110 01100001 01110100 01101000 01100001 01101110 01001010 01101111 01101110 01100001 01110100 01101000 01100001 01101110 x : X Immutable Network Local Remote

Figure 2.3: Technical Details of an Immutable Local Object Passed to a Remote Method

Sample Java Code

The code in Algorithm 2 shows a remote object called myAccount. This object is made available, outside this remote runtime environment, through an export operation. Remote objects can nd the object using the relevant RMI registry, where it is registered under the name "MyAccount".

Algorithm 2 Remote Environment Export myAccount

// y

Account myAccount = new Account("Jonathan"); PortableRemoteObject.exportObject(myAccount);

Context ctx = new InitialContext( aPropertiesObject ); ctx.rebind("MyAccount ", myAccount);

The sample in Algorithm 3 shows how the remote object myAccount of Algo-rithm 2 is accessed in the local context through a stub myRemoteAccount. A local immutable object called amount is passed to a method withdraw of the remote object stub myRemoteAccount. During the execution of this remote method, a copy of the object amount, in the remote address space, is used.

(35)

2.2. PROBLEM SCENARIOS 21 Algorithm 3 Sample code ry.f(x)

// ry

Context ctx = new InitialContext( aPropertiesObject ); RemoteAccount myRemoteAccount =

(RemoteAccount) PortableRemoteObject.narrow( ctx.lookup("MyAccount "), RemoteAccount.class); // x

Money amount = new Money(100.0); // call

myRemoteAccount.withdraw( amount );

2.2.4 Mutable Local Object Passed to a Local Method

Graphical Representation

Figure 2.4 shows a mutable local object that is passed as an argument to a local method. In this illustration, the mutable object is of type Z and is named z. It is passed as an actual parameter to a method f, called on an object y of type Y, in the same address space. The call considered in this scenario is: y.f(z).

Network Local Remote y : Y y.f( z ) z : Z Mutable reference

Figure 2.4: Mutable Local Object Passed to a Local Method Explanation

This scenario is analogous to the scenario of Section 2.2.2, included for complete-ness. The only dierence is that instead of passing an immutable object x, now a mutable object z is passed to the method f. The object z is accessed using aliasing, hence the correct value of this mutable object is used.

Sample Java Code

The sample in Algorithm 4 shows a local mutable object myFriend passed to a method transferAmountTo of an object myAccount in the same address space

(36)

as myFriend. During the method execution of transferAmountTo, a copy of the reference myFriend is used to access the mutable Person-object.

Algorithm 4 Sample code y.f(z)

// auxiliary

Money amount = new Money(100.0); // y

Account myAccount = new Account("Jonathan"); // z

Person myFriend = new Person("Laura"); // call

myAccount.transferAmountTo( amount, myFriend );

2.2.5 Mutable Local Object Passed to a Remote Method

Graphical Representation

Figure 2.5 shows a mutable local object that is passed as an argument to a re-mote method. In this illustration, the mutable object is of type Z and is named z. It is passed as a parameter to a method f, called on an object ry of type RemoteObjectStubY, in the same address space. The reference ry is actually a remote stub to the object y of type Y, living in a remote address space. The call considered in this scenario is: ry.f(z).

Network Local Remote y : Y : RemoteObjectSkeletonY ry : RemoteObjectStubY ry.f( z ) z : Z Mutable serialization

Figure 2.5: Mutable Local Object Passed to a Remote Method Explanation

This scenario is comparable to the scenario of Section 2.2.3, but now a synchro-nization issue arises. The remote stub ry passes the parameter z to the actual method f of the remote object y. The actual execution of f is done in a remote

(37)

2.2. PROBLEM SCENARIOS 23 address space on a copy of z. Since z is mutable, it might change in the local environment while a copy is in use in the remote environment.

Figure 2.6 shows the technical details of how a local object z with stateβ is

serialized into a byte-stream by the local stub ry of the remote object y. The corresponding skeleton in the remote runtime environment de-serializes the byte-stream into a new object z with state β0 in the remote address space. This

causes the out-of-sync problems. The state β at the local side can change after

the value is serialized, causing a changed state β1 at the local side and a state β0 at the remote side. As a result, any changes made to the local copy of z will

not be reected in the de-serialized copy of z at the remote side. And vice versa, any changes made to the de-serialized copy of z at the remote side will not be reected in the local copy of z.

y : Y : RemoteObjectSkeletonY ry : RemoteObjectStubY 01001100 01100001 01110101 01110010 01100001 01001100 01100001 01110101 01110010 01100001 z : Z z : Z Mutable Mutable Out of Sync Network Local Remote

Figure 2.6: Technical Details of a Mutable Local Object Passed to a Remote Method

Sample Java Code

The same code of Algorithm 2 is used to make the remote object called myAccount available outside its runtime environment.

The sample in Algorithm 5 shows how the remote object myAccount is ac-cessed in the local context through a stub myRemoteAccount. A local mutable object myFriend is passed to a method transferAmountTo of the remote object stub myRemoteAccount. During the execution of this remote method, a copy of the object myFriend is used in the remote address space. Any changes to the local object myFriend will not be reected in the remote copy, causing the out-of-sync problems.

(38)

Algorithm 5 Sample code ry.f(z)

// ry

Context ctx = new InitialContext( aPropertiesObject ); RemoteAccount myRemoteAccount =

(RemoteAccount) PortableRemoteObject.narrow( ctx.lookup("MyAccount "), RemoteAccount.class); // auxiliary

Money amount = new Money(100.0); // z

Person myFriend = new Person("Laura"); // call

myRemoteAccount.transferAmountTo( amount, myFriend );

2.2.6 Immutable Remote Object Passed to a Local Method

Graphical Representation

Figure 2.7 shows an immutable remote object that is passed as an argument to a local method. In this illustration, the immutable object is of type X and is named x. This object x is locally made available through its remote stub rx of type RemoteObjectStubX. This remote stub rx is passed as a parameter to a method f, called on an object y of type Y in the local address space. The call considered in this scenario is: y.f(rx).

x : X Network Local Remote : RemoteObjectSkeletonX rx : RemoteObjectStubX Immutable y.f( rx ) y : Y reference

Figure 2.7: Immutable Remote Object Passed to a Local Method Explanation

This is the basic form of passing a remote object to a local method. The param-eter rx passed to the method f, will be accessed by f using aliasing. Hence, f gets a copy of the reference rx and actually accesses the same remote object stub of x.

(39)

2.2. PROBLEM SCENARIOS 25 Sample Java Code

The code in Algorithm 6 shows a remote object called amount. This object is made available, outside this remote runtime environment, through an export operation. Remote objects can nd the object using the relevant RMI registry, where it is registered under the name "Amount".

Algorithm 6 Remote Environment Export amount

// x

Money amount = new Money(150.0);

PortableRemoteObject.exportObject(amount);

Context ctx = new InitialContext( aPropertiesObject ); ctx.rebind("Amount ", amount);

The sample in Algorithm 7 shows how the remote object amount of Algo-rithm 6 is accessed in the local context through a remote stub remoteAmount. This stub remoteAmount is passed to a method withdraw of an object myAccount in the same address space as the remoteAmount stub. During the method ex-ecution of withdraw, a copy of the stub remoteAmount is used to access the immutable remote Money-object.

Algorithm 7 Sample code y.f(rx)

// rx

Context ctx = new InitialContext( aPropertiesObject ); RemoteMoney remoteAmount =

(RemoteMoney) PortableRemoteObject.narrow( ctx.lookup("Amount "), RemoteMoney.class); // y

Account myAccount = new Account("Jonathan"); // call

myAccount.withdraw( remoteAmount );

2.2.7 Immutable Remote Object Passed to a Remote

Method

Graphical Representation

Figure 2.8 shows an immutable remote object that is passed as an argument to a remote method. In this illustration, the immutable remote object is of type X and is named x. This object x is locally made available through its remote stub rx of type RemoteObjectStubX. This remote stub rx is passed as a parameter to a method f, called on an object ry of type RemoteStubY in the local address space. The reference ry is actually a remote stub to the object y of type Y, living

(40)

in the remote address space. A performance degradation arises since the remote method is now accessing an object in the same address space through a stub. The call considered in this scenario is: ry.f(rx).

x : X Network Local Remote : RemoteObjectSkeletonX rx : RemoteObjectStubX Immutable y : Y : RemoteObjectSkeletonY ry : RemoteObjectStubY ry.f( rx ) serialization

Figure 2.8: Immutable Remote Object Passed to a Remote Method Mind that if rx and ry live in separate remote spaces, the scenario is equiva-lent to the scenario of Section 2.2.3. If rx and ry live in separate remote spaces, this scenario is the only available combination. In this last case, there is no per-formance degradation, rather low perper-formance occurs because of the distribution. Explanation

The remote stub ry passes the parameter rx to the actual method f of the remote object y. The actual execution of f is carried out in a remote address space on a copy of this stub rx. But, since rx was a stub to a remote object, the copy of the stub rx is used to access the same object x in the remote address space.

Figure 2.9 shows the technical details of how a local stub rx is serialized into a byte-stream by the local stub ry of the remote object y. The corresponding skeleton in the remote runtime environment de-serializes the byte-stream into a new stub rx in the remote address space. The remote method now executes using this remote stub rx in the same address space to access a local object x. This way, a performance degradation arises since the remote method is accessing this immutable object through a stub, although the actual object lives in the same address space.

(41)

2.2. PROBLEM SCENARIOS 27 x : X : RemoteObjectSkeletonX rx : RemoteObjectStubX Immutable y : Y : RemoteObjectSkeletonY ry : RemoteObjectStubY 01110011 01110100 01110101 01100010 01011111 01001010 01110011 01110100 01110101 01100010 01011111 01001010 rx : RemoteObjectStubX Network Local Remote

Figure 2.9: Technical Details of an Immutable Remote Object Passed to a Remote Method

Sample Java Code

The same code of Algorithm 6 is used to make the remote object called amount available outside its runtime environment.

On the other hand, the same code of Algorithm 2 is used to make the remote object called myAccount available outside its runtime environment.

The sample in Algorithm 8 shows how the remote object amount of Algo-rithm 6 is accessed in the local context through a remote stub remoteAmount. This stub remoteAmount is passed to a method withdraw of a remote object stub myRemoteAccount. During the method execution of withdraw, a copy of the stub remoteAmount is used to access the immutable Money-object although it lives in the same address space.

(42)

Algorithm 8 Sample code ry.f(rx)

// rx

Context ctx = new InitialContext( aPropertiesObject ); RemoteMoney remoteAmount =

(RemoteMoney) PortableRemoteObject.narrow( ctx.lookup("Amount "), RemoteMoney.class); // ry

Context ctx = new InitialContext( aPropertiesObject ); RemoteAccount myRemoteAccount =

(RemoteAccount) PortableRemoteObject.narrow( ctx.lookup("MyAccount "), RemoteAccount.class); // call

myRemoteAccount.withdraw( remoteAmount );

2.2.8 Mutable Remote Object Passed to a Local Method

Graphical Representation

Figure 2.10 shows a mutable remote object that is passed as an argument to a local method. In this illustration, the mutable object is of type Z and is named z. This object z is locally made available through its remote stub rz of type RemoteObjectStubZ. This remote stub rz is passed as a parameter to a method f, called on an object y of type Y in the local address space. The call considered in this scenario is: y.f(rz).

Network Local Remote z : Z : RemoteObjectSkeletonZ rz : RemoteObjectStubZ Mutable y : Y y.f( rz ) reference

Figure 2.10: Mutable Remote Object Passed to a Local Method Explanation

This scenario is analogous to the scenario of Section 2.2.6. The dierence is that instead of passing a stub rx to an immutable object x, now a stub rz to mutable

(43)

2.2. PROBLEM SCENARIOS 29 object z is passed. This is comparable to the basic form of passing a remote object to a local method. The parameter rz passed to the method f, will be accessed by f using aliasing. Hence, f gets a copy of the reference rz and actually accesses the same remote object stub of z.

Sample Java Code

The code in Algorithm 9 shows a remote object called myFriend. This object is made available, outside this remote runtime environment, through an export operation. Remote objects can nd the object using the relevant RMI registry, where it is registered under the name "MyFriend".

Algorithm 9 Remote Environment Export myFriend

// z

Person myFriend = new Person("Laura"); PortableRemoteObject.exportObject(myFriend);

Context ctx = new InitialContext( aPropertiesObject ); ctx.rebind("MyFriend ", myFriend);

The sample in Algorithm 10 shows how the remote object myFriend of Algo-rithm 9 is accessed in the local context through a remote stub myRemoteFriend. This stub myRemoteFriend is passed to a method transferAmountTo of an ob-ject myAccount in the same address space as the myRemoteFriend stub. During the execution of transferAmountTo, a copy of the stub myRemoteFriend is used to access the mutable remote Person-object.

Algorithm 10 Sample code y.f(rz)

// rz

Context ctx = new InitialContext( aPropertiesObject ); RemotePerson myRemoteFriend =

(RemotePerson) PortableRemoteObject.narrow( ctx.lookup("MyFriend "), RemotePerson.class); // y

Account myAccount = new Account("Jonathan"); // auxiliary

Money amount = new Money(100.0); // call

(44)

2.2.9 Mutable Remote Object Passed To a Remote

Method

Graphical Representation

Figure 2.11 shows a mutable remote object that is passed as an argument to a remote method. In this illustration, the mutable object is of type Z and is named z. This object z is locally made available through its remote stub rz of type RemoteObjectStubZ. This remote stub rz is passed as a parameter to a method f, called on an object ry of type RemoteObjectStubY in the same address space. The reference ry is actually a remote stub to the object y of type Y, living in the remote address space. The call considered in this scenario is: ry.f(rz).

Network Local Remote y : Y : RemoteObjectSkeletonY ry : RemoteObjectStubY ry.f( rz ) z : Z : RemoteObjectSkeletonZ rz : RemoteObjectStubZ Mutable serialization

Figure 2.11: Mutable Remote Object Passed to a Remote Method Mind that if rz and ry live in separate remote spaces, the indirect access of z is necessary to access the mutable object state.

Explanation

This scenario is comparable to the scenario of Section 2.2.7. However, in con-tradiction to the scenario of Section 2.2.5 the current scenario does not lead to synchronization issues. All actions that are directly caused by this scenario are free of synchronization problems. The remote stub ry passes the parameter rz to the actual method f of the remote object y. The actual execution of f is done in a remote address space on a copy of this stub rz. But, since rz is a stub to a remote object, the copy of the stub rz is used to access the same object z in the remote address space.

Figure 2.12 shows the technical details of how a local stub rz is serialized into a byte-stream by the local stub ry of the remote object y. The corresponding

Figure

Figure 2.3: Technical Details of an Immutable Local Object Passed to a Remote Method

Figure 2.3:

Technical Details of an Immutable Local Object Passed to a Remote Method p.34
Figure 2.6 shows the technical details of how a local object z with state β is serialized into a byte-stream by the local stub ry of the remote object y

Figure 2.6

shows the technical details of how a local object z with state β is serialized into a byte-stream by the local stub ry of the remote object y p.37
Figure 2.7: Immutable Remote Object Passed to a Local Method Explanation

Figure 2.7:

Immutable Remote Object Passed to a Local Method Explanation p.38
Figure 2.8: Immutable Remote Object Passed to a Remote Method Mind that if rx and ry live in separate remote spaces, the scenario is  equiva-lent to the scenario of Section 2.2.3

Figure 2.8:

Immutable Remote Object Passed to a Remote Method Mind that if rx and ry live in separate remote spaces, the scenario is equiva-lent to the scenario of Section 2.2.3 p.40
Figure 2.9: Technical Details of an Immutable Remote Object Passed to a Remote Method

Figure 2.9:

Technical Details of an Immutable Remote Object Passed to a Remote Method p.41
Figure 2.10 shows a mutable remote object that is passed as an argument to a local method

Figure 2.10

shows a mutable remote object that is passed as an argument to a local method p.42
Figure 2.11 shows a mutable remote object that is passed as an argument to a remote method

Figure 2.11

shows a mutable remote object that is passed as an argument to a remote method p.44
Figure 2.12: Technical Details of a Mutable Remote Object Passed to a Remote Method

Figure 2.12:

Technical Details of a Mutable Remote Object Passed to a Remote Method p.45
Figure 2.14: Interception at Server Side

Figure 2.14:

Interception at Server Side p.51
Figure 2.15: Deployment Pattern

Figure 2.15:

Deployment Pattern p.52
Table 3.1: Nested Methods: State of the implicit Object when Exception is Thrown

Table 3.1:

Nested Methods: State of the implicit Object when Exception is Thrown p.72
Figure 3.3: Composition of Objects

Figure 3.3:

Composition of Objects p.73
Table 3.3: Case Study Implemented in Java

Table 3.3:

Case Study Implemented in Java p.77
Figure 4.2: Use of the Transactional Notation

Figure 4.2:

Use of the Transactional Notation p.87
Figure 4.3: Compensational Transactions

Figure 4.3:

Compensational Transactions p.91
Figure 4.6: Transaction Retrying

Figure 4.6:

Transaction Retrying p.105
Figure 5.1: Long Running Transaction as a Sequence of Small Transactions Figures 5.2, 5.3 and 5.4 show dierent scenarios where a small transaction is triggered to abort, resulting in the abort of the long running transaction.

Figure 5.1:

Long Running Transaction as a Sequence of Small Transactions Figures 5.2, 5.3 and 5.4 show dierent scenarios where a small transaction is triggered to abort, resulting in the abort of the long running transaction. p.116
Figure 5.2: Small Transaction (left) Aborting Long Running Transaction In Figure 5.3, an abort is signaled(marked as 1) in the second small  transac-tion, causing this second transaction to abort resetting its state changes

Figure 5.2:

Small Transaction (left) Aborting Long Running Transaction In Figure 5.3, an abort is signaled(marked as 1) in the second small transac-tion, causing this second transaction to abort resetting its state changes p.117
Figure 5.3: Small Transaction (middle) Aborting Long Running Transaction Finally, Figure 5.4 shows the last small transaction receiving an abort  sig-nal(marked as 1)

Figure 5.3:

Small Transaction (middle) Aborting Long Running Transaction Finally, Figure 5.4 shows the last small transaction receiving an abort sig-nal(marked as 1) p.118
Figure 5.4: Small Transaction (right) Aborting Long Running Transaction Note that in Figure 5.4, the last compensating transaction is never used, it is shown here for completeness

Figure 5.4:

Small Transaction (right) Aborting Long Running Transaction Note that in Figure 5.4, the last compensating transaction is never used, it is shown here for completeness p.119
Figure 5.6: Child Transaction (left) Aborting Closed Nested Transaction

Figure 5.6:

Child Transaction (left) Aborting Closed Nested Transaction p.124
Figure 5.5: Closed Nested Transaction

Figure 5.5:

Closed Nested Transaction p.124
Figure 5.7: Child Transaction (middle) Aborting Closed Nested Transaction The reader can infer that if the third child transaction bookCar aborts, it resets its state changes and triggers the parent transaction's abort signal.

Figure 5.7:

Child Transaction (middle) Aborting Closed Nested Transaction The reader can infer that if the third child transaction bookCar aborts, it resets its state changes and triggers the parent transaction's abort signal. p.125
Figure 5.8: Small Transaction (left) Aborting Long Running Transaction with Retry Semantics

Figure 5.8:

Small Transaction (left) Aborting Long Running Transaction with Retry Semantics p.129
Figure 5.9: Small Transaction (Middle) Aborting Long Running Transaction with Retry Semantics

Figure 5.9:

Small Transaction (Middle) Aborting Long Running Transaction with Retry Semantics p.130
Figure 5.10: Child Transaction (left) Aborting Closed Nested Transaction with Retry Semantics

Figure 5.10:

Child Transaction (left) Aborting Closed Nested Transaction with Retry Semantics p.131
Figure 5.11: Child Transaction (middle) Aborting Closed Nested Transaction with Retry Semantics

Figure 5.11:

Child Transaction (middle) Aborting Closed Nested Transaction with Retry Semantics p.132
Figure 5.12: Child Aborting in a Nested-Nested Transaction

Figure 5.12:

Child Aborting in a Nested-Nested Transaction p.134
Figuur 1: Wijzigbaar Lokaal Object Doorgeven aan een Methode op Afstand Uitleg

Figuur 1:

Wijzigbaar Lokaal Object Doorgeven aan een Methode op Afstand Uitleg p.168
Figuur 7: Retry op een Transactie Retry concept in Objectgerichte programmeertalen.

Figuur 7:

Retry op een Transactie Retry concept in Objectgerichte programmeertalen. p.182

References