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
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.