En esta página: Objetos Remotos 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
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.
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
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.
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
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.
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.
|