Se me pidió implementar un ejemplo de comunicación RMI en Java para un curso de Sistemas distribuidos. Y como estaba en inglés, traduzco el ejemplo que encontré en tutorial de introducción oficial de Java™ RMI. El famoso Hello, world
Los códigos
Lamentablemente, por la licencia, debo poner todos los comentarios iniciales correspondientes a los disclaimer, así que por eso se ven largos los códigos.
Hola.java
/*
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
* NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
* USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
* ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package ejemplo.hola;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hola extends Remote {
String diHola() throws RemoteException;
}
Servidor.java
/*
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
* NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
* USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
* ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package ejemplo.hola;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Servidor implements Hola{
public Servidor() {}
public String diHola(){
return "Hola, mundo";
}
public static void main(String args[]){
try {
Servidor obj = new Servidor();
Hola stub = (Hola) UnicastRemoteObject.exportObject(obj, 0);
// Liga los datos (stub) del objeto remoto en el registro
Registry registro = LocateRegistry.getRegistry();
registro.bind("Hola",stub);
System.err.println("Servidor listo");
} catch (Exception e) {
System.err.println("Excepción del servidor: " + e.toString());
e.printStackTrace();
}
}
}
Cliente.java
/*
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
* NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
* USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
* ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
package ejemplo.hola;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Cliente {
private Cliente() {}
public static void main(String[] args){
String host = (args.length < 1) ? null : args[0];
try {
Registry registro = LocateRegistry.getRegistry(host);
Hola stub = (Hola) registro.lookup("Hola");
String respuesta = stub.diHola();
System.out.println("respuesta: " + respuesta);
} catch (Exception e) {
System.err.println("Exception del cliente: " + e.toString());
e.printStackTrace();
}
}
}
Cómo compilarlo y ejecutarlo
Para compilarlo, sólo hay que ejecutar el comando usual:
javac -d clases Hola.java Servidor.java Cliente.java
El directorio donde se guardarán las clases (en este ejemplo llamado clases debe existir previamente.
El árbol con los archivos debería quedar como en la siguiente imagen:

Repito. La carpeta clases debe existir previamente.
Para ejecutar este ejemplo, se necesita hacer lo siguiente:
- Iniciat el registro Java RMI
- Iniciar el servidor
- Ejecutar el cliente
Iniciar el registro Java RMI
Para iniciar el registro, ejecuta el comando rmiregistry en el host del servidor. Este comando no produce ningún mensaje de salida (cuando es satisfactorio) y típicamente corre en background. Para más informción, vea la documentación de las herramientas de rmiregistry [paraSolaris, Windows].
Por ejemplo, en Solaris™:
rmiregistry &
En OS X con Java 5 por lo menos es igual que en Solaris pero sin el &
rmiregistry
O, en la plataforma Windows:
start rmiregistry
Por defecto, el registro corre en el puerto TCP 1099. Para iniciar un registro en un puerto diferente, especifica el número de puerto desde la línea de comandos. Por ejemplo, para iniciar el registro en el puerto 2001 sobre la plataforma Windows:
start rmiregistry 2001
Si el registro estará ejecutándose en un puerto distinto del 1099, necesitarás especificar el número de puerto en las llamadas a LocateRegistry.getRegistry en las clases Server y Client. Por ejemplo, si el registro está ejecutándose sobre el puerto 2001 en este ejemplo, la llamada a getRegistry en el servidor sería:
Registry registry = LocateRegistry.getRegistry(2001);
Iniciar el servidor
Para iniciar el servidor, ejecuta la clase Servidor usando el comando java siguiente:
En Solaris:
java -classpath clases -Djava.rmi.server.codebase=file:clases/ ejemplo.hola.Servidor &
En OS X:
java -classpath clases -Djava.rmi.server.codebase=file:clases/ ejemplo.hola.Servidor
Bajo la plataforma Windows:
start java -classpath clases -Djava.rmi.server.codebase=file:clases/ ejemplo.hola.Servidor
donde clases es el directorio raíz del árbol de archivos de las clases (el mismo clases de cuando fueron compilados los archivos fuentes). Definiendo la propiedad de sistema java.rmi.server.codebase asegura que el registro pueda cargar la definición de interfaz remota (ojo que el slash final es importante).
La salida del servidor debería verse como esto:
Servidor listo
El servidor mantiene ejecutándose hasta que el proceso es terminado por el usuario (típicamente matando al proceso).
Ejecutar el cliente
Una vez que el servidor está listo, el cliente puede ser ejecutado de la siguiente forma:
java -classpath clases ejemplo.hola.Cliente
donde clases es el directorio raíz del árbol de archivos de las clases (el mismo clases de cuando fueron compilados los archivos fuentes).
La salida del cliente es el siguiente mensaje:
respuesta: Hola, mundo
Referencias
Etiquetas: codigo, sun
18.11.08.
0 comentarios