Obiektowe programowanie rozproszone Java RMI Krzysztof Banaś Systemy rozproszone 1
Java RMI Mechanizm zdalnego wywołania metod Javy (RMI Remote Method Invocation) posiada kilka charakterystycznych cech, m.in.: różną semantykę przesyłania obiektów, zależnie od ich rodzaju przesyłanie przez wartość dla obiektów lokalnych przesyłanie przez referencję dla obiektów zdalnych zdolność do pobierania kodu z odległych lokalizacji dzięki: przenośności kodu wykonywalnego Javy możliwościom maszyn wirtualnych Javy Krzysztof Banaś Systemy rozproszone 2
Java RMI Tworzenie rozproszonego obiektowego programu Javy składa się z podobnych kroków jak w przypadku innych środowisk RPC: definicja interfejsu tworzenie programu serwera implementującego realizację usług zdefiniowanych w interfejsie tworzenie programu klienta korzystającego z usług zdefiniowanych w interfejsie uruchomienie programu serwera uruchomienie programu klienta Krzysztof Banaś Systemy rozproszone 3
Java RMI Uruchomienie zdalnej usługi RMI wiąże się z dodatkowymi krokami, poza samym uruchomieniem programu serwera należy uprzednio uruchomić program rejestru RMI (rmiregistry), za pomocą którego program serwera dokonuje rejestracji utworzonego obiektu realizującego zdalny interfejs, a program klienta uzyskuje zdalną referencję do tego obiektu jeśli zachodzi taka potrzeba należy udostępnić kod klas, który będzie przesyłany pomiędzy maszynami wirtualnymi Javy, w tym kod skompilowanego zdalnego interfejsu Krzysztof Banaś Systemy rozproszone 4
Java RMI Krzysztof Banaś Systemy rozproszone 5
Przykład interfejs RMI package compute; import java.rmi.remote; import java.rmi.remoteexception; public interface Compute extends Remote { <T> T executetask(task<t> t) throws RemoteException; Krzysztof Banaś Systemy rozproszone 6
Przykład Interfejs Compute zakłada, że zdalne obiekty implementujące go będą realizowały procedurę executetask, przy czym obiekt zadania zostanie przesłany jako argument procedury Ażeby umożliwić takie działanie definicja interfejsu Task (implementowanego przez obiekt zadania) także musi być dostępna wraz z definicją interfejsu Compute: package compute; public interface Task<T> { T execute(); Krzysztof Banaś Systemy rozproszone 7
Przykład serwer RMI package engine; import java.rmi.remoteexception; import java.rmi.registry.locateregistry; import java.rmi.registry.registry; import java.rmi.server.unicastremoteobject; import compute.compute; import compute.task; public class ComputeEngine implements Compute { public ComputeEngine() { super(); public <T> T executetask(task<t> t) { return t.execute(); /* procedura main */ Krzysztof Banaś Systemy rozproszone 8
Przykład serwer RMI public static void main(string[] args) { if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); try { String name = "Compute"; Compute engine = new ComputeEngine(); Compute stub = (Compute) UnicastRemoteObject.exportObject(engine, 0); Registry registry = LocateRegistry.getRegistry(); registry.rebind(name, stub); System.out.println("ComputeEngine bound"); catch (Exception e) { System.err.println("ComputeEngine exception:"); e.printstacktrace(); Krzysztof Banaś Systemy rozproszone 9
Przykład definicja klasy implementującej package client; import compute.task; import java.io.serializable; import java.math.bigdecimal; public class Pi implements Task<BigDecimal>, Serializable { private static final long serialversionuid = 227L; private final int digits; public Pi(int digits) { this.digits = digits; public BigDecimal execute() { return computepi(digits); /** Kod obliczenia Pi definicja funkcji computepi */ Krzysztof Banaś Systemy rozproszone 10
Przykład program klienta package client; import java.rmi.registry.locateregistry; import java.rmi.registry.registry; import java.math.bigdecimal; import compute.compute; 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(); Krzysztof Banaś Systemy rozproszone 11
Przykład uruchomienie kodu System serwera: uruchomienie programu rmiregistry uruchomienie programu serwera informacja o miejscu przechowania klas serwera adres internetowy systemu, w ramach którego funkcjonują obiekty serwera pliki zawierające definicje strategii zapewniania bezpieczeństwa System klienta uruchomienie programu klienta informacja o miejscu przechowywania potrzebnych klas klienta pliki zawierające definicje strategii zapewniania bezpieczeństwa adres internetowy serwera (jeśli nie jest dostarczony inaczej) Krzysztof Banaś Systemy rozproszone 12