Obiektowe programowanie rozproszone Java RMI

Transkrypt

Obiektowe programowanie rozproszone Java RMI
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