La utilidad del RMI es poder ejecutar funciones en otro ordenador , interesante si queremos por ejemplo hacer cálculos dentro de un programa y nuestro cliente no es lo suficiente potente, pues mediante RMI accederíamos a los objetos necesarios que residirían en un ordenador más potente y todo como si estuviesen nuestro propio ordenador.
La interfaz RMI declara cuales de estos métodos son accesibles desde otras Java Virtual Machines (JVM). Necesitamos crear el siguiente escenario para poder trabajar con RMI: Un interfaz que indique qué funciones son accesibles, un objeto que implemente dichas funciones, un servidor que dé de alta a la interfaz y un cliente que acceda a la interfaz remotamente.
Existen varias reglas que deben implementarse para funcionar correctamente:
En la interficie solamente se declaran las funciones que pueden usarse remotamente y en el cliente se implementan.
Interfaz ejemplo: HelloInt.java
/// Interfaz del programa HelloWorld mediante RMI
// Carlos Morales, 2002
package rmihello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface HelloInt extends Remote{
String sayHello() throws RemoteException;
}
Comentarios:
Implementación ejemplo: HelloImpl.java
/// Implementación del programa HelloWorld mediante RMI
// Carlos Morales, 2002
package rmihello;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class HelloImpl extends UnicastRemoteObject implements HelloInt{
public HelloImpl() throws RemoteException{
super(); // implicit
}
public String sayHello() throws RemoteException{
return "Hello World";
}
}
Comentarios:
El servidor será el encargado de dar de alta al programa. Este necesita:
Servidor ejemplo: HelloServer.java
/// El Servidor de la aplicación HelloWorld mediante RMI
// Carlos Morales, 2002
package rmihello;
import java.rmi.RMISecurityManager;
import java.rmi.Naming;
public class HelloServer{
public static void main(String arg[]){
/// 1. Crear e instalar un controlador de securidad (security manager)
if(System.getSecurityManager()==null){
System.setSecurityManager(new RMISecurityManager());
}
try{
/// 2. Crear una o mas instancias al objeto remoto
HelloImpl remObj = new HelloImpl();
/// 3. Registrar al menos uno de los objetos remotos
// Ligar el objeto con el nombre "HelloServerBind"
Naming.rebind("//MiHost/HelloServerBind",remObj);
System.out.println("HelloServerBind dado de alta en el rmiregistry");
}catch( Exception e){
System.out.println(e.toString());
}
}
}
Comentarios:
El cliente debe "bajarse" la interfaz del servidor y quien le diga al servidor que operaciones debe ejecutar. Para ello se necesita que:
Cliente ejemplo: HelloClientRMI.java
/// El Cliente de la aplicación HelloWorld mediante RMI
// Carlos Morales, 2002
package rmihello;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.rmi.Naming;
public class HelloClientRMI{
public static void main(String arg[]){
/// 1. Crear e instalar un security manager.
if(System.getSecurityManager()==null)
System.setSecurityManager(new RMISecurityManager());
try{
System.out.println("Lado del Cliente -");
/// 2. Bajarse la interfaz mediante RMI.
HelloInt interf = (HelloInt)Naming.lookup("//hostRemoto/HelloServerBind");
/// 3. Usar las funciones de la interfaz.
System.out.println("Stub dice... " + interf.sayHello());
}catch(Exception e){
System.out.println("Exception: " +e.toString());
}
}
}
Comentarios:
Tenemos 3 ficheros por la parte del servidor (HelloInt.java, HelloImpl.java y HelloServer.java) que deben ser compilados a la vez. Y luego tenemos por parte del cliente el fichero HelloClientRMI.java.
Todos residirán en el directorio ejemplo:
Para compilar los ficheros del servidor introducir:
La opción -d nos indica el directorio de los ficheros fuente. Al estar incluido en el package rmihello el compilador creará un directorio llamado rmihello y pondrá allí los ficheros .class
Luego tenemos que generar los Stubs y lo Skeletons con el compilador rmi de la siguiente manera:
El Stub es la clase que trabaja en el cliente y el skeleton en el servidor y ambos encapsulan RMI. Los dos ficheros generados automáticamente son: HelloImpl_Stub.class y HelloImpl_Skel.class
Para compilar el cliente:
Necesitamos ejecutar tres cosas: el RMIregistry, el servidor y el cliente.
1. Al ejecutar el registro RMI (RMIregistry) podrá dar de alta aplicaciones RMI y preguntar por ellas. Como se ha dicho antes este se da de alta en el puerto 1099 pero también se puede configurar. Si se quiere saber más sobre el rmiregistry visitar las páginas de java.sun.com según sea para Solaris o bien sea para Win32.
Para arrancar introducir en la línea de comandos:
2. Al ejecutar el servidor damos de alta en el RMIregistry nuestra aplicación para que puedan acceder a ella desde otras partes. Y se ejecuta en la línea de comandos con:
Esta operación es la más delicada y puede dar miles de fallos insospechados. Se sabe que todo ha funcionado correctamente si se observa un HelloServerBind dado de alta en el rmiregistry lo que indica que no ha habido ninguna Excepción.
Puede ser por el contrario que hayan errores, si la Java Virtual Machine nos 'vomita' un angustioso
java.lang.ClassNotFoundException
posiblemente sea porque los stubs no estan en el CLASSPATH.
También puede lanzarnos un
java.security.AccessControlException: access denied
(java.net.SocketPermission 127.0.0.1:1099 connect,resolve)
que además de pillarnos desprevenidos nos dolerá.
Si aparece esto recomiendo rezar un par de padre nuestros, confesarse y pasarse por los links de la Bibliografía
que nos indican cómo solucionarlo. Recuerdo que los Firewalls pueden bloquear el acceso a estos puertos.
3. Al arrancar el cliente desde cualquier máquina accedemos al servidor y este nos debe retornar el resultado de las operaciones que en este caso será un simple String.
En el lado del cliente deben estar presentes los ficheros HelloClientRMI.class (el cliente en sí), HelloInt.class (la interfaz necesaria para hacer el cast) y el HelloImpl_Stub.class (que es el Stub).
Ejecutar en la línea de comandos:
Espero que hayas aprendido algo y te hayas divertido también. Si hay cualquier comentario, fallos conceptuales, o lo que sea escribirme. Ahora bien si ejecutando esto destrozaís el ordenador, o entraís en el pentagono yo no tengo nada que ver, vaya me excluyo de toda responsabilidad.
Copyright © 2002 by Carlos Morales. All rights reserved.
Bibliografía
En la red:
Libros de la compañía Sun:
Web: http://developer.java.sun.com/developer/infodocs/#books Título: Advanced Programming for the JavaTM 2 Platform Autores: Calvin Austin and Monica Pawlan Publicado por: Addison Wesley Professional, ISBN: 0201715015, November 1999