Download pptx - Mre žno računarstvo

Transcript

Mreno raunarstvo

Mreno raunarstvo18. glava: Remote Method Invocation (RMI) Mree imaju 2 fundamentalne primene:Prva primena je premetanje fajlova i podataka izmeu hostova i tie se FTP, SMTP, HTTP, NFS, IMAP, POP i mnogih drugih protokolaDruga primena je omoguavanje jednom hostu da izvrava programe na drugom hostu. Tradicionalno, to rade Telnet, rlogin, RemoteProcedureCall (RPC) i mnogo database middleware-a.RMI (Remote Method Invocation) je primer druge primene mrea: izvravanje programa na hostu udaljenom od lokalne maineRMIDelovi jednog programa izvravaju se na lokalnom raunaru, dok se drugi delovi istog programa izvravaju na udaljenom hostu.RMI stvara iluziju da se ovaj distribuirani program izvrava na jednom sistemu sa jednim memorijskim prostorom koji sadri sav kod i podatke koriene na bilo kojoj od strana stvarne fizike konekcijeta je Remote Method Invocation?RMI doputa da Java objekti na razliitim hostovima meusobno komuniciraju na nain slian onome na koji komuniciraju objekti koji se izvravaju na istoj VM: pozivanjem metoda objekataUdaljeni objekat (remote object) ivi na serveru. Svaki udaljeni objekat implementira udaljeni interfejs (remote interface) koji odreuje koji od njegovih metoda moe biti pozvan od strane klijenata.Klijenti pozivaju metode udaljenog objekta skoro isto kao to pozivaju lokalne metode.PrimerObjekat koji se izvrava na lokalnom klijentu moe proslediti upit bazi kao String argument metoda objekta baze koji se izvrava na udaljenom serveru da ga zamoli da sumira niz slogova.Server moe vratiti rezultat klijentu kao double.Ovo je efikasnije nego download-ovati sve slogove i sumirati ih lokalno.Primer 2: Java-kompatibilni web serveri mogu implementirati udaljene metode (remote methods) koji doputaju klijentima da trae kompletan indeks javno dostupnih fajlova na sajtu. Ovo moe dramatino smanjiti vreme koje server provodi popunjavajui zahteve web spider-a kao to je Google.Sa programerske take gledita, udaljeni objekti i metodi funkcioniu u velikoj meri kao lokalni objekti i metodi na koje smo navikli. Svi detalji implementacije su sakriveni.Samo importujemo jedan paket, potraimo udaljeni objekat u registry-ju (to je 1 linija koda), i obezbedimo da se hvata RemoteException kada pozivamo metode objekta. Od te take nadalje moemo koristiti udaljeni objekat skoro slobodno i jednostavno kao to koristimo objekat koji se izvrava na naem sopstvenom sistemu.Apstrakcija nije savrena. Remote method invocation je mnogo sporiji i manje pouzdan negoli regularan local method invocation. Stvari mogu poi, i polaze naopako sa remote method invocation koje ne utiu na local method invocation. (RemoteExceptions). Meutim, RMI pokuava da sakrije razliku izmeu local i remote method invocation to je mogue vie. Udaljeni objekatFormalnije, udaljeni objekat je objekat sa metodima koji mogu biti pozvani sa druge VM u odnosu na onu na kojoj sam objekat ivi, uopteno, sa VM koja se izvrava na drugom raunaru.Svaki udaljeni objekat implementira 1 ili vie udaljenih interfejsa koji deklariu koji metodi udaljenog objekta mogu biti pozvani od strane drugog sistemaPrimerPretpostavimo da je weather.centralpark.org PC konektovan na Internet u Central Park weather station, koji prati temperaturu, vlanost vazduha, vazduni pritisak, brzinu i smer vetra i sline informacije kroz konekcije sa raznim instrumentima, i treba da uini ove podatke dostupnim udaljenim raunarimaJava program koji se izvrava na tom PC-ju moe ponuditi interfejs koji obezbeuje tekue vrednosti podataka o vremenu:Weather.java (udaljeni interfejs)import java.rmi.*;import java.util.Date;

public interface Weather extends Remote{ public double getTemperature() throws RemoteException; public double getHumidity() throws RemoteException; public double getPressure() throws RemoteException; }

Uobiajeno, ovaj interfejs je ogranien na druge programe koji se izvravaju na istom PC-ju, zapravo u istoj VM.Meutim, remote method invocations doputaju da druge VM, koje se izvravaju na drugim raunarima, u drugim krajevima sveta, pozivaju ove metode kako bi dobile podatke o vremenu.Npr. Java program koji se izvrava na stallion.elharo.com moe potraiti tekui Weather objekat u RMI registry na weather.centralpark.orgRegistry e mu poslati referencu na objekat koji se izvrava na VM na weather.centralpark.orgProgram na stallion.elharo.com moe potom koristiti ovu referencu kako bi pozvao metod getTemperature(). Ovaj metod e se izvriti na serveru u Central Park-u, ne na lokalnoj maini.Meutim, vratie double vrednost lokalnom programu (koji se izvrava u Bruklinu).Ovo je jednostavnije nego dizajnirati i implementirati novi soket-zasnovan protokol za komunikaciju izmeu meteoroloke stanice i njenih klijenata. Detalji uspostavljanja konekcija izmeu hostova i transfera podataka su skriveni u RMI klasama.Za sada, zamislili smo javni, svima dostupan, servis.Meutim, postoje neki metodi za koje ne elimo da svako moe da ih pozivaVeina RMI aplikacija ima strogo ogranien skup doputenih korisnika.Sam RMI ne obezbeuje nikakva sredstva ograniavanja kome je doputen pristup RMI serverima.Ove mogunosti mogu se dodati RMI programima pomou Java Authentication and Authorization Service (JAAS). Serijalizacija objekataKada se objekat prosledi Java metodu ili ga metod vrati, ono to je zaista preneseno je referenca na objekat. Referenca je dvostruki indirektni pokaziva na lokaciju objekta u memoriji.Prosleivanje objekata izmeu dve maine zbog toga stvara neke probleme. Udaljena maina ne moe itati ta je u memoriji lokalne maine. Referenca koja je validna na jednoj maini, besmislena je na drugoj.***Postoje dva naina za reavanje ovog problema.Prvi je da se objekat konvertuje u niz bajtova i ti bajtovi poalju udaljenoj maini. Udaljena maina prima bajtove i rekonstruie ih u kopiju objekta. Meutim, promene na kopiji se ne odraavaju automatski na originalni objekat.Drugi nain je proslediti specijalnu udaljenu referencu na objekat. Kada udaljena maina pozove metod za ovu referencu, poziv putuje natrag kroz Internet do lokalne maine koja je originalno kreirala objekat. Promene uinjene na bilo kojoj maini odraavaju se na oba kraja konekcije jer oni dele isti objekat.***Konvertovanje objekata u sekvencu bajtova je tee nego to se to ini na prvi pogled, jer polja objekta mogu biti reference na druge objekte; objekte na koje ova polja ukazuju takoe treba iskopirati kada se kopira taj objekat. A ovi objekti mogu pokazivati na neke druge objekte, koje takoe treba kopirati.Serijalizacija objekata je ema kojom se objekti mogu konvertovati u bajtove i proslediti drugoj maini koja izgrauje originalni objekat iz bajtova. Ovi bajtovi se takoe mogu upisati na disk i kasnije proitati otuda, doputajui nam da sauvamo stanje itavog programa u jednom jedinom objektu***Iz bezbednosnih razloga, Java ima neka ogranienja na to koji objekti mogu biti serijalizovani.Svi primitivni tipovi mogu biti serijalizovani.Neudaljeni Java objekti mogu biti serijalizovani samo ako implementiraju java.io.Serializable interfejsKlase String i Component implementiraju gaKontejnerske klase poput Vector su serijabilne (serializable) ako su takvi i svi objekti koje sadre.Dalje, potklasa serijabilne klase je i sama serijabilna. Npr. java.lang.Integer i java.lang.Float su serijabilne jer je klasa iz koje su izvedene, java.lang.Number, takva. ***Izuzeci, greke i drugi throwable objekti su uvek serijabilni.Veina AWT i Swing komponenata, kontejnera i dogaaja je serijabilnoMeutim, adapteri dogaaja, filteri slika i peer klase nisuTokovi, itai i pisai i veina drugih I/O klasa nijeWrapper klase tipova su serijabilne osim za VoidKlase u paketu java.math su serijabilneKlase u java.lang.reflect nisu.Klasa URL jesteMeutim, Socket, URLConnection i veina drugih klasa u java.net nijeCORBARMI nije jedina mogunost kada se radi o distribuiranim objektnim sistemima. Njegovo najvee ogranienje je to se mogu pozivati samo metodi napisani u Javi.ta ako ve imamo aplikaciju napisanu u nekom drugom jeziku, npr. C++, i elimo da komuniciramo sa njom?Najuoptenije reenje za distribuirane objekte je CORBA, the Common Object Request Broker Architecture.Corba doputa da objekti napisani u razliitim jezicima meusobno komunicirajuRMI kako funkcionieJava krije mnoge stvari od nas. Meutim, ne kodi nikada da se razume kako stvari zaista funkcioniuKljuna razlika izmeu udaljenih i lokalnih objekata je to su udaljeni objekti u drugoj VM.Uobiajeno, objekti argumenti se prosleuju metodima i objekti povratne vrednosti bivaju vraeni od metoda da referiu na neto u odreenoj VM. To se zove prosleivanje reference.Meutim, ovakav pristup ne funkcionie kada pozivajui i pozvani metod nisu u istoj VM. Razliite VM mogu implementirati reference na potpuno razliite i nekompatibilne naineKoriste se 3 razliita mehanizma za prosleivanje argumenata i vraanje rezultata udaljenih metoda u zavisnosti od tipa prosleenih podataka.Primitivni tipovi (int, boolean, double, ...) se prosleuju po vrednosti, kao i u pozivu lokalnih Java metodaReference na udaljene objekte (tj. objekti koji implementiraju Remote interfejs) se prosleuju kao udaljene reference koje omoguavaju da primalac pozove metode udaljenih objekata. Slino kao to se reference na lokalne objekte prosleuju lokalnim Java metodimaObjekti koji ne mogu biti serijalizovani ne mogu biti prosleeni udaljenim metodima.Udaljeni objekti se izvravaju na serveru, ali mogu biti pozvani objektima koji se izvravaju na klijentuNeudaljeni, serijabilni objekti izvravaju se na klijentskom sistemu.***Da bi se proces uinio to je mogue vie transparentnim za programera, komunikacija izmeu klijenta i servera je implementirana nizom slojeva:Server Program ------------------- Client ProgramSkeleton StubRemote Reference Layer Remote ReferenceL.Transpor Layer ------------------- Transport LayerProgrameru izgleda kao da se klijent direktno obraa serveru. Zapravo, klijent komunicira samo sa Stub objektom koji je zamena za stvarni objekat na udaljenom sistemu. Stub prosleuje konverzaciju remote reference sloju, koji pria sa transport layerom...Vei deo vremena mi o ovome ne moramo da mislimo vie nego to mislimo o tome kako telefon prevodi na glas u niz elektrinih impulsa koji se prevode nazad u zvuk na drugoj strani telefonskog pozivaCilj RMI-ja je da omogui da na program prosledi argumente metodima i uzme povratne vrednosti od njih bez brige o tome kako se ti argumenti i povratne vrednosti prenose preko mree. U najgorem sluaju, moraemo da rukujemo jo 1 dodatnom vrstom izuzetaka koje moe izbaciti udaljeni metodRegistryPre nego to pozovemo metod udaljenog objekta, neophodna nam je referenca na taj objekat.Da bismo je dobili, traimo je od registry-ja po imenu.Registry je poput mini-DNS-a za udaljene objekte.Klijent se konektuje na registry i daje mu URL udaljenog objekta koji eli. Registry odgovara referencom na objekat koju klijent moe koristiti da bi pozvao metode na serveruStub objekatU stvarnosti, klijent samo poziva lokalne metode u stub-objektu. Stub je lokalni objekat koji implementira udaljene interfejse udaljenog objekta;to znai da stub ima metode koji odgovaraju potpisima svih metoda koje udaljeni objekat eksportujeZapravo, klijent misli da poziva metod udaljenog objekta, ali zapravo poziva ekvivalentni metod stub-a.Stub-ovi se koriste u VM klijenata umesto stvarnih objekata i metoda koji ive na serveruKorisno je razmiljati o stub-u kao o surogatu udaljenog objekta na klijentu.

ImplementacijaVeina metoda neophodnih za rad sa udaljenim objektima nalazi se u 3 paketa:java.rmi, java.rmi.server, java.rmi.registryPaket java.rmi definie klase, interfejse i izuzetke koji e biti vieni na strani klijentaOni su nam neophodni kada piemo programe koji pristupaju udaljenim objektima, ali sami po sebi nisu udaljeni objektiPaket java.rmi.server definie klase, interfejse i izuzetke koji e biti vidljivi na strani servera. Ove klase se koriste kada se pie udaljeni objekat koji e biti pozivan od strane klijenataPaket java.rmi.registry definie klase, interfejse i izuzetke koji se koriste za lociranje i imenovanje udaljenih objekataNapomenaU ovom poglavlju, kao i u Sun-ovoj dokumentaciji, serverska strana se uvek smatra udaljenom, a klijentska lokalnom. Ovo moe biti zbunjujue, posebno kada piemo udaljeni objekat. Tada obino razmiljamo sa take gledita servera, kome je klijent udaljenServerska stranaDa bismo kreirali novi udaljeni objekat, prvo definiemo interfejs koji nasleuje java.rmi.Remote interfejs.Remote je marker-interfejs koji nema sopstvenih metoda, njegova jedina svrha je da taguje udaljene objekte tako da mogu biti identifikovani kao takviJedna definicija udaljenog objekta je da je to instanca klase koji implementira Remote interfejs ili bilo koji njegov podinterfejsUdaljeni interfejsNa podinterfejs od Remote definie koje metode udaljenog objekta klijenti mogu zvati. Udaljeni objekat moe imati mnogo javnih metoda, ali samo oni deklarisani u udaljenom interfejsu mogu se pozivati od strane udaljenih klijenata. Ostali javni metodi mogu se pozivati samo unutar VM na kojoj objekat iviSvaki metod podinterfejsa mora deklarisati da izbacuje RemoteException. RemoteException je superklasa za veinu izuzetaka koji mogu biti izbaeni prilikom korienja RMI. Mnogi od ovih su povezani sa ponaanjem eksternih sistema i mrea i time su izvan nae kontrolePrimer: FibonacciJednostavan interfejs za udaljeni objekat koji rauna Fibonaijeve brojeve proizvoljne veliineFibonaijeve brojeve ini sekvenca koja poinje sa:1, 1, 2, 3, 5, 8, 13, ... u kojoj je svaki broj suma prethodna dva. Prva dva broja se zadaju eksplicitno.Ovaj udaljeni objekat se moe izvravati na monom serveru kako bi raunao rezultate za klijente manje snageInterfejs deklarie dva preklopljena (overloaded) metoda getFibonacci(), od kojih jedan uzima int kao argument, a drugi BigInteger. Oba metoda vraaju BigInteger, jer Fibonaijevi brojevi vrlo brzo vrlo mnogo rastu.Sloeniji udaljeni objekat moe imati mnogo vie metodaNita u ovom interfejsu ne govori nita o tome kako je izraunavanje implementirano. Npr. moe biti izraunato direktno, korienjem metoda java.math.BigInteger klase. Moe biti uraeno podjednako jednostavno efikasnijim metodima com.ibm.BigInteger klase. Moe biti izraunato int-ovima za male vrednosti n, a BigInteger za velike.Svako izraunavanje moe biti izvreno neposredno ili moe biti iskorien fiksirani broj niti kako bi se ograniilo optereenje serveraIzraunate vrednosti mogu biti keirane za bre dobijanje u buduim zahtevima, bilo interno ili u fajlu ili bazi podataka. Bilo ta ili sve od ovoga je mogueKlijent ne zna, i ne interesuje ga, kako server dolazi do rezultata sve dok je taj rezultat ispravanImpl-klasaSledei korak je definisanje klase koja implementira ovaj udaljeni interfejsKlasa treba da bude izvedena iz java.rmi.server.UnicastRemoteObjectbilo direktno ili indirektno (tj. da nasleuje drugu klasu koja nasleuje UnicastRemoteObject)Bez previe detaljisanja, UnicastRemoteObject obezbeuje metode koji ine da RMI funkcioniePosebno ova klasa radi tzv. marshalling i unmarshalling udaljenih referenci na objekatMarshalling i UnmarshallingMarshalling je proces kojim se argumenti i povratne vrednosti konvertuju u tok bajtova koji moe biti poslat preko mreeUnmarshalling je obrnut proces: konverzija toka bajtova u grupu argumenata i povratnu vrednost.Ako izvoenje klase iz UnicastRemoteObject nije podesno, npr. jer bismo eleli da nasledimo neku drugu klasu, moemo eksportovati na objekat kao udaljeni njegovim prosleivanjem nekom od statikih UnicastRemoteObject.exportObject() metoda:public static RemoteStub exportObject(Remote obj) throws RemoteException public static Remote exportObject(Remote obj, int port) throws RemoteException public static Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteExceptionOni kreiraju udaljeni objekat koji koristi na objekat da bi odradio posao. Ovo je slino kao to Runnable objekat moe da se koristi kako bi dao niti ono to treba da radi, kada nije pogodno naslediti klasu Thread.Meutim, ovaj pristup ima manu jer spreava korienje dinamikih proksija u Java 1.5ActivatablePostoji 1 vrsta RemoteServer u standardnoj Java biblioteci: java.rmi.activation.Activatable (apstraktna klasa, izvedena iz RemoteServer)UnicastRemoteObject postoji dok se izvrava server koji ga je kreirao. Kada server umre, objekat zauvek nestajeActivatable objekti doputaju klijentima da se rekonektuju na servere u raznim trenucima izmeu gaenja i restarta servera i pristupaju istim udaljenim objektima. Takoe, postoje statiki Activatable.exportObject() metode koje pozivamo ako ne elimo da nasledimo klasu ActivatablePrimer: FibonacciImplKlasa implementira udaljeni interfejs FibonacciIma konstruktor i 2 getFibonacci() metodaJedino su getFibonacci() metodi dostupni klijentu jer su jedino oni definisani Fibonacci interfejsomKonstruktor se koristi na strani servera i nije dostupan klijentuFibonacciImpl() konstruktor samo poziva konstruktor superklase koji eksportuje objekat, tj. kreira UnicastRemoteObject na nekom portu i poinje da oslukuje konekcije. Konstruktor je deklarisan da izbacuje RemoteException jer UnicastRemoteObject konstruktor moe izbaciti taj izuzetakgetFibonacci(int n) metod je trivijalan. Prosto vraa rezultat konvertovanja svog argumenta u BigInteger i poziva drugog getFibonacci() metodaDrugi metod zapravo vri izraunavanje. On koristi BigInteger kako bi omoguio izraunavanje proizvoljno velikih Fibonaijevih brojeva za proizvoljno veliki indeks. Ovo moe troiti mnogo CPU snage i ogromne koliine memorije. Zbog toga moda elimo da to izraunavanje premestimo na server specijalizovan za tu vrstu izraunavanja umesto da ga izvravamo lokalno.Iako je getFibonacci() udaljeni metod, u njemu nema niega to ga razlikuje od lokalnih metoda.Ovo je jednostavan sluaj, ali ak i mnogo kompleksniji udaljeni metodi nisu algoritamski razliiti od svojih lokalnih kopija. Jedina razlika da je udaljeni metod deklarisan u udaljenom interfejsu, a lokalni metod nije je potpuno eksterna za sam metodServer: FibonacciServerDalje, treba da napiemo server koji ini Fibonacci udaljeni objekat dostupnim svetuSve to on ima je main() metod. Poinje ulaskom u try-blok koji hvata RemoteException. Zatim konstruie novi FibonacciImpl objekat i vezuje ga za ime fibonacci koristei klasu Naming kako bi komunicirao sa lokalnim registry-jem. Registry prati koji su dostupni objekti na RMI serveru i imena kojima se oni mogu zahtevati.Kada se kreira novi udaljeni objekat, objekat dodaje sebe i svoje ime u registry Naming.bind() ili Naming.rebind() metodom.Klijenti potom mogu traiti objekat po imenu ili dobiti listu svih udaljenih objekata koji su dostupni.Primetimo da ne postoji pravilo koje kae da ime koje objekat ima u registry-ju mora da ima veze sa imenom klase. Npr. Mogli bismo nazvati ovaj objekat Fred. Zapravo, moe postojati vei broj instanci iste klase, pri emu su sve vezane u registry-ju, svaka sa razliitim imenom.Nakon to se registruje, server tampa poruku na System.out signalizirajui da je spreman da prihvata udaljene pozive. Ako neto krene naopako, catch-blok tampa jednostavnu poruku o greciIako se main() metod ovde zavrava prilino brzo, server e nastaviti da se izvrava, jer nedemonska nit je pokrenuta kada je FibonacciImpl vezan za registry.Ovim se zavrava serverski kod koji treba da napiemoKompajliranje stub-ova (ne treba od Java 1.5)RMI koristi stub-klase da posreduju izmeu lokalnih i udaljenih objekata. Svaki udaljeni objekat na serveru predstavljen je stub-klasom na klijentu. Stub sadri informacije o Remote interfejsu (u ovom primeru, da Fibonacci objekat poseduje 2 getFibonacci() metoda)Java 1.5 moe ponekad generisati ove stub-ove automatski kada su potrebni. U Java 1.4 i prethodnim, moraju se runo kompajlirati stub-ovi za svaku udaljenu klasu. ak i u Java 1.5 moraju se runo kompajlirati stub-ovi za udaljene objekte koji nisu potklase od UnicastRemoteObject, ve su eksportovani pozivom metoda UnicastRemoteObject.exportObject()rmicNa sreu, ne moramo sami pisati stub-klase: one mogu biti generisane automatski od strane bajt koda udaljene klase koristei rmic utility koji je sastavni deo JDK-a.Da bismo generisali stub-ove za FibonacciImpl udaljeni objekat, pokrenemo rmic na udaljenim klasama za koje elimo da generiemo stub-ove.Npr.rmic FibonacciImplrmic ita .class fajl klasa koje implementiraju Remote interfejs i proizvodi .class fajlove za stub-ove neophodne za udaljeni objekat. Argument komandne linije za rmic je puno kvalifikovano ime klase udaljenog objekta (ovde je klasa u bezimenom paketu!!!)rmic podrava iste opcije komandne linije kao i javac kompajler, npr. -classpath i -dnpr. ako klasa nije

u classpath, moemo zadati lokaciju classpath argumentom komandne linije. Sledea komanda trai FibonacciImpl.class u direktorijumu test/clases:rmic -classpath test/classes FibonacciImpl

Pokretanje serveraSada smo spremni da pokrenemo serverZapravo, dva servera treba da pokrenemo: sam udaljeni objekat (FibonacciServer u ovom primeru) i registry koji omoguava lokalnim klijentima da download-uju referencu na udaljeni objekat. Poto server oekuje da komunicira sa registry-jem, prvo moramo pokrenuti registry.Postarati se da su sve stub i server klase u serverovom classpath i ukucati: rmiregistry & (za Linux)pod Windows-om, startuje se iz DOS prompta sa: start rmiregistryU oba primera, registry se izvrava u pozadini.registry pokuava da oslukuje na portu 1099, po default-u. Ako ne uspe, posebno sa porukom poput java.net.SocketException: Address already in use, onda neki drugi program koristi port 1099, mogue (ne nuno) drugi registry servis.Registry se moe pokrenuti na drugom portu dopisivanjem broja porta:rmiregistry 2048 &Ako se koristi drugi port, neophodno je ukljuiti taj port u URL koji referie na ovaj registry servis.Konano, spremni smo da pokrenemo serverTo se ini na potpuno isti nain kao i za bilo koju drugu klasu sa main() metodom: java FibonacciServer(klasa je u bezimenom paketu!!!)Sada su server i registry spremni da prihvataju pozive udaljenih metoda

Klijentska stranaSledee piemo klijenta koji se konektuje na ove servere kako bi napravio pozive udaljenih metodaPre nego to regularni Java objekat moe pozvati metod, neophodna mu je referenca na objekat iji e metod zvatiPre nego to klijentski objekat moe pozvati udaljeni metod, neophodna mu je udaljena referenca na objekat iji e metod zvati. Program dohvata ovu udaljenu referencu iz registry-ja na serveru na kom se udaljeni objekat izvrava. On pretrauje registry pozivom lookup() metoda registry-ja. Tana ema imenovanja zavisi od registry-ja; java.rmi.Naming obezbeuje URL-zasnovanu emu za lociranje objekataKao to se moe videti u narednom kodu, ovi URL-ovi su dizajnirani tako da su slini sa http URL-ovima:Protokol je rmifile-polje URL-a odreuje ime udaljenog objektaPolja za hostname i port su uobiajena

Object o1 = Naming.lookup(rmi://login.ibiblio.org/fibonacci);Object o2 = Naming.lookup(rmi://login.ibiblio.org:2048/fibonacci);Objekat dohvaen iz registry-ja gubi informaciju o svom tipu. Zato, pre korienja objekta, moramo ga kastovati u udaljeni interfejs koji udaljeni objekat implementira (ne u stvarnu klasu, koja je sakrivena od klijenata):Fibonacci calculator = (Fibonacci)Naming.lookup(fibonacci);Nakon to je referenca na objekat dobijena, i njen tip restauriran, klijent moe koristiti referencu kako bi pozivao udaljene metode objekta sasvim isto kao kada koristi normalnu referencu da pozove metode lokalnog objekta. Jedina razlika je to mora hvatati RemoteException za svaki udaljeni poziv.try{ BigInteger f56 = calculator.getFibonacci(56); System.out.println(The 56th Fibonacci number is + f56); BigInteger f156 = calculator.getFibonacci(new BigInteger(156)); System.out.println(The 156th Fibonacci number is + f156);}catch(RemoteException ex){ System.err.println(ex);}

Klasa se kompajlira na uobiajeni nain.Primetimo da zbog toga to se objekat koji Naming.lookup() vrati kastuje u Fibonacci, bilo Fibonacci.java bilo Fibonacci.class fajl mora biti dostupan na lokalnom hostu.Generalni zahtev kod kompajliranja klijenta je imati ili byte ili source code udaljenog interfejsa na koji se klijent konektuje.Do neke mere, ovo se moe malo oslabiti, koristei reflection API, ali se ipak mora znati bar neto o API-ju udaljenog interfejsa. Vei deo vremena, ovo nije problem poto su server i klijent napisani od strane istog programera ili timaPokretanje klijentaPostarati se da klijent poseduje:FibonacciClient.classFibonacci.class iFibonacciImpl_Stub.class u svom class path Ako i klijent i server koriste Java 1.5 nije nam neophodna stub-klasa)Na klijentskom sistemu kucamo:java FibonacciClient rmi://host.com/fibonacci 0 1 2 3 4 5 55 155Klijent konvertuje argumente komandne linije u BigInteger objekte. alje te objekte preko ice udaljenom serveru. Server prima svaki od tih objekata, rauna Fibonaijev broj za taj indeks i alje BigInteger objekat nazad klijentu preko Interneta.Zapravo, mogue je izvravati i klijent i server na istoj maini, mada nije interesantno.Loading Classes at RuntimeSve to klijent zapravo treba da zna o udaljenom objektu je njegov udaljeni interfejs. Sve ostalo to mu je potrebno npr. stub-klase moe biti uitano od web servera (ne RMI servera) u vreme izvravanja koristei class loader.Zapravo, ova mogunost uitavanja klasa iz mree je jedna od jedinstvenih mogunosti Jave.Posebno je korisna u apletima. Web server moe poslati browser-u aplet koji povratno komunicira sa serverom, npr. kako bi omoguio da klijent ita i pie fajlove na serveru. Meutim, kao i uvek kada se klase uitavaju od hosta kome potencijalno ne verujemo, one moraju biti proverene Security Manager-om.Naalost, iako su udaljeni objekti prilino jednostavni za upotrebu kada moemo da instaliramo neophodne klase u class path lokalnog klijenta, kada moramo dinamiki da uitamo stub-ove i druge klase, teko je.Dohvatanje objekta lokalnog klijenta za download-ovanje udaljenih objekata sa servera zahteva jako preciznu manipulaciju. Sasvim mala greka spreava pokretanje programa i samo najoptiji izuzetak se izbacuje da kae programeru u emu je pogreio.Koliko je tano teko naterati programe da rade zavisi od konteksta u kome se udaljeni objekti izvravaju.Uopteno, donekle je jednostavnije obraditi aplet klijente koji koriste RMI nego samostalne klijentske aplikacijeSamostalne aplikacije su dopustive ako klijent moe raunati da ima pristup istim .class fajlovima kao i server. Samostalne aplikacije koje treba da uitaju te fajlove sa servera granie se sa nemoguim.Primer: FibonacciAppletaplet klijent za Fibonacci udaljeni objekatima istu osnovnu strukturu kao prethodni klijentkoristi TextArea da prikae poruku od servera umesto System.outrmi URL je izgraen od apletovog codebase. Ovo pomae da se izbegnu bezbednosni problemi koji nastaju kada aplet pokua da otvori mrenu konekciju sa hostom razliitim od onoga sa koga potie.RMI-zasnovani apleti svakako nisu izuzetak od uobiajenih restrikcija za mrene konekcijePrimer: FibonacciApplet.html jednostavan HTML fajl koji se moe koristiti za uitavanje apleta u web browser-u.

RMI Applet

RMI Applet

Smestiti:FibonacciImpl_Stub.classFibonacciApplet.html iFibonacciServer.class u isti direktorijum na naem web serveru.Dodati ovaj direktorijum u serverov class path i startovati rmiregistry na serveruZatim pokrenuti FibonacciServer na serveru. Npr.rmiregistry &java FibonacciServer &Osigurati da se oba programa izvravaju na stvarnoj web server maini. Kako bi proli bezbednosne restrikcije apleta, i rmiregistry i FibonacciServer moraju da se izvravaju na maini koja predaje fajl FibonacciApplet.class web klijentima.Sada uitavamo FibonacciApplet.html u web browser sa klijenta.Za aplikacije, mnogo je jednostavnije ako moemo da uitamo sve klase koje su nam neophodne pre pokretanja programa. Moemo uitati klase sa web servera koji se izvrava na istom serveru kao i udaljeni objekat, ako je potrebno.Da bismo to uinili, postavimo java.rmi.server.codebase Java sistemsko svojstvo (system property) na serveru (gde se udaljeni objekat izvrava) na URL na kom su .class fajlovi smeteni na mrei. Npr. da bismo zadali da se klase mogu nai na http://www.cafeaulait.org/rmi2/kucamo:java -Djava.rmi.server.codebase=http://www.cafeaulait.org/rmi2/ FibonacciServer &

Fibonacci server readyAko se klase nalaze u paketima, java.rmi.server.codebase svojstvo pokazuje na direktorijum koji sadri top-level com ili org direktorijum, pre nego direktorijum koji sadri same .class fajloveI server i klijent e uitati .class fajlove sa ove lokacije ako ih prvo ne pronau u lokalnom class path.Svaki klijentski program koji piemo bi normalno morao da zna poprilino o sistemu sa kojim komunicira da bi uradio neto korisno. Ovo obino ukljuuje bar da je udaljeni interfejs dostupan na klijentu u vreme kompajliranja i izvravanja. ak i ako koristimo reflection da bismo to izbegli, ipak moramo da znamo potpise i neto o ponaanju metoda koje elimo da pozovemo.RMI je izvravanje 1 programa na veem broju maina, a ne vie programa na razliitim mainama koji meusobno komunicirajuprema tome, jednostavnije je ako obe strane konekcije imaju dostupan sav kod kada program zapone izvravanjepaket java.rmisadri klase koje vide klijenti (objekti koji pozivaju udaljene metode)i klijenti i serveri treba da importuju java.rmiovaj paket sadri 1 interfejs, 3 klase i pregrt izuzetaka Remote interfejs taguje objekte kao udaljenene deklarie nijedan metodudaljeni objekti obino implementiraju podinterfejs od Remote koji deklarie neke metode. Metodi koji su tu deklarisani su metodi koji se mogu udaljeno pozivati1 objekat moe implementirati vei broj Remote interfejsaklasa Namingjava.rmi.Naming obraa se registry-ju koji se izvrava na serveru kako bi mapirao URL-ove poput rmi://login.ibiblio.org/myRemoteObject u odreene udaljene objekte na odreenim hostovimaO registry-ju se moe razmiljati kao o DNS-u za udaljene objekte. Svaki unos u registry-ju ima ime i referencu na objekat. Klijenti daju ime (preko URL), a dobiju referencu na udaljeni objekatrmi URL izgleda potpuno isto kao http URL osim to je ema rmi umesto httppath deo URL-a je proizvoljno ime koje je server vezao za odreeni udaljeni objekat, ne ime fajlaNajvei nedostatak je to iz bezbednosnih razloga (izbegavanje man-in-the-middle-napada) mora da se izvrava na istom serveru kao i udaljeni objekti. Ne moe registrovati vei broj objekata na nekoliko razliitih servera. Ako je ovo previe restriktivno, Java Naming and Directory Interface (JNDI) kontekst moe ubaciti dodatni sloj indirekcije tako da vei broj RMI registry-ja moe biti predstavljen kroz jedan direktorijum. Klijenti treba da znaju samo adresu glavnog JNDI direktorijuma. Ne treba da znaju adrese svih pojedinanih RMI registry-ja koje JNDI menja.metodi klase Namingklasa ima 5 javnih metoda:list() lista sva imena iz registry-jalookup() za dati URL trai odgov. udaljeni objekatbind() vezuje ime za odreeni udaljeni objekatrebind() vezuje ime za neki drugi udaljeni objekatunbind() uklanja ime iz registry-japublic static String[] list(String url) throws RemoteException, MalformedURLExceptionvraa niz String-ova, po jedan za svaki URL koji je trenutno vezanurl argument je URL Naming registry-ja koji se pretraujekoristi se samo protokol, host i port, a path deo se ignorielist() izbacuje MalformedURLException ako url nije validan rmi URL.RemoteException se izbacuje ako bilo ta drugo nije u redu, npr. registry nije dostupan ili odbija da dostavi zahtevanu informacijuPrimer: program lista sva imena trenutno vezana u odreenom registry-ju. To je ponekad korisno prilikom debagovanja RMI problema. Omoguuje nam da odredimo da li su imena koja koristimo imena koja server oekuje.public static Remote lookup(String url) throws RemoteException, NotBoundException, AccessException, MalformedURLExceptionklijent koristi lookup() metod da bi dobio udaljeni objekat pridruen fajl-delu imenanpr. kada je dat URLrmi://login.ibiblio.org:2001/myRemoteObjectvratie objekat vezan za myRemoteObject iz login.ibiblio.org na portu 2001Metod izbacuje NotBoundException ako udaljeni server ne prepozna imeRemoteException ako udaljeni registry nije dostupan, npr. jer je mrea pala ili se ne izvrava registry servis na zadatom portuAccessException se izbacuje ako server odbije da potrai ime za odreeni hostAko URL nije odgovarajui rmi URL, izbacuje se MalformedURLExceptionpublic static void bind(String url, Remote object) throws RemoteException, AlreadyBoundException, MalformedException, AcessExceptionserver koristi bind() metod da povee ime, poput myRemoteObject sa udaljenim objektomAko je to uspeno, klijenti e moi da dobiju stub udaljenog objekta iz registry-ja koristei URL poputrmi://logib.ibiblio.org:2001/myRemoteObjectMalformedURLException ako url nije validan rmi URLRemoteException ako registry nije dostupanAccessException (potklasa od RemoteException) ako klijentu nije doputeno da vezuje objekte u registry-juAko je URL ve vezan za lokalni objekat AlreadyBoundExceptionpublic static void unbind(String url) throws....... rebind()...Klasa RMISecurityManagerklijent uitava stub-ove od potencijalnog nepoverljivog servera. U ovom smislu, odnos izmeu klijenta i stub-a je donekle poput veze izmeu browser-a i apleta. Iako je stub predvien samo da radi marshalling argumenata i unmarshalling povratne vrednosti i alje ih preko mree, sa stanovita VM, stub je samo jo 1 klasa sa metodima koji mogu uraditi bilo ta.stub-ovi kreirani pomou rmic ne bi trebalo da se ponaaju drugaije nego to je upravo opisano, ali nema razloga da neko ne moe da runo izmeni stub pa da on radi i uasne radnje kao to su itanje fajlova i brisanje podatakaJava VM ne doputa da se stub klase uitavaju preko mree osim ako postoji SecurityManager objekat (kao i druge klase, stub klase se mogu uvek uitati iz lokalnog class path)Za aplete, standardni AppletSecurityManager zadovoljava ovu potrebuAplikacije mogu koristiti klasu RMISecurityManager kako bi se zatitile od loe kreiranih stub-ova.public class RMISecurityManager extends SecurityManager

u Java 1.1 ova klasa implementira policy koji doputa da se klase uitaju sa serverovog codebase to nije nuno isto to i server, i omoguuje neophodnu mrenu komunikaciju izmeu klijenta, servera i codebase1.2 ne doputa ak ni to, previe restriktivna klasa, ak beskorisno1.5 Sun priznaje problem: RMISecurityManager implementira policy koja se ne razlikuje od one koju implementira SecurityManagerprema tome, RMI aplikacija treba da koristi klasu SecurityManager ili drugu SecurityManager implementaciju prilagoenu aplikacijiRemote Exceptionsu paketu java.rmi definisano je 16 izuzetakaveina je izvedena iz java.rmi.RemoteException (a on je izveden iz java.io.IOException)AlreadyBoundException i NotBoundException su izvedeni iz java.lang.ExceptionDakle, svi se ovi moraju hvatati1 runtime exception: RMISecurityException, potklasa od SecurityExceptionUdaljeni metodi zavise od mnogo stvari koje nisu pod naom kontrolom: npr. stanje mree i drugih neophodnih servisa kao to je DNS. Prema tome, svaki udaljeni metod moe da ne uspe: nema garancije da mrea nee pasti kada se pozove metod. Posledica toga je da svi udaljeni metodi moraju biti deklarisani tako da izbacuju RemoteException, a svi njihovi pozivi moraju biti u try-blokuKada samo elimo da program proradi, najjednostavnije je da hvatamo RemoteExceptionRobusniji programi treba da hvataju specifinije izuzetke i reaguju na prikladan nainklasa RemoteExceptionklasa poseduje 1 javno polje detailpublic Throwable detailkoje moe sadrati stvarni izuzetak izbaen na strani servera, pa daje blie informacije o tome ta ne valjaumesto direktnog korienja polja detail, metod getCause() se koristi od 1.4 i nadalje da vrati ugnjedeni izuzetak:try{ // call remote method ...}catch(RemoteException ex){ System.err.println(ex.getCause()); ex.getCause().printStackTrace();}paket java.rmi.registryKako klijent kome je potreban udaljeni objekat locira taj objekat na udaljenom serveru? Preciznije, kako on dobija udaljenu referencu na objekat?Klijenti saznaju koji udaljeni objekti su dostupni vrei upite nad registry-jem servera. Mogu dobiti reference na te objekteklasa java.rmi.Naming slui za interakciju sa registry-jemInterfejs Registry i klasa LocateRegistry omoguavaju klijentima da dobiju udaljene objekte sa servera po imenuRegistryImpl je potklasa od RemoteObject koja povezuje imena i odreene RemoteObject objekteKlijenti mogu koristiti metode klase LocateRegistry kako bi dobili RegistryImpl za odreeni host i port...LocateRegistry klasa, primeri korienjaNpr. udaljeni objekat koji eli da sebe uini dostupnim klijentima, mogao bi da uradi sledee:Registry r = LocateRegistry.getRegistry();r.bind(MyName, this);Udaljeni klijent koji eli da pozove ovaj udaljeni objekat moe onda rei:Registry r = LocateRegistry.getRegistry(thehost.site.com);RemoteObjectInterface tro = (RemoteObjectInterface) r.lookup(MyName);tro.invokeRemoteMethod();LocateRegistry, createRegistry() metodikreiraju registry i pokreu ga da oslukuje na zadatom portu. Svaki moe izbaciti RemoteException:

public static Registry createRegistry(int port) throws RemoteException

public static Registry createRegistry(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteExceptionpaket java.rmi.servernajsloeniji od svih RMI paketasadri sredstva za izgradnju udaljenih objekata te ga koriste objekti ije e metode klijenti pozivati6 izuzetaka, 9 interfejsa, 10-12 klasa (u zavisnosti od Java verzije)Na sreu, samo nekoliko od njih nam je potrebno da bismo pisali udaljene objekteBitne klase su RemoteObject (osnova za sve udaljene objekte), RemoteServer (izvedena iz RemoteObject), UnicastRemoteObject (izvedena iz RemoteServer)Svi udaljeni objekti koje piemo e verovatno ili koristiti ili naslediti UnicastRemoteObjectKlijenti koji pozivaju udaljene metode, ali sami po sebi nisu udaljeni objekti, ne koriste ove klase, pa samim tim ne moraju da importuju java.rmi.serverklasa RemoteObjectapstraktnatehniki, udaljeni objekat je instanca proizvoljne klase koja implementira Remote interfejs. U praksi, veina udaljenih objekata su instance potklasa od RemoteObjectstatiki metod RemoteObject.toStub():public static Remote toStub(Remote ro) throws NoSuchObjectExceptionkonvertuje dati udaljeni objekat u ekvivalentan stub objekat za korienje u klijentskoj VM, to moe biti od pomoi da dinamiki generiemo stub-ove iz servera, bez korienja rmicklasa RemoteServerapstraktna je i onanjena najee koriena potklasa je UnicastRemoteObjectmetod za lociranje klijenta sa kojim komuniciramo:public static String getClientHost() throws ServerNotActiveExceptionvraa String koji sadri hostname klijenta koji je pozvao metod koji se trenutno izvrava. Metod izbacuje ServerNotActiveException ako tekua nit ne izvrava udaljeni metodLogging: za svrhe debagovanja, ponekad je korisno videti pozive koji su izvreni na udaljenom objektu i njegove odgovorepublic static void setLog(OutputStream out)null kao argument iskljuuje logovanjePrimer. da bismo videli sve pozive na System.err piemomyRemoteServer.setLog(System.err);Ako elimo da dodamo ekstra informacije onima koje daje klasa RemoteServer, moemo dohvatiti PrintStream loga metodompublic static PrintStream getLog()Kada ga dobijemo, moemo njime pisati svoje dodatne komentare u log:PrintStream p = RemoteServer.getLog();p.println(There were + n + total calls to the remote object);klasa UnicastRemoteObjectDa bismo kreirali udaljeni objekat, nasleujemo UnicastRemoteObject i deklariemo da naa potklasa implementira neki podinterfejs od java.rmi.RemoteMetodi interfejsa obezbeuju funkcionalnost specifinu za klasu, dok metodi od UnicastRemoteObject rukuju optim zadacima udaljenog objekta poput marshalling-a i unmarshalling-a argumenata i povratnih vrednosti. Sve se ovo odvija iza scene. Kao programer aplikacije, mi ne moramo da brinemo o tome.UnicastRemoteObject se izvrava na jednom hostu, koristi TCP sokete za komunikaciju i ima udaljene refrence koje ne ostaju validne izmeu restartovanja servera.3 protected konstruktoraKada piemo potklasu od UnicastRemoteObject, zovemo jedan od njih, bilo eksplicitno bilo implicitno, u prvoj liniji svakog konstruktora nae potklase. Sva 3 konstruktora mogu izbaciti RemoteException ako udaljeni objekat ne moe biti kreiran.Konstruktor bez argumenata kreira UnicastRemoteObject koji oslukuje na anonimnom portu izabranom u vreme izvravanjaServer oslukuje na anonimnom portu. Normalno, ovakva situacija je besmislena jer je nemogue da klijenti lociraju server (pominjano u poglavljima 9 i 10). U ovom sluaju, klijenti lociraju server korienjem registry-ja koji prati dostupne servere i portove na kojima oni oslukuju.Loa strana oslukivanja na anonimnom portu je to firewall esto blokira konekcije na tom portu.Preostala 2 konstruktora oslukuju na zadatom portu, pa moemo traiti od mrenih administratora da dozvole saobraaj na tim portovima kroz firewallAko mreni administratori nisu kooperativni, moramo da koristimo HTTP tunneling ili proxy server ili obe te stvariexportObject() metodi...


Recommended