Sunteți pe pagina 1din 224

Programare Distribuit

Curs 1 - Introducere: arhitectura aplicaiilor distribuite 1

1. Conceptul de tier (strat)

O aplicaie software poate fi mprit n mai multe niveluri izolate unele de altele. Avantajul este dat de faptul c se ctig o independen ntre nivele, astfel c atunci cnd unul se modific, impactul asupra celorlalte este minim, dac interfaa dintre ele nu se modific. Un astfel de nivel al aplicaiei se numete tier.

2. Arhitectura clasic two-tier

n mod tradiional, aplicaiile sunt structurate pe dou tiers : Presentation Tier i Business Logic/Data Tier. Problema acestei abordri este generat de faptul c logica de business este coninut n procedurile stocate n baza de date. Fiecare SGBD are propriul limbaj n care se scriu procedurile stocate, deci este greu portabil. n cele mai multe cazuri, aplicaiile create folosind doar dou straturi sunt nescalabile i greu portabile. Scalabilitatea este proprietatea unei aplicaii de a fi extins (pentru a putea fi utilizat de mai muli utilizatori, n ideea acoperirii nevoilor unei organizaii n expansiune) folosind mai multe sisteme de calcul 3 dar fr a fi nevoie s se modifice codul surs.

Totui avantajul unei asemenea arhitecturi este acela c traficul necesar n reea este mai mic, deoarece procesarea se face local n serverul de baze de date. Pe de alt parte, Java este folosit tot mai mult ca limbaj pentru procedurile stocate. Dezavantaje: nescalabilitatea aplicaiei, driverul de baze de date este instalat la client. Astfel orice modificare a driverului este costisitoare, deoarece necesit ca fiecare client s-i schimbe driverul.

3. Arhitectura multi tier

ntr-o arhitectur multi tier se interpun ntre cele dou tiers din modelul clasic unul sau mai multe straturi noi. De fapt, ceea ce se realizeaz este separarea logicii de business de cea legat de baza de date. n acest fel se poate ctiga independena fa de baza de date. De obicei, aplicaiile multi tiers sunt divizate n trei straturi:

Data tier Business Logic Tier Presentation Tier

Stratul de date este compus din una sau mai multe baze de date care pot conine pe lng date i logica de procesare sub form de proceduri stocate. Stratul de logic de business este stratul n care ruleaz componentele software. Serverul utilizat n acest strat are rolul de a furniza un mediu de via potrivit pentru componentele software. Acest server are rolul de a realiza un management eficient al componentelor i de a le furniza anumite servicii. De exemplu, serverul poate furniza un serviciu de acces la baza de date, permind componentelor s salveze i s ncarce date din Data tier. Un alt rol important al serverului este s fac disponibile componentele pentru utilizare, s le instanieze dup necesiti, deci s le gestioneze ciclul de via.

Stratul de prezentare are rolul de a prezenta informaia la client, de obicei folosind tehnologii ca Java Server Pages i servlets sau Active Server Pages, iar ca server folosind servere Web.

4. Caracteristicile unei aplicaii multi tier

Costurile deployment-ului (instalarea i punerea n funciune)aplicaiilor este mai mic, deoarece driverele pentru bazele de date sunt instalate la partea de server i nu sunt necesare instalrile la fiecare client ca n modelul clasic. Modificarea bazei de date se poate face cu uurin deoarece clienii nu mai acceseaz direct baza de date, ci middle tier care va face legtura cu baza de date. Deci o modificare a bazei de date va duce doar la modificri ale middle tier, fr a necesita vreo modificare la partea aplicaiei client.
8

Modificarea logicii de business este uor de realizat deoarece nu este nevoie de recompilarea clientului. Prile vitale ale aplicaiei (situate n Business Logic Tier i Data Tier) pot fi protejate folosind firewalls amplasate ntre Presentation Tier i Business Logic Tier.

Resursele pot fi reutilizate n mod eficient exploatnd faptul c, de obicei, clienii fac alte lucruri pe lng utilizarea de resurse, ca de exemplu, utilizarea interfeei grafice. Se poate implementa un mecanism prin care componentele folosesc impreun conexiunile la resurse. Acest mecanism, pooling mechanism, are avantajul creterii scalabilitii aplicaiei. Acest mecanism se poate aplica i componentelor, avnd ca rezultat faptul c un client nu va avea nevoie de o component dedicat doar lui. Acesta este un avantaj major al arhitecturii multi tier fa de arhitectura two tier (cea clasic) unde fiecare client avea o component dedicat lui.
10

Erorile sunt localizate, nu se propag de la un tier la altul. Dac apare o eroare critic, ea se gsete ntrun singur tier. Celelalte tiers pot s funcioneze fr probleme n continuare, punnd la dispoziie propriile capabiliti pentru a face fa situaiei. De exemplu, dac serverul de aplicaii n care ruleaz componentele din middle tier cade, rmne totui n funciune serverul Web din Presentation Tier care poate afia o pagin de site down pentru clieni.

11

Dezavantajul aplicaiilor cu arhitecturi multi tier este necesitatea unui debit mai mare n reeaua de calculatoare, dac nu se face o proiectare inteligent a obiectelor distribuite. Aceasta apare deoarece straturile aplicaiei sunt separate fizic, aflndu-se de multe ori pe maini diferite, iar obiectele distribuite trebuie s comunice unele cu altele. Toate acestea duc la creterea traficului. Exist totui posibilitatea de a elimina o parte din trafic, dac se face o proiectare a obiectelor distribuite, astfel nct s se apeleze ntre ele ct mai rar i atunci s-i transmit unul altuia datele n mod eficient.
12

n concluzie, cele dou arhitecturi au avantajele dar i dezavantajele lor. Dac se dorete realizarea unei aplicaii care s aib trafic minim, atunci se va folosi arhitectura clasic, ce two tier, ns vor fi probleme cu portabilitatea i cu modificrile ulterioare ale codului, i cu scalabilitatea. Dac se folosete arhitectura multi tier, atunci se va ctiga portabilitate i uurin n realizarea modificrilor ulterioare, precum i scalabilitate, dar se va pierde din eficiena utilizrii traficului disponibil. ns o bun proiectare a aplicaiei poate atenua mult din acest dezavantaj.
13

5. Conceptul de component software

Aplicaii cu arhitectur multi tier se realizeaz folosind componente software distribuite beneficiind astfel de toate avantajele menionate anterior. Pentru a rspunde nevoilor organizaiilor, s-a impus ideea de component software. Exist mai multe implementri ale acestui concept: Microsoft, Sun, OMG (Object Management Group).

14

O definiie : O component software este o poriune de cod care implementeaz un set de interfee. Este o unitate discret de aplicaie logic care poate fi controlat. Componentele nu sunt aplicaii de sine stattoare, nu pot funciona singure. Ele sunt utilizate n mod asemntor pieselor de puzzle pentru a rezolva probleme mai mari. Ideea de componente software este foarte practic. O companie poate cumpra un modul bine definit care rezolv o problem i l poate utiliza mpreun cu altele pentru a rezolva probleme mai mari. O component software are o granularitate mai mare dect cea a unei clase, dar, n mod evident, mai mic dect a ntregii aplicaii.
15

O alt definiie: Componentele software sunt uniti de compunere cu interfee specificate prin contract i care au doar dependene de context explicite. O component software poate fi instalat i utilizat de tere pri. Componentele i potenialii utilizatori ai acestora se dezvolt independent, motiv pentru care este important ca serviciile oferite de ctre o component s fie fcute cunoscute prin interfeele implementate de component. Mai mult, distribuia i instalarea componentelor se face sub forma binar, deci clienii lor nu vor avea acces la codul surs.

16

Avantajele utilizrii componentelor software:

Timpul n care poate s fie dezvoltat o aplicaie scade, ceea ce permite firmei s aib o poziie mai bun pe pia. Nu este nevoie de persoane cu experien vast pentru a creea o aplicaie folosind componente software cumprate(totui realizarea componentelor necesit cunotine solide de programare obiectual). Se poate reutiliza codul n alte aplicaii, n acest fel costul total al unei aplicaii scade.

17

Programare Distribuit
Curs 2 - Programare distribuit folosind sockets 18

1 Prezentare general

Interfaa de programare a aplicaiilor (API Application Programming Interface) oferit iniial n sistemele Unix,pentru lucrul cu familia de protocoale TCP/IP, este cunoscut sub numele de programarea cu sockets (socluri). Ulterior programarea cu socluri a fost oferit i n alte sisteme de operare, n forme compatibile cu cea de pe Unix. n principiu aceast API asigur comunicarea cu nivelul transport (TCP sau UDP) al familiei de protocoale, ntruct acest nivel este cel care pune la dispoziie comunicarea capt-la-capt necesar aplicaiilor de reea.
19

Orice API depinde att de platforma pe care se bazeaz (sistemul de operare, Unix), ct i de limbajul pentru care este destinat (C).Formal, un API const dintr-o bibliotec de funcii disponibil programatorilor. Exist o analogie evident ntre operaiile cu perifericele ntr-un sistem de calcul i comunicaiile n reea ale acelui sistem. Apelurile sistem prevzute pentru accesul la fiiere pot servi i comunicarea n reea, dar pentru a ine cont de particularitile reelelor, a fost imaginat un concept nou, acela de socket. Ca i fiierele, soclurile sunt reprezentate n sistem prin descriptori(aceeai ca i pentru fiiere), dar spre deosebire de fiiere un soclu exist doar n memorie.

20

Particulariti ale lucrului n reea:

Relaia client-server tipic aplicaiilor de reea este asimetric, deci un program care opereaz n reea trebuie s cunoasc ce rol joac. O comunicare n reea poate fi cu conexiune sau fr conexiune. n primul caz asemnarea cu fiierele este mai clar, dar pentru comunicarea fr conexiune nu exist o analogie cu open, pentru c fiecare operaie poate implica un alt proces eventual pe un alt calculator. Numrul de parametrii care trebuie specificai pentru o conectare n reea este mai mare dect cel necesar la operaiile cu fiiere: protocolul, adresa local i la distan, procesul local i cel de la distan.
21

Cel puin la unele protocoale sunt importante limitele ntre nregistrri, pe cnd comunicarea cu fiierele este orientat pe flux de octei.

Exist de aceea cteva apeluri sistem noi, unele utilizate att pentru comunicarea cu conexiune, ct i fr conexiune, iar altele specifice pentru fiecare din cele dou moduri de comunicare.

22

2 Ce este socket?

Un socket este un capt de comunicaie sau punct final de comunicaie care poate fi numit i adresat ntr-o reea. Este locul unde programul de aplicaie se ntlnete cu furnizorul mediului de transport. Din perspectiva unui program de aplicaie, un socket este o resurs alocat de sistemul de operare. Din punct de vedere al unui sistem de operare, este o structur de date ntreinut de ctre nucleul sistemului de operare. Aceast structur este referit n programele de aplicaie printr-un ntreg numit descriptor de socket.
23

Se pot face dou analogii cu comunicaia cotidian:

Un socket = o cutie potal n care proprietarul ei (programul de aplicaie) depune corespondena de trimis i de unde i ridic corespondena primit, iar factorul potal (furnizorul mediului de transport) deschide cutia de cteva ori pe zi, ridic corespondena de expediat i depune corespondena sosit la adresa respectiv. Un socket = un aparat telefonic la care proprietarul formeaz un numr i dup stabilirea legturii ncepe s discute cu persoana de la cellalt capt al firului; aparatul plus ntreaga reea telefonic asigur stabilirea legturii i asigur stabilitatea acesteia pn la nchiderea unuia dintre cele dou aparate.
24

Dou aplicaii pot comunica ntre ele prin socket doar dup ce fiecreia dintre ele sistemul de operare i-a alocat un socket. Exist un numr de descriptori de socket rezervai pentru aplicaiile de sistem, restul descriptorilor fiind disponibili pentru utilizatori. Interfaa socket ascunde utilizatorului detaliile reelei fizice, ea este caracterizat numai prin serviciile pe care le asigur. Comunicaia prin socket este parte integrant a nivelului sesiune din cadrul modelului OSI. n prezent, mecanismul socket este operaional pe toate sistemele de operare de tip Unix. Din 1990 au aprut pachete care permit utilizarea acestui mecanism i sub variantele de Microsoft Windows.
25

3 Tipuri de socket

Din punctul de vedere al transportului efectuat, se disting dou tipuri de socket:


Comunicarea este posibil numai dac la ambele capete este utilizat acelai tip de socket.

socket stream socket datagram.

26

Interfaa socket stream definete un serviciu orientat pe conexiune. Datele sunt transmise fr erori i fr duplicri. Ele sunt recepionate n aceeai ordine n care au fost transmise. Fluxul de date prin reea este realizat astfel nct s se evite depirea unei valori maxime de octei la un moment dat. Nu se impun nici un fel de limitri asupra datelor, acestea considerndu-se simple iruri de octei. Transportul este realizat folosind protocolul TCP. Fiind vorba despre un serviciu orientat pe conexiune, este potrivit analogia cu aparatul telefonic. Unul din protocoalele nivelului aplicaie, FTP (File Transfer Protocol) folosete serviciile oferite de socket stream.
27

Interfaa socket datagram definete un serviciu fr conexiune n care datagramele sunt transmise ca i pachete separate. Acest serviciu nu d garanii asupra recepionrii datelor, care pot fi pierdute ori duplicate, iar datagramele pot ajunge n alt ordine dect cea n care au fost transmise. Mrimea unei datagrame este limitat de numrul de octei care pot fi transmii ntr-o singur tranzacie. Nu se realizeaz nici o dezasamblare i reasamblare a pachetelor. Pentru socket datagram transportul este realizat folosind protocolul UDP. Analogia cu cutia potal este potrivit acestui tip de socket.

28

Dintre protocoalele nivelului aplicaie, TFTP i NFS se bazeaz pe un socket datagram.

Trivial FTP este un protocol mai simplu dect FTP. El permite transferul fiierelor ntre procesele client i server dar nu permite autentificarea utilizatorului, listarea coninutului directoarelor sau schimbarea directorului curent. Network File System este un serviciu prin intermediul cruia mai multe maini legate ntr-o reea local i pun n comun sistemele de fiiere, acestea fiind vzute de ctre utilizator ca un singur sistem de fiiere care le nglobeaz pe toate.
29

n vederea alegerii unui anumit tip de socket trebuie luate n considerare mai multe aspecte:

Realizarea unei comunicaii cu o aplicaie existent impune folosirea aceluiai protocol ca i aplicaia respectiv (de ex., dac aplicaia folosete protocolul TCP, atunci se va utiliza socket stream). Sigurana i eficiena comunicaiei.

Socket stream asigur o conexiune sigur, acest lucru realizndu-se cu reducerea performanei, deoarece sunt necesare eforturi de calcul suplimentare pentru meninerea conexiunii i verificrilor de corectitudine. Din fericire, la nivelul utilizatorului acest lucru nu se observ. Socket datagram este nesigur deoarece pachetele pot fi ignorate, alterate sau duplicate n timpul transmisiei. Se poate utiliza n cazul n care aplicaia implementeaz ea nsi un mecanism propriu de corectitudine, sau dac aplicaia nu este prea sensibil la transmisii eronate. Avantaj: viteza de prelucrare.

30

Cantitatea de date care se transfer. Pentru cantiti mari de date se va utiliza socket stream. Tipul reelei. Dac comunicaia se desfoar ntr-o reea LAN atunci de cele mai multe ori socket datagram este suficient. Pentru reele WAN este recomandabil folosirea socket stream.

31

4 Scheme cadru de implementri client/server

Programarea aplicaiilor care folosesc socket urmeaz scenarii bine stabilite. Este vorba de apelarea funciilor sistem n funcie de tipul de socket i de faptul c un program joac rol de server sau de client. De multe ori cand se folosete socket datagram dispare nelesul clasic de client i de server.

32

4.1 Scenariul aplicaiilor socket stream

Pentru aplicaiile care folosesc protocol cu servicii orientate pe conexiune, deci socket stream, se folosesc cteva apeluri sistem. Unele dintre ele sunt apelate de ctre server, altele de ctre client. Succesiunea lor este dat n figura urmtoare.

33

34

Se observ ca mai nti este pornit serverul iar clientul este lansat mai trziu astfel nct s existe sigurana c poate gsi disponibile serviciile solicitate. Att serverul ct i clientul au o parte de iniializare dup care urmeaz descrierile aciunilor curente. Partea de iniializare a serverului:

socket - cere nucleului sistemului s creeze un socket prin care s poat fi contactat de ctre clieni. Aici se fixeaz familia de adrese folosit, precum i tipul de socket folosit. bind transmite nucleului numrul de port la care serverul ateapt s fie contactat precum i faptul c poate fi contactat prin orice interfa de reea de pe maina server.
35

listen cere nucleului s dimensioneze lungimea cozii de ateptare la socket. socket cere nucleului sistemului s creeze un socket prin care s poat fi contactat de ctre server. Aici se fixeaz familia de adrese folosit, precum i tipul de socket folosit: stream sau datagram. la un moment dat clientul execut un apel sistem connect, prin care i transmite nucleului lui adresa IP i numrul de port ale serverului cruia dorete s-i cear un serviciu. Nucleul prin mecanismul socket contacteaz serverul solicitat.
36

Partea de iniializare client

Relaia curent ntre un client i un server:

Serverul, odat cu lansarea apelului sistem accept rmne n ateptare pn cnd un client l contacteaz. Odat contactat, el primete adresa IP i numrul de port ale clientului care l-a contactat. Clientul execut un apel send (sau mai multe) prin care transmite serverului un mesaj prin care i cere un serviciu. Serverul, prin apelul (apelurile) sistem recv recepioneaz acest mesaj. Serverul execut aciunile necesare satisfacerii cererii clientului. Trimiterea rezultatului de ctre server ctre client se face similar: serverul trimite prin apeluri send, iar clientul recepioneaz prin apeluri recv.
37

Apelurile sistem send i recv se comport ca i funcii care execut operaii de intrare/ieire obinuite (read, write). Printre argumente nu mai apar adrese IP, nici numere de porturi, acestea fiind fixate n momentul contactrii connect-accept.

38

4.2 Scenariul aplicaiilor socket datagram

Pentru aplicaiile fr conexiune setul de apeluri sistem este prezentat n figura urmtoare:

39

Actiunile necesare servirii cererii

40

Se observ c un client nu trebuie s stabileasc o conexiune cu serverul ci trimite direct datagrame cu apelul sistem sendto. Serverul nu accept conexiuni ci emite un apel sistem recvfrom i ateapt pn la sosirea unei datagrame. n datagram este coninut i adresa de reea a procesului client, astfel c serverul cunoate unde s trimit rspunsul.

41

Prile de iniializare ale serverului i clientului:

socket cere nucleului sistemului s creeze un socket prin care s poat comunica cu partenerii. Aici se fixeaz familia de adrese folosit, precum i tipul de socket folosit: stream sau datagram. bind transmite nucleului numrul de port prin care se va comunica.

Relaia curent ntre un client i un server: la un moment dat clientul execut un apel sistem sendto, prin care i transmite nucleului lui adresa IP i numrul de port ale serverului cruia dorete s-i cear un serviciu, precum i mesajul prin care i cere serverului un serviciu.

42

Nucleul, prin mecanismul socket contacteaz serverul solicitat i-i transmite mesajul. n cazul n care cererea este compus din mai multe mesaje, ele sunt trimise succesiv prin apeluri independente. Serverul, odat cu lansarea apelului sistem recvfrom rmne n ateptare pn cnd un client l contacteaz. Odat contactat, el primete adresa IP, numrul de port ale clientului care l-a contactat precum i mesajul prin care i se cere un serviciu.
43

Apoi serverul execut aciunile necesare satisfacerii cererii clientului. Trimiterea rezultatului de ctre server ctre client se face similar: serverul trimite prin apeluri sendto, iar clientul recepioneaz prin apeluri recvfrom, eventual prin mesaje succesive, fiecare dintre ele purtnd adresele IP de contact i numerele de port.

44

Programare Distribuit
Curs 3

45

1 Apelarea procedurilor la distan

Dezvoltarea aplicaiilor distribuite este diferit de cea a aplicaiilor clasice, nedistribuite. Faptul c aplicaia nu se desfoar ntr-un singur spaiu de adrese creeaz cteva probleme noi:

Ce sarcini vor fi executate local i ce sarcini vor fi executate la distan? Trebuie definit un protocol care s specifice procedurile la distan, argumentele, rezultatele ei i semantica acestor proceduri. Cum vor fi localizate aplicaiile ca servicii n reea? Ce se va ntmpla cu clienii atunci cnd acetia nu pot comunica cu un server? Cum vor fi tratate erorile de comunicaie n reea?
46

Astfel firmele productoare de software care dezvolt astfel de aplicaii in cont de aceste probleme. De ex., firma Sun Microsystems a dezvoltat, n conformitate cu cerinele de mai sus, n 1985, platforma ONC (Open Network Computing) care const dintr-un pachet de rutine numit RPC i un pachet XDR (External Data Representation). Firma Sun a fost prima care a standardizat RPC/XDR i a fcut publice sursele i specificaiile acestora.

47

n plus, printre dificultile scrierii aplicaiilor client/server cu ajutorul soclurilor se remarc necesitatea de a introduce cod specific pentru conectare att n client, ct i n server, precum i necesitatea de a ine cont de arhitecturile potenial diferite ale calculatoarelor pe care ruleaz clientul i serverul.

48

O modalitate de a evita aceste dificulti a fost propus sub denumirea de apel de procedur la distan (RPC Remote Procedure Call) i implementat ulterior n mai multe variante comerciale. Varianta care s-a impus n final a fost cea a companiei Sun, utilizat la realizarea unor aplicaii clasice, cum ar fi NFS (Network File System). Conceptual, RPC se situeaz deasupra nivelului transport din familia de protocoale TCP/IP, utilizat n cele mai cunoscute implementri de RPC. Aceasta nseamn c i activitatea proiectanilor de aplicaii va fi mai abstract, o serie de detalii fiind preluate de suportul de execuie care nsoesc implementrile 49 RPC.

Orice implementare a conceptului RPC ofer cel puin urmtoarele faciliti:

O notaie pentru specificarea formatului datelor schimbate ntre client i server, precum i a procedurilor apelabile de la distan puse la dispoziie de server. Un instrument pentru generarea automat a codului pentru stub-ul client i pentru skeleton-ul server necesare la fiecare procedur apelabil la distan. Un serviciu de legtur (port mapper), care s permit clienilor o gsire mai uoar a serverului. O bibliotec de funcii auxiliare.

50

n esen, tehnica RPC permite apelul i execuia unei proceduri care nu se afl neaprat n acelai spaiu de adrese cu procesul care o apeleaz. Altfel spus, procedura poate fi pe acelai calculator pe care se execut procesul apelant sau se poate afla pe un alt calculator, chiar de un alt tip. Un RPC se desfoar analog cu apelul/execuia/revenirea dintr-o procedur clasic, numai c cel care apeleaz i cel apelat sunt (cel puin) executate pe dou maini diferite. n figura urmtoare este ilustrat acest mecanism pentru citirea unui fiier:

51

52

Mecanismul realizeaz semantica unui astfel de apel printr-o schem de comunicare ntre procese, i anume transmiterea de mesaje (message passing). n momentul apelului se face un schimb de mesaje pentru parametrii de intrare. La terminarea execuiei procedurii se face un al doilea schimb de mesaje, pentru ntoarcerea rezultatelor. Utilizatorul nu trebuie s intervin deoarece RPC tie singur s realizeze aceste schimburi de mesaje.
53

Una dintre principalele probleme care apare la RPC atunci cnd calculatoarele sunt de diverse tipuri, este faptul c, acelai tip de date se poate reprezenta diferit pe cele dou calculatoare. Reprezentrile diferite se refer att la dimensiunile reprezentrilor, ct i la ordinea octeilor din reprezentare. Din acest motiv, s-a impus elaborarea de standarde i de rutine care adopt un mod de reprezentare universal pentru principalele tipuri elementare de date.
54

Reprezentrile universale trebuie s fie acoperitoare fa de tipurile de calculatoare actuale. De exemplu, pachetul RPC/XDR a fost standardizat sub forma unor rutine n stilul limbajului C. Folosirea lui din alte limbaje, sub diverse SO, era condiionat de asigurarea unei interfee dintre limbajul C i limbajul respectiv sub SO dat.

55

RPC simplific dezvoltarea de aplicaii distribuite oferind un model de programare familiar. Acesta ascunde practic detaliile programrii n reea i permite concentrarea ateniei asupra aplicaiei nsi. Structurnd aplicaiile ca proceduri care ofer diverse servicii, se pot dezvolta aplicaii complexe. Multe proceduri pot fi folosite n diferite aplicaii de ctre diferii clieni. Natura intrinsec modular a aplicaiilor induce n mod natural o mai bun nelegere a aplicaiei. Bibliotecile RPC ascund dependenele de SO. Astfel, portarea aplicaiilor se face practic fr probleme, dac cele dou SO au implementat biblioteca RPC/XDR conform standardului.

56

Modelul RPC descrie modul n care coopereaz procesele din diferite noduri ale unei reele pentru a realiza o activitate comun. Paradigma RPC se bazeaz pe conceptul de apel de procedur din limbajele de programare clasice. Diferena semantic esenial ntre ele este aceea c: n abordarea clasic apelantul i subprogramul sunt active n acelai proces i folosesc mpreun acelai spaiu de adrese n timp ce n modelul RPC exist dou procese, un proces client i un proces server plasate n general pe sisteme distincte i deci n spaii i cu mecanisme de adresare diferite. n figura urmtoare este ilustrat principiul RPC:
57

58

Alinierea RPC la aplicaiile obinuite este realizat n principal de cele dou componente cotor. Cotorul client trimite argumentele de apel ale procedurii i ntoarce rezultatele apelului. Un argument poate fi de intrare, de ieire sau de intrare i de ieire. Cotorul client codific argumentele de intrare din reprezentarea local a datelor n reprezentarea universal.

59

Dup codificarea parametrilor de intrare, el creeaz un mesaj cu aceste argumente i apeleaz executivul client, care de obicei este o rutin de bibliotec ce suport funciile cotorului client. Acesta (executivul client) transmite aceti parametrii la executivul serverului. Executivul serverului preia acest mesaj i-l trimite mai departe cotorului server. Acesta decodific argumentele din reprezentarea universal n reprezentarea local a serverului, dup care apeleaz procedura din aplicaia server.
60

Cnd procedura s-a executat complet, ea ntoarce cotorului server rezultatul. Cotorul codific rezultatul n reprezentarea universal i creeaz un mesaj. Apoi apeleaz executivul serverului (o rutin de bibliotec). Acesta, la rndul lui, transmite mesajul spre executivul clientului. Executivul client decodific rezultatul din reprezentarea universal n reprezentarea local a clientului, dup care ntoarce rezultatul aplicaiei client.
61

Ca i un apel normal de procedur, RPC este o operaie sincron. Deci procesul client este blocat pe durata transferurilor i a execuiei procedurii. Evident, acest fenomen este acceptabil numai ntr-o anumit msur. n consecin s-au efectuat extinderi ale conceptului, prin aa-numitele thread-uri (fire de execuie, procese de categorie uoar).

62

Astfel, un proces normal poate fi compus dintr-o serie de thread-uri executabile independent n interiorul procesului normal. Acestea partajeaz acelai spaiu de adrese i face s creasc eficiena calculelor. n ideea operaiilor sincrone, o aplicaie client iniiaz un apel RPC ntr-un thread i apoi face alte calcule. Terminarea execuiei rutinei RPC este semnalat printr-o ntrerupere software.

63

2. Dezvoltarea aplicaiilor distribuite eterogene (CORBA)

Noiunea de enterprise este destul de larg, ea semnificnd orice firm, organizaie, companie care utilizeaz calculatoare ce ruleaz aplicaii de uz intern. Aceasta nu nseamn c aplicaiile dezvoltate i folosite de o firm anume nu pot fi folosite i de altele. Fiecare companie are diferite departamente: management, marketing, proiectare i dezvoltare de programe, resurse umane, etc.
64

Dei fiecare departament folosete aplicaii specifice, totui aceleai departamente ale mai multor firme ar putea folosi aceleai aplicaii. n industria calculatoarelor, termenul enterprise este utilizat pentru a desemna o organizaie care utilizeaz sisteme de calcul. Acest termen desemneaz corporaii, mici afaceri, instituii non-profit, instituii guvernamentale, etc. Totui, n practic, termenul este aplicat mai degrab organizaiilor mai mari.
65

Pe msura dezvoltrii tehnicii de calcul i odat cu apariia arhitecturii client/server, se impun noi strategii de dezvoltare a aplicaiilor folosite n industrie. Dezvoltarea aplicaiilor enterprise implic frecvent integrarea unor aplicaii existente scrise n limbaje diferite i sub platforme (hw/SO) diferite. n asemenea situaii infrastructura de integrare (middleware) trebuie s asigure nu numai suportul pentru comunicarea ntre componentele situate n diverse locaii, dar i suportul pentru asigurarea transparenei ntre limbaje i platforme.
66

Definirea cerinelor i specificarea unei infrastructuri de integrare orientat pe obiecte adecvat problemelor enunate mai sus face din anul 1989 obiectul de activitate al organizaiei numite Object Management Group (OMG) care reunete n acest scop peste 800 de companii i instituii. Specificarea realizat este numit CORBA (Common Object Request Broker Architecture) i reprezint una din tehnologiile cunoscute sub denumirea generic de

gestionarea obiectelor distribuite (Distributed Object Management - DOM).

67

O alt asemenea tehnologie a fost dezvoltat de Microsoft (care nu face parte din OMG) i se numete DCOM (Distributed Component Object Model). Pe scurt, CORBA este un cadru standard n care proiectanii i implementatorii de software pot integra relativ uor i rapid module i aplicaii software existente cu module i aplicaii noi, pentru a obine aplicaii mai complexe i mai puternice. CORBA combin tehnologia orientat pe obiecte cu modelul client/server pentru a pune la dispoziie o imagine uniform a sistemelor de calcul dintr-o ntreprindere orice exist n reea este privit ca un 68 obiect.

3 Aplicaii distribuite bazate pe componente

Printre avantajele frecvent menionate ale programrii orientate pe obiecte este reutilizabilitatea, adic proprietatea de a putea compune aplicaii prin reutilizarea unor entiti software anterior dezvoltate. Acest avantaj nu este realizabil ns n practic fr respectarea anumitor reguli i restricii. Experiena a condus n etape la dezvoltarea componentelor software ca uniti de reutilizare.

69

O alt posibil definiie a componentelor software:

uniti de compunere cu interfee specificate prin contract i care au doar dependene de context explicite. O component software poate fi instalat independent i poate fi utilizat de tere pri.

Componentele i potenialii utilizatori ai acestora se dezvolt independent i din acest motiv este important ca serviciile oferite de o component s fie fcute cunoscute prin interfeele implementate de component.
70

n plus, distribuia i instalarea componentelor se face sub form binar, deci clienii lor n general nu vor avea acces la codul surs. O component poate fi reimplementat (de exemplu, pentru performane de execuie mai bune) i reinstalat (n format binar) ntr-o aplicaie fr a recompila aplicaia. Pe de alt parte, specificarea unei componente trebuie s includ i cerinele componentei fa de ambiana n care va fi utilizat. Cerinele ar putea fi exprimate n particular i sub forma unor proprieti, care apar ca informaii externe codului propriu-zis al componentei. Componenta va funciona corect numai dac aceste cerine sunt satisfcute.
71

Este posibil i o alt abordare a problemei componentelor: dac ambiana n care componentele vor funciona este cunoscut, ele pot fi scrise innd cont de ambian i n felul acesta codificarea lor va fi mai simpl. Ambiana poate oferi o serie de servicii la care componentele au asigurat implicit accesul i deci n cod nu mai apare explicit nimic legat de aceste servicii.

72

ntr-o anumit msur Enterprise Java Beans este o tehnologie dezvoltat n acest sens. Deosebirea fa de RMI sau CORBA const n faptul c cele dou tehnologii ofer interfee de programare (API) care trebuie utilizate explicit n codul clienilor sau serverelor, pe cnd componentele beneficiaz implicit de o serie de servicii. Este responsabilitatea suportului software n care componentele vor fi executate s asigure aceste servicii. Una din direciile importante n care a evoluat platforma Java este cea a suportului pentru dezvoltarea aplicaiilor complexe necesare n activitile de baz ale majoritii ntreprinderilor sau instituiilor.
73

Asemenea aplicaii se caracterizeaz pe lng complexitate, prin urmtoarele caracteristici:

Organizarea multistrat: modelul tradiional client/server este insuficient, impunndu-se o separare n minim 3 straturi: clientul, serverul care conine logica ntreprinderii i stratul bazelor de date. Necesitatea asigurrii consistenei permanente a datelor, ceea ce impune comportarea tranzacional, de regul sub forma tranzaciilor distribuite. Asigurarea securitii informaiilor. Scalabilitatea, adic posibilitatea obinerii unor performane corespunztoare indiferent de volumul i complexitatea prelucrrilor.
74

Exist n prezent n platforma Java (Java 2 Enterprise Edition J2EE) un numr de interfee pentru programatorii de aplicaii (API) care mpreun formeaz Enterprise Java APIs : RMI, JDBC, JNDI .a.

75

Programare Distribuit
Curs 4 - Programare distribuit n limbajul Java 76

Limbajul Java ofer mecanisme simple de gestiune a aplicaiilor distribuite. La baza acestora st conceptul de socket a crui implementare n Java va fi prezentat n acest curs. Tehnica de apel la distan a metodelor este cunoscut sub numele de RMI (Remote Method Invocation). Aceasta este doar una dintre direciile de extindere a pachetului java.net standard. Motivul alegerii este acela c ea reprezint o extindere natural a tehnicii RPC, descris anterior.
77

1 Prezentare general a pachetului java.net

Acest pachet reprezint o infrastructur puternic i flexibil de programare n reea. Multe din clasele pachetului java.net fac parte din aceast infrastructur i nu sunt folosite direct n programele de aplicaii. Din aceast cauz, n figura urmtoare e prezentat doar partea din structura pachetului care este direct utilizabil n programe.

78

79

ntreg pachetul este structurat pe un singur nivel; toate clasele descind direct din clasa Object. Clasele pachetului sunt destinate s realizeze patru funciuni principale:

Gestiunea adreselor Internet i implementarea socket Comunicarea prin UDP Comunicarea prin TCP Accesul la resursele Internet prin URL.

80

2 Clasele InetAddress i Socket

Clasa InetAddress reprezint o adres Internet i este folosit la crearea de obiecte Socket, att pentru comunicare prin UDP ct i prin TCP. Structura clasei:

public final class InetAddress extends Object{ public static InetAddress getLocalHost() throws UnknownHostException; public static synchronized InetAddress getByName(String host) throws UnknownHostException; public static synchronized InetAddress[] getAllByName (String host) throws UnknownHostException; public String getHostName(); public byte[] getAddress(); }

81

Aceast clas nu are un constructor public, n schimb are trei metode statice care ntorc instanieri de clase InetAddress. Metoda getLocalHost ntoarce o InetAddress pentru hostul local. Metoda getByName ntoarce o InetAddress pentru maina indicat prin host, care este fie o adres Internet, fie o adres IP n notaia punctual. Metoda getAllByName ntoarce un tablou de InetAddress cu toate adresele care localizeaz hostul specificat. Metoda getHostName ntoarce numele hostului gazd, iar getAddress ntoarce adresa IP n forma binar, ntr-un ir de octei primul fiind cel mai semnificativ.
82

Structura clasei Socket:

public final class Socket extends Object{ public Socket(String host, int port) throws UnknownHostException, IOException; public Socket(String host, int port, boolean stream) throws UnknownHostException, IOException; public Socket(InetAddress adresa, int port) throws IOException; public Socket(InetAddress adresa, int port, boolean stream) throws IOException; public InputStream getInputStream() throws IOException; public OutputStream getOutputStream() throws IOException; public int getLocalPort(); public int getPort(); public InetAddress getInetAddress(); public synchronized void close() throws IOException; }

83

La crearea unui socket, adresa mainii la distan poate fi precizat fie prin adresa IP reprezentat ntrun obiect InetAddress, fie prin adresa Internet furnizat printr-un ir. n plus, se indic i portul de comunicaie. Dac se folosete ultimul constructor, parametrul stream are valoarea true, dac se dorete comunicaie prin TCP, i are valoarea false pentru comunicaie UDP.

84

Metodele getInputStream i getOutputStream sunt cele mai importante.Ele ntorc obiecte de tip InputStream, respectiv OutputStream. Prin intermediul acestora se pot apela toate metodele de acces la stream, ca i cum accesul s-ar face la un fiier local. Metoda getLocalPort ntoarce numrul portului local folosit de socket. Metoda getPort ntoarce portul de la distan la care este conectat socketul. Metoda getInetAddress ntoarce InetAddress a hostului de la distan.
85

3 Transmiterea i recepionarea prin UDP

Comunicarea prin UDP este adesea folosit n comunicaii simple unde este mai important viteza i mai rar n cazurile n care datele ce se transmit sunt importante. Utilizarea acestei comunicri n Java este asigurat de dou clase: DatagramPacket i DatagramSocket. Structura clasei DatagramPacket care descrie pachetele trimise prin protocolul UDP:

86

public final class DatagramPacket extends Object{ public DatagramPacket(byte[] t, int lungt); public DatagramPacket(byte[] t, int lungt, InetAddress adresa, int port); public byte[] getData(); public int getLength(); public int getPort(); public InetAddress getAddress(); }

87

Primul constructor este folosit pentru recepia unei datagrame. I se precizeaz un tablou de byte i o lungime maxim de recepionat. Al doilea constructor este folosit pentru emisia unei datagrame. Se indic un tablou de unde s se preia datele, lungimea de transmis, InetAddress a destinatarului i portul la care acesta ateapt. Metoda getData ntoarce n tabloul de byte datele transmise/recepionate de pachet. Celelalte metode au semnificaia prezentat anterior.
88

Structura clasei DatagramSocket:

public class DatagramSocket extends Object{ public DatagramSocket() throws SocketException; public DatagramSocket(int port) throws SocketException; public void send(DatagramPacket p) throws IOException; public synchronized void receive(DatagramPacket p) throws IOException; public getLocalPort(); public synchronized void close(); }

89

La crearea unui obiect DatagramSocket, se precizeaz eventual doar portul. n cazul n care e folosit primul constructor, se ocup unul din porturile disponibile. Metoda send transmite pachetul specificat ca argument, care trebuie s aib destinaia deja fixat. Pentru a recepiona un pachet, trebuie creat un DatagramSocket care s atepte la un anumit port mesaje. Acest socket poate fi folosit pentru a recepiona pachete trimise doar pentru portul specificat. Trebuie creat apoi un DatagramPacket cu un buffer specificat pentru recepia mesajelor, dup care se va apela metoda receive pentru DatagramSocket. Aceasta recepioneaz blocuri de date i le pune n bufferul specificat pentru DatagramPacket.

90

4 Comunicare prin TCP

Aplicaiile care comunic la distane mari, ca i aplicaiile complexe i sofisticate utilizeaz transmisia prin TCP. Perechile client server pot fi ambele scrise n Java, dar este posibil ca unul dintre protagoniti s fie scris i ntr-un alt limbaj. Clasa ServerSocket este folosit pentru crearea de programe server. Ea are rolul de a atepta i de a accepta cererile de conexiune de la clieni. Serverul e ntiinat de stabilirea conexiunii prin primirea unui obiect de tip Socket, prin intermediul cruia se va realiza comunicaia. Structura clasei:
91

public final class ServerSocket extends Object{ public ServerSocket(int port) throws IOException; public ServerSocket(int port, int nr) throws IOException; public Socket accept() throws IOException; public int getLocalPort(); public InetAddress getInetAddress(); public void close(); }

92

Se observ c, la crearea unui obiect ServerSocket, se precizeaz doar portul de comunicaie.Dac el are valoarea 0, atunci se consider orice port liber. Al doilea parametru din cel de-al doilea constructor stabilete lungimea maxim a cozii cererilor de conexiune. Dac o cerere vine ntr-un moment n care coada este plin, conexiunea e refuzat. Metoda accept este cea mai important. n momentul conectrii unui client, aceasta ntoarce un socket prin intermediul cruia se realizeaz comunicaia.
93

4.1 Implementarea unui server

Pentru o mai mare siguran n comunicaie dect cea prin UDP, se poate folosi clasa Socket care implementeaz conexiuni n reea prin stream-uri. Un model clasic de comunicare n reea este ca unul sau mai muli clieni s poat trimite cereri la un server. Serverul folosete un socket pentru a accepta conexiunile de la clieni. Metodele getInputStream i getOutputStream furnizeaz dou obiecte de tip stream prin care se comunic cu clienii.
94

Cnd se primete o cerere de la un client, se aloc un nou obiect Socket conectat la acelai port la care asculta serverul cnd a primit cererea. n acest mod, noul thread comunic cu clientul printr-un nou socket, iar serverul poate servi ali clieni. Acest server este multithread. Fiecare obiect server este un thread. Ele ruleaz metoda run tot timpul ateptnd conexiuni de la clieni. La crearea unui nou socket serverul creeaz i un nou thread, a crui metod run realizeaz toat comunicarea cu clientul i execut toate serviciile pe care serverul le ofer.
95

4.2 Variante de implementare client


Un client este de obicei o aplicaie standalone sau un applet. Indiferent de tip, el creeaz un obiect Socket pentru a stabili o conexiune cu un server. Prin metodele getInputStream i getOutputStream se obin obiectele perechi de comunicare cu serverul.

96

5 Accesul la resurse Internet prin URL

URL (Uniform Resource Locator) se refer la orice resurs de pe World Wide Web, mpreun cu protocolul de acces la el. O resurs poate fi un fiier, un director sau o referin la un obiect mai complex, cum ar fi o cerere de accesare a unei baze de date sau un instrument de cutare specializat. n Java, prin clasa URL se ofer o interfa foarte simpl pentru manevrarea unui URL: fiierul referit de URL poate fi accesat uor, pot fi deschise streamuri pentru a citi sau a scrie ntr-un URL etc.
97

public final class URL extends Object{ public URL(String protocol, String host, int port, String fisier)throws MalformedURLException; public URL(String protocol, String host, String fisier)throws MalformedURLException; public URL(String specificare)throws MalformedURLException; public URL(URL context, String host)throws MalformedURLException; public String getProtocol(); public String getHost(); public int getPort(); public String getFile(); public String getRef(); public String toExternalForm(); public final Object getContent() throws IOException; public final InputStream openStream() throws IOException; public URLConnection openConnection() throws IOException; }
98

Definiia clasei URL:

Un URL e precizat n constructor ca un simplu ir care nglobeaz ntreaga specificare a URL, sau indicnd separat, protocol, host, port i specificaiile de fiier. Metodele get ntorc diferite componente ale unui URL reprezentat printr-un obiect URL. Datele sau obiectele referite printr-un URL pot fi aduse din Internet n trei moduri:

Atunci cnd se dorete un control mai serios asupra coninutului unui URL, se folosete clasa URLConnection. Cu ajutorul ei se pot obine o serie de informaii de control referitoare la un URL folosind obiecte asociate obiectului URLConnection (tipul coninutului, lungimea, data ultimei modificri,etc.).
99

Direct, prin intermediul metodei getContent. Printr-un InputStream, folosind metoda openStream. Printr-o conexiune URL, folosind metoda openConnection.

Programare Distribuit
Curs 5

100

1 Exemplu cu server concurent pentru comunicarea orientat pe conexiune.

Exemplul din lucrarea de laborator poate s fie rescris astfel nct pentru fiecare conectare acceptat de server s se genereze un nou fir de execuie care s se ocupe de comunicarea cu clientul respectiv. Codul principal al serverului este acum foarte simplu, constnd doar din acceptarea de cereri de conectare i generarea de noi fire de execuie. Deoarece codul clientului nu se modific, acesta nu mai este reluat n curs.

101

Fiierul ServerConc.java

import java.net.*; import java.io.*; public class ServerConc{ public static void main(String[] args){ Socket client; int c=0; try{ ServerSocket ss=new ServerSocket(15812); while(true){ client=ss.accept(); c++; new ThreadConc(client,c).start(); } }catch (Exception e) {System.out.println("Eroare server princ:"+e);} } }
102

Fiierul ThreadConc.java import java.net.*; import java.io.*; public class ThreadConc extends Thread{ private Socket insock; private int contor; public ThreadConc(Socket inp, int c){ insock=inp; contor=c; } public void run(){ String mes=""; String co=Integer.toString(contor);

103

try{
DataInputStream in= new DataInputStream(insock.getInputStream()); DataOutputStream out= new DataOutputStream(insock.getOutputStream()); out.writeUTF("Pentru a termina comunicarea trimiteti un mesaj care incepe cu: \"GATA!\""); boolean gata=false; while(!gata){ mes=in.readUTF(); out.writeUTF("Am primit din firul"+co+mes+"\n"); if(mes.startsWith("GATA!")){ out.writeUTF("GATA!!!!!"); gata=true;} } insock.close(); }catch(Exception e){System.out.println("Eroare server: "+e);} } }
104

S-a introdus i posibilitatea de a urmri c se lucreaz cu fire diferite prin al doilea parametru al constructorului firelor de tip ThreadConc.

105

2 Comunicarea de grup. Clasa MulticastSocket.


ncepnd cu JDK 1.1 a fost introdus nc un tip de socket, pentru comunicaiile multicast. Clasa MulticastSocket, dedicat acestor comunicaii, deriv din DatagramSocket i are faciliti suplimentare pentru ataarea la grupuri de comunicaii (grupuri multicast). Un grup multicast este specificat printr-o adres IP de clas D (deci n domeniul 224.0.0.1 239.255.255.255) i de un numr de port UDP standard.
106

Cnd se trimite un mesaj la un grup multicast, acest mesaj este recepionat de toi membrii momentani ai grupului (care au specificat aceeai adres IP i acelai numr de port). Emitorul mesajului nu este n mod obligatoriu membru al grupului. Cei doi constructori ai clasei:

public MulticastSocket() throws IOException; public MulticastSocket(int port) throws IOException;

creaz un socket multicast i l leag la orice port disponibil/la un port specificat.


107

Metodele clasei sunt:

public void joinGroup(InetAddress mcastaddr) throws IOException;

socketul multicast curent devine membru al grupului multicast de la adresa specificat.


public void leaveGroup(InetAddress mcastaddr) throws IOException;

socketul multicast curent se retrage din grupul multicast specificat.


108

public synchronized void send (DatagramPacket p, byte ttl) throws IOException;

- trimite un pachet datagram la destinaie, cu un TTL (time-to-live) diferit de cel implicit al socketului; se recomand a fi folosit cnd este necesar un anumit TTL, altfel se folosete metoda send a clasei DatagramSocket.
public void setTTL(byte ttl) throws IOException;

- stabilete valoarea TTL pentru pachetele trimise de socketul curent.


public byte getTTL() throws IOException; - returneaz valoarea TTL pentru socketul curent.
109

public void setInterface(InetAddress inf) throws SocketException;

- stabilete adresa de reea pe care se emit pachetele multicast de la socketul curent, dac se dorete ca aceasta s fie diferit de cea implicit.
public InetAddress getInterface() throws SocketException;

- returneaz adresa de reea folosit pentru pachetele multicast.

110

Structura de program tipic pentru comunicarea multicast:


byte[] msg=...; InetAddress group = InetAddress.getByName("228.5.6.7"); MulticastSocket socket = new MulticastSocket("5678"); socket.joinGroup(group); DatagramPacket dp=new DatagramPacket(msg,msg.length,group,5678); socket.send(dp); byte[] buf=new byte[1024]; DatagramPacket recv=new DatagramPacket(buf, buf.length); socket.receive(recv); .......................... socket.leaveGroup(group); ...........................
111

3 Administratori de securitate

Problema securitii a fost una dintre cerinele fundamentale avute n vedere la proiectarea limbajului Java, ea fiind cu att mai important n cazul programelor destinate a funciona n reele de calculatoare. Soluia la care s-a ajuns ncepnd cu JDK1.1 este reflectat de clasa abstract java.lang.SecurityManager, care pune la dispoziie interfaa de programare i implementri pariale(implicite) ale unora dintre metode.
112

Fiecare aplicaie scris n Java poate avea propriul administrator (manager) de securitate, care s reflecte cerinele de securitate specifice aplicaiei. Implicit, suportul de execuie Java nu introduce nici un fel de restricii (deci nu exist un administrator de securitate implicit pentru programele de tip aplicaie). Pe de alt parte, browserele compatibile Java introduc asemenea administratori, care realizeaz politica restrictiv de acces pentru appleturi.
113

De asemenea, n cazul apelurilor de metode la distan (RMI) care vor fi descrise n cursul urmtor, exist administrator de securitate cu restricii destul de dure, a crui utilizare este obligatorie. n principiu, clasa SecurityManager ofer metode prin care se pot verifica drepturile de execuie ale unor operaii considerate critice (cum ar fi accesul la fiiere) iar aplicaiile se vor scrie astfel nct nainte de a executa o astfel de operaie s verifice (apelnd metoda corespunztoare) dac operaia este permis. Multe astfel de verificri se fac implicit n suportul de execuie.
114

Crearea unui administrator de securitate pentru o aplicaie implic selectarea operaiilor care sunt permise i a celor care sunt interzise sau cu restricii (de exemplu, parole) i re-implementarea corespunztoare a metodelor clasei SecurityManager. Se poate verifica dac o aplicaie are instalat un administrator de securitate:

SecurityManager sm=System.getSecurityManager();

Dac se obine pentru sm valoarea null , aplicaia nu are nc instalat administrator de securitate. Astfel, sm este obiectul prin care se verific drepturile de execuie pentru diverse operaii. 115

n realitate, majoritatea acestor verificri se fac implicit prin modul cum sunt realizate diverse funcii n suportul de execuie Java.

116

4 Clasa SecurityManager

Exist un singur constructor:

protected SecurityManager();

- construiete un nou manager de securitate. O aplicaie nu poate crea un nou manager de securitate dac deja are unul (se genereaz ntr-un asemenea caz SecurityException).

117

Cteva dintre metodele clasei:

public boolean getInCheck();

- verific dac este n curs un test de securitate.


public void checkAccess(Thread g);

- genereaz SecurityException dac firul apelant nu are dreptul de a modifica firul dat ca argument(este apelat din suportul de execuie pentru metodele stop, suspend, resume, setPriority ale clasei Thread).
118

public void checkExit(int status);

- genereaz SecurityException dac firul apelant nu are dreptul de a opri JVM cu codul de stare dat ca parametru.
public void checkExec(String cmd);

- genereaz SecurityException dac firul apelant nu are dreptul de a crea un subproces (se apeleaz de ctre metodele exec ale clasei Runtime). Implementarea implicit genereaz ntotdeauna excepie.
119

public void checkRead(String file);

- genereaz SecurityException dac firul apelant nu are dreptul s citeasc din fiierul cu numele dat. Implementarea implicit genereaz ntotdeauna excepie.
public void checkWrite(String file);
-

analog cu checkRead corespunztor.


120

public void checkDelete(String file);


-

genereaz SecurityException dac firul apelant nu are dreptul de tergere asupra fiierului cu numele dat ca argument(se apeleaz din metoda delete a clasei File). Implementarea implicit genereaz ntotdeauna excepie.

public void checkConnect(String host, int port);


-

genereaz SecurityException dac firul apelant nu are dreptul de a deschide o conectare prin socket la calculatorul i portul specificate ca argumente. Implementarea implicit genereaz ntotdeauna excepie.
121

public void checkListen(int port);

- genereaz SecurityException dac firul apelant nu are dreptul s atepte cereri de conectare la portul specificat. Implementarea implicit genereaz ntotdeauna excepie.
public void checkAccept(String host, int port);

- genereaz SecurityException dac firul apelant nu are dreptul s accepte conectri de la calculatorul i portul specificate. Metoda este apelat de ctre metoda accept a clasei ServerSocket. Implementarea implicit genereaz ntotdeauna excepie.

122

public void checkMulticast (InetAddress maddr); - testeaz dac n contextul de execuie curent este permis utilizarea multicastului.

123

5 Exemplu: clientul pentru aplicaia de trimitere n ecou a mesajelor, implementat cu administrator de securitate

Se pot introduce administratori de securitate att n partea de client ct i n partea de server a unei aplicaii. Frecvent ns controlul diverselor operaii este necesar mai ales pentru componenta client. ntruct implementarea implicit din clasa SecurityManager pentru toate operaiile de tip check este generarea unei excepii de securitate, se va introduce de regul o re-implementare a tuturor acestor metode, n felul urmtor: cele care nu se controleaz au implementare vid iar pentru cele controlate se implementeaz politica de control dorit. n exemplul urmtor, se controleaz operaiile de conectare prin socket i de acces la fiiere (n realitate la fluxurile ataate socketului). Pentru a menine simplitatea implementrii s-a ales o politic de control simpl, respectiv specificarea unei parole, aceeai pentru toate operaiile controlate.
124

Codul surs al clientului, mpreun cu administratorul de securitate:


import java.net.*; import java.io.*; public class SMClient{ public static void main(String[] args){ String mesin=""; String mesout=""; int c; byte[]b=new byte[256]; SecurityManager sm=new SockSecurityManager("hfjkfj"); try{ System.setSecurityManager(sm); }catch (SecurityException se) {System.out.println("Security Manager already set");} try{ Socket s=new Socket(args[0],15812); DataInputStream intrare=new DataInputStream(s.getInputStream()); DataOutputStream iesire=new DataOutputStream(s.getOutputStream()); boolean gata=false;
125

while(!gata){ System.in.read(b); for(c=0;c<b.length;c++) mesout+=(char)b[c]; iesire.writeUTF(mesout); mesin=intrare.readUTF(); System.out.println(mesin); if(!(mesout.startsWith("GATA!"))){ for(c=0;c<b.length;c++)b[c]=0; mesout="";} else gata=true; } s.close(); }catch(Exception e){System.out.println("Client error:"+e);} } }
126

class SockSecurityManager extends SecurityManager{ private String password; SockSecurityManager(String password){ super(); this.password=password; }

127

private boolean accessOK(){ int c; DataInputStream dis=new DataInputStream(System.in); String response; System.out.println("Parola?"); try{ response=dis.readLine(); if(response.equals(password)) return true; else return false; }catch(IOException e){ return false; }

128

public void checkConnect(String host, int port){ if(!accessOK()) throw new SecurityException("Error connect 2"); } public void checkListen(int port){ if(!accessOK()) throw new SecurityException("Error listen 2"); } // similar celelalte metode care se controleaza public void checkExec(String command){} // similar celelalte metode care nu se controleaza }

129

Aceast implementare (parial) a managerului de securitate introduce relativ puine restricii. n majoritatea aplicaiilor este necesar introducerea
unor restricii mai severe.

130

Programare Distribuit
Curs 6 - Apelarea metodelor la distan (RMI Remote Method Invocation) -

131

Dei n Java operaiile cu sockets (ca i cele de I/O) sunt realizate ca operaii asupra obiectelor, se pstreaz semantica de un nivel de abstractizare relativ redus a conceptului de socket aa cum este oferit acesta n sistemul de operare. Programatorii de aplicaii trebuie s-i construiasc propriile protocoale plecnd de la nivelul transport, specific pentru socket, ceea ce n cazul unor aplicaii mai complexe implic un efort semnificativ. Se poate imagina i pentru limbajele OO o modalitate de programare a aplicaiilor distribuite analoag apelului de procedur la distan (RPC).
132

Aspecte care trebuie luate n considerare atunci cnd se realizeaz un sistem de programare distribuit OO:

dac obiectele sunt mobile sau staionare; dac obiectele se transmit (comunic) prin copiere sau prin referin; ce dimensiuni (complexitate, granularitate) trebuie s aib un obiect pentru a fi satisfcute anumite criterii de eficien; ce nivel de verificare a tipurilor se ofer; dac obiectele sunt sau nu active, persistente, replicate etc.

133

ncepnd cu JDK 1.1 se ofer pentru limbajul Java un sistem de programare distribuit OO sub numele de RMI care este considerat un punct posibil n spaiul de proiectare a unor astfel de sisteme cu criteriile sugerate mai sus. Urmtoarele versiuni de JDK au adus modificri i extinderi.

134

1. Caracteristicile generale ale RMI

Un sistem suport pentru RMI trebuie s ofere soluii cel puin pentru urmtoarele probleme:

generarea automat a codului pentru stub i skeleton, care poate fi uneori mai complex dect codul serverului propriu-zis; asigurarea suportului de execuie adecvat unui mecanism de comunicare client-server; semnalarea unor excepii specifice apelurilor la distan; asigurarea unui grad ridicat de transparen n codul programelor client prin oferirea unui serviciu de nume.

135

Un obiect la distan (remote object) este definit n Java ca un obiect ale crui metode pot fi apelate (invocate) dintr-o alt main virtual Java, posibil situat pe un alt calculator. Obiectele la distan sunt exemplare ale unor clase care implementeaz metodele unor interfee la distan i numai asemenea metode pot fi apelate de clienii unui obiect la distan. Deci RMI se poate defini ca aciunea de a apela o

metod a unei interfee la distan pe un obiect la distan. Sintaxa unui asemenea apel nu difer de
cea pentru apelarea metodelor locale.

136

Exist ns cteva deosebiri:

Clienii obiectelor la distan interacioneaz cu interfeele la distan i nu direct cu clasele care implementeaz acele interfee; Argumentele locale i rezultatele unui apel la distan se transmit prin copiere i nu prin referin, pentru c referirile la obiecte sunt valabile numai n cadrul aceleiai maini virtuale. Obiectele la distan se transmit prin referire i nu prin copierea implementrii efective a obiectului; n realitate referirea este la un surogat al obiectului la distan, care se afl n aceeai main virtual cu apelantul; Clienii vor avea de-a face cu noi tipuri de excepii, pentru c modalitile n care pot eua apelurile la distan sunt mai complexe i mai numeroase dect n cazul apelurilor locale.

137

A fost necesar s se defineasc puncte de start specifice pentru clasele, interfeele i excepiile la distan, iar n cazul claselor apare, de fapt o ierarhie, cu mai multe puncte de plecare posibile. Situaia aceasta este prezentat n figura de mai jos:

138

Din punctul de vedere al organizrii n pachete se precizeaz c:


Interfaa Remote este n pachetul java.rmi; Clasele RemoteObject, RemoteServer i UnicastRemoteObject sunt situate n pachetul java.rmi.server; RemoteException face parte din pachetul java.rmi.

Alte interfee i clase sunt cuprinse n alte dou pachete distincte, java.rmi.registry i java.rmi.dgc i vor fi prezentate ulterior.

139

Interfaa Remote nu conine nici o metod, servind doar ca punct de plecare pentru RMI:

public interface Remote{}

Toate interfeele legate de lucrul cu obiecte la distan trebuie s extind Remote n mod explicit.

140

Clasa RemoteException este superclasa tuturor excepiilor care pot fi generate de ctre suportul de execuie RMI. Este obligatoriu ca toate metodele declarate ntr-o interfa la distan s specifice java.rmi.RemoteException n clauza lor throws. Aceast excepie se genereaz de exemplu n caz de eroare n reea sau dac obiectul server pentru un anumit apel nu poate fi contactat.

141

Rolul clasei RemoteObject este s reimplementeze


metodele toString() i equals() ale lui Object ntro form adecvat pentru RMI. Funciile necesare pentru a crea obiecte i a le face disponibile la distan (a le exporta) sunt prevzute n clasa abstract java.rmi.server.RemoteServer i vor fi implementate n subclasele acesteia. Este rolul subclaselor, de exemplu, s stabileasc dac serverul este un obiect unic sau este replicat (necesitnd astfel comunicarea cu locaii multiple).
142

n JDK se ofer o singur variant de semantic pentru servere, prin clasa java.rmi.server.UnicastRemoteObject care definete un obiect la distan unicat (nereplicat) ale crui referiri sunt valabile ct timp procesul care l-a lansat este activ sau poate fi activat la cerere, n condiii speciale. Este permis ca o clas care implementeaz o interfa la distan s extind o alt clas dect UnicastRemoteObject, dar n cazul acesta va fi responsabilitatea clasei s asigure semantica adecvat operaiilor equals i toString, precum i a mecanismelor de comunicare.
143

Dup cum s-a menionat, obiectele client nu interacioneaz direct cu obiectele care implementeaz o interfa la distan (servere), ci cu surogate (stubs) ale acestora, care se vor gsi n aceeai main virtual cu clientul. Obiectele surogat au exact aceleai interfee la distan ca i obiectele pe care le reprezint, dar nu includ poriunile locale din graful care constituie ierarhia tipului obiectului la distan.

144

Pentru ca un client s apeleze o metod a unui obiect la distan, clientul trebuie s dein o referire la acel obiect. n acest scop, n RMI este inclus un server de nume (prin clasa java.rmi.Naming) la care obiectele server se nregistreaz i de la care clienii pot obine referiri, dac tiu numele sub care este nregistrat serverul. Att la nregistrare, ct i la obinerea referinei se lucreaz cu numele interfeei la distan pentru a reda tipul. n server se poate ns lucra i cu numele clasei care face implementarea.
145

2 Arhitectura sistemului RMI

n varianta din JDK, sistemul RMI este implementat n trei nivele: surogat/schelet, referire la distan, transport, aa cum se ilustreaz n figur:

146

Nivelul surogat/schelet constituie interfaa ntre

nivelul aplicaie i restul sistemului RMI. Responsabilitile acestui nivel n partea clientului (surogat) sunt:

Iniierea unui apel ctre obiectul la distan (prin apelarea serviciilor din nivelul referire la distan); Transmiterea la distan a datelor (argumentelor) printr-un flux de ordonanare (marshal stream) obinut de la nivelul de referire la distan, folosind mecanismul de serializare din Java; Anunarea nivelului de referire la distan c trebuie efectuat apelul; De-ordonanarea valorii returnate sau a excepiei primite din fluxul de ordonanare; Anunarea nivelului referire la distan c s-a terminat apelul.
147

Responsabilitile n partea serverului sunt:

De-ordonanarea argumentelor din fluxul de ordonantare; Efectuarea unui apel ascendent (up-call) spre implementarea propriu-zis a obiectului la distan; Ordonanarea valorii returnate (sau a excepiei) n fluxul de ordonanare.

Surogatele i scheletele specifice unei aplicaii se genereaz automat, pe baza implementrii obiectului la distan, prin compilatorul rmic, inclus n JDK.

148

Nivelul de referire la distan are dou componente

care coopereaz, una destinat prii de client i cealalt pentru partea de server. La acest nivel se stabilete dac apelul se face unicast sau replicat i eventual strategiile de replicare, persisten i reconectare. Componenta din partea de client conine informaiile specifice despre client i comunic, prin intermediul nivelului transport, cu componenta pentru server din calculatorul la distan (dac, de exemplu, ar exista un server replicat, s-ar putea trimite apelul fiecreia dintre replicile serverului).
149

Asemntor, componenta din partea serverului implementeaz semantica referirilor la distan nainte de a trimite apelul spre nivelul schelet (de exemplu, ar putea asigura semantica de livrare atomic multicast, prin comunicarea cu celelalte servere din grup). Se reamintete c JDK ofer numai comunicare unicast, de regul doar pe perioada ct serverul este activ. Nivelul de referire la distan transmite datele spre nivelul transport printr-o conectare bazat pe flux. Este ns principial posibil ca la nivelul transport s se lucreze cu protocolfr conexiune.
150

Nivelul transport este responsabil pentru:

Stabilirea unor conexiuni spre spaiile de adrese la distan (ale JVM) i gestionarea conexiunilor; Ateptarea unor apeluri i stabilirea legturilor pentru apelurile sosite; Gestionarea unei tabele de obiecte la distan care se gsesc n spaiul de adrese; Localizarea dispecerului pentru destinaia unui apel la distan i transmiterea conexiunii ctre acel dispecer.

151

Exist 4 abstracii fundamentale cu care se opereaz la acest nivel:

Un punct final (endpoint) desemneaz un spaiu de adrese sau o main virtual Java (JVM). n implementare punctele finale sunt puse n coresponden cu nivelul lor transport, adic dac se d un punct final se poate obine nivelul transport corespunztor. Un canal este abstracia pentru legtura dintre dou spaii de adrese i deci va fi responsabil pentru gestionarea conexiunilor ntre spaiul de adrese local i un anumit spaiu de adrese la distan. O conexiune este abstracia pentru un transfer de date (execuia unei operaii de I/O).

152

Transportul este abstracia pentru gestionarea canalelor. n

cadrul transportului exist numai cte un canal ntre spaiul local i un spaiu la distan. Dndu-i-se un punct final pentru un spaiu de adrese la distan, un transport stabilete un canal spre acel spaiu de adrese. Abstracia transport este de asemenea responsabil pentru acceptarea apelurilor pe conexiunile de intrare la spaiul de adrese, pentru stabilirea unui obiect conexiune corespunztor apelului i pentru dispecerizarea spre nivelele mai nalte din sistem.

Proiectarea sistemului RMI permite s existe mai multe transporturi pentru un spaiu, ceea ce nseamn de exemplu c n aceeai main virtual sar putea lucra att cu TCP ct i cu UDP.
153

Reprezentarea concret a unei referiri la un obiect la distan const dintr-un punct final i un identificator de obiect i se numete referire vie (live reference). Dac se d o referire vie pentru un obiect la distan, transportul poate folosi punctul final pentru a stabili o conexiune cu spaiul de adrese n care se afl obiectul la distan, iar n partea serverului transportul folosete identificatorul de obiect pentru a cuta destinaia apelului la distan.

154

Suportul de execuie RMI face uz de firele de execuie ale limbajului Java pentru realizarea apelurilor de metode la distan. Astfel, suportul asigur c apelurile de la maini virtuale diferite se execut n fire diferite. Apelurile care provin de la aceeai main virtual client sunt executate cnd n acelai fir, cnd n fire diferite (datorit politicii de reutilizare a socketurilor).

155

Se ridic i n sistemele distribuite problema colectrii automate a deeurilor. n RMI a fost implementat un algoritm bazat pe numrarea referinelor. n maina virtual client algoritmul lucreaz astfel: cnd o nou referire vie apare n maina virtual, numrtorul de referine al referirii vii este incrementat. Prima referire la un obiect trimite serverului pentru obiectul respectiv un mesaj referenced. Cnd se constat local c o referire vie nu mai este folosit, finalizarea acesteia decrementeaz numrtorul. Dac acesta a fost ultima referire (numrtorul devine null) se trimite serverului un mesaj unreferenced.
156

n maina virtual server, cnd un obiect la distan nu este referit de nici un client, obiectul este referit n suportul de execuie printr-o referire slab, care permite colectorului de deeuri s elimine obiectul dac acesta nu are referiri locale. Dac ns exist referiri locale, obiectul poate fi transmis n apeluri la distan sau poate fi returnat clienilor. Dac se transmite un obiect la distan, identificatorul mainii virtuale creia i s-a transmis se adaug la setul de referiri. Obiectele la distan sunt colectate numai atunci cnd nu mai au nici un fel de referiri (nici locale, nici la distan). n cazul partiionrii reelei poate apare o colectare prematur (pentru c transportul ajunge s considere c a aprut o cdere a clientului).
157

Programare Distribuit
Curs 7 - Apelarea metodelor la distan. RMI. (continuare)158

Se prezint n continuare problema ncrcrii dinamice a claselor. Regula fundamental este aceea c ntotdeauna ncrctorul de clase care ncarc o anumit clas este folosit n continuare pentru ncrcarea tuturor interfeelor i claselor direct utilizate de acea clas:

Dac este vorba de un applet, atunci se folosete AppletClassLoader pentru a aduce din reea de la locaia specificat de atributul codebase al paginii de Web care conine marcajul <applet>, clasele referite.

159

ncrctorul de clase implicit se folosete pentru a ncrca o clas (a crei metod main este activat prin comanda java) folosind pentru localizarevaloarea variabilei de mediu locale CLASSPATH. RMIClassLoader este folosit pentru a ncrca acele clase care nu se folosesc direct de ctre aplicaie (client sau server): surogatele i scheletele obiectelor la distan i clasele extinse ale argumentelor i valorile returnate de apelurile RMI. Asemenea clase sunt cutate n urmtoarele locaii, n aceast ordine:

Variabila CLASSPATH local.Clasele se ncarc ntotdeauna local dac exist local. Pentru obiectele (la distan sau nu) transmise ca parametri sau valori returnate localizarea se face folosind URL-ul codificat n fluxul de ordonanare care conine obiectul serializat. Dac clasa a fost ncrcat de alt ncrctor de clase dect cel implicit se folosete URL-ul acelui ncrctor iar n caz contrar, dac este definit, URL-ul pentru java.rmi.server.codebase. Pentru surogatele i scheletele obiectelor la distan create n maina virtual local se folosete URL-ul specificat de proprietatea java.rmi.server.codebase.
160

O aplicaie poate fi configurat cu proprietatea java.rmi.server.useCodebaseOnly, care dezautorizeaz ncrcarea claselor din reea i foreaz ca toate clasele s se ncarce numai din baza de cod definit local. Dac acest lucru nu este posibil, apelul metodei va eua cu o excepie. ncrcarea dinamic a claselor pune probleme de securitate, dac clasele nu sunt ncrcate local. Pentru ca RMIClassLoader s poat ncrca clasele din reea este necesar s fie activ un manager de securitate, altfel generndu-se o excepie.
161

Activarea managerului de securitate trebuie s fie prima aciune a unui program Java astfel nct s poat controla toate aciunile urmtoare ale programului. Managerul de securitate asigur c toate clasele ncrcate satisfac cerinele de securitate Java (de exemplu c vin de la surse de ncredere i c nu ncearc s acceseze funcii speciale). n cazul applet-urilor se aplic ntotdeauna restriciile clasei AppletSecurity, care asigur c toate clasele vin numai de la acelai calculator ca i appletul sau de la calculatoare desemnate pentru baza de cod. Aplicaiile trebuie s-i defineasc propriul manager de securitate sau s foloseasc varianta restrictiv RMISecurityManager. Dac nu este activat nici un manager de securitate, aplicaia nu-i poate ncrca clasele din reea.
162

1 Clasele RMI accesibile programelor client

n dezvoltarea prii de client a unei aplicaii, respectiv la scrierea unui applet destinat s lucreze cu obiecte la distan, se utilizeaz interfaa Remote, deja prezentat, precum i clasele RemoteException i Naming. Toate acestea formeaz pachetul java.rmi, mpreun cu un numr de excepii derivate din RemoteException i cu clasa RMISecurityManager folosit la ncrcarea claselor surogat n aplicaii (nu i n appleturi) i descris separat.

163

Clasa Naming constituie mecanismul prin care clienii pot obine referiri la obiectele la distan(este folosit i n partea de server a programelor distribuite pentru nregistrarea obiectelor cu rol de server la distan). Localizarea obiectelor la distan se face prin URL. Clasa are numai metode statice i nu definete constructori:

public static Remote lookup(String nume) throws NotBoundException, MalformedURLException, UnknownHostException, RemoteException;

returneaz o referire (de tipul general indicat prin interfaa Remote) la obiectul identificat prin nume (care trebuie s fie un URL). Toate excepiile generate sunt derivate din RemoteException.
164

public static String[] list (String name) throws RemoteException, MalformedURLException, UnknownHostException;

Returneaz sub form de tablou de iruri URL-urile tuturor obiectelor la distan momentan nregistrate n maina virtual indicat prin argumentul name, care apare de regul ca un nume de calculator. Se pot afla astfel numele tuturor obiectelor la distan nregistrate ca server pe un anumit calculator i apoi se poate selecta cel dorit, dac numele date serverelor sunt suficient de sugestive.
165

Urmtoarele 3 metode ale clasei Naming vor fi utilizate la nregistrarea serverelor dar vor fi prezentate aici pentru a ntregi descrierea clasei:
public static void bind(String name, Remote obj) throws AlreadyBoundException, MalformedURLException, UnknownHostException,RemoteHostException;

leag un nou obiect, cu identitatea precizat prin obj sub numele name n registrul de nume al mainii virtuale din care se face apelul. Se presupune c obiectul nu a fost anterior legat.
166

public static rebind(String name, Remote obj) throws RemoteException, MalformedURLException, UnknownHostException;

leag din nou obiectul obj sub numele name, nlocuind dac este cazul o alt legtur existent sub acelai nume.
public static void unbind(String name) throws RemoteException, NotBoundException,MalformedURLException;

terge o legtur existent n registru sub numele dat ca argument.


167

n afara numelor de excepii deja ntlnite mai apar n pachetul java.rmi:


AccessException, ConnectException, MarshalException, NoSuchObjectException, RMISecurityException, ServerError, ServerException, ServerRuntimeException, StubNotFoundException, UnexpectedException, UnmarshalException.

Unele dintre excepii sunt prevzute cu mai multe variante de constructori, pentru a permite specificarea la generare a unor informaii mai detaliate.
168

2 Clasele RMI accesibile programelor server

Exceptnd clasa RMISecurityManager care se afl n pachetul java.rmi, celelalte clase i interfee utilizate de programele server RMI se gsesc n pachetul java.rmi.server. Cum s-a menionat deja, clasa RemoteObject reimplementeaz metoda equals() a clasei Object pentru a permite compararea referirilor la obiecte la distan. Metoda returneaz true dac dou obiecte Remote (referiri la surogate) refer acelai obiect la distan (compar referirile la distan).
169

Metoda toString() returneaz un ir care descrie obiectul la distan cu precizarea c acest ir, ca i coninut i sintax este dependent de implementare i deci poate varia. Clasa RemoteObject are doi constructori:

protected RemoteObject(); protected RemoteObject(RemoteRef newref); - creeaz un obiect la distan, iniializat cu referirea la distan specificat (RemoteRef este o interfa din pachetul java.rmi.server).

Clasa RemoteServer este superclasa comun tuturor implementrilor de servere i ofer potenial o gam variat de semantici pentru referirile la distan. O specificare a clasei abstracte RemoteServer arat astfel:
170

package java.rmi.server; public abstract class RemoteServer extends RemoteObject{ protected RemoteServer(); protected RemoteServer(RemoteRef ref); public static String getClientHost() throws ServerNotActiveException; public static void setLog(java.io.OutputStream out); public static java.io.PrintStream getLog(); }

Se observ c i n acest caz toate metodele clasei sunt statice. Metoda getClientHost(), cnd este apelat dintrun fir de execuie care este n cursul tratrii unui apel de metod la distan, returneaz numele calculatorului pe care ruleaz clientul. Celelalte dou metode stabilesc, respectiv obin (citesc) identitatea fluxului folosit pentru crearea unui jurnal de apeluri la server.
171

Clasa UnicastRemoteObject deriv din RemoteServer i ofer suport pentru referiri punct-la-punct la obiecte active, folosind fluxuri bazate pe TCP. Deci serverele care deriv din UnicastRemoteObject sunt ne-replicate, iar referirile la ele vor fi valabile numai cel mult pe durata de via a procesului (firului) care creaz acest server. Clasa are un singur constructor fr argumente n regim de acces protected i dou metode clone i export.

172

public Object clone() throws CloneNotSupportedException;

reimplementeaz metoda cu acelai nume din clasa Object i returneaz o copie (clon) a obiectului la distan pentru care este apelat, distinct de original. Noul obiect este imediat exportat, adic disponibil pentru a primi apeluri la distan (dac este nregistrat i poate fi identificat de clieni sau dac i se distribuie astfel de apeluri).

173

public static RemoteStub exportObject (Remote obj) throws RemoteException;

se folosete pentru a exporta un obiect la distan unicast, care nu este implementat prin extinderea clasei UnicastRemoteObject. Odat exportat, obiectul poate fi transmis ca argument ntr-un apel RMI sau returnat ca rezultat al unui apel RMI. Cnd se transfer obiectul, n timpul ordonanrii, se caut surogatul la distan corespunztor i acest surogat este de fapt transmis sau returnat.
174

Clasa RMISecurityManager din pachetul java.rmi definete politica de securitate pentru surogatele RMI n programele aplicaii (nu i n applet-uri). Se poate folosi acest manager de securitate n cazul n care aplicaia nu necesit funcii de securitate specializate, fiindc el este foarte restrictiv: dezautorizeaz toate funciile, cu excepia definirii i accesului la clase astfel nct clasele pentru obiectele la distan, argumentele lor i valorile returnate s poat fi ncrcate cnd sunt necesare.
175

Specificarea unui manager de securitate se face n metoda main a aplicaiei n felul urmtor:

System.setSecurityManager(new RMISecurityManager);

n lipsa unui manager de securitate, RMI nu va putea ncrca clasele surogat dect din sistemul local de fiiere, conform valorii variabilei CLASSPATH. Un manager de securitate trebuie s implementeze metodele clasei abstracte java.lang.SecurityManager, care permit unei aplicaii s determine nainte de a efectua o operaie potenial periculoas, dac aceasta ar urma s fie fcut printr-o clas adus de un ncrctor de clase i nu instalat local. Aplicaia poate autoriza sau dezautoriza apoi operaia.
176

Majoritatea metodelor au nume care ncep cu cuvntul check, iar utilizarea lor se face conform urmtoarei scheme:

SecurityManager security=System.getSecurityManager(); if(security!=null) { security.checknume_operatie(argument,....); }

177

n acest mod managerul de securitate poate preveni efectuarea respectivei operaii prin generarea unei excepii: rutinele managerului revin normal dac operaia este permis sau genereaz excepia SecurityException dac operaia nu este permis. Cteva exemple de metode din RMISecurityManager sunt:

public synchronized void checkAccess(Thread t) throws RMISecurityException; - surogatele nu au dreptul s modifice argumentul Thread. public synchronized void checkCreateClassLoader() throws RMISecurityException; - surogatele nu au dreptul s creeze ncrctoare de clase i nici s execute metode ale clasei ClassLoader. public synchronized void checkPropertiesAccess() throws RMISecurityException; - surogatele nu pot accesa ntreaga list de proprieti a sistemului, ci numai pe cele explicit etichetate ca accesibile surogatelor;
178

public synchronized void checkListen(int port) throws RMISecurityException; - surogatele nu pot asculta la nici un port. public synchronized void checkConnect(String host, int port, Object context) throws RMISecurityException; - clasele ncrcate (inclusiv surogatele) pot face conectri dac sunt apelate prin transportul RMI.

Clasa RMIClassLoader este un utilitar care se poate folosi de ctre aplicaii pentru a ncrca clase de la un URL (din reea). Suportul de execuie RMI folosete un ncrctor de clase propriu pentru a ncrca surogatele, scheletele i alte clase necesare surogatelor i scheletelor. Procesele server trebuie s declare suportului de execuie RMI localizarea claselor surogate i parametri sau valori returnate ce vor fi disponibile clientilor lor, prin proprietatea java.rmi.server.codebase.
179

3 Serviciul de nregistrare (de nume) a obiectelor la distan

Pachetul java.rmi.registry conine dou interfee, Registry i RegistryHandler, precum i clasa LocateRegistry, prin care se realizeaz serviciul de nregistrare i regsire a obiectelor la distan, bazat pe nume simple. Este posibil ca fiecare proces server s-i defineasc propriul registru de obiecte sau s foloseasc un singur asemenea registru pentru un anumit calculator. Registrul este la rndul su un obiect la distan.
180

Interfaa Registry specific metodele de cutare, legare, re-legare, tergere i listare a coninutului unui registru. De fapt, clasa java.rmi.Naming folosete interfaa Registry pentru a pune la dispoziie clienilor un serviciu de nume bazat pe URL. Operaiile bind, unbind i rebind sunt permise numai dac solicitanii sunt pe acelai calculator ca i serverul, dar lookup poate veni de oriunde.

181

Clasa LocateRegistry conine metode statice care returneaz o referire la un registru, precum i o metod prin care se creaz un registru. Referirile returnate sunt n realitate referiri la un surogat la distan al registrului.
public final class LocateRegistry{ public static Registry getRegistry() throws java.rmi.RemoteException; public static Registry getRegistry(int port) throws java.rmi.RemoteException; public static Registry getRegistry(String host) throws java.rmi.UnknownHostException; public static Registry getRegistry(String host,int port) throws java.rmi.RemoteException, jama.rmi.UnknownHostException; public static Registry createRegistry(int port)throws java.rmi.RemoteException; }

182

Cele 4 metode getRegistry vor returna referiri la registrul de pe calculatorul curent; de pe calculatorul curent la portul specificat; de pe calculatorul cu numele dat; de pe calculatorul cu numele dat, la portul dat (portul implicit, specificat n interfaa Registry este 1099). Metoda createRegistry creaz i export un registru pe calculatorul local, la portul specificat. Acest registru implementeaz un serviciu de nume simplu, n care numele unui obiect la distan (String) este pus n coresponden cu o referire la distan. Legturile astfel create sunt valabile numai pentru activarea curenta registrului. Dac acest server este repornit, trebuie refcute toate legturile.

183

Interfaa RegistryHandler se folosete pentru legtura cu o implementare particular a serverului de nume i are specificarea:
public interface RegistryHandler{ Registry registryStub(String host,int port) throws java.rmi.RemoteException, java.rmi.UnknownHostException; Registry registryImpl(int port)throws java.rmi.RemoteException;

Prima metod returneaz un surogat pentru a contacta un registru la distan pe calculatorul i la portul specificate. A doua metod construiete i export un registru la portul specificat (diferit de zero). n JDK este inclus un registru de obiecte la distan implicit, care se activeaz prin comanda rmiregistry &.
184

4. Clasele i interfeele pentru surogate i schelete

n pachetul java.rmi.server se gsesc cteva clase i interfee utilizate de surogatele i scheletele generate de compilatorul rmic. Clasa abstract RemoteStub, derivat din RemoteObject este superclasa comun pentru toate surogatele. Ea furnizeaz un cadru n care se pot realiza diferite semantici pentru referirile la distan. Specificarea acestei clase:

public abstract class RemoteStub extends RemoteObject{ protected RemoteStub(); protected RemoteStub(RemoteRef ref); protected static void setRef(RemoteStub stub, RemoteRef ref);}

185

Interfaa RemoteCall este folosit de surogate i schelete pentru efectuarea unui apel la un obiect la distan i are urmtoarea specificare:

package java.rmi.server; import java.io.*; public interface RemoteCall{ ObjectOutput getOutputStream() throws IOException; void releaseOutputStream() throws IOException; ObjectInput getInputStream() throws IOException; void releaseInputStream() throws IOException; ObjectOutput getResultStream(boolean succes) throws IOException, StreamCorruptedException; void executeCall() throws Exception; void done() throws Exception; }
186

Primele 4 metode se refer la fluxurile de obiecte prin care se realizeaz ordonanarea/de-ordonanarea argumentelor sau rezultatelor apelului. De exemplu, getInputStream returneaz fluxul de intrare din care surogatul i extrage prin de-ordonanare rezultatele sau din care scheletul extrage argumentele. Metoda getResultStream returneaz un flux de ieire (dup ce scrie n acesta o informaie-antet referitoare la succesul apelului). Obinerea fluxului cu rezultate trebuie s reueasc doar o dat pentru fiecare apel. Dac success este true, rezultatul este normal; n caz contrar rezultatul este o excepie, de exemplu, StreamCorruptedException dac fluxul a fost deja obinut o dat pentru acest apel.
187

Metoda executeCall() va conine ceea ce este necesar pentru efectuarea apelului, iar done() permite o curire dup ce s-a terminat apelul la distan. Interfaa RemoteRef reprezint un descriptor(handle) pentru un obiect la distan. Fiecare surogat conine cte un exemplar de RemoteRef care const din reprezentarea concret a referinei. O metod a interfeei este :

RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum, long hash) throws RemoteException;

creaz un obiect de apel adecvat pentru un nou apel de metod la distan obj. Tabloul de operaii op conine operaiile disponibile asupra obiectului la distan iar opnum este un indice n tabloul de operaii prin care se indic operaia pentru apelul curent.
188

Interfaa ServerRef reprezint descriptorul n partea serverului pentru implementarea unui obiect la distan:

public interface ServerRef extends RemoteRef{ RemoteStub exportObject(java.rmi.Remote obj, RemoteServer server, Object data) throws java.rmi.RemoteException; String getClientHost() throws ServerNotActiveException; }

Metoda exportObject caut sau creaz un obiect surogat client pentru implementarea de obiect Remote obj. Parametrul server este obiectul server la distan pentru implementare (poate fi acelai ca i obj) iar data conine informaii necesare pentru a exporta obiectul(de exemplu un numr de port).
189

Interfaa Skeleton este folosit numai n implementarea scheletelor generate de compilatorul rmic:

public interface Skeleton{ void dispatch (Remote obj, RemoteCall call, int opnum, long hash) throws Exception; Operation[] getOperation(); }

Metoda dispatch de-ordonaneaz argumentele din fluxul de intrare obinut de la obiectul call, apeleaz metoda (indicat de opnum) pe implementarea efectiv a obiectului obj i ordonaneaz valoarea returnat sau genereaz o excepie.
190

Clasa Operation pstreaz o descriere a unei metode pentru un obiect la distan: public public public public class Operation{ Operation (String op); String getOperation(); String toString();

191

Programare Distribuit
Curs 8 -RMI(continuare)

192

1. Clasele i interfaa pentru colectorul de deeuri

Interfaa DGC (de la Distributed Garbage Collector) este folosit n partea de server a algoritmului distribuit de colectare a deeurilor, care implementeaz cele dou metode ale interfeei, dirty i clean:

193

package java.rmi.dgc; import java.rmi.server.ObjID; public interface DGC extend java.rmi.Remote{ Lease dirty(ObjID[] ids, long sequenceNum, Lease lease) throws java.rmi.RemoteException; void clean(ObjID[] ids, long seqNum, VMID vmid, boolean strong) throws java.rmi.RemoteException; }

194

Un client trebuie s apeleze metoda dirty cnd deordonaneaz o referire la distan (clientul va fi indicat prin VMID). Cnd clientul nu mai are referiri pentru o anumit referire la distan el apeleaz clean. Dup un apel euat la dirty trebuie fcut un apel clean cu strong avnd valoarea true, astfel nct la server s se rein numrul de secven al apelului pentru a se putea ulterior detecta apelurile primite altfel dect n ordinea normal. Referirile la obiectele la distan sunt mprumutate (leased) de ctre clieni, pe perioade specificate, care ncep din momentul primirii apelului dirty.
195

Este responsabilitatea clientului s rennoiasc mprumuturile nainte de expirare; n caz contrar colectorul de deeuri presupune c obiectul la distan nu mai este referit de acel client. Un obiect al clasei Lease conine un identificator unic al clientului prin VMID (virtual machine identifier) i o durat de mprumut (de tip long). Pentru fiecare obiect la distan exportat n maina virtual local, colectorul de deeuri (CD) pstreaz o list de referiri identificatorii clienilor care dein referiri la acel obiect.
196

Cnd se acord un mprumut, CD adaug VMID-ul clientului la lista fiecrui obiect indicat n tabloul ids. Numrul de secven trebuie s creasc pentru fiecare apel la CD. Unii clieni nu pot genera un VMID unic, pentru c acesta conine adresa efectiv a calculatorului i aceasta nu le este unora accesibil din motive de securitate. n acest caz clientul folosete VMID=null, dar CD i va asigna un VMID care va fi folosit la urmtoarele apeluri.
197

Este necesar un singur apel la dirty pentru fiecare apel la distan, chiar dac clientul deine mai multe referine pentru acel obiect. Clasa ObjID se folosete pentru identificarea unic a obiectelor la distan n cadrul unei maini virtuale. Fiecare identificator conine un numr de obiect i un identificator al spaiului de adrese, care este unic pentru un anumit calculator. Identificatorul obiectului se asigneaz atunci cnd se export obiectul la distan. Clasa ObjID reimplementeaz metodele equals i toString i prevede doi constructori (unul fr argumente i unul cu argument ntreg).
198

Al doilea constructor genereaz identificatori de obiecte binecunoscui de exemplu utilizai de serviciul de nume i de colectorul de deeuri. Aceste numere nu vor intra n conflict cu cele generate de primul constructor. Clasa UID se folosete pentru a crea identificatori care sunt unici n raport cu calculatorul pe care s-au generat. Aceti identificatori se folosesc n ObjID ca partea care indic un spaiu de adrese. Clasa VMID furnizeaz identificatori unici universali, n raport cu toate mainile virtuale Java (constau dintr-un UID i o adres de calculator).
199

2. Tipare de programare. Fabrica de obiecte

Datorit limitrilor sistemului RMI i a cerinelor frecvente din aplicaii, se impun dou tipare n utilizarea RMI: fabrica de obiecte i apelul invers. Deoarece RMI nu asigura pentru servere dect semantica UnicastRemoteObject, un server nu putea fi n mod obinuit activat (pornit) de ctre un client. Exist ns aplicaii n care crearea dinamic a serverelor poate fi util.

200

Se poate realiza aceast creare dinamic a serverelor printr-un artificiu: aplicaia dispune de o fabric de obiecte, adic de un obiect la distan, cu semantica uzual de UnicastRemoteObject care ns creaz, la solicitarea unor clieni, obiecte la distan noi n aceeai main virtual ca i el i returneaz clienilor referiri la distan la aceste obiecte. n continuare clienii vor solicita serviciile noilor obiecte la distan care apar astfel ca servere create dinamic.

201

De regul fabrica de obiecte dispune de o singur metod, pentru crearea unui obiect la distan de o anumit clas, structura aplicaiei putnd fi reprezentat ca n figura urmtoare:

202

Pentru a detalia modul de lucru cu acest tipar se consider ca potenial aplicaie o carte de telefon personal. Pentru fiecare client va exista cte un exemplar al acesteia (creat din clasa ServerCarteTelefon), dar toate exemplarele sunt meninute pe un acelai calculator i ofer operaiile specificate n urmtoarea interfa la distan:

203

public interface CarteTelefon extends Remote{ void addEntry(Entry e) throws RemoteException; String lookupNumber(String p) throws RemoteException; void deleteEntry(Entry e) throws RemoteException; }

Pe lng aceast interfa se mai definete i interfaa la distan a fabricii de obiecte introdus n arhitectura aplicaiei:
public interface FabrCarteTelefon extends Remote{ CarteTelefon getCarteTelefon(String owner);

Metoda primete ca argument numele proprietarului care poate fi utilizat, de exemplu, pentru a ncrca dintr-un fiier forma actual a crii de telefon pentru solicitant sau pentru controlul accesului la un anumit exemplar al crii. 204

Implementarea fabricii de obiecte se face conform urmtoarei schie:


public class Fabrica extends UnicastRemoteObject implements FabrCarteTelefon{ Fabrica() throws RemoteException{ //constructorul fabricii } public CarteTelefon getCarteTelefon(String owner) throws RemoteException{ ServerCarteTelefon carteNoua=new ServerCarteTelefon(owner); return carteNoua;}}
205

Nu este obligatoriu ca n orice aplicaie fiecare apel al metodei fabricii de obiecte s conduc la crearea unui obiect nou. Este posibil, de exemplu, s se returneze o referire la distan spre acelai server pentru mai muli clieni i s se creeze servere noi numai dac numrul clienilor pentru un server depete o anumit limit. Pentru partea de client a aplicaiei schia de implementare este urmtoarea:
public class ClientCarteTelefon{ . try{ Remote obd=Naming.lookup(FABRCARTEL);//numele sub //care s-a inregistrat fabrica de carti de telefon }catch(java.rmi.NotBoundException e){ System.out.println(eroare de cautare+e.toString());} //se transforma Remote in FabrCarteTelefon FabrCarteTelefon fct; if(obd instanceof FabrCarteTelefon) fct=(FabrCarteTelefon)obd;
206

//se apeleaza fabrica pentru a produce o noua carte de telefon CarteTelefon ct; try{ ct=fct.getCarteTelefon(eu);}//eu numele proprietarului catch(java.rmi.RemoteException e){ System.out.println(eroare de apel+e.toString());} //exemplu de apel la cartea nou creata try{ String numar=ct.lookupNumber(Ionescu);} catch (java.rmi.RemoteException e){ System.out.println(eroare de apel+e.toString());} .. } Ca de obicei, apelurile din client se fac ntotdeauna prin nume de interfee implementate de obiectele la distan. De remarcat c dou clase (ServerCarteTelefon i Fabrica) implementeaz interfee la distan i deci trebuie prelucrate cu rmic.

Numai fabrica de obiecte se nregistreaz ns la serverul de nume.


207

2.2 Tipare de programare.Apeluri inverse.

Pentru aplicaiile n care clienii utilizeaz informaii variabile n timp, gestionate de un server, este important ca modificrile de informaii s devin accesibile clientului ct mai rapid. O modalitate ar fi ca din clieni s se apeleze periodic metodele corespunztoare din server, ceea ce ns poate conduce la un trafic suplimentar n reea inacceptabil. Soluia mai eficient este ca nsui serverul s anune clienii atunci cnd apar modificri. n felul acesta traficul n reea apare numai cnd este strict necesar i numai cu clienii care i-au manifestat explicit interesul pentru a fi anunai de modificri.

208

n plus, i serverul va avea o solicitare mai redus (numr mai mic de apeluri) i poate alege momentul cel mai convenabil pentru anunarea modificrilor. Serverul va anuna clienii tot prin efectuarea unor apeluri de metode. Astfel de apeluri, dela server la client, se numesc apeluri inverse (callbacks).

n RMI pentru a putea realiza apelurile inverse este necesar s se defineasc o nou interfa la distan i s se implementeze aceast interfa de ctre clieni. Pe de alt parte interfaa la distan implementat de server va trebui s prevad o metod prin care clienii i pot nregistra la server interesul pentru a fi anunai de apariia unor modificri.

209

Implementarea serverului va conine informaii i cod pentru a ine evidenaclienilor care solicit apeluri inverse i pentru a efectua aceste apeluri. Lund ca exemplu tot crile de telefon personale, se adaug acum cerina ca modificarea numrului de telefon a unei persoane s fie considerat operaie distinct i s fie anunat tuturor clienilor care solicit acest lucru. Noua interfa la distan care va fi implementat de server va arta astfel:

210

public interface CarteTelefon extends Remote{ void addEntry(Entry e) throws RemoteException; String lookupNumber(String p) throws RemoteException; void deleteEntry(Entry e) throws RemoteException; void modifyEntry(Entry e) throws RemoteException; void addCallback(CTInvers ctobj) throws RemoteException; }

Ultimele dou intrri sunt noi, addCallback fiind cea prin care un client va solicita s fie luat n eviden pentru anunarea modificrilor.
211

CTInvers este numele interfeei ce va fi implementat de clieni i are specificarea:


public interface CTInvers extends Remote{ void schimbStare(Entry e);

Se observ c interfaa ce va fi implementat de clieni extinde remote deci este interfa la distan. n realitate, apelul metodei schimbStare se face din server, dar identitatea clientului i este comunicat direct de acesta i nu trebuie gsit prin intermediul unui serviciu de nume. n acest scop se folosete metoda exportObject() a clasei UnicastRemoteObject.
212

Scenariul implementrii serverului este urmtorul (se prezint numai prile care intervin n realizarea apelurilor inverse):
import java.rmi.*; import java.rmi.server; import java.util.*; public class ServerCarteTelefon extends UnicastRemoteObject implements CarteTelefon{ . Vector callbackObjects;//structura pentru a tine evidenta clientilor care //solicita apeluri inverse .. public void addCallback(CTInvers ctObj){ callbackObjects.addElement(ctObj); ..//alte metode

213

public void modifyEntry(Entry e) throws RemoteException{ //operatii necesare la modificare for(int i=0; i<callbackObjects.size();i++){ //apeleaza invers clientii inregistrati CTInvers callback=(CTInvers)callbackObjects.elementAt(i); callback.schimbStare(e); }}}

S-a adugat o structur Vector pentru a se ine evidena clienilor care solicit apeluri inverse. Implementarea metodei suplimentare addCallback poate fi foarte simpl: doar introducerea unui nou element n Vector. Cea mai important modificare apare la implementarea metodei modifyEntry, care conine codul pentru a comunica noua valoare a intrrii tuturor clienilor nregistrai n Vector.
214

Pentru client, un scenariu de implementare ar arta:


import java.rmi.*; import java.server.*; public class ClientCarteTelefon implements CTInvers{ . public void schimbStare(Entry e){ //operatiile include probabil un apel la metodele deleteEntry //si addEntry a severului pentru cartea de telefon

} //inregistrarea clientului pentru apeluri inverse va fi cel mai //probabil facuta in constructor

215

public ClientCarteTelefon(){ . try{ Remote robj=Naming.lookup(CARTE_TELEFON);} catch(java.rmi.NotBoundException e){ System.out.println(eroare cautare+e);} CarteTelefon ct; if(robj instanceof CarteTelefon) ct=(CarteTelefon) robj; try{ ct.addCallback(this);}//inregistrare pentru apel invers catch(java.rmi.RemoteException e){ System.out.println(eroare in apel la distanta+e);} }} ..//alte metode ale clientului }
216

3. Activarea obiectelor la distan

Este posibil ca n aplicaiile distribuite orientate pe obiecte s existe la un moment dat un numr mare de obiecte (de ordinul miilor sau mai mare), astfel nct apare problema meninerii tuturor acestor obiecte n stare activ pe perioade lungi de timp, ceea ce ar conduce la un consum mare de resurse. O alt problem este aceea de a permite clienilor s dein referine persistente la obiectele la distan astfel nct s se poat restabili comunicarea cu acestea dup o cdere de sistem (n mod normal referinele la obiectele distribuite sunt valide numai cnd obiectele sunt active.)
217

Prin activarea obiectelor la distan n Java se ofer o facilitate pentru gestionarea execuiei obiectelor i pentru lucrul cu referine persistente. Se numete obiect activ un obiect la distan instaniat i exportat ntr-o main virtual Java pe un calculator oarecare. Un obiect este pasiv dac nu a fost nc instaniat (sau exportat), dar ar putea fi adus n stare activ. Activarea implic asocierea obiectului cu o JVM, ceea ce mai departe poate implica ncrcarea clasei obiectului ntr-o JVM i restaurarea strii sale persistente (dac exist).
218

n implementarea activrii n RMI s-a optat pentru activarea lene (lazy activation) ceea ce nseamn c aceasta nu se produce dect n urma primei apelri a unei metode a obiectului. Pentru fiecare obiect la distan cunoscut n sistem, un client poate obine un descriptor persistent (identificator de activare) care alctuiete, mpreun cu o referin la distan tranzitorie o referin la distan defectabil (faulting remote reference). Iniial referina tranzitorie (numit i referin vie) este nul, dar la apelarea unei metode se declaneaz protocolul de activare prin care se obine o referin vie valid. n continuare apelurile de metode se realizeaz prin aceast referin vie.
219

Protocolul de activare implic urmtoarele entiti: referina defectabil, activatorul, un grup de activare ntr-o JVM i obiectul la distan ce urmeaz a fi activat. Activatorul (de regul, cte unul n fiecare calculator) supervizeaz activitatea, ndeplinind simultan dou roluri:

Baz de informaii pentru realizarea corespondenei ntre identificatorii de activare i informaiile de activare (clasa obiectului, localizarea acestuia,etc.). Manager de JVM care iniiaz JVM cnd este necesar i dirijeaz cererile de activare spre grupul de activare corespunztor din JVM.
220

Un grup de activare (cte unul pentru o JVM) este entitatea care recepioneaz o cerere de activare i returneaz activatorului obiectul activat. Protocolul funcioneaz astfel:
Folosind identificatorul de activare, referina defectabil apeleaz activatorul (care apare ca o interfa intern a RMI). Activatorul caut n baza sa de date descriptorul de activare n care se afl identificatorul de grup al obiectului (precizeaz n ce main virtual va fi activat obiectul) precum i datele de iniializare n form ordonanat (posibil numele unui fiier care conine starea persistent, dac aceasta exist) i clasa obiectului (nume i cod). Dac grupul de activare exist activatorul dirijeaz cererea de activare spre acel grup. n caz contrar activatorul iniializeaz o JVM care s execute grupul de activare i apoi dirijeaz cererea de activare la acel grup. Grupul de activare ncarc clasa obiectului i instaniaz obiectul folosind un constructor special cu mai multe argumente, inclusiv descriptorul de activare anterior nregistrat.
221

Cnd activarea obiectului s-a ncheiat grupul de activare transmite activatorului o referin la obiect ordonanat. Aceasta nregistreaz referina vie i o returneaz referinei defectabile. Referina defectabil (care apare n stub-ul unui client) dirijeaz apelurile de metode prin referina vie spre obiectul la distan.

Pentru a putea utiliza activarea este necesar ca pe sistemul unde se afl obiecte distribuite (la distan) s ruleze o implementare a interfeelor sistemului de activare, cunoscut sub numele rmid (demonul de activare RMI). Demonul de activare se pornete din linia de comand sau dintr-un shell script (la fel ca rmiregistry) i rmne activ pe toat durata funcionrii sistemului.
222

Pentru ca un obiect distribuit s poat fi accesat printr-un identificator de activare trebuie ca el s ndeplineasc dou condiii:

nregistrarea unui descriptor de activare (ActivationDesc) se poate realiza n mai multe moduri:

S aib nregistrat un descriptor de activare. S conin un constructor special care va fi apelat de sistemul RMI atunci cnd activeaz obiectul.

Prin crearea unui obiect activabil dintr-o clas ce extinde clasa Activatable (n loc de UnicastRemoteObject) cu un constructor special al acesteia. Prin crearea unui obiect care extinde UnicastRemoteObject i apelul metodei statice register a clasei Activatable. Prin exportarea explicit a unui obiect activabil cu ajutorul uneia dintre metodele exportObject ale clasei Activatable, care au ca parametri un ActivationDesc, implementarea unui obiect Remote i un numr de port.

223

n toate cazurile nregistrarea este realizat ntr-un program separat (parte a aplicaiei, dar numai cu rol de iniializare) care se ruleaz nainte ca primul client s fac apel la o metod a obiectului la distan activabil. O schi a unei asemenea aplicaii este prezentat n figur:

224

S-ar putea să vă placă și