En RMI
intervienen dos progamas java que están ejecutándose en el mismo o distintos
ordenadores.
Uno de
ellos, llamado servidor, “publica” algunos de los objetos/clases que tiene
instanciadas, es decir, los pone visibles desde la red, de forma que otros
programas java puedan llamar a sus métodos.
El otro
programa, llamado cliente, localiza en el servidor el objeto publicado y llama
a sus métodos. Estos métodos se ejecutan en el programa servidor y devuelven un
resultado (por el return habitual) que recoge el cliente en su ordenador.
El cliente
se queda “colgado” en la llamada hasta que el servidor termina de ejecutar el código
y devuelve un resultado.
Los objetos
que comparten el servidor se conocen como objetos remotos.
a)
Se
crea una interface (remota) con los métodos que queremos que se publiquen, es
decir, los métodos que queremso que pueda llamar el cliente
·
Esta
interface debe heredar de la interface Remote.
·
Todos
los métodos de ésta interface deben lanzar una RemoteException.
b)
Se
implementa la interface remota creando una clase que herede de UnicastREmoteObjet con un constructor
que lance una RemoteException.
public class ObjetoRemoto extends java.rmi.server.UnicastRemoteObject implements InterfaceRemota{
public ObjetoRemoto() throws
java.rmi.RemoteException{super();}
public int suma(int a, int b){
return a + b;
}
}
c)
Se
compila de forma habitual
d)
Al
fichero .class se le pasa el comando rmic
(está en $JAVA_HOME/bin) para generar el objeto stub.
rmic paquete.ObjetoRemoto
e)
Se
inicia el servicio de registro RMI. Antes de lanzar nuestro servidor, debemos lanzar
un programa llamado rmiregistry que
también viene con java (está en $JAVA_HOME/bin). Este programa es el que
realmente sabe todos los objetos que se publican en este ordenador. La llamada Naming.rebind() en realidad coneca con
rmiregistry en este ordenador y le avisa que ObjetoRemoto debe publicarse al
exterior.
Rmiregistry necesita encontrar la clase ObjetoRemoto_Stub.class, así que en el
servidor debemos fijar la propiedad java.rmi.server.codebase con el path, en
formato url, desde el que rmiregistry puede acceder a esta clase.
System.setProperty("java.rmi.server.codebase",
"file:/un_path/");
f)
Se
lanza el servidor
g)
En
el cliente. Se escribe la clase cliente
InterfaceRemota objetoRemoto = (InterfaceRemota)Naming.lookup("//IP_del_Servidor/ObjetoRemoto");
System.out.println("2 + 3 = ");
System.out.println(objetoRemoto.suma(2, 3));
h)
Se
compila de forma habitual. Para compilar necesitaremos el fichero InterfaceRemota.class
i)
Se
lanza el cliente. Si no hemos puesto RMISecurityManager,
necesitaremos los ficheros InterfaceRemota.class
y ObjetoRemoto_Stub.class para
ejecutar.
Arrancar un
RMISecurityManager y escribir un
fichero java.policy de permisos es
peligroso por lo siguiente:
- Si no instalamos el RMISecurityManager, tenemos una seguridad por defecto bastante restrictiva. Si no sabemos, es mejor dejar la de defecto.
- Si instalamos el RMISecurityManager, estamos habilitando una cosa llamada carga dinámica de clases. La carga dinámica de clases consiste en que un cliente pueda enviarnos una clase hecha por él y que no esté en el servidor. Esa clase puede tener código malicioso.
- Si instalamos el RMiSecurityManager, las clases tanto del servidor como las cargadas dinámicamente de los clientes, tienen permiso para hacer aquellas cosas que se les permite en el fichero java.policy. Es decir, el fichero java.policy dice si una clase concreta tiene o no permisos para escribir o leer en disco duro, establecer sockets, etc. En muchos tutoriales, para evitar problemas en el ejemplo y no extenderse en explicaciones, ponen el fichero java.policy con todos los permisos para todo el mundo. Cualquier clase que venga de un cliente podría borrarnos el disco duro.
- Por ello se aconseja no poner RMISecurityManager, salvo que se necesite carga dinámica de clases. En ese caso, no dejar el fichero java.policy con todos los permisos para todo el mundo.
0 comments:
Publicar un comentario