Download JAVA - RMI - PoliformaT

Document related concepts
no text concepts found
Transcript
Diseño Y Aplicaciones de Sistemas Distribuidos
Invocación de métodos remotos
en Java:
JAVA - RMI
Joan Vila
DISCA / UPV
Departament d’Informàtica de Sistemes i Computadors
Universitat Politècnica de València
JAVA-RMI

JAVA-RMI: Java Remote Method Invocation
– Sistema de invocación de métodos remotos que (a diferencia de CORBA)
asume un entorno homogéneo de Máquina Virtual Java.
– Proporciona un modelo de objetos distribuidos similar al de Java,
integrándolo en el lenguaje de manera natural. En este sentido permite:

Invocar métodos de interfaces remotas

Pasar una referencia a un objeto remoto en una invocación (local o remota)

Soportar callbacks de servidores a Applets.
– Presenta algunas limitaciones respecto al modelo de objetos de Java


Los clientes siempre interaccionan con las interfaces, nunca con las
implementaciones.
Los argumentos no remotos de la invocaciones y los resultados siempre se
pasan por copia, nunca por referencia.

Los objetos remotos se pasan por referencia no por copia

Existen excepciones adicionales que pueden ocurrir durante una RMI.
Procesamiento distribuido en Java
© Joan Vila
51
Java-RMI

Arquitectura de JAVA-RMI
Server object
Client object
Skeletons
Stubs
Objects references level
Transport level
Procesamiento distribuido en Java
© Joan Vila
52
Java-RMI

Concurrencia en Java-RMI
Cuando varios clientes invocan métodos concurrentemente sobre un objeto
servidor son, en general, ejecutados por diferentes hilos.
– Invocaciones de clientes diferentes son siempre ejecutadas en hilos
diferentes.
– Invocaciones del mismo cliente pueden no ser ejecutadas por hilos
diferentes dependiendo de la implementación de la máquina virtual.
Client object
Server object
Client object
Procesamiento distribuido en Java
© Joan Vila
53
Java-RMI

Generación de stubs y skeletons
– Generados automáticamente por un preprocesador llamado rmic
– Se generan a partir del fichero de implementación del objeto servidor (no a
partir de su interfaz)

Servicio de nombres
– Los nombres no son transparentes a la ubicación:
//host/objectName
– Se accede a través de la clase java.rmi.Naming

Cliente: Remote ref = Naming.lookup("//" +host + "/NombreObjeto");

Servidor: Naming.rebind("//" + myURL + "/NombreObjeto", obj);
– En todo host donde residan servicios, debe ejecutarse un servidor de
nombres, llamado rmiregistry. Este servidor sólo mantiene entradas
de servicios locales.
Procesamiento distribuido en Java
© Joan Vila
54
Java-RMI
Client
Server
Interface
javac
lookup
Client
rebind
rmi
registry
Stub
Server
javac
Server
Skeleton
rmic
Procesamiento distribuido en Java
© Joan Vila
55
Java-RMI

Objetos como argumentos en invocaciones
– Los objetos se pueden pasar por valor o por referencia en las
invocaciones a métodos remotos.
 Paso por valor: los objetos locales se pasan por valor (migration)
 Pass by reference: los objetos remotos se pasan por referencia
– Serializacion de objetos: Java-RMI dispone de un sofisticado
mecanismo de serialización que permite convertir objetos en secuencias
de bytes aptos de ser enviados por un OutputStream como,p.e., un
socket.
– Los objetos pasados por valor deben implementar la interfaz
Serializable.
class aClass implements java.io.Serializable;
aclass X;
ObjectOutputStream
ObjectOutputStream(sock.getOutputStream());
Procesamiento
distribuido en Java
os.writeObject(x);
os = new
© Joan Vila
56
Java-RMI

Clases e interfaces RMI
Defined in packages
java.rmi and java.rmi.server
Interfaces
Classes
Remote
RemoteObject
IOException
RemoteServer
RemoteException
extends
UnicastRemoteObject
Procesamiento distribuido en Java
Implements
© Joan Vila
57
Java-RMI

Clases e interfaces RMI
– Todos los objetos servidores RMI deben declarar un interfaz. Este interfaz
debe ser subclase de java.rmi.remote.

Obliga a propagar excepciones de comunicación en la declaración de
métodos.
– La clase java.rmi.server.RemoteObject proporciona la
semántica de la clase Object para objetos remotos:

igualdad, conversión a String
– La clase java.rmi.server.RemoteServer
métodos para crear y exportar objetos.
proporciona
– La clase UnicastRemoteObject es una especialización de la
anterior que proporciona soporte para invocar objetos (no replicados).
Procesamiento distribuido en Java
© Joan Vila
58
Un ejemplo en Java-RMI (i)

Un ejemplo simple
– La aplicación echo

La interfaz del servicio
de
a
red ote
e
H em
R
public interface EchoIntRMI extends java.rmi.Remote {
String echo(String aString) throws java.rmi.RemoteException;
}
Procesamiento distribuido en Java
Ex
c
es epc
pe ion
cíf
ica es
s
© Joan Vila
59
Un ejemplo en Java-RMI (i)

El cliente de echo
Java siempre resuelve las referencias remotas en tiempo de ejecución
(late binding).
Interfaz
objeto
remoto }
public interface EchoIntRMI extends java.rmi.Remote { ...
...
Binding
ing
Narrow
Remote ref = Naming.lookup("//" +host + "/EchoObject");
EchoIntRMI eo = (EchoIntRMI) ref;
eo.echo(“hola”);
Procesamiento distribuido en Java
ces
a
f
r
inte
e
d
o
álog
t
a
C
© Joan Vila
60
Un ejemplo en Java-RMI (i)
package RMI.Echo;
import java.io.*;
import java.rmi.*;

El cliente de echo
EchoRMI.java
public class EchoRMI {
public static void main(String[] args) {
if (args.length<1) {
System.out.println("Usage: Echo <host>"); System.exit(1);
}
try {
EchoIntRMI obj = (EchoIntRMI) Naming.lookup("//"+args[0]+"/EchoObject");
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String input,output;
while ((input = stdIn.readLine()) != null) {
output = obj.echo(input);
System.out.println("echo: " + output);
}
} catch (Exception e) {
System.out.println("EchoRMI exception: " + e.getMessage());
}
}
}
Procesamiento distribuido en Java
© Joan Vila
61
Un ejemplo en Java-RMI (i)

El objeto echo (i)
EchoObjectRMI.java
package RMI.Echo;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.net.InetAddress;
public class EchoObjectRMI
extends UnicastRemoteObject implements EchoIntRMI
{
public EchoObjectRMI() throws RemoteException {
super();
}
public String echo(String aString) throws RemoteException {
return aString;
}
Procesamiento distribuido en Java
Implementa
el interfaz
Constructor
Proporcionar
implementacion
a los métodos
© Joan Vila
62
Un ejemplo en Java-RMI (i)
El objeto echo (i): método main

public static void main(String args[]) {
System.setSecurityManager(new RMISecurityManager());
String myURL="localhost";
try {
EchoObjectRMI obj = new EchoObjectRMI();
myURL=InetAddress.getLocalHost().getHostName();
Naming.rebind("//" + myURL + "/EchoObject", obj);
} catch (Exception e) {
System.out.println("EchoObject error: " + e.getMessage())
Instanciar un
Gestor Seguridad
Instanciar
la clase
Registrar objeto
en el servicio
de nombres
}
}
}
Procesamiento distribuido en Java
© Joan Vila
63
JAVA-RMI

“Migración” de objetos
– La aplicación ComputeEngine
Enviar Tarea
ComputePi
Cliente
Compute
Engine
Devolver resultado
Procesamiento distribuido en Java
© Joan Vila
64
Un ejemplo en Java-RMI (ii)

“Migración” de objetos
Definición de interfaces (i): el objeto servidor
package compute;
Compute.java
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Compute extends Remote {
Object executeTask(Task t) throws RemoteException;
}
Procesamiento distribuido en Java
Hereda de
Remote
© Joan Vila
65
Un ejemplo en Java-RMI (ii)

“Migración” de objetos
Definición de interfaces (ii): la tarea a migrar
package compute;
Task.java
import java.io.Serializable;
public interface Task extends Serializable {
Object execute();
}
Procesamiento distribuido en Java
Hereda de
Serializable
© Joan Vila
66
Un ejemplo en Java-RMI (ii)

“Migración” de objetos
El objeto servidor (i)
package engine;
ComputeEngine.java
import java.rmi.*;
import java.rmi.server.*;
import compute.*;
public class ComputeEngine extends UnicastRemoteObject
implements Compute {
public ComputeEngine() throws RemoteException {
super();
}
a de
d
e
r
e
H
bject
O
e
t
o
stRem
a
c
i
n
U
Implementa
Compute
public Object executeTask(Task t) {
return t.execute();
}
Procesamiento distribuido en Java
© Joan Vila
67
Un ejemplo en Java-RMI (ii)

“Migración” de objetos
El objeto servidor (ii): el método main
ComputeEngine.java
...
public class ComputeEngine extends UnicastRemoteObject
implements Compute {
ar
...
stal er
n
i
r e anag
a
e
public static void main(String[] args) {
r
C
M
rity
u
c
if (System.getSecurityManager() == null) {
Se
System.setSecurityManager(new RMISecurityManager());
}
String name = "//localhost/Compute";
try {
Compute engine = new ComputeEngine();
Registrar objeto
en servidor de
Naming.rebind(name, engine);
nombres
System.out.println("ComputeEngine bound");
} catch (Exception e) {
Procesamiento distribuido en Java
© Joan Vila
68
Un ejemplo en Java-RMI (ii)

“Migración” de objetos
El cliente (i): el método main
package client;
ComputePi.java
import java.rmi.*;
import java.math.*;
import compute.*;
public class ComputePi {
lar
a
t
s
n
r e i anager
a
public static void main(String args[]) {
e
r
C
M
rity
u
c
if (System.getSecurityManager() == null) {
Se
System.setSecurityManager(new RMISecurityManager());
}
...
Procesamiento distribuido en Java
© Joan Vila
69
Un ejemplo en Java-RMI (ii)

“Migración” de objetos
El cliente (ii): el método main
package client;
...
ComputeEngine.java
to
e
j
public class ComputePi {
ob r de
r
public static void main(String args[]) {
ca ido s
s
v
Bu ser bre
...
en nom
try {
String name = "//" + args[0] + "/Compute";
Compute comp = (Compute) Naming.lookup(name);
Instancia
Pi task = new Pi(Integer.parseInt(args[1]));
de task
BigDecimal pi = (BigDecimal) (comp.executeTask(task));
System.out.println(pi);
Invoca
r obje
} catch (Exception e) {
to
System.err.println("ComputePi exception: " + e.getMessage());
e.printStackTrace();
}
}
}
Procesamiento distribuido en Java
© Joan Vila
70
Un ejemplo en Java-RMI (ii)

“Migración” de objetos
El cliente (ii): la tarea Pi
package client;
import compute.*;
import java.math.*;
Pi.java
public static BigDecimal calculatePi(int digits) {
...
}
public class Pi implements Task {
}
...
Imp
lem
private int digits;
enta
de
public Pi(int digits) {
this.digits = digits;
}
public Object execute() {
return calculatePi(digits);
}
Procesamiento distribuido en Java
Tas
k
Implementa el
método
execute
© Joan Vila
71