Java RMI Remote Method Invocation Invocación Remota de Métodos en Java Contenido Introducción Implementación Diseño de la interfaz remota. Implementación de la interfaz remota. Obtención de las clases Stub y Skeleton. Aplicación del Servidor. Aplicación del Cliente. Ejecución Registro de objetos remotos Iniciar el Servidor Establecer la política de seguridad Iniciar el Cliente. Universidad de Huelva I.T. Informática Programación Concurrente Introducción Programación Distribuida Modelo cliente-servidor Servidor Cliente Cliente Universidad de Huelva I.T. Informática Programación Concurrente Introducción Arquitectura RMI Cliente Capa de Aplicación Servidor Stub Capa Proxy Skeleton Capa de Referencia Remota Capa de Transporte Universidad de Huelva I.T. Informática Programación Concurrente Introducción Arquitectura RMI Cliente Servidor Interface Remota Stub Implementación Interface Remota Aplicación Cliente Skeleton Aplicación Servidor Registra Objetos Universidad de Huelva I.T. Informática Programación Concurrente Introducción Pasos para el desarrollo de aplicaciones Implementación Diseño y compilación de la interfaz remota. Implementación de la interface remota en una clase y su compilación. Obtención de las clases Stub y Skeleton a partir de la interface remota. Desarrollo y Compilación de la Aplicación del Servidor. Desarrollo y Compilación de la Aplicación del Cliente. Ejecución Registro de objetos remotos Iniciar el Servidor Establecer la política de seguridad Iniciar el Cliente. Durante la explicación realizaremos un ejemplo tipo “Hola, Mundo!”. Universidad de Huelva I.T. Informática Programación Concurrente Implementación Diseño de la Interface Remota import java.rmi.*; public interface <nombInterfaceRemota> extends Remote { // prototipos de los métodos remotos que deben lanzar // la excepción RemoteException. } Compilación javac <nombInterfaceRemota>.java Æ <nombInterfaceRemota>.class Interface de nuestro ejemplo: IntSaludo.java import java.rmi.*; public interface IntSaludo extends Remote { // Un método remoto que recibe y devuelve una cadena String saludo(String soy) throws RemoteException; } Universidad de Huelva I.T. Informática Programación Concurrente Implementación Implementación de la interface remota import java.rmi.*; import java.rmi.server.*; class <nombClase> extends UnicastRemoteObject implements IntSaludo { // El constructor debe invocar al constructor de UnicastRemoteObject: super(); // Se deben implementar los métodos remotos de la Interface. } Compilación javac <nombClase>.java Æ <nombClase>.class En nuestro ejemplo: ClsSaludo.java import java.rmi.*; import java.rmi.server.*; class ClsSaludo extends UnicastRemoteObject implements IntSaludo { public ClsSaludo() throws RemoteException { super(); } public String saludo(String soy) throws RemoteException { return “Hola “+soy; } } Universidad de Huelva I.T. Informática Programación Concurrente Implementación Las clases Stub y Skeleton // ojo sólo versiones anteriores a jdk 1.5 Las clases Stub y Skeleton son obtenidas a partir de la clase anterior. Compilador de Java RMI: rmic rmic <nombClase> Æ Crear un fichero .jar con las clases jar cvf <ficheroClass>.jar *.class Æ nombClase_Stub.class nombClase_Skel.class <ficheroClass>.jar $ InterfaceRemota.class nombClase.class nombClase_Stub.class nombClase_Skel.class En nuestro Ejemplo Universidad de Huelva jar cvf *.class saludo.jar Æ I.T. Informática saludo.jar Programación Concurrente Implementación La aplicación del servidor import java.rmi.*; public class <apServidor> { … // Establecer el gestor de seguridad System.setSecurityManager(new RMISecurityManager()); // Instancias de Objetos Remotos // Registros de Objetos Remotos try { nombClase <objRemoto> = new nombClase(); Naming.rebind(“<url>\<nomObj>”, <objRemoto>); } catch (Exception ex) { System.err.println(“Error: " + ex.getMessage()); e.printStackTrace(); } … } Compilación: javac <apServidor>.java Universidad de Huelva I.T. Informática Æ <apServidor>.class Programación Concurrente Implementación La aplicación del servidor de nuestro Ejemplo import java.rmi.*; public class apServidor { public static void main(String arg[]) { // Establecer el gestor de seguridad System.setSecurityManager(new RMISecurityManager()); // Instancias de Objetos Remotos // Registros de Objetos Remotos try { ClsSaludo objRemoto = new ClsSaludo(); Naming.rebind("//localhost/nomObj", objRemoto); System.out.println("Objeto Registrado"); } catch (Exception ex) { System.err.println("Error: " + ex.getMessage()); ex.printStackTrace(); } } } Universidad de Huelva I.T. Informática Programación Concurrente Implementación La aplicación del Cliente import java.rmi.*; public class <apCliente> { … // Obtener la referencia del objeto remoto y convertirla al tipo interface remota // invocar métodos remotos try { obj = (<InterfaceRemota>) Naming.lookup(“<url>/<objRemoto>"); obj.metodoRemoto(); } catch (Exception e) { System.out.println("Excepcion: " + e.getMessage()); e.printStackTrace(); } … } Compilación: javac <apCliente>.java Universidad de Huelva I.T. Informática Æ <apCliente>.class Programación Concurrente Implementación La aplicación del Cliente de nuestro ejemplo import java.rmi.*; public class apCliente { public static void main(String arg[]) { // Obtener la referencia del objeto remoto y convertirla al tipo interface remota // invocar métodos remotos try { IntSaludo obj = (IntSaludo) Naming.lookup("//localhost/nomObj"); System.out.println(obj.saludo("Jose Luis")); } catch (Exception e) { System.out.println("Excepcion: " + e.getMessage()); e.printStackTrace(); } } } Universidad de Huelva I.T. Informática Programación Concurrente Pasos previos a la ejecución El bin de java debe estar en el path: c:\set path=”c:\Archivo deProgramas\java\jdk1.5.0\bin” Deben compilarse los fuentes en el entorno o usando linea de comando: javac *.java Producirá un .class por cada clase fuente en el servidor y en el cliente (si son maquinas distintas) El Classpath debe estar disponible donde se encuentren las clases en la maquina servidora y cliente (caso de que sean distintas) c:\rmi>set CLASSPATH = . o set CLASSPATH = “Directorio donde estan los .class” En nuestro ejemplo set CLASS PATH = “c:\rmi” Universidad de Huelva I.T. Informática Programación Concurrente Ejecución Iniciar el registro de objetos: rmiregistry (Nota: es posible establecer un puerto específico) rmiregistry ó mejor start rmiregistry Iniciar el servidor. (supongase que el directorio de trabajo es c:\ejRMI) Especificar el fichero .jar que contiene las clases Establecer la política de seguridad java -Djava.rmi.server.codebase=file:/c:\ejRMI\<ficheroClass>.jar -Djava.security.policy=<java.policy> <apServidor> Fichero para la política de seguridad grant { permission java.net.SocketPermission "*:1024-65535", "connect,accept"; permission java.net.SocketPermission "*:80", "connect"; }; Si queremos permitir todo, el fichero puede ser sólo esta línea: grant { permission java.security.AllPermission; }; Iniciar el Cliente: Universidad de Huelva java <apCliente> I.T. Informática Programación Concurrente Ejecución de nuestro ejemplo Registrar Objetos: Iniciar Servidor: (supongase que el directorio de trabajo es c:\rmiEj3) start rmiregistry java -Djava.rmi.server.codebase=file:/c:\rmiEj3\saludo.jar -Djava.security.policy=java.policy apServidor Iniciar Cliente java apCliente Universidad de Huelva I.T. Informática Programación Concurrente Productor - Consumidor Interface Remota public interface IBuffer extends java.rmi.Remote { void poner(int num) throws java.rmi.RemoteException; int coger() throws java.rmi.RemoteException; } Universidad de Huelva I.T. Informática Programación Concurrente Productor - Consumidor Implementación Interface Remota class CBuffer extends UnicastRemoteObject implements IBuffer { private int almacen[]=new int[4]; private int ent, sal, cont; public CBuffer() throws RemoteException { super(); ent=sal=cont=0; } public synchronized void poner(int n) throws RemoteException { while (cont==4) try { wait(); } catch(InterruptedException e) {} almacen[ent]=n; ent = (ent + 1) % 4;cont++; notify(); } public synchronized int coger() throws RemoteException { while (cont==0) try { wait(); } catch(InterruptedException e) {} int o = almacen[sal]; sal = (sal + 1) % 4;cont--; notify(); return o; } Universidad de Huelva I.T. Informática Programación Concurrente Productor - Consumidor Cliente productor import java.rmi.*; class CProductor { IBuffer obj; void producir() { try { obj = (IBuffer) Naming.lookup("//localhost/ObjBuffer"); } catch (Exception e) { System.out.println("Excepcion: " + e.getMessage()); } for(int i=1;i<=10;i++) { System.out.println("Quiero Escribir"); try { obj.poner(d); } catch (Exception e) { System.out.println("Excepcion: " + e.getMessage()); } System.out.println("Puesto: " + i); } } public static void main(String args[]) { CProductor c = new CProductor(); c.producir(); } } Universidad de Huelva I.T. Informática Programación Concurrente Productor - Consumidor Cliente Consumidor import java.rmi.*; class CConsumidor { IBuffer obj;int d; void consumir() { try { obj = (IBuffer)Naming.lookup("//localhost/ObjBuffer"); } catch (Exception e) { System.out.println("Excepcion: " + e.getMessage());} do { System.out.println("Quiero leer"); try { d = obj.coger(); } catch (Exception e) { System.out.println("Excepcion: " + e.getMessage()); } System.out.println("Leido: " + d); }while(d!=10); } public static void main(String args[]) { CConsumidor c = new CConsumidor(); c.consumir(); } } Universidad de Huelva I.T. Informática Programación Concurrente Java RMI Invocación Remota de Métodos