1 / 30

Programowanie sieciowe w Javie RMI

Programowanie sieciowe w Javie RMI. Wykład 11. mgr inż. Michał Misiak. Remote Method Invocation. RMI jest to API, które pozwala na zdalne wywoływanie procedur RPC (Remote Procedure Calls) w ramach JVM JVM mogą być rozmieszczone na różnych maszynach

garran
Download Presentation

Programowanie sieciowe w Javie RMI

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programowanie sieciowe w JavieRMI Wykład 11 mgr inż. Michał Misiak

  2. Remote Method Invocation • RMI jest to API, które pozwala na zdalne wywoływanie procedur RPC (Remote Procedure Calls) w ramach JVM • JVM mogą być rozmieszczone na różnych maszynach • Aplikacje RMI składają się z dwóch elementów serwera i klienta • Aplikacje nazywane są distributed object application • RMI pozwala na dynamiczne ładowanie definicji klas (stan + zachowanie) – możliwość zdalnego rozszerzenia funkcjonalności rozproszonych aplikacji • Początkowo RMI API zostało zaprojektowane do wspierania różnych rodzajów transportu np. HTTP.

  3. Serwer: tworzy zdalne obiekty i udostępnia na nie referencje oczekuje na wywołanie metod na tych obiektach przez klienta Klient: uzyskuje referencje na jeden bądź więcej obiektów zdalnych umieszczonych na serwerze woła metody na zdalnych obiektach Serwer i Klient RMI

  4. Funkcje Distributed Object Apps • Lokalizacja zdalnych obiektów. • Wiele sposobów na uzyskanie referencji np. obiekty mogą zostać zarejestrowane w usłudze nazw RMI-Registry lub referencja może zostać przekazana podczas wywoływania innej zdalnej metody. • Komunikacja ze zdalnymi obiektami • Komunikacja ze zdalnymi obiektami obsługiwana jest bezpośrednio przez RMI. Dla programisty komunikacja RMI wygląda identycznie jak wołanie metod. • Załadowanie definicji klas • Możliwość załadowania definicji klasy lub przesłania jej po przez sieć.

  5. Komunikacja RMI JVM 2 JVM 1 RMI, 2 rmiregistry Klient RMI RMI, 1 RMI, 3 1 – zarejestrowanie zdalnego obiektu w usłudze nazw 2 – uzyskanie referencji do Obiektu o żądanej nazwie 3 – wywołanie metody na zdalnym obiekcie Serwer RMI

  6. Zdalne interfejsy obiekty i metody • Rozproszone aplikacje RMI składają się z interfejsów i klas. Klasy implementują metody z interfejsów oraz ew. dodatkowe • Obiekty, których metody mogą być wołane po przez zewnętrzną JVM nazywają się zdalnymi obiektami (remote object) • Obiekt staje się obiektem zdalnym w wyniku implementacji zdalnego interfejsu, a interfejs ten ma następujące cechy: • rozszerza java.rmi.Remote • każda z metod interfejsu deklaruje java.rmi.RemoteException

  7. Zdalne wołanie metod Remote JVM Local JVM SIEĆ Klient Serwer Rozliczeniowy wypłac_pieniadze(instancja pieniadza) STUB SKELETON RMI Runtime RMI Runtime

  8. Stub i Skeleton • Klient woła zdalną metodę, wywołanie przekazywane jest do STUB’a • STUB jest odpowiedzialny za przesłanie zdalnego wywołania do leżącego po stronie serwera SKELETON’a • STUB otwiera gniazdo dla zdalnego serwera, serializuje parametry obiektu i przekazuje strumień danych do SKELETON’u • SKELETON zawiera metodę, która odbiera zdalne wywołanie, odtwarza zserializowane parametry i wywołuje rzeczywistą zdalną implementację obiektu.

  9. Kroki przy tworzeniu aplikacji RMI • Projekt i implementacja komponentów rozproszonej aplikacji RMI • Kompilacja źródeł • Generacja Stub i Skeleton • Uczynienie klas dostępnych po przez sieć • Uruchomienie rmiregistry • Uruchomienie aplikacji

  10. Projektowanie i implementacja komponentów • Określenie, które komponenty są lokalne, a które zdalne • Definicja zdalnych interfejsów. Określają metody, które będą mogły być wołane zdalnie przez klienta. • Implementacja zdalnych obiektów. Zdalny obiekt musi implementować jeden bądź, więcej zdalnych interfejsów. Jeśli jakaś lokalna klasa jest przekazywana jako parametr bądź zwracana jako wartość musi zostać zaimplementowana jako zdalna. • Implementacja klienta.

  11. Uczynienie klas dostępnych przez sieć • Jednym ze sposobów jest umieszczenie skompilowanych klas na web serwerze.

  12. Przykładowy projekt aplikacji RMI • Nazwa projektu Compute Engine (CE), Java Sun Tutorial • CE jest obiektem na serwerze, który otrzymuje od klienta różnego rodzaju zdania, dokonuje ich przeliczenia i zwraca wynik • CE charakteryzuje się dużą elastycznością realizowanych zdań i może być wykorzystywany przez wielu klientów • Oczywiście zbiór zdań nie musi być predefiniowany w momencie uruchamiania, czy też pisania silnika • Wymaganie! Klasa reprezentująca zadanie musi implementować predefiniowane interfejsy. • Aplikacja CE nie musi mieć świadomości zawartości zadania, klasy ładowane są dynamicznie – takie aplikacje nazywają się behavior-based application

  13. Projekt zdalnego interfejsu • Głównym element służącym komunikacji pomiędzy klientem, a serwerem jest protokół, który reprezentowany jest przez zdalny interfejs • Compute Interfece pozwala na wykonywanie metod przez CE. Implementując interfejsu java.rmi.Remote wskazuje na to, że jest zdalny. • Task Interface mówi o tym jak powinno zostać dane zadanie wykonane. Jest parametrem, który jest umieszczany w metodzie executeTask(Task)

  14. Compute & Task interface Implementacja tego interfejsu mówi, że dany komponent jest zdalny. Compute Interface wyjątek rzucany przez RMI, w np. przypadku utraty komunikacji package compute; import java.rmi.Remote; import java.rmi.RemoteException; public interface Compute extends Remote { <T> T executeTask(Task<T> t) throws RemoteException; } Task Interface package compute; public interface Task<T> { T execute(); } Uwaga! Obiekty przenoszone są po przez wartość. Generyczny typ zwracany po wykonaniu zdania.

  15. Implementacja zdalnych interfejsów • Klasa reprezentująca zdalny obiekt powinna: • Deklarować zdalne interfejsy • Definiować konstruktor dla każdego zdalnego obiektu • Implementować metody zdalnego interfejsu • Inicjalizacja zdalnego obiektu i eksport do RMI runtime w ramach RMI serwera • utworzenie i instalacja security manager • utworzenie i eksport zdalnych obiektów • Rejestracja przynajmniej jednego obiektu w rmiregistry lub innej usłudze nazw np. JNDI ComputeEngine.java

  16. Deklaracja zdalnego interfejsu i jego implementacja • Deklaracja implementacji zdalnego interfejsu: • public class ComputeEngine implements Compute • Konstruktor ComputeEngine oraz metoda main mogą być wołane jedynie lokalnie. • Metoda main tworzy instancje ComputeEngine i czyni ją dostępną dla klienta • Konstruktor woła bezparametrowo konstruktor klasy bazowej

  17. Implementacja zdalnych metod public <T> T executeTask(Task<T> t) { return t.execute(); } Implementacja metody executeTask tworzy swego rodzaj protokół pomiędzy klientem a serwerem. Parametr typu Task musi implementować interfejs, który posiada metodę execute.

  18. Umieszczanie obiektów w RMI • Każdy typ argumentu lub wartości zwracanej może być przekazywany w sytuacji, gdy jest: prymitywnym typem, zdalnym obiektem, typem, który może być zserializowany • Obiekty typów takich jak: wątki, deskryptory pliku – nie mogą być serializowane • Dana klasa jest serializowana, wówczas, gdy implementuje interfejs Serializable • Obiekty zdalne przekazywane są przez referencje. Referencja na zdalny obiekt to STUB. • STUB – proxy po stronie klienta, który implementuje pełen zbiór interfejsów zdalnych, implementowanych przez obiekt zdalny • Obiekty lokalne przekazywane są jako kopie, wykorzystując serializację. • Wszystkie pola są kopiowane z wyjątek transient i static. • W przypadku przekazywania obiektu zdalnego, dostępne są wyłącznie interfejsy zdalne dla zdalnego JVM. Metody w ramach interfejsów nie-zdalnych nie będą widoczne dla zdalnego JVM.

  19. Implementacja metody main • Wykorzystywana do uruchomienia ComputeEngine – musi zainicjalizować wybrane komponenty: • Utworzenie i instalacja Security Manager • Uczynienie obiektów zdalnych widocznych dla klienta

  20. Utworzenie i instalacja Security Manager • Chroni system przez niezaufanymi źródłami • Określa prawa dostępu do zasobów: wykonywanie określonych poleceń, korzystanie z lokalnego systemu plików • Niezainstalowanie SM uniemożliwi ściągnięcie klas dla parametrów przekazywanych w zdalnym wywołaniu lub zwracanych Tworzenie i instalowanie SM if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }

  21. Udostępnianie zdalnych obiektów klientowi • UnicastRemoteObject.exportObject – • metoda eksportuje dostarczone zdalne obiekty, tutaj jest to engine • drugi parametr to port TCP. Wartość 0 oznacza port anonimowy – port jest wybierany przez system, bądź przy starcie RMI • poprawne wykonanie metody exportObject pozwala na wykonywanie zdalnych wywołań przez ComputeEngine • typ na który jest rzutowanie to Compute, gdyż Compute jest interfejsem zdalnym • metoda exportObject może rzucić wyjątkiem RemoteException • Wyjątek RemoteException jest rzucany w przypadku braku zadeklarowanych zasobów, np. wybrany port jest już wykorzystywany. Compute engine = new ComputeEngine(); Compute stub = (Compute) UnicastRemoteObject.exportObject(engine, 0);

  22. rmiregistry • Jest to szczególny typ obiektu zdalnego, który służy do znajdowywania referencji na inne zdalne obiekty po przez nazwę • rmiregistry służy przeważnie do znajdowania pierwszego zdalnego obiektu, za pomocą którego będą uzyskane referencje na inne zdalne obiekty • Wywołanie metody getRegistry bez parametrów powoduje założenie rejestru na lokalnej maszynie na porcie 1099 • Utworzony obiekt ComputeEngine nie jest nigdy przekazywany. Następuje przekazanie wyłączenie STUB w wyniku wyszukania danego obiektu zdalnego w rejestrze nazw • Nie jest konieczne utrzymywanie przy życiu obiektu ComputeEngine. Dopóki istnieje referencja na ComputeEngine w innej JVM dopóty serwer nie zostanie wyłączony. Registry registry = LocateRegistry.getRegistry(); registry.rebind(name, stub);

  23. Program klienta • Na kliencie wymagana jest definicja zadania, które zostanie wykonane zdalnie • Klasa ComputePi wyszukuje i wywołuje obiekt Compute • Klasa Pi implementuje interfejs zadania (Task Interface) oraz definiuje pracę, która powinna zostać wykonana przez ComputeEngine public interface Task<T> { T execute(); }

  24. Interfejs Task i klasa ComputePi public interface Task<T> { T execute(); } Nazwa hostu, na którym Compute jest uruchomione public class ComputePi { public static void main(String args[]) { if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } try { String name = "Compute"; Registry registry = LocateRegistry.getRegistry(args[0]); Compute comp = (Compute) registry.lookup(name); Pi task = new Pi(Integer.parseInt(args[1])); BigDecimal pi = comp.executeTask(task); System.out.println(pi); } catch (Exception e) { System.err.println("ComputePi exception:"); e.printStackTrace(); } } }

  25. Mechanizm działania ComputeEngine • Uwaga! • Każda zseralizowana klasa musi deklarować • zmienną statyczną serialVersionUID w celu • zapewnienia kontroli wersji serializacji Registry.lookup rmiregistry ComputePi Registry.rebind Compute.executeTask ComputeEngine

  26. Kompilacja interfejsów • Projekt został podzielony na 3 pakiety: • compute – zawiera interfejsy Compute and Task • engine – implementacja klasy ComputeEngine • client – zawiera kod klienta ComputePi oraz implementacje zadania Pi • Stworzenie JAR z interfejsów • javac compute\Compute.java • compute\Task.java jar cvf compute.jar compute\*.class • Umieszczenie plików w ogólnie dostępnym z sieci miejscu

  27. Kompilacja serwera • Kompilacja: • javac -cp c:\home\ann\public_html\classes\compute.jar engine\ComputeEngine.java

  28. Kompilacja klienta • Kompilacja: • javac -cp c:\home\jones\public_html\classes\compute.jar client\ComputePi.java client\Pi.java • Klasę Pi należy ponownie skompilować ponieważ ma być dostępna dla serwera.

  29. Specyfikacja Security Manager Dla serwera: grant codeBase "file:/home/ann/src/" { permission java.security.AllPermission; }; Wszelkie przyzwolenia dla kodu znajdującego się w katalogu źródłowym Dla klienta: grant codeBase "file:/home/jones/src/" { permission java.security.AllPermission; };

  30. Uruchomienie serwera i klienta • Uruchomienie rejsteru RMI • start/javaw rmiregistry Uruchomienie serwera java -cp c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar -Djava.rmi.server. codebase=file:/c:/home/ann/public_html/classes/compute.jar -Djava.rmi.server. hostname=zaphod.east.sun.com -Djava.security.policy=server.policy engine.ComputeEngine Uruchomienie klienta java -cp c:\home\jones\src;c:\home\jones\public_html\classes\compute.jar -Djava.rmi.server.codebase=file:/c:/home/jones/public_html/classes/ -Djava. security.policy=client.policy client.ComputePi zaphod.east.sun.com 45

More Related