Sie sind auf Seite 1von 26

RMI AVANZADO...............................................................................................................................................

1
CALLBACK DE CLIENTE................................................................................................................................2
INCREMENTO DE LA PARTE CLIENTE PARA CALLBACK DE CLIENTE ..................................................................3
INCREMENTO DE LA PARTE SERVIDORA PARA CALLBACK DE CLIENTE.............................................................4
PASOS PARA CONSTRUIR UNA APLICACIN RMI CON CALLBACK DE CLIENTE................................................5
STUB DOWNLOADING....................................................................................................................................7
EL GESTOR DE SEGURIDAD DE RMI........................................................................................................8
INSTANCIACIN DE UN GESTOR DE SEGURIDAD EN UN PROGRAMA RMI........................................................9
LA SINTAXIS DE UN FICHERO DE POLTICAS DE SEGURIDAD DE JAVA..............................................................9
UTILIZANDO STUB DOWNLOADING Y UN FICHERO DE POLTICAS DE SEGURIDAD.........................................10
ALGORITMOS PARA CONSTRUIR UNA APLICACIN RMI, QUE PERMITA STUB DOWNLOADING.......................11
RESUMEN........................................................................................................................................................13
EJERCICIOS....................................................................................................................................................14
REFERENCIAS...............................................................................................................................................14

RMI avanzado
En el ltimo captulo, Java RMI se describi como ejemplo de un sistema de
objetos distribuidos. En dicho captulo slo se mostraron las caractersticas de
diseo ms bsicas de RMI, aunque se mencion que el API posea un extenso
conjunto de caractersticas. El lector puede ignorar este captulo si no est
interesado en explorar de forma ms detallada RMI. Sin embargo, es muy
recomendable el uso de los gestores de seguridad (vase seccin 8.3) en todas
las aplicaciones RMI.
Este captulo analizar algunas de las caractersticas avanzadas de RMI ms
interesantes, a saber, [descarga?] stub downloading, gestores de seguridad,
y callback de cliente. Aunque no se trata de caractersticas inherentes del
paradigma de objetos distribuidos, se trata de mecanismos que pueden ser tiles
para los desarrolladores de aplicaciones. Adicionalmente, el estudio de estos
temas permite al lector reforzar su conocimiento del paradigma de objetos
distribuidos en general, y del API de RMI en particular.

Callback de cliente
Considrese una aplicacin RMI donde un objeto servidor debe notificar a los
procesos participantes la ocurrencia de algn evento. Como ejemplos, en un chat,
cuando un nuevo participante entra, se avisa al resto de los participantes de este
hecho; en un sistema de subastas en tiempo real, cuando empiezan las ofertas, se
debe avisar a los procesos participantes. Esta caracterstica tambin es til en un
juego en red cuando se informa a los jugadores de la actualizacin del estado del
juego. Dentro del entorno del API bsico bsica de RMI presentado presentada en
el captulo anterior, es imposible que el servidor inicie una llamada al cliente para
transmitirle alguna clase de informacin que est disponible, debido a que una
llamada a mtodo remoto es unidireccional (del cliente al servidor). Una forma de

llevar a cabo la transmisin de informacin es que cada proceso cliente realice un


sondeo al objeto servidor, invocando de forma repetida un mtodo remoto, que
supngase que se llama haComenzadoOferta, hasta que el mtodo devuelva el
valor booleano verdadero:
InterfazServidor h =
(InterfazServidor) Naming.lookup(URLRegistro);
while (!(h.haComenzadoOferta()) {;}
// comienza la oferta
El sondeo (polling) es de hecho una tcnica empleada en muchos programas de
red. Pero se trata de una tcnica muy costosa en trminos de recursos del
sistema, ya que cada invocacin a un mtodo remoto implica un thread separado
en la mquina servidora, adems de los recursos de sistema que su ejecucin
conlleva. Una tcnica ms eficiente se denomina callback: permite que cada
objeto cliente interesado en la ocurrencia de un evento se registre a s mismo con
el objeto servidor, de forma que el servidor inicie una invocacin a un mtodo
remoto del objeto cliente cuando dicho evento ocurra. La figura Figura 8.1
compara las dos tcnicas: sondeo y callback.
En RMI, el callback de cliente es una caracterstica que permite a un objeto
cliente registrarse a s mismo con un objeto servidor remoto para callbacks, de
forma que el servidor pueda llevar a cabo un invocacin al mtodo del cliente
cuando el evento ocurra. Hay que observar que con el los callbacks de clientes,
las invocaciones de los mtodos remotos se convierten en bidireccionales, o
duplexdplex, desde el cliente al servidor y viceversa. Debido a que el API de RMI
bsicobsica, introducido introducida en el captulo anterior, slo permite
invocacin de mtodos remotos de clientes en objetos servidores, se necesita
claramente sintaxis adicional para dar soporte a esta nueva caracterstica.
Cuando un objeto servidor realiza un callback, los papeles de los dos procesos se
invierten: el objeto servidor se convierte en cliente del objeto cliente, debido a que
el primero inicia una invocacin de mtodo remoto en el segundo.
La figura Figura 8.2 muestra la arquitectura de RMI con callback de cliente.
Comparada con la arquitectura bsica de RMI, se puede observar que en este
caso se necesitan dos conjuntos de proxies, uno para la interfaz remota del
servidor, como en la arquitectura bsica de RMI, y otro para una interfaz adicional,
la interfaz remota del cliente. La interfaz remota del cliente proporciona un mtodo
remoto que puede invocar el servidor a travs del callback.
Como ejemplo, se incrementar la aplicacin HolaMundo, presentada en el
captulo anterior, de forma que el objeto cliente se registre con el servidor para
callback y entonces se le notifique cualquier registro de otro objeto cliente para
callback con el servidor.

Incremento [AUNQUE ES CORRECTO GRAMATICALMENTE, QUIZS A M ME


SUENA MEJOR ALGO COMO EXTENSIN PERO QUEDA A TU
CRITERIO] de la parte cliente para callback de cliente
Para el callback, el cliente debe proporcionar un mtodo remoto que permita al
servidor notificarle el evento correspondiente. Esto puede hacerse de una forma
similar a los mtodos remotos del objeto servidor. En la siguiente subseccin se
describe la sintaxis necesaria para llevar a cabo esto.
La interfaz remota de cliente
Es importante recordar que el objeto servidor proporciona una interfaz remota que
declara los mtodos que un objeto cliente puede invocar. Para el callback, es
necesario que el objeto cliente proporcione una interfaz remota similar. Se le
denominar interfaz remota de cliente(por ejemplo, InterfazCallbackCliente ), por
oposicin a la interfaz remota de servidor (por ejemplo, InterfazCallbackServidor).
La interfaz remota de cliente debe contener al menos un mtodo que ser
invocado por el servidor en el callback. Como ejemplo, se describe la siguiente
interfaz remota de cliente:
public interface InterfazCallbackCliente
extends java.rmi.Remote {
// Este mtodo remoto es invocado por un servidor
// que realice un callback al cliente que implementa
// esta interfaz.
// El parmetro es una cadena de caracteres que
// contiene informacin procesada por el cliente
// una vez realizado el callback.
// Este mtodo devuelve un mensaje al servidor.
public String notificame(String mensaje)
throws java.rmi.RemoteException;
} // final de la interfaz
El servidor debe invocar el mtodo notificame cuando realiza el callback, pasando
como argumento una cadena de caracteres (String). Una vez recibido el callback,
el cliente utiliza esta cadena para componer otra cadena que devuelve al servidor.
La implementacin de la interfaz remota de cliente
Al igual que la interfaz remota de servidor, es necesario implementar la interfaz
remota de cliente en una clase, denominada ImplCallbackCliente en el ejemplo, tal
y como se muestra a continuacin:
import java.rmi.*;
import java.rmi.server.*;
public class ImplCallbackCliente extends UnicastRemoteObject
implements InterfazCallbackCliente {
public ImplCallbackCliente() throws RemoteException {
super();

}
public String notificame (String mensaje) {
String mensajeRet =Callback recibido: + mensaje;
System.out.println(mensajeRet);
return mensajeRet;
}
} // final clase ImplCallbackCliente
En este ejemplo el mtodo de callback notificame simplemente imprime la cadena
de caracteres que le pasa el servidor como argumento, y devuelve otra cadena a
dicho servidor.
Al igual que la interfaz remota de servidor, se debe utilizar el compilador rmic con
la implementacin de la interfaz remota de cliente para generar los proxies
necesarios en tiempo de ejecucin.
Incremento de la clase cliente
En la clase del objeto cliente, se necesita aadir cdigo al cliente para que
instancie un objeto de la implementacin de la interfaz remota de cliente. A
continuacin, se registra con el servidor una referencia al objeto utilizando un
mtodo remoto proporcionado por el servidor (vase la prxima seccin,
Incremento de la parte servidora para callback de cliente). Un ejemplo de cmo
debe realizarse esto se muestra a continuacin:
InterfazCallbackServidor h =
(InterfazCallbackServidor) Naming.lookup(URLRegistro);
InterfazCallbackCliente objCallback =
new ImplCallbackCliente();
// registrar el objeto para callback
h.registrarCallback(objCallback);
Las figuras entre la 8.3 hasta la 8.5 presentan el cdigo del software de la parte
cliente para la aplicacin HolaMundo modificada.
Incremento de la parte servidora para callback de cliente
En la parte del servidor, se necesita aadir un mtodo remoto para que el cliente
pueda registrarse para callback. En el caso ms sencillo, la cabecera del mtodo
puede ser anloga a la siguiente:
public void registrarCallback(
// Se puede elegir el nombre de mtodo deseado
InterfazCallbackCliente objCallbackCliente
) throws java.rmi.RemoteException;
Como argumento se pasa una referencia a un objeto que implementa la interfaz
remota de cliente (InterfazCallbackCliente, no ImplCallbackCliente). Tambin se
puede proporcionar un mtodo eliminarRegistroCallback, para que un cliente
pueda cancelar el registro (de forma que no reciba ms callbacks). La
implementacin de estos mtodos, as como la implementacin de un mtodo
local hacerCallbacks para realizar los callbacks se muestra en la figura 8.7. La

figura 8.6 muestra el fichero con la interfaz del servidor aumentado con las
cabeceras de los mtodos adicionales. La figura 8.8 muestra el cdigo para el
objeto servidor, que queda sin modificar respecto a la anterior versin, presentada
en el captulo anterior.
El servidor necesita emplear una estructura de datos que mantenga una lista de
las referencias a la interfaz de cliente registradas para callbacks. En el cdigo de
ejemplo, un objeto Vector es utilizado para este propsito, aunque se puede
sustituir por cualquier otra estructura de datos apropiada. Cada llamada a
registrarCallback implica aadir una referencia al vector, mientras que cada
llamada a eliminarRegistroCallback supone borrar una referencia del vector.
En el ejemplo, el servidor realiza un callback (mediante el mtodo hacerCallbacks)
siempre que se realiza lleva a cabo una llamada a registrarCallback, donde se
enva al cliente a travs de callback, el nmero de clientes actualmente
registrados. En otras aplicaciones, los callbacks se pueden activar por otros
eventos y pueden gestionarse a travs de un manejador de eventos.
En el ejemplo, un cliente elimina su registro despus de un determinado periodo
de tiempo. En las aplicaciones reales, la cancelacin del registro se puede realizar
al final de la sesin del cliente (tal como en el caso de una sesin de chat o en una
sesin de subastas).
Pasos para construir una aplicacin RMI con callback de cliente
En las siguientes pginas se presenta una descripcin revisada del procedimiento
para construir una aplicacin RMI paso a paso, permitiendo callback de cliente.
Algoritmo para desarrollar el software de la parte del servidor
1. Crear un directorio donde se almacenen todos los ficheros generados por la
aplicacin.
2. Especificar la interfaz remota de servidor en InterfazCallbackServidor.java.
Compilarla y revisarla hasta que no exista ningn error de sintaxis.
3. Implementar la interfaz en ImplCallbackServidor.java. Compilarlo y revisarlo
hasta que no exista ningn error de sintaxis.
4. Utilizar el compilador RMI rmic para procesar la clase de la implementacin y
generar los ficheros stub y skeleton para el objeto remoto:
rmic ImplCallbackServidor
Los ficheros generados se pueden encontrar en el directorio como
ImplCallbackServidor_Skel.class y ImplCallbackServidor_Stub.class. Los pasos
3 y 4 deben repetirse cada vez que se cambie la implementacin de la interfaz.
5. Obtener una copia del fichero class de la interfaz remota del cliente.
Alternativamente, obtener una copia del fichero fuente para la interfaz remota y
compilarlo utilizando javac para generar el fichero class de la interfaz
InterfazCallbackCliente.class.
6. Crear el programa correspondiente al objeto servidor ServidorEjemplo.java.
Compilarlo y revisarlo hasta que no exista ningn error de sintaxis.

7. Obtener una copia del fichero stub de la interfaz remota del cliente
ImplCallbackCliente_Stub.class.
8. Activar el objeto servidor
java ServidorEjemplo
Algoritmo para desarrollar el software de la parte cliente
1. Crear un directorio donde se almacenen todos los ficheros generados por la
aplicacin.
2. Especificar la interfaz remota de cliente en InterfazCallbackCliente.java.
Compilarla y revisarla hasta que no exista ningn error de sintaxis.
3. Implementar la interfaz en ImplCallbackCliente.java. Compilarlo y revisarlo
hasta que no exista ningn error de sintaxis.
4. Utilizar el compilador RMI rmic para procesar la clase de la implementacin
ImplCallbackCliente.class y generar los ficheros stub y skeleton
ImplCallbackCliente_Skel.class y ImplCallbackCliente_Stub.class para el objeto
remoto:
rmic ImplCallbackCliente
Los ficheros generados se pueden encontrar en el directorio como
ImplCallbackCliente_Skel.class y ImplCallbackCliente_Stub.class. Los pasos 3
y 4 deben repetirse cada vez que se cambie la implementacin de la interfaz.
5. Obtener una copia del fichero class de la interfaz remota del servidor.
Alternativamente, obtener una copia del fichero fuente para la interfaz remota y
compilarlo utilizando javac para generar el fichero class de la interfaz Interfaz.
6. Crear el programa correspondiente al objeto cliente ClienteEjemplo.java.
Compilarlo y revisarlo hasta que no exista ningn error de sintaxis.
7. Obtener una copia del fichero stub de la interfaz remota del servidor
ImplCallbackServidor_Stub.class.
8. Activar el objeto cliente
java ClienteEjemplo
La figura 8.9 muestra los ficheros que se necesitan en los dos extremos, cliente y
servidor, cuando se utiliza callback de cliente. (Como se mencion en el captulo
anterior, desde la versin 1.2 de Java no se requieren clases skeleton en las
aplicaciones RMI. Las funciones de las clases skeleton se realizan a travs de una
tcnica denominada reflexin.)

Stub downloading
En la arquitectura de un sistema de objetos distribuidos se requiere un proxy para
interactuar con la llamada a un mtodo remoto de un objeto cliente. En Java RMI,
este proxy o intermediario es el stub de la interfaz remota del servidor. En el
captulo anterior se describieron la forma en la que se generan los proxies de la
interfaz remota del servidor (ambos el stub y el skeleton) mediante el compilador
RMI rmic. La clase stub generada debe estar en el nodo cliente en tiempo de
ejecucin cuando un programa cliente se ejecute. Esto se puede resolver

colocando manualmente el fichero class del stub en el mismo paquete o directorio


que el programa del objeto cliente.
Java RMI proporciona un mecanismo que permite que los clientes obtengan
dinmicamente los stubs necesarios [developen.java.sun.com, 2]. Mediante stub
downloading dinmico, no se necesita una copia de la clase del stub en el nodo
cliente. Por el contrario, ste se transmite bajo demanda desde un servidor Web
web al nodo cliente cuando se activa dicho cliente.
Stub downloading utiliza la habilidad de descargar dinmicamente software Java
de cualquier URL a una mquina virtual Java (JVM, Java Virtual Machine)
ejecutndose en un proceso separado, normalmente en un sistema fsico
diferente [java.sun.com/products, 1]. Mediante el uso de stub downloading, el
desarrollador almacena una clase stub en un servidor Web web como un
documento Webweb, que puede ser descargado (utilizando HTTP) cuando un
objeto cliente se ejecuta, de la misma forma que se lleva a cabo la descarga de
applets. El uso de HTTP para descargar applets se discutir en el captulo
Captulo 11.
Al igual que antes, un servidor exporta un objeto contactando con el registro RMI y
registrando una referencia remota al objeto, especificando un nombre simblico
para la referencia. Si se desea utilizar stub downloading, el servidor debe tambin
indicar al registro el URL donde se encuentra almacenado la clase stub. Los
mecanismos para realizar esto se presentarn en una seccin posterior.
De la misma forma que antes, un cliente que desee invocar un mtodo remoto de
un objeto exportado contacta con el registro RMI en el nodo servidor para traer la
referencia remota a travs del nombre. Sin stub downloading, el objeto stub (un
fichero class Java) debe colocarse en el nodo cliente manualmente y debe ser
localizable por la mquina virtual Java. Si se utiliza stub downloading (es decir, se
han realizado los pasos necesarios descritos en el prrafo anterior con el objeto
servidor), entonces se puede obtener dinmicamente la clase stub de un servidor
HTTP de forma que puede interactuar con el objeto cliente y el soporte en tiempo
real de RMI. La clase stub descargada no es persistente, es decir, no se almacena
de forma permanente en el nodo cliente, sino que por el contrario el sistema libera
la clase correspondiente cuando la sesin del cliente finaliza. Si no se utiliza cache
en el servidor Webweb, cada ejecucin de la clase cliente requiere la descarga del
stub del servidor Webweb.
La figura 8.10 muestra la interaccin entre el objeto cliente, el objeto servidor y el
registro RMI cuando se utiliza stub downloading. Pronto se describirn los
algoritmos necesarios para ejecutar una aplicacin mediante el uso de stub
downloading. Antes, se debe presentar un tema relacionado: el gestor de
seguridad de RMI.

El gestor de seguridad de RMI


Aunque stub downloading es una caracterstica til, su uso supone un problema
para el sistema de seguridad. Este problema no est asociado al uso de RMI, sino
a la descarga de objetos en general. Cuando un objeto como un stub RMI se
transfiere desde un nodo remoto, su ejecucin entraa el riesgo de ataques
maliciosos al nodo local. Debido a que un objeto descargado procede de un origen
desconocido, la ejecucin de su cdigo, si no se restringe, podra causar estragos
en el nodo local, provocando daos similares a los causados por un virus de
computador [cert.org, 3].
Para evitar los problemas de seguridad del uso de stub downloading, Java
proporciona una clase denominada RMISecurityManager. Un programa RMI
puede instanciar un objeto de esta clase. Una vez instanciado, el objeto supervisa
durante la ejecucin del programa todas las acciones que puedan suponer un
riesgo de seguridad. Estas acciones incluyen el acceso a ficheros locales y la
realizacin de conexiones de red, ya que dichas acciones podran suponer
modificaciones de los recursos locales no deseadas o mal uso de los recursos de
red. En particular, el soporte en tiempo real de RMI requiere que un proceso
servidor instale un gestor de seguridad antes de exportar cualquier objeto que
requiera stub downloading, y que un cliente instale un gestor de seguridad antes
de que puede realizar la descarga del stub.
Aunque la nocin de gestor de seguridad no se introdujo en el captulo anterior, se
recomienda su uso en todas las aplicaciones RMI, independientemente de que se
utilice stub downloading o no. Por defecto, un gestor de seguridad RMI es muy
restrictivo: no permite acceso a los ficheros y slo permite conexiones al nodo
origen. (Esta restriccin de acceso tambin se utiliza en las descargas de applets.)
Esta restriccin, sin embargo, no permite a un objeto cliente RMI contactar con el
registro RMI del nodo del objeto servidor y tampoco le permite llevar a cabo stub
downloading. Es posible relajar estas condiciones instalando un fichero especial
conocido como fichero de poltica de seguridad, cuya sintaxis especifica el tipo
de restriccin que un gestor de seguridad, incluyendo los gestores de seguridad
RMI, debe utilizar. Por defecto, existe un fichero de poltica de seguridad en un
directorio especial de cada sistema que utiliza Java. Las restricciones
especificadas en el fichero de polticas de seguridad del sistema las restricciones
por defecto anteriormente mencionadas sern empleadas por el gestor de
seguridad a menos que se sobreescriban mediante el uso de un fichero de
polticas alternativo. Alternativamente, una aplicacin puede especificar un fichero
de polticas de seguridad, de forma que las restricciones las impone la propia
aplicacin. Para los ejercicios realizados por el lector, se recomienda que se
especifique un fichero de seguridad con cada aplicacin que se ejecute, de forma
que se tenga control exclusivamente sobre las restricciones impuestas en la
aplicacin del lector, sin afectar a las restricciones de otros programas. En algunos
sistemas, puede ocurrir que un usuario normal no tenga privilegio de acceso para
modificar el fichero por defecto de polticas de seguridad de Java.

A continuacin, se describe cmo una aplicacin utiliza el gestor de seguridad de


RMI.
Instanciacin de un Gestor de Seguridad en un programa RMI
La clase RMISecurityManager se puede instanciar tanto en el objeto cliente como
en el objeto servidor utilizando la siguiente sentencia:
System.setSecurityManager(new RMISecurityManager());
Esta sentencia debera aparecer antes del cdigo de acceso al registro RMI. Las
figuras 8.11 y 8.12 muestran los ejemplos del programa HolaMundo, presentados
en el captulo anterior, pero instanciando un gestor de seguridad.
La sintaxis de un fichero de polticas de seguridad de Java
Un fichero de polticas de seguridad de Java es un fichero de texto que contiene
cdigos que permiten especificar la concesin de permisos especficos. A
continuacin se muestra un fichero tpico java.policy para una aplicacin RMI.
grant {
// Este permiso permite a los clientes RMI realizar
// conexiones de sockets a los puertos pblicos de
// cualquier computador.
// Si se arranca un puerto en el registro RMI en este
// rango, no existir una violacin de acceso de
// conexin.
// permission java.net.SocketPermission *:1024-65535,
//
connect,accept,resolve;
// Este permiso permite a los sockets acceder al puerto
// 80, el puerto por defecto HTTP que el cliente
// necesita para contactar con el servidor HTTP para
// stub downloading
permission java.net.SocketPermission *:80, connect;
};
Se recomienda al lector que cuando realice los ejercicios, haga una copia de este
fichero para la aplicacin con el nombre java.policy en el mismo directorio tanto en
el nodo del objeto cliente como en el nodo del objeto servidor.
Cuando se active el cliente, hay que utilizar la opcin del mandato que permite
especificar que el proceso cliente debe tener los permisos definidos en el fichero
de polticas, de la siguiente forma:
java Djava.security.policy=java.policy ClienteEjemplo
Del mismo modo, el servidor debe activarse del siguiente modo:
java Djava.security.policy=java.policy ServidorEjemplo

Estos dos mandatos asumen que el fichero de polticas se llama java.policy y est
disponible en el directorio actual de la parte servidora y cliente.
Una descripcin detallada de las polticas de seguridad Java, incluyendo una
explicacin de la sintaxis utilizada en este fichero, se puede encontrar en
[java.sun.com/marketing, 4].
Utilizando Uso de stub downloading y un fichero de polticas de seguridad
1. Si debe descargarse el stub de un servidor HTTP, transferir transfiera la clase
stub a un directorio apropiado del servidor HTTP, por ejemplo, el al directorio
stubs del nodo www.miempresa.com, y asegurarse asegrese de que el
permiso de acceso del fichero es de lectura para todos los usuarios.
2. Cuando se activa el servidor, se debe especificar las siguientes opciones del
mandato:
java Djava.rmi.server.codbase=<URL>
-Djava.security.policy=
<ruta completa del fichero de polticas de seguridad>
donde
<URL> es el URL del directorio donde se encuentra la clase stub; por ejemplo,
http://www.miempresa.com/stubs/.
Obsrvese la barra del final del URL, que indica que el URL especifica un
directorio, no un fichero.
<ruta completa del fichero de polticas de seguridad> especifica el fichero de
polticas de seguridad de la aplicacin; por ejemplo, java.security, si el fichero
java.security se encuentra en el directorio actual.
Por ejemplo,
java
Djava.rmi.server.codebase=http://www.miempresa.com/stubs/
-Djava.security.policy=java.security HolaMundoServidor
(todo en una lnea)
arrancar la aplicacin HolaMundoServidor y permitir realizar stub downloading
del directorio stubs del servidor Web web de www.miempresa.com.
La figura 8.13 muestra el conjunto de ficheros que se necesitan para una
aplicacin RMI y donde se deben colocar, suponiendo stub downloading dinmico.
(Por simplicidad, se asume que la aplicacin no usa callback de cliente. Se
podran aadir los ficheros necesarios para realizar callback de cliente, si se
desear.)
En la parte del servidor, los ficheros necesarios son los ficheros class del servidor,
la interfaz remota, la implementacin de la interfaz (generada por javac), el fichero
class del stub (generado por rmic), la clase del skeleton (generado por rmic), y el

fichero de polticas de seguridad de la aplicacin. En la parte cliente, los ficheros


que se necesitan son el fichero class del cliente, el fichero class de la interfaz
remota del servidor y el fichero de polticas de seguridad de la aplicacin.
Finalmente, el fichero class del stub se debe almacenar en el nodo HTTP del cul
cual se descarga el stub.
Algoritmos para construir una aplicacin RMI, que permita stub downloading
A continuacin se realiza una descripcin del procedimiento paso a paso para la
construccin de una aplicacin RMI, teniendo en cuenta el uso de stub
downloading. De nuevo, por cuestiones de simplicidad, se han obviado los detalles
para el callback de cliente.
Algoritmo para desarrollar el software de la parte del servidor
1. Crear un directorio donde se almacenen todos los ficheros generados por la
aplicacin.
2. Especificar la interfaz remota de servidor en InterfazEjemplo.java. Compilarla y
revisarla hasta que no exista ningn error de sintaxis.
3. Implementar la interfaz en ImplEjemplo.java. Compilarlo y revisarlo hasta que
no exista ningn error de sintaxis.
4. Utilizar el compilador RMI rmic para procesar la clase de la implementacin y
generar los ficheros stub y skeleton para el objeto remoto:
rmic ImplEjemplo
Los ficheros generados se pueden encontrar en el directorio como
ImplEjemplo_Skel.class y ImplEjemplo_Stub.class. Los pasos 3 y 4 deben
repetirse cada vez que se cambie la implementacin de la interfaz.
5. Crear el programa del objeto servidor ServidorEjemplo.java. Compilarlo y
revisarlo hasta que no exista ningn error de sintaxis.
6. Si se desea stub downloading, copiar el fichero stub en un directorio apropiado
del servidor HTTP.
7. Si se utiliza el registro RMI y no ha sido ya activado, activarlo. Por ejemplo:
rmiregistry <nmero de puerto, 1099 por defecto>
Alternativamente, se puede codificar la activacin en el programa del objeto
servidor.
8. Construir un fichero de polticas de seguridad para la aplicacin denominado
java.policy (u otro nombre), y colocarlo en un directorio apropiado o en el
directorio actual.
9. Activar el servidor, especificando (1) el campo codebase si se utiliza stub
downloading, y (2) el fichero de polticas de seguridad.
java Djava.rmi.server.codebase=http://nodo.dom.edu/stubs/
-Djava.security.policy=java.policy ServidorEjemplo
Este mandato se ejecuta en una nica lnea, aunque se puede utilizar un
carcter de continuacin de lnea (\) en un sistema UNIX. Se recomienda
poner el mandato en un fichero de texto ejecutable (tal como ejecServidor.bat

en un sistema Windows o ejecServidor en un sistema UNIX) y ejecutar el


fichero para arrancar el servidor.
Para la aplicacin HolaMundo, el fichero ejecServidor.bat contendra esta lnea:
java -Djava.security.policy=java.policy
-Djava.rmi.server.codebase=
http://www.csc.calpoly.edu/~mliu/stubs/ HolaMundoServidor
De nuevo, no debera haber saltos de lneas en el fichero
Algoritmo para desarrollar el software de la parte cliente
1. Crear un directorio donde se almacenen todos los ficheros generados por la
aplicacin.
2. Obtener una copia del fichero class de la interfaz remota del servidor.
Alternativamente, obtener una copia del fichero fuente para la interfaz remota y
compilarlo utilizando javac para generar el fichero class de la interfaz
InterfazEjemplo.
3. Si se desea utilizar stub downloading, obtener una copia del fichero class del
stub (supngase que se llama ImplEjemplo_Stub.class) y colocarlo en el
directorio actual.
4. Construir un fichero de polticas de seguridad para la aplicacin denominado
java.policy (u otro nombre), y colocarlo en un directorio apropiado o en el
directorio actual.
5. Activar el cliente, especificando el fichero de polticas de seguridad.
java -Djava.security.policy=java.policy ClienteEjemplo
Este mandato se ejecuta en una nica lnea, aunque se puede utilizar un
carcter de continuacin de lnea (\) en un sistema UNIX. Se recomienda
poner el mandato en un fichero de texto ejecutable (tal como ejecCliente.bat en
un sistema Windows o ejecCliente en un sistema UNIX) y ejecutar el fichero
para arrancar el cliente.
Para la aplicacin HolaMundo, el fichero ejecCliente.bat contendra esta lnea:
java -Djava.security.policy=java.policy HolaMundoCliente
De nuevo, no debera haber saltos de lneas en el fichero
Si se utiliza callback de cliente, deben insertarse en este algoritmo los pasos
adicionales descritos en la seccin anterior Pasos para construir una aplicacin
RMI con callback de cliente.

Resumen
En este captulo se han analizado algunas de las caractersticas avanzadas del
API de Java RMI. Aunque estas caractersticas no son parte inherente del
paradigma de objetos distribuidos, son interesantes y tiles para algunas
aplicaciones.
Callback de cliente
El callback de cliente es til para las aplicaciones que deseen que el servidor
les notifique la ocurrencia de algn evento.
El callback de cliente permite que un objeto servidor realice una invocacin de
mtodo remoto de un cliente a travs de la referencia a una interfaz remota de
dicho cliente.
Para dotar a la aplicacin de callback de cliente, el software de la parte cliente
debe proporcionar una interfaz remota, instanciar un objeto que implemente
dicha interfaz y pasar la referencia del objeto al servidor. El objeto servidor
guarda estas referencias del cliente en una estructura de datos. Cuando el
evento esperado ocurre, el objeto servidor invoca un mtodo callback (definido
en la interfaz remota del cliente), pasando los datos a los clientes apropiados.
Se necesitan dos conjuntos de stub y skeleton: uno para las interfaz remota del
servidor y el otro para la interfaz remota del cliente.
Stub downloading y gestor de seguridad
La caracterstica de stub downloading permite que un cliente pueda cargar una
clase stub en tiempo de ejecucin.
Stub downloading requiere la configuracin de la propiedad
java.rmi.server.codebase cuando se inicia el servidor: esta propiedad debe
configurarse con el directorio de un servidor HTTP donde se encuentre
almacenada la copia del fichero class del stub y accesible a todos los usuarios.
Stub downloading requiere la instalacin de un gestor de seguridad RMI tanto
en la parte cliente como en la servidora.
Para llevar a cabo stub downloading, es necesario el uso de un gestor de
seguridad, ya que la ejecucin de un objeto descargado de una mquina
desconocida puede suponer una amenaza para el computador cliente.
Un gestor de seguridad lleva a cabo las restricciones especificadas en un
fichero de polticas de seguridad de Java, que puede ser el fichero de polticas
del sistema o un fichero de polticas aplicado solamente a una aplicacin
individual.
En este captulo se mostr un ejemplo de fichero de polticas de seguridad
para aplicaciones RMI.
Por cuestiones de seguridad, el uso de los gestores de seguridad es
recomendable en todas las aplicaciones RMI, independientemente de que
utilicen stub downloading o no.

Ejercicios [SE PODRA PONER EN IMPERATIVO EN VEZ


DE INFINITIVO]
1. En el contexto de Java RMI, qu es el callback de cliente? Por qu es til?
2. Probar el programa ejemplo Callback en uno o ms mquinas.
a. Crear una carpeta (denominada callback) para este ejercicio. Crear dos
subcarpetas con los nombres Servidor y Cliente, respectivamente en el
PC. Copiar los ficheros fuente en las carpetas Servidor y Cliente
respectivamente.
b. Seguir los algoritmos presentados en el captulo para configurar y ejecutar
los objetos servidor y cliente. Escribir un informe indicando las acciones
realizadas y las salidas.
c. Arrancar varios clientes sucesivamente. Escribir en el informe las acciones
y las salidas de los programas.
d. Copiar el contenido de la carpeta callback en una carpeta nueva. Modificar
los ficheros fuente en la nueva carpeta, de forma que el servidor notifique
solamente a un cliente cuando se hayan registrado para callback
exactamente tres clientes. Mostrar los cambios realizados en los ficheros
fuente.
e. Volviendo a la carpeta callback, arrancar un servidor y un cliente,
especificando un tiempo de duracin del cliente de 600 segundos. Mientras
el cliente espera por callback, abortar el proceso cliente mediante el uso de
Ctrl-C. Rpidamente arrancar un nuevo proceso cliente de forma que el
servidor intenta realizar un callback a todos los clientes registrados. Apuntar
lo que se observa.
Realizar cambios al cdigo fuente de forma que los problemas observados
no ocurran. Describir los cambios realizados a los programas. Entregar los
listados fuente modificados.
3. En un ejercicio del captulo anterior, se peda utilizar RMI para escribir una
aplicacin que fuera un prototipo de un sistema de encuestas de opinin.
Modificar la aplicacin para que cada cliente proporcione una interfaz de
usuario de forma que se pueda realizar un voto. Adicionalmente, se debe
mostrar en la pantalla del usuario el recuento actual siempre que se realice un
nuevo voto (sea desde este cliente o desde cualquier otro cliente).
Recopilar todos los listados de los ficheros fuentes, incluyendo los ficheros de
las interfaces. Se recomienda una demostracin de los programas en el
laboratorio.
4. En el contexto de Java RMI, qu es stub downolading? Por qu es til?
5. Experimentar con stub downloading utilizando el ejemplo presentado en la
seccin Seccin 8.3 de este captulo. Los ficheros deben encontrarse en la
carpeta stubDownloading de los ejemplos de programas.
a. Crear una carpeta (llamada stubDownloading) para este ejercicio. Crear dos
subcarpetas en el PC y denominarlas Servidor y Cliente, respectivamente.
Copiar los ficheros RMI del ejemplo HolaMundo en la carpeta
correspondiente.
b. Compilar los ficheros. Utilizar rmic para generar los ficheros stub y skeleton
en la carpeta Servidor. Copiar el fichero class stub en la carpeta Cliente.

c. Arrancar un servidor de la carpeta Servidor sin especificar stub


downloading (es decir, sin configurar la propiedad codebase al arrancar el
intrprete Java). A continuacin, arrancar un cliente de la carpeta Cliente.
Comprobar que funcionan de la forma esperada.
d. En la carpeta Cliente, borrar el fichero HolaMundoImpl_Stub.class. Arrancar
un cliente de nuevo. Debera obtenerse una notificacin de excepciones
Java en tiempo de ejecucin debido a la ausencia de la clase stub.
e. Volviendo a la carpeta Servidor, copiar el fichero
HolaMundoImpl_Stub.class a un servidor Web web desde el que haya
acceso, en un directorio denominado stubs (o algn otro nombre).
Donde sea aplicable, establecer las protecciones de acceso al directorio
stubs y al fichero stub, de forma que se pueda leer por todo el mundo.
Arrancar un servidor desde la carpeta Servidor, esta vez especificando stub
downloading (es decir, configurando la propiedad codebase para permitir
que se realice stub downloading desde el directorio donde se encuentra el
fichero class del stub).
f. Volviendo a la carpeta Cliente, probar a ejecutar el cliente de nuevo. Si las
funciones de stub downloading funcionan como se espera, el cliente debe
funcionar esta vez.
g. Probar a duplicar la carpeta Cliente y arrancar otros clientes en diferentes
sistemas de la misma forma, utilizando stub downloading.
Escribir un informe describiendo el experimento.
6. Repetir el ejercicio en el ejemplo Callback. Este vez, el cliente debe poder
realizar un stub downloading del stub del servidor dinmicamente, mientras
que el servidor debe poder obtener el stub del cliente dinmicamente tambin.
Se recomienda que la primera vez que se realice este experimento, se utilice
una copia de los ficheros stub. A continuacin borrar el stub de servidor de la
carpeta cliente, y probar a ejecutar el cliente con stub downloading.
Consecutivamente, borrar el stub del cliente de la carpeta servidor, y probar a
ejecutar el servidor con stub downloading. Escribir un informe describiendo el
experimento.

Referencias
1. Descarga dinmica de cdigo utilizando RMI,
http://java.sun.com/products/jdk/1.2/docs/guide/rmi/codebase.html
2. Introduccin a la computacin distribuida con RMI,
http://developer.java.sun.com/developer/onlineTraining/rmi/RMI.html
3. CERT Coordination Center, CERT/CC Computer Virus Resources,
http://www.cert.org/other_sources/viruses.html
4. Java Remote Method Invocation Computacin distribuida para Java,
http://java.sun.com/marketing/collateral/javarmi.html

Figuras
Figura 8.1 Sondeo (polling) frente a callback.

Figura 8.2 La arquitectura de RMI con callback de cliente.


Figura 8.3 Fichero InterfazCallbackCliente.java de la aplicacin HolaMundo
modificada.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

import java.rmi.*;
/**
* Esto es una interfaz remota para ilustrar el
* callback de cliente.
* @author M. L. Liu
*/
public interface InterfazCallbackCliente
extends java.rmi.Remote{
// Este mtodo remoto se invoca mediante callback
// de servidor, de forma que realiza un callback a
// un cliente que implementa esta interfaz.
// @message una cadena de caracteres que contiene
// informacin procesada por el cliente.
public void notificame(String mensaje)
throws java.rmi.RemoteException;
} // fin interfaz

Figura 8.4 Fichero ImplCallbackCliente.java de la aplicacin HolaMundo


modificada.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

import java.rmi.*;
import java.rmi.server.*;
/**
* Esta clase implementa la interfaz remota
* InterfazCallbackCliente.
* @author M. L. Liu
*/
public class ImplCallbackCliente extends
UnicastRemoteObject
implements InterfazCallbackCliente {
public ImplCallbackCliente () throws
RemoteException {
super( );
}
public String notificame(String mensaje){

18

String mensajeRet = "Callback recibido: +


mensaje;

19
20
21
22
23

System.out.println(mensajeRet);
return mensajeRet;
}
} // fin clase ImplCallbackCliente

Figura 8.5 Fichero ClienteEjemplo.java de la aplicacin HolaMundo modificada.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

import java.io.*;
import java.rmi.*;
/**
* Esta clase representa el objeto cliente para un
* objeto distribuido de la clase ImplCallbackServidor,
* que implementa la interfaz remota
* InterfazCallbackServidor. Tambin acepta callbacks
* del servidor.
*
*
*
* @author M. L. Liu
*/
public class ClienteEjemplo {
public static void main(String args[]) {
try {
int puertoRMI;
String nombreNodo;
InputStreamReader ent =
new InputStreamReader(System.in);
BufferedReader buf= new BufferedReader(ent);
System.out.println(
Introduce el nombre de nodo del registro
RMI:);
nombreNodo = buf.readLine();
System.out.println(
Introduce el nmero de puerto del
registro RMI:);
String numPuerto = buf.readLine();
puertoRMI = Integer.parseInt(numPuerto);
System.out.println(
Introduce cuantos segundos va a
permanecer registrado:);
String duracionTiempo = buf.readLine();

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

int tiempo = Integer.parseInt(duracionTiempo);


String URLRegistro =
rmi://localhost:+ numPuerto +
/callback;
// Bsqueda del objeto remoto y cast al objeto
// de la interfaz
InterfazCallbackServidor h =
(InterfazCallbackServidor)
Naming.lookup(URLRegistro);
System.out.println(Bsqueda completa );
System.out.println(El servidor dice +
h.decirHola());
InterfazCallbackCliente objCallback =
new ImplCallbackCliente();
// registrar para callback
h.registrarCallback(objCallback);
System.out.println(Registrado para
callback.);
try {
Thread.sleep(tiempo*1000);
}
catch (InterruptedException exc) { // sobre el
mtodo sleep
h.eliminarRegistroCallback(objCallback);
System.out.println(No registrado para
callback.);
}
} // fin try
catch (Exception e) {
System.out.println(
Excepcin en ClienteEjemplo: + e);
}
} // fin main
} // fin clase

Figura 8.6 Fichero InterfazCallbackServidor.java de la aplicacin HolaMundo


modificada.
1
2
3
4
5
6
7
8

import java.rmi.*;
/**
* Esto es una interfaz remota para ilustrar el
* callback de cliente.
* @author M. L. Liu
*/

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

public interface InterfazCallbackServidor extends


Remote{
public String decirHola( )
throws java.rmi.RemoteException;
//
//
//
//
//

Este mtodo remoto permite a un objeto


cliente registrarse para callback
@param objClienteCallback es una referencia
al objeto del cliente; el servidor lo
utiliza para realizar los callbacks

public void registrarCallback(


InterfazCallbackCliente objCallbackCliente)
throws java.rmi.RemoteException;
// Este mtodo remoto permite a un objeto
// cliente cancelar su registro para callback
public void eliminarRegistroCallback(
InterfazCallbackCliente objCallbackCliente)
throws java.rmi.RemoteException;
}

Figura 8.7 Fichero ImplCallbackServidor.java de la aplicacin HolaMundo


modificada.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

import java.rmi.*;
import java.rmi.server.*;
import java.util.Vector;
/**
* Esta clase implementa la interfaz remota
* InterfazCallbackServidor.
* @author M. L. Liu
*/
public class ImplCallbackServidor extends
UnicastRemoteObject
implements InterfazCallbackServidor {
private Vector listaClientes;
public ImplCallbackServidor () throws
RemoteException {
super( );

19
20
21
22
23
24
25
26
27
28
29
30
31

listaClientes = new Vector();


}
public String decirHola()
throws java.rmi.RemoteException {
return(Hola Mundo);
}
public void registrarCallback(
InterfazCallbackCliente objCallbackCliente)
throws java.rmi.RemoteException {
// almacena el objeto callback en el vector
if (!
(listaClientes.contains(objCallbackCliente))) {

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

listaClientes.addElement(objCallbackCliente);
System.out.println(Nuevo cliente
registrado );
hacerCallbacks();
} // fin if
}
// Este mtodo remoto permite a un objeto cliente
// cancelar su registro para callback
// @param id es un identificador para el cliente;
// el servidor lo utiliza nicamente para
identificar al cliente registrado.
public synchronized void eliminarRegistroCallback(
InterfazCallbackCliente objCallbackCliente)
throws java.rmi.RemoteException{
if
(listaClientes.removeElement(objCallbackCliente)){
System.out.println(Cliente no registrado
);
} else {
System.out.println(
eliminarRegistro: el cliente no fue
registrado.
}
}
private synchronized void hacerCallbacks( ) throws
java.rmi.RemoteException {
// realizar callback de un cliente registrado
System.out.println(
**************************************\n +
Callback iniciado - );

58
59
60
61
62
63
64
65
66
67

68
69
70
71

for (int i=0; i<listaClientes.size(); i++) {


System.out.println(haciendo callback
nmero+ i \n);
// convertir el objeto vector a un objeto
callback
InterfazCallbackCliente proxCliente =
(InterfazCallbackCliente)
listaClientes.elementAt(i);
// invocar el mtodo de callback
proxCliente.notificame(Nmero de
clientes registrados=
+ listaClientes.size());
} // fin for
System.out.println(************************************
**\n
+ Servidor completo callbacks -);
} // fin hacerCallbacks
} // fin clase ImplCallbackServidor

Figura 8.8 Fichero ServidorEjemplo.java de la aplicacin HolaMundo modificada.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

import
import
import
import
import
import

java.rmi.*;
java.rmi.server.*;
java.rmi.registry.Registry;
java.rmi.registry.LocateRegistry;
java.net.*;
java.io.*;

/**
* Esta clase representa el objeto servidor para un
* objeto distribuido de la clase Callback, que
implementa la interfaz remota InterfazCallback.
* @author M. L. Liu
*/
public class ServidorEjemplo {
public static void main(String args[]) {
InputStreamReader ent =
new InputStreamReader(System.in);
BufferedReader buf= new BufferedReader(ent);
String numPuerto, URLRegistro;
try {
System.out.println(

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

Introducir el nmero de puerto del


registro RMI:);
numPuerto=(buf.readLine()).trim();
int numPuertoRMI =
Integer.parseInt(numPuerto);
arrancarRegistro(numPuertoRMI);
ImplCallbackServidor objExportado =
new ImplCallbackServidor( );
URLRegistro =
rmi://localhost: + numPuerto +
/callback;
Naming.rebind(URLRegistro, objExportado);
System.out.println(Servidor callback
preparado.);
} // fin try
catch (Exception exc) {
System.out.println(
Excepcin en ServidorEjemplo.main: +
exc);
} // fin catch
} // fin main
// Este mtodo arranca un registro RMI en el nodo
// local, si no existe en el nmero de puerto
especificado.
private static void arrancarRegistro(int
numPuertoRMI)
throws RemoteException {
try {
Registry registro =
LocateRegistry.getRegistry(numPuertoRMI);
registro.list();
// Esta llamada lanza una excepcin
// si el registro no existe
}
catch (RemoteException e) {
// No existe registro vlido en el puerto
Registry registro =
LocateRegistry.createRegistry(numPuertoRMI);
}
} // fin arrancarRegistro
} // fin clase

Figura 8.9 Colocacin de los ficheros en una aplicacin RMI con callback de
cliente.

Figura 8.10 Stub downloading.


Figura 8.11 HolaMundoServidor.java haciendo uso de un gestor de seguridad.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

import
import
import
import
import
import

java.rmi.*;
java.rmi.server.*;
java.rmi.registry.Registry;
java.rmi.registry.LocateRegistry;
java.net.*;
java.io.*;

/**
* Esta clase representa el objeto servidor para un
* objeto distribuido de la clase HolaMundo, que
implementa la interfaz remota InterfazHolaMundo. Se
instala un gestor de seguridad para realizar stub
downloading seguro.
* @author M. L. Liu
*/
public class HolaMundoServidor {
public static void main(String args[]) {
InputStreamReader ent =
new InputStreamReader(System.in);
BufferedReader buf= new BufferedReader(ent);
String numPuerto, URLRegistro;
try {
System.out.println(
Introducir el nmero de puerto del
registro RMI:);
numPuerto=(buf.readLine()).trim();
int numPuertoRMI =
Integer.parseInt(numPuerto);

27
28

// arrancar un gestor de seguridad esto


es

29

// necesario si se utiliza stub


downloading

30
31
32
33
34
35
36

System.setSecurityManager(
new RMISecurityManager());
arrancarRegistro(numPuertoRMI);
ImplHolaMundo objExportado = new
ImplHolaMundo();
URLRegistro =
rmi://localhost: + numPuerto +
/holaMundo;

37
38
39

Naming.rebind(URLRegistro, objExportado);
System.out.println(
Servidor registrado. El registro
contiene:);

40

// listar los nombres registrados


actualmente

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

listarRegistro(URLRegistro);
System.out.println(Servidor Hola Mundo
preparado.);
} // fin try
catch (Exception exc) {
System.out.println(
Excepcin en HolaMundoServidor.main: +
exc);
} // fin catch
} // fin main
// Este mtodo arranca un registro RMI en el nodo
// local, si no existe en el nmero de puerto
especificado.
private static void arrancarRegistro(int
numPuertoRMI)
throws RemoteException {
try {
Registry registro =
LocateRegistry.getRegistry(numPuertoRMI);
registro.list(); // Esta llamada lanza
// una excepcin si el registro no existe
}
catch (RemoteException e) {
// No existe registro vlido en el puerto
System.out.println(
El registro RMI no se localiza en este
puerto
+ numPuertoRMI);
Registry registro =
LocateRegistry.createRegistry(numPuertoRMI);
System.out.println(
Registro RMI creado en el puerto +
numPuertoRMI);
}
} // fin arrancarRegistro
// Este mtodo lista los nombres registrados en RMI
private static void listarRegistro(String
URLRegistro)

74

throws RemoteException, MalformedURLException


{

75
76
77
78
79
80
81
82

System.out.println(
Registro + URLRegistro + contiene: );
String [] nombres = Naming.list(URLRegistro);
for (int i=0; i< nombres.length; i++)
System.out.println(nombres[i]);
} // fin listarRegistro
} // fin clase

Figura 8.12 HolaMundoCliente.java haciendo uso de un gestor de seguridad.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

import java.io.*;
import java.rmi.*;
/**
* Esta clase representa el objeto cliente para un
* objeto distribuido de la clase HolaMundo, que
* implementa la interfaz remota InterfazHolaMundo.
* Se instala un gestor de seguridad para realizar stub
downloading seguro.
* @author M. L. Liu
*/
public class HolaMundoCliente {
public static void main(String args[]) {
try {
int puertoRMI;
String nombreNodo;
InputStreamReader ent =
new InputStreamReader(System.in);
BufferedReader buf= new
BufferedReader(ent);
System.out.println(
Introduce el nombre de nodo del registro
RMI:);
nombreNodo = buf.readLine();
System.out.println(
Introduce el nmero de puerto del
registro RMI:);
String numPuerto = buf.readLine();
puertoRMI = Integer.parseInt(numPuerto);
// arrancar un gestor de seguridad esto
es

30

// necesario si se utiliza stub


downloading

31

System.setSecurityManager(new
RMISecurityManager());

32
33
34

String URLRegistro =
rmi://localhost:+ numPuerto +
/holaMundo;

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

// Bsqueda del objeto remoto y cast al


// objeto de la interfaz
InterfazHolaMundo h =
(InterfazHolaMundo)Naming.lookup(URLRegistro);
System.out.println(Bsqueda completa );
// invocar el mtodo remoto
String mensaje=h.decirHola());
System.out.println(HolaMundoCliente: +
mensaje);
} // fin try
catch (Exception e) {
System.out.println(
Excepcin en HolaMundoCliente: + e);
}
} // fin main
} // fin clase

Figura 8.13 Colocacin de los ficheros RMI en una aplicacin que utiliza stub
downloading.

Notas al margen
Pgina 241
Los mtodos registrarCallback y eliminarRegistroCallback modifican una
estructura comn (el objeto Vector que contiene referencias a los callback de
clientes). Dado que estos mtodos se pueden invocar concurrentemente, es
importante que se protejan con exclusin mutua. En este ejemplo la exclusin
mutua se consigue a travs del uso de un mtodo sincronizado (synchronized).
Pgina 245
En Java, un paquete es un conjunto de clases, interfaces u otros paquetes
relacionados y que estn declarados.
Pgina 246
Caching de Web es una tcnica que emplea la tcnica ms general de caching
para evitar transferir un mismo documento repetidas veces.

Das könnte Ihnen auch gefallen