Você está na página 1de 11

Llamada a m

etodos remotos (RMI).


Curso 04/05

LP (Telematica)
Universitat de Val`encia

Tema 9
Llamada a m
etodos remotos (RMI).
Departament dInform`
atica. Universitat de Val`encia

Indice
1. Introducci
on

1.1. C
omo funciona RMI? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2. Usando RMI

2.1. Fase de desarrollo: el servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.1.1. Creaci
on de una interface que describe el servicio . . . . . . . . . . . . . . . . . . . . . . .

2.1.2. Implementaci
on de la interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.1.3. Generaci
on de stub (SDK 1.2) o stub y skeleton (SDK 1.1) . . . . . . . . . . . . . . . . .

2.1.4. Clase que crea una instancia del servicio y la registra . . . . . . . . . . . . . . . . . . . . .

2.2. Fase de ejecuci


on: el servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.2.1. Iniciar rmiregistry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.2.2. Iniciar el servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.3. Fase de desarrollo: el cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.3.1. Creaci
on del cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.4. Fase de ejecuci


on: el cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.4.1. Iniciar el cliente

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.5. Una situaci


on realista: carga din
amica clases

juan.gutierrez@uv.es

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9
9

P
agina: 1

Llamada a m
etodos remotos (RMI).
Curso 04/05

1.

LP (Telematica)
Universitat de Val`encia

Introducci
on

Que es RMI (Remote Method Invocation)? Es una tecnologa Java que permite enviar mensajes a
objetos situados en otra maquina virtual desde una aplicaci
on que este ejecut
andose en una maquina
virtual.
En su version basica requiere que toda la aplicaci
on (tanto el cliente como el servidor) esten
desarrollados en Java.

Maquina Virtual
M
aquina Virtual

metodo1()

Cliente RMI

Servidor RMI

n
Respuesta

Objeto remoto
metodo1()

Esto permite tener los objetos distribuidos en diversas m


aquinas.
Esta tecnologa permite que se puedan pasar argumentos al metodo remoto y recibir los datos que
devuelve (en ambos casos pueden ser tipos primitivos u objetos de clases que sean serializables).
Cada servicio RMI (objeto remoto) se define mediante una interface, que fija los metodos que se
pueden invocar en el objeto remoto.
Esta interface debe estar disponible en el cliente y en el servidor.
La tecnologa RMI no es un concepto nuevo. Antes de la programaci
on orientada a objetos exista
tecnologa que permita realizar llamadas a funciones y procedimientos remotos (RPC, Remote Procedure Calls).
En sistemas orientados a objetos tambien se puede utilizar CORBA (Common Object Request Broker Arquitecture o Arquitectura Com
un de Agente de Solicitud de Objetos) que soportan la utilizaci
on
de diferentes lenguajes.
Java soporta RMI sobre IIOP (Internet Inter-ORB) con lo cual es posible integrar RMI con CORBA.

1.1.

C
omo funciona RMI?

Los sistemas que utilizan RMI se dividen en dos categoras: clientes y servidores.
El servidor proporciona un servicio RMI y el cliente llama a metodos del objeto ofrecido por el
servicio.

juan.gutierrez@uv.es

P
agina: 2

Llamada a m
etodos remotos (RMI).
Curso 04/05

LP (Telematica)
Universitat de Val`encia

El servicio RMI se debe registrar en un servicio de consulta para permitir a los clientes encontrar
el servicio.
El J2SE incluye una aplicacion llamada rmiregistry, que lanza un proceso que permite registrar
servicios RMI mediante un nombre. Este nombre identifica al servicio, esto se hace as ya que en una
maquina puede haber diferentes servicios.
Una vez que el servicio se ha registrado, el servidor esperar
a a que lleguen peticiones RMI desde
los clientes.
El cliente solicita el servicio mediante el nombre con el que fue registrado y obtiene una referencia
al objeto remoto.
El formato utilizado por RMI para representar una referencia al objeto remoto es el siguiente
rmi://hostname:puerto/nombreServicio

Una vez obtenida la referencia remota (ya sea mediante rmiregistry, leyendo el URL de un archivo,...)
los clientes pueden enviar mensajes como si se tratase de objetos ejecutandose en la misma m
aquina
virtual.
Los detalles de red de las peticiones y las repuestas son transparentes para el desarrollador. Esto
se consigue mediante el uso de stub (a partir de la versi
on 1.2, ya que en la versi
on 1.1 se requera
generar un skeleton).
Las capas de la arquitectura RMI son las siguientes:

Capa de stub y skeletons


La capa de stub y skeletons se sit
ua bajo la aplicaci
on. En esta capa, RMI utiliza el patr
on de
dise
no Proxy. En el patron Proxy, un objeto en un contexto es representado por otro (el proxy) en un
contexto separado.
En el uso que se hace en RMI del patr
on proxy, la clase stub realiza el papel del proxy de la
implementacion del servicio remoto.
Mediante la utilizacion de este patron es posible acceder al servicio como si se tratase de objetos
locales.
juan.gutierrez@uv.es

P
agina: 3

Llamada a m
etodos remotos (RMI).
Curso 04/05

LP (Telematica)
Universitat de Val`encia

Antes de que el stub pase una peticion al servicio remoto debe agrupar los par
ametros (ya sean
tipos primitivos, objetos o ambos) para la transmisi
on, operaci
on conocida como marshalling.
La clase skeleton es una clase generada por RMI. Esta clase es la responsable de comunicarse con el
stub durante la comunicacion RMI. Debe reconstruir los par
ametros para formar los tipos primitivos
y objetos, lo que es conocido como unmarshalling.
A partir de la version 1.2 del SDK, el nuevo protocolo utilizado para RMI no necesita la clase
skeleton.

Capa de Referencia Remota


Esta capa es utilizada por la capa de stub y skeleton. Es la capa responsable del funcionamiento
independientemente de la la capa de transporte que se este utilizando.
Esta capa proporciona un objeto RemoteRef que representa la conexi
on con el objeto remoto.
El objeto stub utiliza el metodo invoke() de RemoteRef para enviar las llamadas a los metodos del
objeto remoto.

Capa de Transporte
La capa de transporte realiza la conexi
on entre las m
aquinas virtuales. Todas las conexiones son
conexiones de red basadas en flujos que utilizan TCP/IP.
Sobre TCP/IP, RMI utiliza un protocolo llamado Java Remote Method Protocol (JRMP).
Sun e IBM han trabajado de forma conjunta para obtener la nueva versi
on de RMI llamada RMIIIOP, en la que se puede trabajar con el protocolo IIOP en lugar de JRMP para comunicar clientes y
servidores.

2.

Usando RMI

2.1.
2.1.1.

Fase de desarrollo: el servidor


Creaci
on de una interface que describe el servicio

En este ejemplo, el objeto remoto va a ofrecer un u


nico metodo getMensaje() que devuelve un String.
La interface que describe el servicio es la siguiente (debe extender a la interface Remote).

juan.gutierrez@uv.es

P
agina: 4

Llamada a m
etodos remotos (RMI).
Curso 04/05

LP (Telematica)
Universitat de Val`encia

i m p o r t j a v a . rmi . ;
/ I n t e r f a c e que d e s c r i b e e l s e r v i c i o RMI
D e f i n e l o s m
e todos que s e pueden l l a m a r d e s d e e l c l i e n t e
/
p u b l i c i n t e r f a c e Saludo e x t e n d s Remote {
/ Metodo que s e d e b e implementar
@return una S t r i n g
@throws RemoteException
/
p u b l i c S t r i n g g e t M e n s a j e ( ) t h r o w s RemoteException ;
}

Compilamos:
j a v a c Saludo . j a v a

2.1.2.

Implementaci
on de la interface

El siguiente paso a realizar es crear una clase que implemente a la interface anterior.
Esta clase puede extender a una de las siguientes clases:

UnicastRemoteObject si el objeto va a estar ejecut


andose en la m
aquina virtual remota.
Activatable si el objeto se cargar
a en la m
aquina virtual remota cuando alg
un cliente enve un

mensaje.

En el ejemplo mostrado optamos por la primera opci


on.
Esta clase puede tener otros metodos aparte de los especificados en la interface pero no podr
an ser
llamados por el cliente.
i m p o r t j a v a . rmi . s e r v e r . ;
i m p o r t j a v a . rmi . ;
/ C l a s e que implementa a l a i n t e r f a c e que d e s c r i b e e l s e r v i c i o
/
p u b l i c c l a s s SaludoImpl e x t e n d s UnicastRemoteObject
i m p l e m e n t s Saludo {
p r i v a t e S t r i n g cadena ;
p u b l i c SaludoImpl ( ) t h r o w s RemoteException {
cadena = Mensaje d e s d e e l s e r v i d o r RMI ;
}
/ Metodo d e f i n i d o en l a i n t e r f a c e S a l u d o /
p u b l i c S t r i n g g e t M e n s a j e ( ) t h r o w s RemoteException {
r e t u r n cadena ;
}
}

juan.gutierrez@uv.es

P
agina: 5

Llamada a m
etodos remotos (RMI).
Curso 04/05

LP (Telematica)
Universitat de Val`encia

Compilamos:
j a v a c SaludoImpl . j a v a

2.1.3.

Generaci
on de stub (SDK 1.2) o stub y skeleton (SDK 1.1)

Si tanto el servidor como los servidores son Java, podemos trabajar con RMI sobre el protocolo
JRMP.
Si vamos a trabajar con el SDK 1.2 podemos hacer lo siguiente:
rmic v1 . 2 SaludoImpl

Esto genera la clase SaludoImpl Stub.class


Si vamos a trabajar con el SDK 1.1 (quiz
a por compatibilidad con software existente) realizamos
lo siguiente:
rmic v1 . 1 SaludoImpl

Lo cual genera las clases SaludoImpl Stub.class (para el cliente) y la clase SaludoImpl Skeleton.class
(para el servidor).

2.1.4.

Clase que crea una instancia del servicio y la registra

Vamos a crear ahora el servidor RMI.


import
import
import
import

j a v a . n e t . MalformedURLException ;
j a v a . rmi . Naming ;
j a v a . rmi . RMISecurityManager ;
j a v a . rmi . RemoteException ;

/
S e r v i d o r RMI
/
public c l a s s SaludoServidor {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
// I n s t a l a m o s un RMISecurityManager ( )
System . s e t S e c u r i t y M a n a g e r ( new RMISecurityManager ( ) ) ;
try {
// Creamos e l o b j e t o que o f r e c e m o s como s e r v i c i o
Saludo s a l = new SaludoImpl ( ) ;
// . . . y l o r e g i s t r a m o s
// Puesto que no estamos e s p e c i f i c a n d o e l h o s t n i e l p u e r t o
// t e n d r
a n l o s v a l o r e s por d e f e c t o : / / l o c a l h o s t y 1 0 9 9
Naming . r e b i n d ( Saludo , s a l ) ;

juan.gutierrez@uv.es

P
agina: 6

Llamada a m
etodos remotos (RMI).
Curso 04/05

LP (Telematica)
Universitat de Val`encia

} c a t c h ( RemoteException e ) {
e . printStackTrace () ;
} c a t c h ( MalformedURLException e ) {
e . printStackTrace () ;
}
}
}

2.2.
2.2.1.

Fase de ejecuci
on: el servidor
Iniciar rmiregistry

rmiregistry es una utilidad ofrecida por Sun para registrar los servicios RMI.
rmiregistry crea e inicia un registro de objetos remotos en un determinado puerto de la maquina
local. Si se omite el puerto, el registro se inicia en el puerto 1099.
Un registro de objetos remotos es un servicio de nombres que es utilizado por los servidores RMI de
la maquina para asociar objetos remotos con nombres. Los clientes en la m
aquina local o en maquinas
remotas pueden buscar objetos remotos a traves del nombre con el que se ha registrado el servicio.
Desde el directorio en el que se encuentran todas las clases se lanza el registro:
rmiregistry

2.2.2.

Iniciar el servidor

Puesto que se ha instalado un gestor de seguridad RMI hemos de crear un archivo en el que se
especifiquen lo permisos otorgados a la aplicaci
on (en este caso ser
an permisos de conexi
on para los
sockets). El archivo servidor.policy contiene lo siguiente:
grant {
p e r m i s s i o n java . net . SocketPermission :1024 65535 , connect , accept ;
p e r m i s s i o n java . net . SocketPermission : 8 0 , connect , accept ;
};

Desde el directorio donde se encuentran las clases compiladas lanzamos el servidor:


java

Djava . s e c u r i t y . p o l i c y=s e r v i d o r . p o l i c y S a l u d o S e r v i d o r

juan.gutierrez@uv.es

P
agina: 7

Llamada a m
etodos remotos (RMI).
Curso 04/05

2.3.
2.3.1.

LP (Telematica)
Universitat de Val`encia

Fase de desarrollo: el cliente


Creaci
on del cliente

El cliente del servicio RMI sera:


import
import
import
import
import

j a v a . n e t . MalformedURLException ;
j a v a . rmi . Naming ;
j a v a . rmi . NotBoundException ;
j a v a . rmi . RMISecurityManager ;
j a v a . rmi . RemoteException ;

/
C l i e n t e RMI
/
public c l a s s SaludoCliente {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
// El argumento s e r
a e l h o s t donde e s t
a el servicio
S t r i n g u r l = // l o c a l h o s t / ;

System . s e t S e c u r i t y M a n a g e r ( new RMISecurityManager ( ) ) ;


try {
// Obtencion de l o s s e r v i c i o s RMI d i s p o n i b l e s
String [ ]

s e r v i c i o s = Naming . l i s t ( u r l ) ;

// Se muestran l o s s e r v i c i o s RMI
f o r ( i n t i =0; i <s e r v i c i o s . l e n g t h ; i ++)
System . out . p r i n t l n ( s e r v i c i o s [ i ] ) ;
// Obtenemos l a r e f e r e n c i a a l o b j e t o remoto
Saludo s a l = ( Saludo ) Naming . l o o k u p ( u r l + Saludo ) ;
// Ahora l a u t i l i z a m o s como s i s e t r a t a s e de un o b j e t o
// l o c a l
S t r i n g mensaje = s a l . g e t M e n s a j e ( ) ;
System . out . p r i n t l n ( mensaje ) ;
} c a t c h ( MalformedURLException e ) {
e . printStackTrace () ;
} c a t c h ( RemoteException e ) {
e . printStackTrace () ;
} c a t c h ( NotBoundException e ) {
e . printStackTrace () ;
}
}
}

En el cliente deben estar visibles (en el mismo directorio o en el classpath) la interface que describe
el servicio remoto y la clase stub generada con rmic.

juan.gutierrez@uv.es

P
agina: 8

Llamada a m
etodos remotos (RMI).
Curso 04/05

2.4.

LP (Telematica)
Universitat de Val`encia

Fase de ejecuci
on: el cliente

2.4.1.

Iniciar el cliente

Igual que en el caso anterior hemos de dar permisos a los sockets. El archivo cliente.policy
contiene lo siguiente:
grant {
p e r m i s s i o n java . net . SocketPermission :1024 65535 , connect , accept ;
p e r m i s s i o n java . net . SocketPermission : 8 0 , connect , accept ;
};

Desde el directorio donde se encuentran las clases compiladas lanzamos el cliente:


j a v a Djava . s e c u r i t y . p o l i c y=c l i e n t e . p o l i c y S a l u d o C l i e n t e

2.5.

Una situaci
on realista: carga din
amica clases

En la mayora de situaciones reales, el servidor y el cliente no est


an en la misma m
aquina.
En este caso voy a suponer que en la m
aquina
que va a actuar de servidor RMI se encuentra el directorio Servidor con los siguientes
ficheros:

Servidor
SaludoServidor.class
Saludo.class
SaludoImpl.class
SaludoImpl Stub.class
servidor.policy

Y en la maquina que va a actuar como cliente se encuentra el directorio Cliente con los
siguientes ficheros:

Cliente
SaludoCliente.class
Saludo.class
cliente.policy

En esta situacion como puede acceder el cliente a la clase SaludoImpl Stub.class?


La solucion es que las clases necesarias se carguen de forma din
amica utilizando la capacidad que
ofrece Java para descargar clases desde un URL.
Esto se puede conseguir utilizando un codebase que es una localizaci
on desde la cual la maquina
virtual puede obtener las clases que necesite.
Esta localizacion se puede establecer utilizando la propiedad java.rmi.server.codebase que representa
uno o mas URLs desde donde se pueden descargar los stubs (y otras clases que sean necesarias).
En este caso, el proceso es el siguiente:
juan.gutierrez@uv.es

P
agina: 9

Llamada a m
etodos remotos (RMI).
Curso 04/05

LP (Telematica)
Universitat de Val`encia

Se lanza rmiregistry desde un directorio en el que no este ninguna de las clases del servidor
Se llevan las clases SaludoImpl Stub.class y Saludo.class a un directorio (voy a suponer que
se llama RMI) del servidor, que voy a suponer es un servidor HTTP al que se puede acceder como
http://host
Es decir, que las clases se pueden encontrar en http://host/RMI/
Se lanza el servidor RMI especificando en la propiedad java.rmi.server.codebase el valor
http://host/RMI/. El servidor registra el objeto remoto, asociado a un nombre en el registro.
El registro (rmiregistry) carga las clases Saludo.class y SaludoImpl Stub.class del codebase
especificado por el servidor.

Se lanza el cliente RMI. Solicita una referencia del objeto al registro.


El registro devuelve una refencia (el stub) y si el cliente no encuentra el fichero con la clase
intentara obtenerlo en el codebase especificado.
El cliente pide el fichero con la clase. El codebase que utiliza el cliente es el que qued
o asociado
al stub cuando se registro el objeto remoto.
El cliente descarga la clase SaludoImpl Stub.class de http://host/RMI/.

La instruccion que se ha utilizado para ejecutar el servidor es:


j a v a Djava . s e c u r i t y . p o l i c y=s e r v i d o r . p o l i c y Djava . rmi . s e r v e r . c o d e b a s e=h t t p : / / h o s t /RMI/
SaludoServidor

Y la que se ha utilizado para ejecutar el cliente es:


j a v a Djava . s e c u r i t y . p o l i c y=c l i e n t e . p o l i c y

SaludoCliente

Si se desea ver cuales son las llamadas que se est


an realizando desde el cliente se pueden establecer
las siguientes propiedades al lanzar el servidor:
Djava . rmi . s e r v e r . l o g C a l l s=t r u e
l o g L e v e l=VERBOSE

Djava . rmi . s e r v e r . l o g L e v e l=VERBOSE

Djava . rmi . l o a d e r .

Si no se dispone de un servidor HTTP o FTP se pueden obtener dos clases que se pueden utilizar
como servidor de ficheros en la direccion:
http://java.sun.com/products/jdk/rmi/class-server.zip
Tras descomprimir y compilar las clases que contiene este fichero zip se puede ejecutar indicando
el n
umero de puerto y el directorio donde se encuentran los ficheros con las clases:
java ClassFileServer 8 0 ruta

juan.gutierrez@uv.es

P
agina: 10

Llamada a m
etodos remotos (RMI).
Curso 04/05

LP (Telematica)
Universitat de Val`encia

Y ejecutar el servidor del siguiente modo:


j a v a Djava . s e c u r i t y . p o l i c y=s e r v i d o r . p o l i c y Djava . rmi . s e r v e r . c o d e b a s e=h t t p : / / l o c a l h o s t /
SaludoServidor

juan.gutierrez@uv.es

P
agina: 11

Você também pode gostar