El sistema RMI (Java Remote Method Invocation)� es un mecanismo que permite a un objeto en una m�quina virtual Java llamar a m�todos de objetos en otra m�quina virtual Java. Cualquier objeto cuyos m�todos puedan ser invocados de esta forma debe implementar el interface java.rmi.Remote. Cuando dicho objeto es invocado, sus argumentos son formateados y env�ados desde la m�quina virtual local a la remota, donde los argumentos son des-formateados y usados. Cuando el m�todo termina, los resultados son formateados desde la m�quina remota y env�ados a la m�quina virtual del llamador.
Para hacer que un objeto remoto sea accesible para otras m�quinas virtuales, un programa lo coloca t�picamente con el registro RMI. El programa suministra al registro el nombre del objeto remoto as� como el propio objeto. Cuando un programa desea tener acceso a un objeto remoto, suministra el nombre del objeto al registro que est� en la misma m�quina que el objeto remoto. El registro devuelve al llamador una referencia (llamada stub [esqueleto]) al objeto remoto.
Cuando el programa recibe el stub del objeto remoto, puede llamar a sus m�todos (a trav�s del stub).
Un programa tambi�n puede obtener referencias a objetos remotos como resultado de llamadas a otros objetos remotos o desde otros servicios de nombres. Por ejemplo, el programa puede buscar una referencia a un objeto remoto desde un servidor LDAP que soporta el esquema definido en la RFC 2713.
El nombre aceptado por el registro RMI tiene la s�ntaxis: "rmi://hostname:port/remoteObjectName", donde hostname y port identifican la m�quina y el puerto, respectivamente, en los que se est� ejecutando el registro RMI y remoteObjectName es el nombre del objeto remoto. hostname, port, y el prefijo, "rmi:", son opcionales. Si no se especifica hostname, el valor por defecto es el host local. Si no se especifica el puerto, el valor por defecto es 1099. Si no es especifica remoteObjectName, entonces el objeto que est� siendo nombrado es el propio registro RMI. Puedes ver la Especificaci�n RMI para m�s detalles.
RMI puede soportarse usando el "Java Remote Method Protocol" (JRMP) y el "Internet Inter-ORB Protocol" (IIOP). El JRMP es un protocolo especializado dise�ado para RMI; el IIOP es el protocolo est�ndar de comunicaci�n entre objetos CORBA. RMI sobre IIOP permite a los objetos remotos Java comunicarse con objetos CORBA que podr�an estar escritos en lenguajes de programaci�n distintos de Java.
Algunos proveedores de servicios, como el LDAP de Sun, soportan uniones de objetos java.rmi.Remote en el directorio. Cuando los objetos java.rmi.Remote y/o las entradas de registro RMI se unen en un espacio de nombres enterprise como el LDAP, los clientes RMI pueden buscar objetos java.rmi.Remote sin conocer en qu� m�quina se est� ejecutando el objeto.
�Unir un Objeto Remoto
|
Antes de Continuar:
Para ejecutar este ejemplo, necesitamos la Java 2 Platform, v1.2 o una versi�n superior. Tambi�n necesitaremos ldapbp.jar, como se explic� en la introducci�n de esta lecci�n. |
El siguiente ejemplo define un interface java.rmi.Remote: Hello que tiene un m�todo, sayHello().
public interface Hello extends Remote {
public String sayHello() throws RemoteException;
}
Tambi�n define una implementaci�n para este interface, HelloImpl.
public class HelloImpl extends UnicastRemoteObject implements Hello {
public HelloImpl() throws RemoteException {
}
public String sayHello() throws RemoteException {
return ("Hello, the time is " + new java.util.Date());
}
}
Este ejemplo tambi�n crea un ejemplar de HelloImpl y lo une al directorio, asign�ndole el nombre "cn=RemoteHello".
// Create the remote object to be bound, and give it a name
Hello h = new HelloImpl();
// Bind the object to the directory
ctx.bind("cn=RemoteHello", h);
Despu�s de que el objeto se haya unido al directorio, una aplicaci�n puede buscarlo usando el siguiente c�digo.
Hello h2 = (Hello)ctx.lookup("cn=RemoteHello");
h2.sayHello();
Para ejecutar este ejemplo, debemos hacer lo siguiente.
- Compilar Hello.java, HelloImpl.java y este
ejemplo.
# javac Hello.java HelloImpl RemoteObj.java
- Ejecutar rmic con HelloImpl como argumento
para producir los stubs (esqueletos) del objeto remoto.
# rmic HelloImpl
- Copiar Hello.class, HelloImpl.class y los ficheros class generados por el rmic a un directorio del servidor Web.
- Especificar este directorio como el codebase para el int�rprete Java.
# java -Djava.rmi.server.codebase=http://web1/example/classes/ RemoteObj
RemoteObj no termina, porque crea el objeto remoto HelloImpl con el que otros clientes RMI pueden contactar para usarlo. Sin embargo, este programa terminar� eventualmente, cuando el objeto remoto se convierta en recolectable para la basura. Para evitar esto, debemos mantener (viva) una referencia al objeto remoto. Si hemos registrado el objeto en el registro RMI, entonces mantener una referencia no ser� necesario porque el registro la mantiene autom�ticamente.
Cuando posteriormente busquemos el objeto desde el directorio, �ste devolver� el objeto HelloImpl unido. El RMI descargar� autom�ticamente las clases necesarias desde el codebase especificado en la propiedad "java.rmi.server.codebase". Puedes ir a la lecci�n Leer Objetos desde el Directorio para ver un ejemplo.
�Unir un Objeto Remoto Usando un Referencia
|
Antes de continuar:
Este ejemplo requiere que hayamos arrancado el registro RMI en nuestra m�quina. Tambi�n necesitamos rmiregistry.jar, como se explic� en la introducci�n de esta lecci�n. |
El siguiente ejemplo usa la mismas clases Hello y HelloImpl del ejemplo anterior. Crea una Reference que contiene una URL RMI ("rmi://mymachine/hello") y la une al directorio.
String rmiurl = "rmi://mymachine/hello";
// Create the reference containing the (future) location of the object
Reference ref = new Reference("Hello", new StringRefAddr("URL", rmiurl));
// Bind the object to the directory
ctx.bind("cn=RefHello", ref);
Luego crea un ejemplar de HelloImpl y lo une al registro RMI local usando la misma URL RMI ("rmi://mymachine/hello").
// Create the remote object to be bound Hello h = new HelloImpl(); // Bind the object to the RMI registry ctx.rebind(rmiurl, h);
Despu�s de que el objeto se haya unido en el directorio y en el registro RMI, una aplicaci�n puede buscar el objeto usando el siguiente c�digo.
Hello h2 = (Hello)ctx.lookup("cn=RefHello");
System.out.println(h2.sayHello());
En efecto, este m�todo tiene m�s de un nivel de indirecci�n que los que ofrec�an los ejemplos anteriores. La informaci�n almacenada en el directorio (la Reference) es realmente un puntero a informaci�n almacenada en otro servicio de nombres (el registro RMI), que a su vez, contiene la referencia al objeto java.rmi.Remote.
Para ejecutar este ejemplo, debemos hacer lo siguiente.
- Realizar los pasos 1-3 del ejemplo anterior.
- Compilar este ejemplo.
# javac RemoteRef.java
- Especificar el directorio codebase como el codebase para el int�rprete Java.
# java -Djava.rmi.server.codebase=http://web1/example/classes/ RemoteRef
RemoteRef no termina, porque crea el objeto remoto HelloImpl con el que pueden contactar otros clientes RMI.
Cuando posteriormente busquemos este objeto en el directorio, �ste devolver� el objeto remoto HelloImpl unido. El RMI descargar� autom�ticamente los ficheros class necesarios desde el codebase especificado en la propiedad "java.rmi.server.codebase". Puedes ir a la lecci�n Leer Objetos desde el Directorio para ver un ejemplo.
�Unir un Objeto Remoto que usa IIOP
|
Antes de Continuar:
Este ejemplo requiere que tengamos ldapbp.jar, como se explic� en la introducci�n a esta lecci�n. Si no estamos usando el Java 2 SDK, v1.3, tambi�n necesitamos instalar el RMI-IIOP Standard Extension. Si no estamos usando el Java 2 SDK, v1.2 o una versi�n superior, tambi�n necesitamos instalar Java IDL, una versi�n que viene con RMI-IIOP Standard Extension. |
El procedimiento de unir un objeto java.rmi.Remote que usa IIOP o JRMP es identico en lo que a JNDI concierne. Desde la perspectiva del usuario/aplicaci�n, s�lo se diferencian en c�mo se genera el esqueleto (stub) para el objeto java.rmi.Remote. La b�squeda del objeto presenta una diferencia mayor: cuando el objeto es buscado desde el directorio (o alg�n otro servicio de nombres) el resultado debe apuntarse usando javax.rmi.PortableRemoteObject.narrow() en lugar de usar el operador de forzado de tipo de Java.
El siguiente ejemplo usa el interface Hello del ejemplo JRMP. Define una implementaci�n de este interface, RiHelloImpl, que es an�loga a HelloImpl, excepto que desciende de javax.rmi.PortableRemoteObject en lugar de java.rmi.server.UnicastRemoteObject.
public class RiHelloImpl extends PortableRemoteObject implements Hello {
public RiHelloImpl() throws RemoteException {
}
public String sayHello() throws RemoteException {
String date = new String((new java.util.Date()).toString());
return ("RMI/IIOP hello | " + date);
}
}
El ejemplo crea un ejemplar de RiHelloImpl y lo une al directorio, asign�ndole el nombre "cn=RmiiiopHello".
// Create the remote object to be bound, and give it a name
Hello h = new RiHelloImpl();
// Bind the object to the directory
ctx.bind("cn=RmiiiopHello", h);
Despu�s de que el objeto se haya unido al directorio, una aplicaci�n puede buscarlo usando el siguiente c�digo.
// Look up the object
org.omg.CORBA.Object cobj = (org.omg.CORBA.Object)ctx.lookup("cn=RmiiiopHello");
// Narrow the object to the desired type
Hello robj = (Hello)PortableRemoteObject.narrow(cobj, Hello.class);
// Invoke the method
System.out.println(robj.sayHello());
Para ejecutar este ejemplo, debemos hacer lo siguiente.
- Compilar Hello.java, RiHelloImpl.java y este
ejemplo.
# javac Hello.java RiHelloImpl RmiiiopObj.java
- Ejecutar rmic con RiHelloImpl como argumento
y la opci�n "-iiop" para producir stubs IIOP para el
objeto remoto.
# rmic -iiop RiHelloImpl
- Copiar Hello.class, RiHelloImpl.class y los ficheros class generados por rmic a un directorio en el servidor Web.
- Especificar este directorio como el codebase para el int�rprete Java.
# java -Djava.rmi.server.codebase=http://web1/example/classes/ RmiiiopObj
RmiiiopObj no termina, porque crea el objeto remoto RiHelloImpl con el que otros clientes RMI pueden contactar y utilizar.
Cuando posteriormente buscamos este objeto desde el directorio, �ste devolver� el objeto remoto RiHelloImpl unido. El RMI descargar� autom�ticamente los ficheros class necesarios desde el codebase especificado en la propiedad "java.rmi.server.codebase".
Puedes ir a la lecci�n Leer Objetos desde el Directorio para ver un ejemplo.