You are on page 1of 16

RMI

El uso de sockets permite la elaboracin de aplicaciones distribuidas. Sin embargo, en


ocasiones, son necesarios enfoques con un mayor grado de abstraccin que el proporcionado
por stos. Al utilizar sockets, las aplicaciones deben desarrollar sus propios mecanismos para
manejar de forma eficiente los mensajes intercambiados, con la consecuente complicacin que
esto conlleva.

La API RMI (Remote Method Invacation) proporciona un mecanismo para facilitar la elaboracin
de aplicaciones distribuidas. Integrado dentro de la jerarqua de paquetes oficiales del lenguaje
de programacin Java, se adapta perfectamente al modelo de programacin de dicho lenguaje.

Como ya se ha comentado, la programacin orientada a objetos se adapta de manera natural a


la programacin de aplicaciones distribuidas. En la programacin orientada a objetos, tareas
parciales de un problema pueden ser modeladas como entidades, que llamaremos objetos, que
se comunican entre ellos durante su ejecucin. En consecuencia, el uso de programacin
orientada a objetos, resulta una evolucin natural en el desarollo de aplicaciones distribuidas;
de forma que tareas parciales, que ahora estarn ubicadas en distintas mquinas, son
modeladas como objetos que intercambian mensajes a travs de la red. RMI integra este
concepto en el lenguaje de programacin Java, de manera que el manejo de objetos en
aplicaciones distribuidas mantenga la semntica propia de los objetos locales de Java. En
consecuencia, RMI puede ser fcilmente integrada con otras APIs de dicho lenguaje.

En RMI, un objeto de Java puede ``marcarse'' como remoto de forma que los procesos de
aplicaciones distribuidas pueden acceder a l como si fuera local. En definitiva, RMI proporciona
un modelo propio de objetos distribuidos, optimizado para las caractersticas de Java.

Remote Method Invocation (RMI)

En el modelo de objetos distribuidos de Java, un objeto distribuido es aquel cuyos mtodos


pueden llamarse desde otra Mquina Virtual Java (JVM), que puede estar ejecutndose en otro
host. Por lo tanto, un objeto remoto ubicado en un proceso puede recibir llamadas desde otros
procesos que se estn ejecutando en diferentes espacios de direcciones (es decir, en diferentes
mquinas).

Una clase remota es cualquier clase cuyas instancias son objetos remotos. Desde el punto de
vista de la mquina virtual que crea instancias de objetos remotos, stos son objetos
``normales''. Se podrn usar como cualquier otro objeto.

Una llamada remota a mtodo es una llamada a un mtodo de un objeto desde un espacio de
direcciones donde ste no reside. Java permite trabajar con objetos en ubicaciones remotas
como si estuvieran en el espacio de direcciones local, es decir, con la misma sintaxis que tiene
las llamadas locales. De esta forma se consigue una total transparencia cara al programador.

Una caracterstica adicional del modelo de objetos remotos de Java es la utilizacin de interfaces
para la manipulacin de estos objetos. Cuando un proceso actuando como cliente quiere
instanciar un objeto, que para l ser remoto, ubicado en un servidor; no instancia directamente
a ste, sino a un intefaz del mismo denominada interfaz remota. Un cliente nicamente necesita
una interfaz remota para poder invocar los mtodos de un objeto remoto.
El uso de interfaces remotas proporciona una serie de ventajas, como son: las implementaciones
de los mtodos no son visibles por los clientes y no hace falta comunicar a los clientes cambios
realizados en las implementaciones de los mtodos.

Es comn hablar de RMI como un middleware, en el sentido que se comporta como un software
que separa las comunicaciones entre clientes y servidores de los protocolos de red y los
mecanismos de comunicacin entre procesos.[6] La figura 3.1 muestra este concepto.

Representacin lgica del middleware

Tpicamente, una aplicacin RMI est compuesta de un cliente y un servidor. El servidor se


encarga de crear los objetos remotos, hacerlos accesibles y permanecer a la espera de llamadas
para esos objetos remotos. El cliente debe conseguir referencias para esos objetos remotos y,
en ese momento, puede hacer uso de ellas para realizar llamadas remotas. Las aplicaciones con
objetos distribuidos necesitan:

Localizar los objetos remotos.- Para ello pueden hacer uso de la utilidad de bsqueda por
nombres propia de RMI, rmiregistry.

Comunicar con los objetos remotos.- Los detalles de la comunicacin entre objetos remotos
quedan a cargo de RMI. Para el programador, la invocacin remota de mtodos es como la
estndar.

Cargar el cdigo de las clases para los objetos remotos.- RMI permite no slo el paso de objetos
completos hacia y desde los procesos remotos sino, adems, la descarga de las clases que
implementan dichos objetos desde ubicaciones remotas.

En la prctica, la comunicacin entre clientes y servidores no es directa, siempre media entre


ambos unos elementos suplentes que se conocen como stub y skeleton.
Un stub acta como un proxy local de un objeto remoto. Debe implementar las mismas
interfaces remotas que implementa el objeto al que representa.

Cuando un objeto local llama a un mtodo de la interfaz remota de un objeto, esta llamada se
realiza en realidad sobre los mtodos del stub local, desde donde se transmite hasta el objeto
remoto. Por lo tanto, no hay comunicacin directa entre objetos locales y remotos sino que se
realiza a travs de los elementos suplentes. El stub se encarga de realizar la conexin con la
mquina virtual remota, enviar los argumentos para el mtodo especificado, esperar la
respuesta y pasrsela al objeto local. El skeleton es la contrapartida del stub, es decir, acta
como proxy del objeto remoto en el lado servidor. Se encarga de recibir las peticiones dirigidas
al objeto servidor y devolver los resultados a quien hizo la peticin. En las versiones actuales del
JDK (Java Development Kit) no es necesaria la utilizacin de los elementos skeleton.

Relaciones entre elementos RMI

El stub constituye la referencia al objeto remoto que representa. Evidentemente, no puede ser
una referencia de memoria o un puntero, ya que los objetos local y remoto se encuentran en
espacios de memoria diferentes. Al ser imposible la comunicacin directa entre objetos que
residen en mquinas virtuales diferentes, se necesitan suplentes que lo permitan, y estos
suplentes son el stub y skeleton. La referencia remota contendr la direccin IP del servidor, un
puerto, un identificador del objeto remoto y una interfaz remota. Ambos, stub y skeleton,
debern implementar las interfaces remotas de los objetos a los que estn asociados.

Tanto el stub como el skeleton utilizan el mecanismo de serializacin para comunicarse con el
objeto remoto. Mediante la serializacin, toda la informacin que es necesaria intercambiar
(objetos pasados como argumentos, ubicacin de las clases de dichos objetos, etc.) es
intercambiada como un flujo de bytes.

RMI puede cargar dinmicamente nuevas clases basndose en la informacin recibida por la
red. Esta informacin tiene forma de URL, puesto que hace referencia a recursos disponibles en
distintas mquinas. Con este mecanismo se pueden localizar, en ubicaciones remotas, las clases
necesarias para instanciar nuevos objetos en tiempo de ejecucin.
Para poder cargar dinmicamente clases de mquinas remotas, RMI obliga a crear e instalar un
gestor de seguridad. ste protege los accesos a los recursos del sistema por parte de cdigo ``no
firmado'' que se ejecute dentro de la mquina virtual. El gestor de seguridad determina si el
cdigo descargado tiene acceso al sistema de ficheros local o puede realizar cualquier otra
operacin privilegiada.

Todos los programas que utilicen RMI deben instalar un gestor de seguridad o RMI no descargar
las clases (concretamente las que no se encuentren en el path local) para los objetos que se
reciban como parmetros. Estas restricciones aseguran que las operaciones realizadas por el
cdigo descargado cumple ciertos requisitos de seguridad.

RMI proporciona un gestor de seguridad propio, RMISecurityManager. Una aplicacin RMI


tambin puede definir y utilizar otra clase SecurityManager que permita un acceso menos
restrictivo a los recursos del sistema, o, a partir del JDK 1.2, utilizar un fichero de privilegios que
ofrezca permisos ms especficos. Estos ficheros suelen nombrarse como java.policy y, para ser
utilizados como gestores de seguridad, se utiliza la propiedad
java.rmi.security.policy=security.policy (suponiendo que ese es el nombre del archivo que
especifica los permisos y que se encuentra en el directorio actual).

La figura muestra la operacin completa de una llamada RMI.

Comunicacin basada en RMI

Un objeto remoto en Java debe implementar la interfaz java.rmi.Remote que acta como flag
para que la mquina virtual lo reconozca como tal. El paso de argumentos y los valores de
retorno que admiten los mtodos remotos tiene las siguientes caractersticas:

Los tipos de datos primitivos y los objetos predefinidos de Java que implementen la interfaz
java.io.Serializable se pasan por valor. Es decir, se copian del espacio de direcciones de una
mquina virtual a otra.

Los objetos (no remotos) cuyas clases implementen la interfaz java.io.Serializable se pasan por
valor.

Los objetos remotos que estn a la espera de peticiones llegadas desde los clientes no se
transmiten sino que, en su lugar, se envan las referencias remotas a los mismos (instancias de
un stub). Por lo tanto, puede concluirse que se envan por referencia.
Los objetos (no remotos) que no implementan java.io.Serializable no pueden enviarse a un
objeto remoto.

Aclarar que, en el lenguaje de programacin Java, el paso de argumentos es slo por valor, sean
tipos primitivos u objetos. Cuando se utiliza la expresin paso por referencia se refiere al paso
por valor de referencias remotas, es decir, el paso de los stubs.

La copia por valor se realiza mediante la serializacin de objetos. De esta forma, los objetos
pueden ser enviados por los clientes en forma de flujo de bytes y pueden ser reconstruidos por
los servidores en sus espacios de direcciones. Adems, se asegura que si un objeto contiene
referencias a otros objetos, stas se incluyen en sus copias.

Estructura en capas

RMI se compone de una arquitectura de tres capas:

Capa de stubs/skeletons.- Dota a clientes y servidores de una interfaz que les permite localizar
objetos remotos para invocar sus mtodos como si fueran locales.

Capa de referencias remotas.- Esta capa se encarga de la creacin y gestin de las referencias a
objetos remotos, manteniendo para ello una tabla de objetos distribuidos. Adems, convierte
las llamadas remotas en peticiones hacia la capa de transporte.

Capa de transporte.- Capa de transporte del conjunto de protocolos TCP/IP. RMI por defecto usa
TCP, aunque admite otros.

En las figura se muestra esquematizada la arquitectura de RMI.

Esquema arquitectura RMI

Servicio de Registro Remoto


RMI necesita un servicio de registro de nombres para permitir que los clientes encuentren los
objetos remotos. Para ello proporciona un servicio de registro propio, implementado por la
aplicacin rmiregistry.

El servicio de registro de RMI, debe estar en funcionamiento antes que los clientes y servidores.
Si no es as, los clientes no pueden encontrar los objetos remotos ni los servidores pueden
atender sus peticiones. Destacar que el servicio de registro de RMI no admite persistencia, es
decir, la informacin de registro se pierde al reiniciar la aplicacin rmiregistry.

Al ejecutar rmiregistry, se activa un proceso que escucha en un puerto TCP especfico. Para que
un cliente pueda acceder a los servicios remotos ofrecidos por un servidor, ste deber
registrarlos previamente en el rmiregistry, asocindoles un nombre lgico. El rmiregistry acta,
en consecuencia, como un servidor DNS, de manera que a las bsquedas por nombre de los
clientes, devuelva los stubs asociados al servicio. La figura muestra cmo se realiza una llamada
remota en RMI utilizando el servicio de registro.

Por otro lado, en la figura se muestra en detalle el proceso de una llamada RMI[6]. La secuencia
completa es la siguiente:

Se ejecuta el servidor de registro RMI, rmiregistry, en la mquina que contendr al objeto


servidor. Una vez activo, permanece a la espera de peticiones utilizando un socket de servidor.

Se crea un objeto en el servidor, se exporta (es decir, se deja preparado para admitir llamadas a
sus mtodos por un determinado puerto) y se registra en el servicio de registro RMI con un
nombre. Al registrarse se crea una instancia del skeleton, que permanece a la escucha usando
un socket de servidor asociado al puerto por el que el objeto se ha hecho accesible.

Se crea el objeto cliente, que llamar a un mtodo de la interfaz del objeto remoto.

El servidor de registro enva al proceso cliente una referencia remota al objeto (stub) como un
flujo de bytes serializado que el cliente utiliza para crear una instancia de ste. Este stub contiene
la direccin IP del host donde reside el objeto remoto, el nmero de puerto por el que escucha
y un identificador del objeto.

El stub serializa los argumentos y enva a la capa de referencias remotas una peticin de
conexin, delegando en ella su envo.

La capa de referencias remotas indica a la capa de transporte que necesita abrir una conexin
para enviarle el flujo de datos resultante de la serializacin.

La capa de transporte crea un socket de cliente para enviar dicho flujo.

En el host remoto, los datos llegan a la capa de transporte y el socket servidor asociado los lee.

La capa de referencias remotas pasa los datos al skeleton.

El skeleton extrae del flujos de datos serializado los objetos incluidos y pasa la llamada al objeto
remoto.

El objeto remoto ejecuta el mtodo invocado con los argumentos proporcionados y, si


corresponde, devuelve un valor al objeto skeleton.

El skeleton enva una peticin de conexin a la capa de referencias remotas y delega en ella el
envo de la respuesta.
La capa de referencias remotas serializa la respuesta y enva el flujo de bytes resultante a la capa
de transporte, indicndole que necesita una conexin.

La capa de transporte remota abre un socket de cliente y enva la respuesta al host local.

sta llega a la capa de transporte del host local y all un socket servidor lo transmite a la capa de
referencias remotas.

La capa de referencias remotas extrae la informacin serializada y la enva al stub.

Finalmente, el stub enva el valor devuelto al objeto local.

Llamada remota en RMI


Proceso esquematizado de una llamada RMI

Conjunto de paquetes de RMI

La API RMI est formada por un conjunto de clases que se encuentran agrupadas en los
siguientes paquetes:

java.rmi

java.rmi.registry

java.rmi.server

java.rmi.activation

java.rmi.dgc

La figura muestra un esquema simplificado de la jerarqua de clases e interfaces del paquete


java.rmi.
Clases e interfaces del paquete java.rmi

El paquete java.rmi

Este paquete proporciona la interfaz Remote y las clases MarshalledObject, Naming y


RmiSecurityManager, junto con una serie de excepciones.

La interfaz Remote, que carece de mtodos, debe ser implementada por toda clase remota para
que sus mtodos sean accesibles. Si no es as, Java no la reconocer como tal.

Mediante una instancia de la clase MarshalledObject se puede manejar el flujo de bytes


serializados de un objeto. Sus mtodos son usados internamente por RMI.

La clase Naming proporciona mtodos para obtener y almacenar referencias de los objetos
remotos mediante URLs. Sus mtodos ms habituales son:

public static void bind(String name, Remote object) throws


AlreadyBoundException,MalformedURLException,RemoteException

public static void rebind(String name, Remote object) throws RemoteException,


MalformedURLException

public static void lookup(String name) throws


NotBoundException,MalformedURLException,RemoteException

El mtodo bind() asocia un nombre a un objeto remoto mediante una URL, es decir, lo registra.
En consecuencia, ese nombre se utiliza para localizar el objeto. Las URL's son de la forma:

rmi://host:port/remote_object_name
Si la especificacin dada en la URL no es correcta, se producir una excepcin del tipo
MalformedURLException. El host y el puerto son opcionales, de manera que si no se incluyen se
toma el host local y el puerto por defecto asociados al servicio de registro RMI.

El cdigo que registra un objeto remoto en el rmiregistry, tpicamente, tiene la forma siguiente:

myClass myInstance=new myClass();

Naming.bind("rmi://host:port/name,myInstance");

Este cdigo registra una instancia de la clase myClass en el rmiregistry mediante la URL
especificada.

La diferencia entre rebind() y bind() radica en el hecho de que el primero permite asociar un
nuevo nombre a un objeto ya registrado, cambiando el actual, mientras que el segundo
ocasionara una excepcin del tipo AlreadyBoundException.

Por otro lado, el mtodo lookup() devuelve una referencia al objeto remoto especificado en la
URL. De esta forma un proceso local puede determinar qu host est proporcionando el servicio
buscado y dnde se ubica el objeto remoto. Esta referencia remota se obtiene en forma de stub,
de manera que se podrn abrir conexiones hacia el host y puerto que especifica el stub y llamar
a los mtodos remotos del objeto.

Una llamada tpica a lookup() sera de la forma:

myClass myInstance=

(myClass)Naming.lookup("rmi://host:port/remote_object_name");

Por ltimo, la clase RMISecurityManager proporciona un gestor de seguridad para las


aplicaciones que utilizan cdigo descargado desde un servidor.

El paquete java.rmi.registry

Este paquete proporciona las interfaces Registry y RegistryHandler, as como la clase


LocateRegistry.

La interfaz Registry define los mtodos bind(), rebind(), y lookup() (as como otros que no hemos
comentado como son unbind() y list()) de la clase Naming.

Por ltimo, la clase LocateRegistry permite recuperar y, por tanto, manejar objetos Registry, que
representan a los procesos que ejecutan el servicio de registro RMI, a partir de un par host-
puerto. Tambin permite crear estos objetos a partir de un puerto o puertos y, si se desea,
factoras de sockets RMI. Las factoras de sockets permiten establecer caractersticas comunes
a los sockets que se quieren crear en una aplicacin determinada.

El paquete java.rmi.server

Este paquete proporciona una serie de clases, interfaces y excepciones para el lado servidor de
las aplicaciones RMI.

Algunas de sus clases principales son:

Clase ObjID.- Genera identificadores de objetos que los hosts declaran como remotos,
proporcionando mtodos para la creacin de los mismos, lectura de stos desde flujos de bytes
e insercin en ellos. Estos identificadores son los propios de un objeto remoto en una referencia
remota.

Clase RemoteObject.- Implementa la clase java.lang.Object (clase raz de todas las clases Java)
para objetos remotos y la interfaz java.rmi.Remote.

Clase RemoteServer.- Hereda de RemoteObject. Es la clase raz de la que heredan todas las
implementaciones de objetos cuyos mtodos son accesibles remotamente, y proporciona la
semntica bsica para el manejo de referencias remotas.

Clase RemoteStub.- Hereda de RemoteObject. Es la clase raz de la que heredan todos los stubs
de los clientes.

Clase RMIClassLoader.- Incluye mtodos estticos para permitir la carga dinmica de clases
remotas. Si un cliente o servidor de una aplicacin RMI necesita cargar una clase desde un host
remoto, llama a esta clase.

Clase RMISocketFatory.- Usada por RMI para obtener sockets cliente y servidor para las llamadas
RMI.

Clase UnicastRemoteObject.- Subclase de RemoteServer. Incluye la implementacin por defecto


de los objetos remotos. Permite llamar a los mtodos remotos mediante conexiones TCP por el
puerto especificado. Si se necesitan objetos remotos con un funcionamiento ms especfico, se
puede extender esta clase para lograrlo. Una clase que herede de UnicastRemoteObject debe
incluir un constructor que soporte excepciones del tipo RemoteException.

Algunas de sus principales interfaces son:

Interfaz RemoteRef.- Usada por los objetos RemoteStub para referirse a objetos remotos.
Incluye mtodos para llamar a los mtodos de objetos remotos.

Interfaz RMIClientSocketFactory.- Usada por RMI para obtener sockets clientes para las llamadas
RMI.

Interfaz RMIFailureHandler.- Especifica los mtodos que se encargan de manejar los fallos
derivados de la creacin de ServerSockets.

Interfaz RMIServerSocketFactory.- Usada por RMI para obtener sockets servidores para las
llamadas RMI.

Interfaz ServerRef.- Extiende la interfaz RemoteRef y es implementada por los objetos remotos
para poder acceder a sus objetos RemoteStub.

Interfaz Unreferenced.- Usada para que los objetos remotos puedan recibir mensajes de aviso
cuando no existan ms clientes con referencias a ellos.

El paquete java.rmi.activation

Permite activar remotamente objetos, desactivarlos cuando ya no se trabaje con ellos y


reactivarlos cuando sea necesario. Entre activacin y desactivacin, conservan su estado.

Desarrollo e implementacin de una aplicacin RMI

Como se ha comentado a lo largo de este documento, una aplicacin RMI tpicamente est
compuesta por un proceso servidor y otro cliente. Un proceso servidor crea una serie de objetos
remotos, hace accesibles referencias a los mismos y queda a la espera de la invocacin de sus
mtodos por parte de los clientes.

Por otra parte, un cliente obtiene una referencia remota a algn objeto del servidor, e invoca
sus mtodos.

En este apartado veremos cmo se lleva este proceso a la prctica.

Interfaces, objetos y mtodos remotos

Una aplicacin distribuida desarrollada utilizando RMI, como cualquier aplicacin Java, est
compuesta por interfaces y clases. Los interfaces definen mtodos, mientras que las clases
implementan los mtodos definidos en los interfaces (tambin puede definir algunos mtodos
adicionales). En una aplicacin distribuida, se asume que algunas implementaciones residen en
diferentes mquinas virtuales. Los objetos que tienen mtodos que pueden llamarse desde
mquinas virtuales localizadas en otros ordenadores, son los objetos remotos.

Un objeto se convierte en remoto implementando un interfaz remoto, que tenga estas


caractersticas.

Un interfaz remoto extiende a java.rmi.Remote.

Cada mtodo del interfaz debe soportar la excepcin java.rmi.RemoteException, adems de


cualquier excepcin especfica de la aplicacin.

El stub de un objeto remoto implementa el mismo conjunto de interfaces que el objeto. En


consecuencia, y haciendo uso de las propiedades bsicas del lenguaje de programacin Java,
como son la herencia y el polimorfismo, se permite la conversin de tipos del stub a cualquiera
de esas interfaces. Un cliente podr recibir siempre su stub aprovechando este mecanismo, que
en la prctica se realizar a travs de la interfaz Remote ya presentada. Adems, slo aquellos
mtodos definidos en una interfaz remota estn disponibles para ser llamados en la mquina
virtual destino, lo cual permite aislar a los objetos remotos y slo hacerlos accesibles a
determinados mtodos.

Disear e implementar los componentes de la aplicacin distribuida

Podemos dividir la creacin de una aplicacin con objetos distribuidos RMI en una serie de pasos
descritos en los apartados siguientes:

Disear e implementar los componentes de nuestra aplicacin distribuida

Compilar los fuentes y generar los stubs

Hacer las clases accesibles a la red

Arrancar la aplicacin

Primero, decidimos la arquitectura de nuestra aplicacin y determinamos qu componentes son


objetos locales y cules accesibles remotamente. Este paso incluye:

Definir los interfaces remotos. Un interfaz remoto especifica los mtodos que pueden ser
llamados remotamente por un cliente.

Implementar los objetos remotos. Los objetos remotos deben implementar uno o varios
interfaces remotos. La clase del objeto remoto podra incluir implementaciones de otros
interfaces (locales o remotos) y otros mtodos (que slo estarn disponibles localmente). Si
alguna clase local va a ser utilizada como parmetro o cmo valor de retorno de alguno de esos
mtodos, tambin debe ser implementada.

Implementar los clientes. Para implementar un cliente que solicite servicio a un objeto remoto,
de este ltimo slo es necesario conocer su interfaz. En el cdigo del cliente se instancian las
llamadas RMI a los objetos remotos mediante dichas interfaces.

Compilar los fuentes y generar los stubs.

Este es un proceso de dos pasos. En el primer paso, se compilan los ficheros fuentes de Java
usando javac, los cuales contienen las implementaciones de los interfaces remotos y las clases
del servidor y del cliente. En el segundo paso se utiliza el compilador rmic para crear los stubs
de los objetos remotos.

Hacer accesibles las clases en la red.

Si se va a permitir que la aplicacin descargue, en tiempo de ejecucin, los ficheros de las clases
Java asociadas a los interfaces remotos, los stubs, u otras clases que necesitemos; se deben
hacen accesibles, por ejemplo, a travs de un servidor web. El mecanismo que lo permite es la
carga dinmica de clases, que ser estudiada posteriormente.

Arrancar la aplicacin.

Arrancar la aplicacin incluye ejecutar el registro de objetos remotos de RMI (rmiregistry), el


servidor y el cliente, en este orden.

El apndice A de este documento muestra, con un ejemplo, los pasos para elaborar una
aplicacin con RMI. El ejemplo (apndice ), presenta un servicio que acepta peticiones de
tareas concretas especificadas por parte de los clientes. Es decir, cada cliente puede especificar
la tarea que desea que el servidor le realice, utilizando para ello el paso de objetos serializados.

Carga dinmica de clases utilizando RMI

Normalmente, tanto el cliente como el servidor disponen de las clases que necesitan para su
funcionamiento. RMI permite mayor flexibilidad con la carga dinmica de clases. De esta forma
se permite que los clientes puedan acceder a nuevos servicios ofrecidos sin necesidad de
hacerles llegar las nuevas clases cada vez que sea necesario.

En el lenguaje de programacin Java, el proceso por el que se instancian objetos a partir de las
clases que los definen, es realizado por el cargador de clases. En consecuencia, el cargador de
clases debera disponer, a priori, de las clases que implementan los objetos involucrados.

En el lado cliente, el cargador de clases debera disponer de los archivos .class de los siguientes
elementos: La interfaz remota, el stub que implementa la interfaz remota, las clases del servidor
cuyas instancias usa el cliente y las clases propias del cliente.

En el lado servidor, el cargador de clases debera disponer de los archivos .class de los siguientes
elementos: La interfaz remota y, si procede, la interfaz de objetos pasados como parmetro, la
clase que implementa la interfaz remota, el skeleton asociado a la implementacin (en el caso
de tratarse de JDK 1.1), el stub que implementa la interfaz remota y las clases propias del
servidor

La figura muestra la distribucin (en lado cliente y servidor) de clases para un ejemplo hipottico.
Distribucin de archivos en una aplicacin RMI

Mediante la carga dinmica de clases, RMI proporciona un mecanismo que facilita la separacin
entre la implementacin del lado cliente y la del servidor. Un cambio realizado en, por ejemplo,
un servidor (que implicara un cambio en el stub); no sera necesario notificarlo al cliente, ya que
la carga dinmica de clases le permite, en tiempo de ejecucin, descargar las nuevas clases. La
propiedad java.rmi.server.codebase permite indicar al cargador de clases desde qu ubicaciones
remotas puede descargar las clases. Esta informacin se incluye en los datos serializados que se
intercambian en una aplicacin RMI.

Cuando un proceso trata de extraer de los datos serializados algn objeto (bien sea un objeto
pasado como parmetro o el propio stub), los pasos que se dan son los siguientes:

Se lee la descripcin de la clase incluida en el flujo

El cargador de clases de Java busca esa clase en el directorio actual

Si no lo encuentra, busca en el CLASSPATH

Si tampoco lo encuentra, comprueba si se ha incluido el codebase en los datos serializados.

De esta forma, ubicando las clases necesarias en un lugar comn y especificando


adecuadamente esta propiedad java.rmi.server.codebase, los clientes y servidores pueden
acceder a ellas aunque no las tengan en sus respectivas mquinas. En consecuencia, podrn
estar accesibles los archivos .class de los stub, que son necesarios tanto para el cliente como
para el servidor y las interfaces implicadas (las del lado servidor y las del lado cliente, si procede,
como ocurra en el ejemplo anterior).

La configuracin ms tpica es ubicar estas clases en un servidor web y configurar la propiedad


java.rmi.server.codebase con la URL correspondiente.

Existen otras alternativas para implementar la carga dinmica de clases. Una posibilidad es usar
applets para el lado cliente, que no necesitan la ubicacin local de las clases implicadas. Usando
applets la ejecucin del cliente se realizar mediante un navegador web. Las peticiones de carga
dinmica de clases (por ejemplo de los stubs) pasarn por el navegador, que las convertir en
peticiones HTTP y las enviar al servidor web. ste enviar las clases (el bytecode) y, al ejecutarse
las llamadas a objetos remotos, sern redirigidas a los objetos servidores RMI.

Destacar que cuando se inicia el rmiregistry hay que asegurarse de que los stubs no estn
accesibles en el directorio actual o en el CLASSPATH, puesto que si es as, el servidor de registros
de RMI ignorar la propiedad java.rmi.server.codebase. En consecuencia, no pasar esta
informacin a los clientes cuando soliciten los stubs. Por lo tanto, estos clientes no podrn
localizar las clases del stub y dems objetos, con lo que lanzarn una excepcin
java.lang.ClassNotFound. Es decir, si el cliente no tienen accesible la clase, no puede interpretar
el objeto que instancia la misma, obtenido de los datos serializados recibidos.

En definitiva, si desarrollamos una aplicacin RMI en la que queremos que los clientes
descarguen dinmicamente las clases de los stubs, habra que hacerlo de la siguiente forma:

En el lado servidor.-

java -Djava.rmi.server.codebase=http://url/directorio/

-Djava.security.policy=mi_archivo_de_seguridad.policy Servidor

Suponiendo, claro est, que tanto el archivo que define las polticas de seguridad como la clase
servidora se encuentran en el directorio actual.

En el lado cliente.-

java -Djava.security.policy= mi_archivo_de_seguridad.policy

Cliente

La figura 3.9 muestra un esquema del funcionamiento de la descarga de clases desde un servidor
web.

Esquema para descarga de clases


Los pasos a seguir son los siguientes:

Se ejecuta el cliente, indicando con la propiedad java.rmi.server.codebase el servidor web que


permite la descarga de las clases

Se localizan los objetos remotos

El cliente recibe el objeto remoto (el stub) serializado

Se busca la definicin de la clase del objeto remoto en el servidor web especificado

Se recibe la clase

Se ejecutan los mtodos remotos requeridos

Resumen

RMI proporciona un mecanismo para la elaboracin de aplicaciones con objetos Java


distribuidos. Al estar integrado dentro de la jerarqua de paquetes oficiales del lenguaje de
programacin Java, se adapta perfectamente al modelo de programacin del mismo.

RMI facilita la elaboracin de aplicaciones que sigan el modelo cliente-servidor. Dada su


naturaleza, resulta muy sencillo integrar RMI con la versin empresarial del lenguaje Java (J2EE);
con el objetivo de desplegar, po ejemplo, los muy extendidos servicios web.

Para concluir, RMI presenta una serie de ventajas e inconvenientes:

Entre sus principales ventajas destaca su sencillez, con RMI los objetos remotos se manejan
como si fueran locales. Por otro lado, al existir una separacin entre interfaces e
implementaciones, en una aplicacin con objetos distribuidos se pueden aprovechar las ventajas
de la programacin orientada a objetos. Adems, la carga dinmica de clases permite, por
ejemplo, que los clientes se conviertan en applets interpretados en un navegador. RMI
proporciona un servicio de registro, rmiregistry, que facilita la localizacin por nombre de los
servicios. Por ltimo, existe la posibilidad de aadir a las comunicaciones RMI protocolos de
seguridad, como SSL o HTTPS.

En contrapartida, uno de sus principales inconvenientes es el uso exclusivo de Java; problema


parcialmente resuelto con la posibilidad, incorporada en las ltimas versiones, de trabajar con
nuevos protocolos que proporcionan interoperatiblidad. Por otro lado, RMI no proporciona
metainformacin, es decir, no dispone de un sistema que informe de los servicios disponibles y
sus APIs (nombre de mtodos, valores de retorno, etc.). Cierta consideracin merece el hecho
de que, al realizar el paso de objetos por valor, cuando se serializa un objeto hay que hacerlo
junto con todos aquellos de los que tiene referencias. Cuanto mayor sea el tamao de estos
objetos, mayor ser el trfico entre mquinas. Por ltimo, no existe un mecanismo que controle
las transacciones realizadas y acte cuando no se completen.

You might also like