22.02.2015 Views

1 Introduction 2 Présentation rapide du mod`ele - ResearchGate

1 Introduction 2 Présentation rapide du mod`ele - ResearchGate

1 Introduction 2 Présentation rapide du mod`ele - ResearchGate

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

¨<br />

¢¡<br />

Conférence Francophone de MOdélisation et SIMulation - MOSIM’06 - <strong>du</strong> £ au ¤ avril ¥§¦¢¦ - Rabat - Maroc<br />

Modélisation, Optimisation et Simulation des Systèmes : Défis et Opportunités ©<br />

Vérification d’assemblage de composants logiciels<br />

Expérimentations avec MEC<br />

Pascal André, Gilles Ardourel, Christian Attiogbé<br />

LINA FRE CNRS 2729<br />

2, rue de la Houssinière, B.P.92208<br />

F-44322 Nantes Cedex 3, France<br />

pascal.andre@univ-nantes.fr<br />

RÉSUMÉ : Le développement à grande échelle de logiciel par assemblage de composants fait actuellement l’objet de<br />

nombreux travaux. Une question cruciale qui se pose au développeur est celle de savoir si un assemblage est correct<br />

ou non. Dans cet article, nous contribuons à répondre à cette question. Nous présentons succinctement un modèle<br />

formel pour la définition de composants et leur composition, puis nous étudions les moyens de vérifier la conformité des<br />

interactions entre composants en nous basant sur les systèmes de transitions qui décrivent les services des composants.<br />

Des expérimentations pratiques sont menées en utilisant MEC.<br />

MOTS-CLÉS : Composants, Services, Spécification formelle, Conformité d’interaction, MEC<br />

1 <strong>Intro<strong>du</strong>ction</strong><br />

Le développement de logiciel par assemblage de composants<br />

fait actuellement l’objet de nombreux travaux. Le<br />

développement logiciel à base de composants (Szyperski<br />

1997, Medvidovic & Taylor 2000, Bergner, Rausch,<br />

Sihling, Vilbig & Broy 2000, Heineman & Councill<br />

2001) consiste à assembler des composants logiciels existants<br />

pour construire des systèmes logiciels complexes.<br />

Cet assemblage peut être étudié à différents niveaux<br />

d’abstraction, de la conception (les architectures logicielles<br />

ADL (Shaw & Garlan 1996)) à l’implantation (architectures<br />

CORBA, J2EE ou .NET). Alors que la plupart<br />

des modèles à composants, notamment ceux précités,<br />

se situent au niveau implantation et considèrent des<br />

composants avec leur comportement, des connecteurs, et<br />

des services ré<strong>du</strong>its à des méthodes, nous considérons un<br />

modèle abstrait, simple avec uniquement des composants<br />

et des services. Les comportements sont associés aux services.<br />

Cela confère une réutilisabilité plus grande aux<br />

composants. De plus on ne contraint pas la prise en<br />

compte des données dans les interactions.<br />

Nos travaux se situent donc à un niveau abstrait, en<br />

ce sens qu’aucun modèle d’implantation n’est privilégié.<br />

Néanmoins, les descriptions de composants et de services<br />

sont suffisamment précises et formelles pour établir des<br />

critères de vérification de propriétés d’assemblage. La<br />

question cruciale qui se pose au développeur est de savoir<br />

si un assemblage est correct ou non. Autrement dit, peuton<br />

détecter avant de développer concrètement le logiciel<br />

en vue, des erreurs dans l’assemblage de composants proposé.<br />

Dans cet article, nous apportons des réponses à cette<br />

question en proposant un modèle formel qui nous sert à<br />

décrire les composants, leurs services et les assemblages<br />

et en étudiant principalement la conformité d’interaction<br />

entre les services offerts et requis pour détecter des incompatibilités<br />

comportementales. Afin d’étudier les propriétés<br />

de notre modèle sans développer, pour l’instant,<br />

d’outils d’analyse spécifiques, nous expérimentons la tra<strong>du</strong>ction<br />

des services, plus précisément de leur description<br />

comportementale, dans différents formalismes, outillés,<br />

de modélisation dynamique des systèmes.<br />

La présentation <strong>du</strong> modèle à composants est faite à travers<br />

un exemple concret dans la section 2. Dans la section<br />

3, nous étudions les moyens de vérifier la conformité<br />

des interactions entre composants en nous basant sur les<br />

systèmes de transitions qui décrivent les services des composants.<br />

Une des voies consiste à utiliser un outil de<br />

vérification de systèmes de transition. Nous avons choisi<br />

MEC, un model-checker simple, pour expérimenter cette<br />

voie. Les services à vérifier sont tra<strong>du</strong>its en MEC (section<br />

4) puis vérifiés dans la section 5. La section 6 est<br />

consacrée aux extensions de la tra<strong>du</strong>ction en MEC. Enfin,<br />

nous positionnons nos travaux dans la section 7.<br />

2 Présentation <strong>rapide</strong> <strong>du</strong> modèle<br />

Kmelia est un modèle à composants basés sur des descriptions<br />

de services. Sommairement, un composant est<br />

défini par un espace d’états, des services et une interface.<br />

L’espace d’état est un ensemble de constantes et de vari-


MOSIM’06 – <strong>du</strong> au ¡ avril ¢¤£¥£¥¦ - Rabat - Maroc<br />

<br />

ComponentInterface<br />

0..*<br />

1<br />

Service<br />

0..*<br />

name : String<br />

originalservice : String<br />

parameters : ArrayList<br />

returnType : String<br />

pre : String<br />

post : String<br />

0..*<br />

-services<br />

-owner<br />

1<br />

1<br />

Component<br />

name : HashMap<br />

properties : HashMap<br />

types : HashMap<br />

variables : HashMap<br />

+components<br />

0..*<br />

provided<br />

-required<br />

0..*<br />

RequiredService<br />

0..*<br />

+intrequired<br />

0..*<br />

0..*<br />

-extrequired<br />

-calrequired<br />

0..*<br />

-serviceInterface<br />

1<br />

-provided<br />

0..*<br />

ProvidedService<br />

-owner<br />

0..*<br />

1..1<br />

-subprovided<br />

0..1<br />

Composition<br />

owner<br />

links<br />

-behavior<br />

LTS<br />

-composition<br />

0..*<br />

0..*<br />

<br />

ServiceInterface<br />

0..*<br />

0..*<br />

Figure 1 : Méta-Modèle simplifié<br />

ables typées, contraintes par un invariant. Les services<br />

modélisent des fonctionalités (offertes ou requises) et sont<br />

eux-mêmes constitués d’une interface (qui peut inclure<br />

des sous-services), d’une description d’état et d’assertions<br />

(pre-post conditions). Le comportement (dynamique)<br />

d’un service offert est caractérisé par un automate, qui<br />

précise les enchaînements d’actions autorisés. L’interface<br />

d’un composant indique les services qu’il propose et ceux<br />

qu’il requiert. Les composants peuvent être assemblés ou<br />

composés. Une composition est un assemblage encapsulé<br />

dans un composant. Dans un assemblage, les services des<br />

composants communiquent par échanges de messages sur<br />

des canaux. Les canaux sont point-à-point (dans la version<br />

actuelle <strong>du</strong> modèle) mais bidirectionnels. La description<br />

détaillée <strong>du</strong> modèle est présentée dans (André, Ardourel,<br />

Attiogbé, Habrias & Stoquer 2005). Nous donnons dans<br />

la figure 1, un métamodèle très simplifié en utilisant la<br />

notation UML.<br />

Nous illustrons le formalisme Kmelia par l’exemple <strong>du</strong><br />

guichet automatique bancaire (GAB), qui a pour avantage<br />

de ne pas nécessiter une longue description informelle<br />

pour sa compréhension. Le GAB propose ici deux services<br />

aux utilisateurs : retrait et consultation.<br />

Dans ces deux cas, le GAB a besoin d’informations de<br />

la part de l’utilisateur, par exemple son code de carte.<br />

L’utilisation d’un modèle à composants nous permet de<br />

séparer la réception et le traitement de ces informations<br />

de la manière dont ces dernières sont obtenues. On décide<br />

ici que des composants dédiés à l’interface homme machine<br />

se chargent d’invoquer les services de base <strong>du</strong> GAB<br />

et de leur fournir les informations nécessaires.<br />

La figure 2 illustre un assemblage pour le GAB.<br />

On y distingue le composant central BASEGAB<br />

dont la spécification nécessite la spécification de<br />

deux autres composants GROUPEMENT BANCAIRE<br />

et BANQUE LOCALE. Deux autres composants<br />

IHM CLIENTR et IHM CLIENTC utilisent ses services<br />

offerts. Dans la définition <strong>du</strong> composant BASEGAB,<br />

aucune hypothèse n’est posée sur les composants qui<br />

offriront les services requis, un composant qui offre<br />

les quatre services convient. De même, aucune hypothèse<br />

n’est faite sur les ”clients” des services offerts.<br />

Nous avons volontairement ré<strong>du</strong>it les interfaces des<br />

composants.<br />

Nous nous appuyons sur le composant central BASEGAB<br />

qui offre les services correspondants aux deux fonctionnalités<br />

principales de l’application.<br />

COMPONENT BASEGAB<br />

INTERFACE<br />

provides : {retrait, consultation}<br />

requires : {verifAut, modifCpte, lireCpte}<br />

TYPES<br />

CB : {code:Integer, id:Integer, limit:Integer}<br />

VARIABLES<br />

dispo : Integer,<br />

caisse : Integer,<br />

cartesConservees : Set<br />

INITIALISATION<br />

dispo = 100 ; caisse = 1000 ;<br />

cartesConservees = {}<br />

PROPERTIES<br />

caisse >= 0 && size(cartesConservees) < 100<br />

La description de l’espace d’états <strong>du</strong> GAB inclut : une<br />

variable caisse, qui indique le montant disponible en


MOSIM’06 – <strong>du</strong> au ¡ avril ¢¤£¥£¥¦ - Rabat - Maroc<br />

GROUPEMENT<br />

BANCAIRE<br />

autorisation<br />

BASEGAB<br />

verifAut<br />

retrait<br />

IHM_CLIENTR<br />

retirer<br />

requete<br />

miseajour<br />

modifCpte<br />

dem_montant<br />

montant<br />

code<br />

dem_code<br />

BANQUE<br />

LOCALE<br />

IHM_CLIENTC<br />

code<br />

requete<br />

solde<br />

lireCpte<br />

consultation<br />

consulter<br />

service offert service requis lien (canal) appel de service<br />

Figure 2 : Assemblage global <strong>du</strong> GAB<br />

caisse ; une variable dispo, qui indique le montant<br />

minimum disponible en caisse pour que le service soit<br />

disponible ; et une variable carteConservées, qui est<br />

une collection des cartes retenues. Un invariant indique<br />

que le montant en caisse doit être positif et que le nombre<br />

de cartes conservées ne dépasse pas une certaine limite<br />

pour que le GAB soit en service.<br />

Nous centrons notre présentation sur le service retrait<br />

offert par le composant BASEGAB. Ce service requiert<br />

trois services dem code pour demander le code de la<br />

carte, dem montant pour demander le montant <strong>du</strong> retrait<br />

et verifAut pour vérifier l’autorisation de retrait<br />

de la part <strong>du</strong> groupement bancaire.<br />

provided retrait (cb : CB)<br />

Interface<br />

calrequires : {dem_code, dem_montant}<br />

extrequires : {verifAut}<br />

Pre<br />

caisse >= dispo<br />

# le service est disponible si<br />

# la caisse contient assez d’argent<br />

Variables # locales au service<br />

nbe : Integer,<br />

# nombre d’essais pour entrer le code<br />

c : Integer,<br />

# code entre par l’utilisateur<br />

a : Integer,<br />

# montant entre par l’utilisateur<br />

rep : Boolean<br />

# reponse de la demande d’autorisation<br />

Behavior<br />

init i # i est l’etat initial<br />

final f # f est un etat final<br />

{ i -- nbe := 3 --> e0 ,<br />

e0 -- __CALLER!!dem_code() --> e1 ,<br />

# appel <strong>du</strong> service requis code chez l’appelant<br />

e1 -- {__CALLER??dem_code(c) ;<br />

nbe := nbe-1 }--> e2 ,<br />

# reception <strong>du</strong> mot de passe (:=)<br />

e2 -- [c=cb.code] rep:=<br />

_verifAut!!verifAut(cb.id, c) --> e3,<br />

# appel synchrone (:=) <strong>du</strong> service verifAut<br />

e2 -- [ccb.code && nbe > 0]<br />

msg("redonnez votre code svp") --> e0 ,<br />

e2 -- [ccb.code && nbe = 0] {<br />

msg("carte conservee") ;<br />

avalerCarte() } --> e4 ,<br />

e3 -- [rep] msg("montant ?") --> e5,<br />

# le groupement autorise,<br />

# on demande le montant<br />

e3 -- [not rep] { msg("refuse") ;<br />

restituerCarte() }--> e4 ,<br />

#==> voir la figure 3


MOSIM’06 – <strong>du</strong> au ¡ avril ¢¤£¥£¥¦ - Rabat - Maroc<br />

IHM_CLIENTR.requete() =<br />

BASEGAB.retrait(cb : CB) =<br />

msg(...)<br />

i<br />

lire(maCarte)<br />

e0<br />

retirer!!retirer(maCarte)<br />

e1 <br />

retirer??retirer(res)<br />

e2<br />

IHM_CLIENTR.code () =<br />

e0<br />

msg(...) ; lire(monCode)<br />

e1<br />

CALLER!!code(monCode)<br />

f<br />

[ccb.code<br />

&& nbe >0]<br />

msg(...)<br />

[c=cb.code]<br />

rep:= verifAut!!<br />

verifAut(cb.id, c)<br />

[rep] msg(...)<br />

i<br />

e0<br />

e1<br />

e2<br />

e3<br />

e5<br />

nbe := 3<br />

CALLER!!dem_code()<br />

CALLER??dem_code(c)<br />

; nbe := nbe - 1<br />

[not rep] msg(...) ;<br />

restituerCarte()<br />

[ccb.code && nbe = 0]<br />

msg(...) ; avalerCarte()<br />

[m > cb.limit]<br />

msg(...)<br />

e4<br />

IHM_CLIENTR.montant () =<br />

e0<br />

e1<br />

e2<br />

msg(...) ; lire(m)<br />

CALLER!!montant(m)<br />

CALLER!!dem_montant()<br />

CALLER??dem_montant(m)<br />

[m i,<br />

i -- lire(maCarte) --> e0 ,<br />

#==> voir la figure 3 e1,<br />

e1 -- __CALLER!!code(monCode) --> f<br />

}<br />

end<br />

provided montant () : Integer<br />

# rend le montant demande par l’utilisateur<br />

Variables # locale au service<br />

m : Integer # montant demande<br />

Behavior<br />

init e0 final e2<br />

{ e0 -- {msg("Entrer le montant");<br />

lire(m) } --> e1,<br />

e1 -- __CALLER!!montant(m) --> e2<br />

}<br />

end<br />

Une représentation graphique facilite la lecture des<br />

systèmes de transitions. La figure 3 en présente<br />

un extrait. A chaque état <strong>du</strong> système de transitions<br />

étiquetées, on peut associer un ensemble de services offerts,<br />

ou de sous-services invocables. La notation e1<br />

, indique que les services code et<br />

montant sont invocables dans l’état e1 ; la suite <strong>du</strong><br />

traitement est poursuivie dans le service appelé. Pratiquement,<br />

cette notation permet de simplifier la description<br />

<strong>du</strong> système de transitions d’un service. Un sous-service<br />

est un service offert qui ne figure pas dans l’interface<br />

<strong>du</strong> composant, les services code et montant sont des<br />

sous-services de IHM CLIENTR. L’usage <strong>du</strong> service requete<br />

est flexible : il peut fonctionner avec un service<br />

requis retirer qui demande facultativement un code et<br />

un montant et ce dans n’importe quel ordre.


MOSIM’06 – <strong>du</strong> au ¡ avril ¢¤£¥£¥¦ - Rabat - Maroc<br />

3 Vérification de conformité des interactions<br />

entre composants<br />

La correction d’un modèle à composants comprend la<br />

correction indivi<strong>du</strong>elle des composants et la correction<br />

des assemblages. La correction indivi<strong>du</strong>elle des composants<br />

est liée à leur cohérence interne (préservation<br />

de l’invariant dans les services, pas de blocage) mais<br />

aussi à la correction des compositions, s’ils sont structurés<br />

hiérarchiquement. La correction des assemblages atteste<br />

que, mis ensemble, les composants restent corrects. Elle<br />

se base sur des propriétés structurelles et comportementales<br />

: pas de circuit dans les dépendances entre composants<br />

et services, pas de besoins non satisfaits, sûreté,<br />

vivacité, conformité des interactions, etc.<br />

Nous nous intéressons ici à la conformité des interactions<br />

sur un canal (typage et assertions sont supposés résolus).<br />

La propriété de sûreté à prouver est : pour toute interaction,<br />

il n’y a pas d’incompatibilité de comportement.<br />

Autrement dit, les services sont corrects deux à deux (correction<br />

locale). La correction globale des interactions<br />

est l’union des corrections locales d’interaction (Attie &<br />

Lorenz 2003). Une interaction est la donnée de trois services<br />

(un contexte) : un service offert (à vérifier) lié à<br />

un autre service offert (l’appelant) via un service requis<br />

dans l’assemblage. Pour prouver la conformité des interactions,<br />

nous procédons par la tra<strong>du</strong>ction des composants<br />

en MEC. Nous avons choisi MEC pour sa simplicité (notation<br />

et concepts, pro<strong>du</strong>its) qui nous permet de l’utiliser à<br />

la fois comme langage d’encodage et d’échange entre les<br />

formalismes/systèmes plus évolués tel que SPIN et Lotos.<br />

MEC (Arnold, Crubillé & Bégay 1994) est un modelchecker.<br />

La technique de model-checking consiste à<br />

décrire l’espace d’états d’un système et à l’explorer par<br />

différents algorithmes afin de déterminer les propriétés<br />

dynamiques <strong>du</strong> système étudié (dans quels états elles sont<br />

vraies). En MEC les propriétés sont exprimées par des<br />

calculs sur les automates, ces calculs sont exprimés sous<br />

forme ensembliste ; ils sont interprétés dans l’algèbre de<br />

Dicky et implantés par des parcours de graphes.<br />

Dans la section 4 nous décrivons les bases la transformation<br />

de spécifications Kmelia en MEC (version 4) pour<br />

un contexte donné. Puis nous étudions les propriétés <strong>du</strong><br />

modèle issu de la tra<strong>du</strong>ction de l’exemple GAB dans la<br />

section 5. Enfin, la section 6 est consacrée aux concepts<br />

de Kmelia qui n’existent pas dans MEC.<br />

4 Tra<strong>du</strong>ction des composants en<br />

MEC<br />

MEC et Kmelia utilisent tous deux des systèmes de<br />

transitions étiquetés pour représenter la dynamique des<br />

systèmes. Néanmoins, l’expression des étiquettes est<br />

plus riche dans Kmelia, qui possède de plus une<br />

structuration hiérarchique d’état. De ce fait, certains<br />

concepts non tra<strong>du</strong>isibles directement (gardes,<br />

paramètres sous-services, etc.) sont ignorés. Rappelons<br />

que le contexte d’une interaction est défini par<br />

un triplet . Le<br />

service offert est lié au service requis dans l’assemblage.<br />

Détermination de la cible La cible est l’ensemble<br />

des services participant à une interaction sur la liaison<br />

requis-offert. Sur la base <strong>du</strong> triplet de contexte,<br />

on filtre l’ensemble des invocations de services pour<br />

déterminer la cible. Les invocations de services et<br />

communications qui se font sur d’autres liaisons (d’autres<br />

canaux) sont assimilées à des actions internes vis-à-vis de<br />

l’interaction considérée. De fait, l’espace combinatoire<br />

est ré<strong>du</strong>it et limité aux interactions entre deux composants<br />

(vérification locale). Dans notre exemple, le contexte<br />

est le triplet .<br />

La cible comprend l’ensemble BASEGAB.retrait,<br />

IHM ClientR.requete, IHM ClientR.code,<br />

ClientR.montant¡ IHM .<br />

Aplatissement des automates Kmelia autorise le rattachement<br />

de services à des états (sous-services optionnels)<br />

et la composition d’actions dans les transitions<br />

(séquentiel, collatéral, parallèle). MEC ne supportant pas<br />

les automates hiérarchiques, un traitement préliminaire<br />

s’impose pour aplatir les automates des services de la<br />

cible. L’automate d’un service attaché à un état e est expansé<br />

de telle sorte que son état initial et final soient rattachés<br />

à e (formant ainsi une boucle). Les noms des états<br />

intermédiaires <strong>du</strong> sous-automate sont préfixés par le nom<br />

de l’état de rattachement. Par exemple, l’automate <strong>du</strong> service<br />

code est expansé sur l’état e1 <strong>du</strong> service requete.<br />

Les transitions composées sont aussi aplaties en faisant<br />

apparaître de nouveaux états intermédiaires. Par exemple,<br />

la séquence e3 -- [not rep] msg("refuse")<br />

; restituerCarte() --> e4 se tra<strong>du</strong>it en 2 transitions<br />

e3 -- [not rep] msg("refuse") --> e3 1<br />

et e3 1 -- restituerCarte() --> e4.<br />

Tra<strong>du</strong>ction des services Le principe général est le suivant<br />

: un service est un processus, décrit en MEC par<br />

un automate ayant pour nom la concaténation <strong>du</strong> nom<br />

<strong>du</strong> composant et <strong>du</strong> nom <strong>du</strong> service. Ainsi le service<br />

BASEGAB.retrait(cb:CB) donne lieu à l’automate<br />

BASEGAB retrait. On considère que chaque service<br />

n’est instancié qu’une fois (un seul exemplaire, un seul<br />

processus). Dans notre exemple, l’état e2 <strong>du</strong> service<br />

retirer <strong>du</strong> composant IHM ClientR est final ; ceci<br />

facilite le calcul des propriétés de terminaison. MEC<br />

n’autorise pas les caractères tels que les parenthèses, les<br />

espaces, les ’, les ? et !, :=, les chiffres, ..., certaines trans-


MOSIM’06 – <strong>du</strong> au ¡ avril ¢¤£¥£¥¦ - Rabat - Maroc<br />

formations sont nécessaires ; par exemple, les caractères<br />

ignorés sont transformés par ’ ’ et les paramètres sont ignorés.<br />

1. Chaque état <strong>du</strong> service est tra<strong>du</strong>it par un état MEC de<br />

même nom (à un renommage près). L’état initial et les<br />

états finaux sont annotés (pour les enlever <strong>du</strong> calcul des<br />

états bloquants).<br />

2. Chaque transition est tra<strong>du</strong>ite par une transition MEC.<br />

Le traitement varie en fonction de l’étiquette. Les appels<br />

de services correspondent aux transitions d’initialisation.<br />

On les préfixe par call. On adopte les conventions<br />

suivantes : une communication canal!msg est tra<strong>du</strong>ite<br />

en emit canal msg, une communication canal?msg<br />

est tra<strong>du</strong>ite en rcv canal msg.<br />

3. Une transition d’initialisation est ajoutée pour la synchronisation<br />

de l’appel de service, son étiquette est celle<br />

<strong>du</strong> service préfixée par start . Le nouvel état initial est<br />

noté init. Les transitions de fin de service sont considérées<br />

comme des transitions ordinaires. Sur chaque état<br />

on ajoute une transition e (action vide) car les automates<br />

peuvent évoluer indépendamment les uns des autres en dehors<br />

des communications.<br />

Vecteur de synchronisation Le vecteur de synchronisation<br />

précise les actions globales <strong>du</strong> système et notamment<br />

les synchronisations entre actions de plusieurs automates.<br />

On retrouve un mécanisme similaire dans les communications<br />

des algèbres de processus. Les actions globales<br />

sont les invocations de services et les communications<br />

dans Kmelia. L’algorithme tient compte de la possibilité<br />

de renommage dans les liaisons. Considérons deux situations<br />

: système séquentiel, système parallèle. Dans un<br />

système séquentiel, une seule action a lieu à chaque instant,<br />

dans un système parallèle plusieurs actions peuvent<br />

se dérouler en même temps si elles sont indépendantes.<br />

Par exemple, une action interne sur deux composants peut<br />

se faire en parallèle, de même qu’un échange sur deux<br />

canaux différents. Cette distinction n’influe pas sur les<br />

propriétés de sûreté (seules des transitions sont ajoutées).<br />

Cas d’un système séquentiel.<br />

On trouve deux types d’actions : action interne à un<br />

service, échange sur un canal. Si un service n’est pas<br />

concerné par une action, cela se note explicitement par<br />

l’étiquette ’e’ dans le vecteur de synchronisation. Le<br />

vecteur est rempli par parcours des automates des services,<br />

compte tenu des liaisons autour <strong>du</strong> contexte de<br />

l’interaction.<br />

1. Chaque action interne i d’un automate A donne lieu à<br />

une ligne dans le vecteur de synchronisation, telle que la<br />

cellule de la colonne de A soit étiquetée par l’action i.<br />

2. Chaque appel de service call S d’un automate A est<br />

synchronisé avec le démarrage de service start S de<br />

l’automate S. Chaque résultat de service res S d’un automate<br />

A est synchronisé avec le retour de service ret S<br />

de l’automate S. Le démarrage <strong>du</strong> service qui invoque le<br />

service de référence est considéré comme une action interne<br />

(IHM ClientR.requete).<br />

3. Chaque réception de message rcv S msg d’un automate<br />

A est synchronisée avec une émission emit S msg<br />

d’un automate A’.<br />

La spécification <strong>du</strong> système séquentiel est la suivante :<br />

transition_system IHM_CLIENTR_DemRetrait < width<br />

= 0 >;<br />

init |- e -> init,<br />

start_requete -> i;<br />

i |- e -> i,<br />

msg -> i;<br />

lire -> e0;<br />

e0 |- e -> e0,<br />

call_retirer -> e1;<br />

e1 |- e -> e1,<br />

start_code -> e1_1,<br />

start_montant -> e1_2,<br />

ret_retirer_retirer -> e2;<br />

...<br />

e2 |- e -> e2;<br />

< initial = { init } ; final = {e2} >.<br />

transition_system BASEGAB_retrait < width = 0 >;<br />

init |- e -> init,<br />

start_retrait -> i;<br />

i |- e -> i,<br />

nbe3 -> e0;<br />

e0 |- e -> e0,<br />

call_dem_code -> e1;<br />

e1 |- e -> e1,<br />

ret_retrait_dem_code -> e1_1;<br />

e1_1 |- nbe_nbe_1 -> e2;<br />

e2 |- e -> e2,<br />

msg -> e0,<br />

msg -> e2_1,<br />

ext_verifAut -> e3;<br />

e2_1 |- e -> e2_1,<br />

avalerCarte -> e4;<br />

e3 |- e -> e3,<br />

msg -> e5,<br />

msg -> e3_1;<br />

e3_1 |- restituerCarte -> e4;<br />

e4 |- e -> e4,<br />

res_retrait_retrait-> f;<br />

e5 |- e -> e5,<br />

call_dem_montant -> e6;<br />

e6 |- e -> e6,<br />

ret_retrait_dem_montant-> e7;<br />

e7 |- e -> e7,<br />

msg -> e3,<br />

debiter -> e7_1;<br />

e7_1 |- restituerCarte -> e8;<br />

e8 |- e -> e7,<br />

res_retrait_retrait -> f;<br />

< initial = { init } ; final = {f} >.<br />

synchronization_system Verif_BASEGAB_retrait <<br />

width = 2 ;<br />

list = (IHM_CLIENTR_retirer, BASEGAB_retrait)>;<br />

\* lancement <strong>du</strong> service appelant *\<br />

( start_retirer . e );<br />

\* actions interne de IHM_CLIENTR_retirer *\<br />

( msg . e );<br />

( lire . e );<br />

\* actions interne de BASEGAB_retrait *\<br />

( e . nbe3 );<br />

( e . nbe_nbe_1);<br />

( e . msg );<br />

( e . ext_verifAut );


MOSIM’06 – <strong>du</strong> au ¡ avril ¢¤£¥£¥¦ - Rabat - Maroc<br />

( e . avalerCarte );<br />

( e . restituerCarte );<br />

( e . debiter);<br />

\* invocations de services *\<br />

( call_retirer . start_retrait );<br />

( ret_retirer_retirer . res_retrait_retrait );<br />

( start_code . call_dem_code );<br />

( res_retirer_code . ret_retrait_dem_code );<br />

( start_montant . call_dem_montant );<br />

( res_retirer_montant .<br />

ret_retrait_dem_montant).<br />

Cas d’un système parallèle.<br />

La version parallèle est obtenue par enrichissant <strong>du</strong><br />

vecteur de synchronisation de la version séquentielle; on<br />

combine deux à deux les lignes <strong>du</strong> vecteur de synchronisation<br />

: s’il y a conflit pour un automate (une seule action<br />

à la fois), la combinaison n’est pas possible, sinon<br />

on fusionne les lignes en écrasant les actions e. On<br />

procède de même pour trois actions en comparant les<br />

lignes à deux actions avec celles à une action, et ainsi de<br />

suite. Dans notre exemple, seules les actions internes peuvent<br />

être fusionnées, toute autre combinaison engendre un<br />

conflit. La spécification <strong>du</strong> système parallèle est la version<br />

séquentielle avec des lignes supplémentaires dans le<br />

vecteur de synchronisation.<br />

( msg . nbe3 );<br />

( msg . nbe_nbe_1);<br />

( msg . msg );<br />

( msg . ext_verifAut );<br />

( msg . avalerCarte );<br />

( msg . restituerCarte );<br />

( msg . debiter);<br />

( lire . nbe3 );<br />

... idem msg<br />

A partir des composants (et services) tra<strong>du</strong>its en MEC<br />

nous pouvons effectuer les vérifications de correction.<br />

5 Vérifications avec MEC<br />

Nous étudions les propriétés <strong>du</strong> système via MEC et<br />

nous montrons que des interactions non conformes sont<br />

détectées par notre méthode : incohérence de protocole<br />

pour le service retrait. Le problème <strong>du</strong> nondéterminisme<br />

dans les communications est soulevé.<br />

L’étude des propriétés dynamiques inclut l’étude des propriétés<br />

structurelles (non-déterminisme, blocage, ...) et<br />

celle des propriétés comportementales (traces, famine...).<br />

L’étude est faite ici par interprétation des expressions<br />

MEC. Soit à évaluer les expressions suivantes :<br />

function inevitable(Y:trans ; X:state)<br />

return Z:state;<br />

begin<br />

Z = X \/ (src(Y /\ rtgt(Z))<br />

- src(Y /\ rtgt(*-Z)))<br />

end.<br />

sync(Verif_BASEGAB_retrait, sys);<br />

dts(sys);<br />

finaux := final[1] /\ final[2];<br />

dead := (* - src(*)) - finaux;<br />

deadlock:=inevitable(*,dead);<br />

La fonction inevitable calcule l’ensemble Z des<br />

états atteignant (que) ceux de X avec les transitions<br />

de Y. L’opérateur sync calcule le pro<strong>du</strong>it synchronisé<br />

(l’automate global <strong>du</strong> système). Le pro<strong>du</strong>it synchronisé<br />

calcule un automate global par pro<strong>du</strong>it libre d’automate,<br />

en ne conservant que les transitions qui figurent dans le<br />

vecteur de synchronisation. La variable finaux donne<br />

l’ensemble des états finaux (tous les services sont finis).<br />

La variable dead donne les états bloquants (qui<br />

n’ont pas de transitions sortantes). La variable deadlock<br />

indique si les états bloquants sont inévitables ou<br />

pas. Dans notre exemple, nous prouvons qu’il n’y a pas de<br />

blocage pour la version séquentielle. Nous l’interprétons<br />

comme une compatibilité des échanges dans l’interaction.<br />

Pour autant, le système n’est pas vivace car il n’est pas<br />

réinitialisable. Le résultat de l’analyse de la spécification<br />

<strong>du</strong> système parallèle est identique à celui de la version<br />

séquentielle ; seul le nombre de transitions change. En effet<br />

il n’y a aucune interaction entre la demande <strong>du</strong> montant<br />

et le retour <strong>du</strong> montant.<br />

Incohérence de comportement Le modèle de la figure<br />

3 est enrichi avec une communication relative à<br />

l’échange de carte. Le service requete <strong>du</strong> composant<br />

IHM CLIENTR de la figure 3 est modifié à partir de l’état<br />

e1 pour inclure la récupération de carte :<br />

e1 -- _retirer?recupCarte(c) --> e1_1 ,<br />

// reception de la carte modifiee<br />

e1_1 -- _retirer??retirer(res) --> e2<br />

Le service offert retrait <strong>du</strong> composant BASEGAB de<br />

la figure 3 est modifié pour renvoyer la carte dans une<br />

communication et non plus par une action interne. La<br />

récupération de la carte (côté client) est synchronisée avec<br />

la restitution de la carte (côté GAB).<br />

e3 -- [not rep] { msg("refuse") ;<br />

__CALLER!recupCarte(c) }--> e4 ,<br />

...<br />

e7 -- [m e8 ,<br />

La tra<strong>du</strong>ction modifie les automates en conséquence et<br />

ajoute une ligne dans le vecteur de synchronisation :<br />

\* communications sur retirer-retrait *\<br />

( rcv_retirer_recupCarte . emit_retrait_recupCarte );<br />

Le résultat fait apparaître un blocage. L’état (e1,e4) est<br />

bloquant ; nous l’interprétons par : le client attend sa carte<br />

qui a été avalée. En effet, nous avions omis de restituer la<br />

carte en cas d’échec (transition e3 -> e4).


MOSIM’06 – <strong>du</strong> au ¡ avril ¢¤£¥£¥¦ - Rabat - Maroc<br />

Non-déterminisme et incohérence Dans cette section,<br />

on met en évidence une incohérence <strong>du</strong>e au nondéterminisme<br />

local. Soit les automates partiels de services<br />

de la figure 4 :<br />

e1<br />

ProcA() =<br />

c?a()<br />

e0<br />

f<br />

i<br />

c?b()<br />

i<br />

e2<br />

e1<br />

ProcB() =<br />

c!a()<br />

Figure 4 : Automates partiels de deux services<br />

Voici un extrait de la tra<strong>du</strong>ction en MEC.<br />

transition_system ProcA < width = 0 >;<br />

e0 |- e -> e0,<br />

rcv_c_a -> e1,<br />

rcv_c_b -> e2;<br />

e1 |- e -> e1,<br />

i -> f; \* f est suppose final *\<br />

e2 |- e -> e2,<br />

i -> f; \* f est suppose final *\<br />

f |- e -> f;<br />

< initial = { e0 } ; final = {f} >.<br />

transition_system ProcB < width = 0 >;<br />

e0 |- e -> e0,<br />

emit_c_a -> e1,<br />

emit_c_b -> e2;<br />

e1 |- e -> e1,<br />

i -> f; \* f est suppose final *\<br />

e2 |- e -> e2,<br />

i -> f; \* f est suppose final *\<br />

f |- e -> f;<br />

< initial = { e0 } ; final = {f} >.<br />

e0<br />

f<br />

i<br />

i<br />

c!b()<br />

synchronization_system testChoix < width = 2 ;<br />

list = ( ProcA, ProcB ) >;<br />

\* actions interne de l’automate ProcA *\<br />

( i . e );<br />

\* actions interne de l’automate ProcB *\<br />

( e . i );<br />

\* communications sur c *\<br />

( rcv_c_a . emit_c_a );<br />

( rcv_c_b . emit_c_b ).<br />

Seules les communications cohérentes sont acceptées,<br />

l’automate global comporte 8 états. Il n’y a pas<br />

de blocage, car les communications incohérentes (e.g.<br />

émission <strong>du</strong> message a sur le service c et réception <strong>du</strong><br />

message b sur le service c) sont refusées par le vecteur<br />

de synchronisation. Pour enrichir la détection des cas<br />

d’incohérences, on peut affiner la description de la communication.<br />

Par exemple, on distingue la sélection <strong>du</strong> service<br />

(canal) de l’envoi de message. Les erreurs détectées<br />

sont celles d’un message incohérent sur le même canal.<br />

Cela revient, dans notre méthode de tra<strong>du</strong>ction, à interpréter<br />

la communication par une transition séquentielle<br />

e2<br />

: sélection en lecture ou écriture d’un canal, puis envoi/réception<br />

<strong>du</strong> message. Par exemple e0 |- rcv c a<br />

-> e1 s’écrit e0 |- rcv c -> e0 1 et e0 1 |- a -> e1.<br />

L’évaluation <strong>du</strong> cas asynchrone pro<strong>du</strong>it le résultat suivant<br />

: 12 états, 14 transitions, un état initial, un état final,<br />

2 blocages. MEC détecte deux cas d’erreur (deux<br />

”deadlocks”) : émission <strong>du</strong> message a sur le service c et<br />

réception <strong>du</strong> message b sur le service c, émission <strong>du</strong> message<br />

b sur le service c et réception <strong>du</strong> message a sur le<br />

service c. On détecte plus d’incohérences, mais la tra<strong>du</strong>ction<br />

est plus lourde. Enfin, on peut encore enrichir la description<br />

en considérant un niveau supplémentaire : choix<br />

<strong>du</strong> canal, choix <strong>du</strong> mode d’émission et choix <strong>du</strong> message.<br />

Cela permet de détecter les émissions des deux côtés ou<br />

les réceptions des deux côtés.<br />

6 Extensions de la tra<strong>du</strong>ction<br />

Nous évoquons dans cette section des extensions à la tra<strong>du</strong>ction<br />

en MEC <strong>du</strong> formalisme Kmelia ; il s’agit notamment<br />

de la prise en compte des gardes, des paramètres<br />

des messages et des instances multiples de services impliquées<br />

dans une interaction.<br />

Prise en compte des gardes MEC ne permet pas de<br />

modéliser les gardes. Il n’est pas imaginable de faire<br />

de l’évaluation dynamique. Pour explorer les traces<br />

d’exécution, une première solution consiste à ajouter des<br />

transitions pour les évaluations de gardes (étiquetées par<br />

guardIsTrue et guardIsFalse par exemple). On<br />

suppose que les gardes sont disjointes et complémentaires.<br />

Lorsque plus de deux alternatives existent (une garde est<br />

une combinaison d’expressions), une solution consiste à<br />

décomposer chaque expression en gardes élémentaires.<br />

Chaque alternative est ainsi étiquetée par une combinaison<br />

des gardes élémentaires. On suppose que les alternatives<br />

de gardes sont disjointes et complémentaires. Par<br />

exemple, les gardes des transitions de l’état e2 <strong>du</strong> service<br />

Retrait de la figure 3 se tra<strong>du</strong>isent en<br />

g_e2_1 == (c = carte.code)<br />

g_e2_2 == (nbe > 0)<br />

...<br />

e2 -- [not g_e2_1 & g_e2_2]<br />

msg("redonnez votre code svp") --> e0 ,<br />

L’analyse statique des gardes (au même titre que<br />

la vérification de l’invariant) permet d’en vérifer la<br />

cohérence. La tra<strong>du</strong>ction en MEC des gardes peut se faire<br />

de deux manières : soit on ajoute des transitions explicites<br />

pour l’évaluation des gardes, soit on ajoute un préfixe aux<br />

étiquettes des transitions. L’inconvénient de la première<br />

solution est qu’on ne sait pas ce qui se passe lorsque<br />

la garde n’est pas vérifiée (état bloquant, attente) ou jamais<br />

vérifiée (état bloquant). Une autre manière de traiter


MOSIM’06 – <strong>du</strong> au ¡ avril ¢¤£¥£¥¦ - Rabat - Maroc<br />

les gardes est d’invalider certains états : après tra<strong>du</strong>ction,<br />

pendant l’analyse des états bloquants, l’utilisateur<br />

peut détecter que certains états bloquants sont inaccessibles<br />

compte-tenu de l’évaluation des gardes. Dans ce<br />

cas, l’utilisateur demande à filtrer ces états (ou une extension<br />

de ces états) lorsque la condition est locale, pour<br />

les éliminer de l’analyse MEC. Il peut alors relancer la<br />

vérification itérativement. Le filtrage peut se faire par exemple<br />

par marquage d’états MEC : si un couple d’états de<br />

service est invalide, tous les états <strong>du</strong> pro<strong>du</strong>it cartésien qui<br />

contiennent ce couple, i.e. quelque soit l’état des autres<br />

services concernés, sont invalides.<br />

Prise en compte des communications et des paramètres<br />

En MEC il n’est pas facile de traiter simplement les<br />

paramètres des communications. Il se pose en effet le<br />

problème des types de données et des plages des valeurs<br />

potentielles pour les données. Une solution est d’associer<br />

un processus MEC à chaque variable (sur la base de la<br />

modélisation d’algorithmes en MEC) et en s’inspirant de<br />

LOTOS, on crée une transition par valeur possible des<br />

paramètres. Cette mise en œuvre est complexe et nécessite<br />

une concordance avec la tra<strong>du</strong>ction des actions en MEC.<br />

Elle va de pair avec le traitement symbolique des gardes.<br />

Prise en compte d’instances de services Un service<br />

offert comporte obligatoirement un état final. Pour implanter<br />

plusieurs occurrences d’un service, une transition<br />

de réinitialisation est ajoutée à l’état final. Le résultat<br />

est un ensemble de processus réinitialisables de telle<br />

sorte qu’un service peut être invoqué plusieurs fois, mais<br />

séquentiellement. L’invocation parallèle de services ne<br />

pose pas de problèmes de définition en MEC car on peut<br />

ajouter autant de colonnes qu’on souhaite dans le vecteur<br />

de synchronisation. Le problème qui reste à traiter concerne<br />

l’identification des services (ajout d’un numéro aux<br />

noms de service) et leur dénombrement. Néanmoins il<br />

n’est pas possible de définir des services récursifs ni de<br />

créer dynamiquement des services.<br />

7 Travaux connexes<br />

Le modèle Kmelia est caractérisé d’une part par son<br />

fondement sur les services, décrits à l’aide de systèmes<br />

de transitions éten<strong>du</strong>s et qui apparaissent dans l’interface<br />

des composants, et d’autre part par la souplesse <strong>du</strong> formalisme<br />

support de description des interactions. Le formalisme<br />

kmelia est relativement simple, compte-tenu <strong>du</strong><br />

petit nombre de concepts qui y sont utilisés. Néanmoins<br />

il est suffisamment riche pour pouvoir exprimer des contraintes<br />

sur les interfaces des composants. Sa flexibilité<br />

est mesurable à travers les possibilités offertes pour la description<br />

et l’utilisation des composants et des services :<br />

sous-services optionnels, utilisation partielle de composants,<br />

actions internes, liaisons explicites, renommage<br />

des liens, interfaces à différents niveaux de précision.<br />

Notre modèle est aussi moins restrictif que celui proposé<br />

dans (Bordeaux, Salaün, Berardi & Mecella 2004, Bracciali,<br />

Brogi & Canal 2002); en effet ces travaux imposent<br />

des limitations comme : l’étude de compatibilité<br />

comportementale entre deux services uniquement, les<br />

systèmes de transitions décrivant les services sont moins<br />

expressifs, ils ne décrivent que des comportements purs et<br />

les données ne sont pas prises en compte.<br />

Ces caractéristiques distinguent nos travaux de la plupart<br />

des travaux sur les comportements dynamiques de<br />

composants (Behavior Protocols) tels (Plasil & Visnovsky<br />

2002, Giannakopoulou, Kramer & Cheung 1999, Pavel,<br />

Noye, Poizat & Royer 2005) qui se basent sur la description<br />

<strong>du</strong> comportement des composants (son protocole)<br />

et non des services. Ces travaux se distinguent<br />

aussi par la qualité <strong>du</strong> formalisme associé aux protocoles<br />

(expressivité, flexibilité, lisibilité) : (Plasil &<br />

Visnovsky 2002) utilise des expressions régulières, les<br />

autres utilisent des automates relativement simples. Sans<br />

atteindre l’expressivité des Statecharts, notre formalisme<br />

permet une structuration plus flexible des automates.<br />

La plupart des travaux intègrent aussi des connecteurs<br />

de composants (Mehta, Medvidovic & Phadke 2000) et<br />

la composition s’en trouve affectée. Nous n’avons pas<br />

de connecteurs, nous avons privilégié l’homogénéité qui<br />

nous procure la simplicité dans la composition des composants.<br />

En effet un seul opérateur de composition est<br />

nécessaire et il est basé sur l’interaction entre les services.<br />

De cette façon, la correction des interactions et<br />

par conséquent la composabilité est basée en partie sur<br />

l’interaction entre les comportements des services. Nous<br />

avons élaboré une solution qui implique localement les<br />

(systèmes de transition des) services pris deux à deux.<br />

Cette solution limite le problème de l’explosion combinatoire<br />

qui est la principale limitation de la plupart des<br />

travaux sur les interactions (De Alfaro & Henzinger 2001,<br />

Yellin & Strom 1997). Ces derniers utilisent des variantes<br />

<strong>du</strong> modèle des automates à états et leurs composition.<br />

La correction des compositions de composants avec<br />

limitation de l’explosion combinatoire est aussi étudiée<br />

dans (Attie & Lorenz 2003). L’approche les auteurs est<br />

différente de la nôtre; plusieurs automates sont utilisés<br />

pour un même composant : un automate par interaction <strong>du</strong><br />

composant avec un autre composant de l’environnement.<br />

8 Discussions et perspectives<br />

Les travaux présentés dans cet article contribuent à la<br />

définition et à la vérification de la compatibilité des composants<br />

dans un assemblage. Nous avons particulièrement<br />

insisté sur la compatibilité des comportements. Le formalisme<br />

Kmelia permet de spécifier des services, des<br />

composants et d’enrichir les interfaces de composants


MOSIM’06 – <strong>du</strong> au ¡ avril ¢¤£¥£¥¦ - Rabat - Maroc<br />

avec des informations sur les comportements dynamiques<br />

des services. Ces comportements sont à la base de la<br />

vérification des interactions entre services. Concrètement<br />

la vérification se fait par tra<strong>du</strong>ction dans un formalisme<br />

outillé. Dans cet article, nous avons présenté la tra<strong>du</strong>ction<br />

dans MEC et les résultats obtenus. MEC a permis<br />

de vérifier la conformité comportementale, lorsque les<br />

contraintes portant sur les parties ”symboliques” (gardes<br />

et paramètres) sont assouplies. Il s’agit d’un premier<br />

niveau de vérification. En parallèle, nous avons mené des<br />

expérimentations avec LOTOS ; on s’aperçoit qu’on peut<br />

pallier en partie à certaines restrictions imposées par MEC<br />

(par exemple on peut utiliser des types ré<strong>du</strong>its pour les<br />

paramètres et un traitement non symbolique des gardes).<br />

La version MEC 5, couplée à Altarica permet elle aussi de<br />

traiter des paramètres et des gardes (lorsqu’elles portent<br />

sur des valeurs associées aux états). Cependant la notion<br />

d’état dans Altarica est plus proche de celle de formalismes<br />

tels que Z ou B, que de celui des automates.<br />

Nous avons développé en Java un prototype (nommé<br />

COSTO : Component Study Toolkit) qui permet<br />

d’expérimenter nos travaux sur les composants et en particulier<br />

la vérification d’interactions. COSTO permet de<br />

compiler des spécifications Kmelia et de les représenter<br />

dans une structure abstraite sous forme d’objets. Les outils<br />

de tra<strong>du</strong>ction vers LOTOS et MEC parcourent la structure<br />

abstraite et génèrent des spécifications dans les langages<br />

correspondants.<br />

Les perspectives à court terme sont de poursuivre nos<br />

expérimentations sur les aspects dynamiques avec Altarica,<br />

SPIN ou PVS, pour établir des comparaisons entre<br />

formalismes et stabiliser notre méthode de vérification<br />

formelle de composants. Concernant les aspects structurels<br />

et fonctionnels des composants, nous nous proposons<br />

de définir des transformations vers des formalismes<br />

adaptés (nous envisageons B et les spécifications<br />

algébriques).<br />

References<br />

André, P., Ardourel, G., Attiogbé, C., Habrias, H. &<br />

Stoquer, C. (2005). A Service-Based Component<br />

Model: Description Formalism, Formal Analysis<br />

and Mechanization, Technical Report RR05.08,<br />

LINA - FRE CNRS 2729 - Nantes. (70 p.).<br />

Arnold, A., Crubillé, P. & Bégay, D. (1994). Construction<br />

and Analysis of Transition Systems with MEC,<br />

AMAST Series in Computing: Vol. 3, World Scientific.<br />

ISBN 981-02-1922-9.<br />

Attie, P. & Lorenz, D. H. (2003). Correctness of Modelbased<br />

Component Composition without State Explosion,<br />

ECOOP 2003 Workshop on Correctness of<br />

Model-based Software Composition.<br />

Bergner, K., Rausch, A., Sihling, M., Vilbig, A. & Broy,<br />

M. (2000). A formal model for componentware, in<br />

G. T. Leavens & M. Sitaraman (eds), Foundations<br />

of Component-Based Systems, Cambridge University<br />

Press, New York, chapter 9, pp. 189–210.<br />

Bordeaux, L., Salaün, G., Berardi, D. & Mecella, M.<br />

(2004). When are two web services compatible?,<br />

TES, pp. 15–28.<br />

Bracciali, A., Brogi, A. & Canal, C. (2002). Dynamically<br />

adapting the behaviour of software components, CO-<br />

ORDINATION ’02: Proceedings of the 5th International<br />

Conference on Coordination Models and Languages,<br />

Springer-Verlag, London, UK, pp. 88–95.<br />

De Alfaro, L. & Henzinger, Thomas, A. (2001). Interface<br />

Automata, Proceedings of the Ninth Annual Symposium<br />

on Foundations of Software Engineering (FSE),<br />

ACM Press, pp. 109–120.<br />

Giannakopoulou, D., Kramer, J. & Cheung, S.-C. (1999).<br />

Behaviour Analysis of Distributed Systems Using<br />

the Tracta Approach., Autom. Softw. Eng. 6(1): 7–<br />

35.<br />

Heineman, G. T. & Councill, W. T. (eds) (2001).<br />

Component-based software engineering: putting the<br />

pieces together, Addison-Wesley Longman Publishing<br />

Co., Inc., Boston, MA, USA.<br />

Medvidovic, N. & Taylor, R. N. (2000). A Classification<br />

and Comparison Framework for Software Architecture<br />

Description Languages, IEEE Transactions on<br />

Software Engineering 26(1): 70–93.<br />

Mehta, N. R., Medvidovic, N. & Phadke, S. (2000). Towards<br />

a taxonomy of software connectors, ICSE ’00:<br />

Proceedings of the 22nd international conference on<br />

Software engineering, ACM Press, pp. 178–187.<br />

Pavel, S., Noye, J., Poizat, P. & Royer, J.-C. (2005). Java<br />

Implementation of a Component Model with Explicit<br />

Symbolic Protocols, SC’2005 - Software Composition,<br />

LNCS, Springer Verlag.<br />

Plasil, F. & Visnovsky, S. (2002). Behavior protocols for<br />

software components. IEEE Transactions on SW Engineering,<br />

28 (9), 2002.<br />

Shaw, M. & Garlan, D. (1996). Software Architecture:<br />

Perspective on an Emerging Discipline, Prentice<br />

Hall.<br />

Szyperski, C. (1997). Component Software: Beyond<br />

Object-Oriented Programming, AddisonWesley<br />

Publishing Company.<br />

Yellin, D. M. & Strom, R. E. (1997). Protocol Specifications<br />

and Component Adaptors, ACM Transactions<br />

on Programming Languages and Systems<br />

19(2): 292–333.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!