Está en la página 1de 19

DESARROLLO DE SISTEMAS DISTRIBUIDOS

CALCULADORA RMI INDICE


INTRODUCCIN ........................................................................................................................................ 2 RMI ............................................................................................................................................................ 2 Contexto ............................................................................................................................................. 2 Arquitectura....................................................................................................................................... 3 Elementos ........................................................................................................................................... 4 Ejemplo ............................................................................................................................................... 4 Compilar y ejecutar el servidor .................................................................................................... 6 DESARROLLO PRCTICO ........................................................................................................................ 8 OperacionesServidor.java ................................................................................................................. 8 Operaciones.java ................................................................................................................................ 8 OperacionesImplementacion.java ................................................................................................ 9 OperacionesCliente.java ................................................................................................................ 11 Java.policy........................................................................................................................................... 13 Capturas de pantalla ....................................................................................................................... 14 Calculadora WEB ........................................................................................................................... 16 Conclusiones ........................................................................................................................................... 19 Bibliografa ............................................................................................................................................... 19

DESARROLLO DE SISTEMAS DISTRIBUIDOS

INTRODUCCIN
RMI RMI (Java Remote Method Invocation) esaa un mecanismo ofrecido por Java para invocar un mtodo de manera remota. Forma parte del entorno estndar de ejecucin de Java y proporciona un mecanismo simple para la comunicacin de servidores en aplicaciones distribuidas basadas exclusivamente en Java. Si se requiere comunicacin entre otras tecnologas debe utilizarse CORBA o SOAP en lugar de RMI. RMI se caracteriza por la facilidad de su uso en la programacin por estar especficamente diseado para Java; proporciona paso de objetos por referencia (no permitido por SOAP), recoleccin de basura distribuida (Garbage Collector distribuido) y paso de tipos arbitrarios (funcionalidad no provista por CORBA). A travs de RMI, un programa Java puede exportar un objeto, con lo que dicho objeto estar accesible a travs de la red y el programa permanece a la espera de peticiones en un puerto TCP. A partir de ese momento, un cliente puede conectarse e invocar los mtodos proporcionados por el objeto. La invocacin se compone de los siguientes pasos: Encapsulado (marshalling) de los parmetros (utilizando la funcionalidad de serializacin de Java). Invocacin del mtodo (del cliente sobre el servidor). El invocador se queda esperando una respuesta. Al terminar la ejecucin, el servidor serializa el valor de retorno (si lo hay) y lo enva al cliente. El cdigo cliente recibe la respuesta y contina como si la invocacin hubiera sido local.

Contexto
Desde la versin 1.1 de JDK, Java tiene su propio ORB: RMI (Remote Method Invocation). A pesar de que RMI es un ORB en el sentido general, no es un modelo compatible con CORBA. RMI es nativo de Java, es decir, es una extensin al ncleo del lenguaje. RMI depende totalmente del ncleo de la Serializacin de Objetos de Java, as como de la implementacin tanto de la portabilidad como de los mecanismos de carga y descarga de objetos en otros sistemas, etc.

DESARROLLO DE SISTEMAS DISTRIBUIDOS El uso de RMI resulta muy natural para todo aquel programador de Java ya que ste no tiene que aprender una nueva tecnologa completamente distinta de aquella con la cual desarrollar. Sin embargo, RMI tiene algunas limitaciones debido a su estrecha integracin con Java, la principal de ellas es que esta tecnologa no permite la interaccin con aplicaciones escritas en otro lenguaje. RMI como extensin de Java, es una tecnologa de programacin, fue diseada para resolver problemas escribiendo y organizando cdigo ejecutable. As RMI constituye un punto especfico en el espacio de las tecnologas de programacin junto con C, C++, Smalltalk, etc. La principal diferencia de utilizar RPC o RMI, es que RMI es un mecanismo para invocacin remota de procedmientos basado en el lenguaje de programacin Java que soporta interaccin entre objetos, mientras que RPC no soporta esta caracterstica.

Arquitectura
La arquitectura RMI puede verse como un modelo de cuatro capas. Primera capa

La primera capa es la de aplicacin y se corresponde con la implementacin real de las aplicaciones cliente y servidor. Aqu tienen lugar las llamadas a alto nivel para acceder y exportar objetos remotos. Cualquier aplicacin que quiera que sus mtodos estn disponibles para su acceso por clientes remotos debe declarar dichos mtodos en una interfaz que extienda java.rmi.Remote. Dicha interfaz se usa bsicamente para "marcar" un objeto como remotamente accesible. Una vez que los mtodos han sido implementados, el objeto debe ser exportado. Esto puede hacerse de forma implcita si el objeto extiende la clase UnicastRemoteObject (paquete java.rmi.server), o puede hacerse de forma explcita con una llamada al mtodo exportObject() del mismo paquete. Segunda capa

La capa 2 es la capa proxy, o capa stub-skeleton. Esta capa es la que interacta directamente con la capa de aplicacin. Todas las llamadas a objetos remotos y acciones junto con sus parmetros y retorno de objetos tienen lugar en esta capa. Tercera capa

La capa 3 es la de referencia remota, y es responsable del manejo de la parte semntica de las invocaciones remotas. Tambin es responsable de la gestin de la replicacin de objetos y realizacin de tareas especficas de la implementacin con los objetos remotos, como el establecimiento de las persistencias semnticas y estrategias adecuadas para la recuperacin de conexiones perdidas. En esta capa se espera una conexin de tipo stream (stream-oriented connection) desde la capa de transporte.

DESARROLLO DE SISTEMAS DISTRIBUIDOS Cuarta Capa

La capa 4 es la de transporte. Es la responsable de realizar las conexiones necesarias y manejo del transporte de los datos de una mquina a otra. El protocolo de transporte subyacente para RMI es JRMP (Java Remote Method Protocol), que solamente es "comprendido" por programas Java. Elementos Toda aplicacin RMI normalmente se descompone en 2 partes: Un servidor, que crea algunos objetos remotos, crea referencias para hacerlos accesibles, y espera a que el cliente los invoque. Un cliente, que obtiene una referencia a objetos remotos en el servidor, y los invoca.

Ejemplo
Un servidor RMI consiste en definir un objeto remoto que va a ser utilizado por los clientes. Para crear un objeto remoto, se define una interfaz, y el objeto remoto ser una clase que implemente dicha interfaz. Veamos como crear un servidor de ejemplo mediante 3 pasos: Definir la interfaz remota. Cuando se crea una interfaz remota: La interfaz debe ser pblica. Debe heredar de la interfaz java.rmi.Remote, para indicar que puede llamarse desde cualquier mquina virtual Java. Cada mtodo remoto debe lanzar la excepcin java.rmi.RemoteException en su clusula throws, adems de las excepciones que pueda manejar.

public interface MiInterfazRemota extends java.rmi.Remote { public void miMetodo1() throws java.rmi.RemoteException; public int miMetodo2() throws java.rmi.RemoteException; } Implementar la interfaz remota public class MiClaseRemota extends java.rmi.server.UnicastRemoteObject implements MiInterfazRemota {
4

DESARROLLO DE SISTEMAS DISTRIBUIDOS

public MiClaseRemota() throws java.rmi.RemoteException { // Cdigo del constructor }

public void miMetodo1() throws java.rmi.RemoteException { // Aqu ponemos el cdigo que queramos System.out.println("Estoy en miMetodo1()"); }

public int miMetodo2() throws java.rmi.RemoteException { return 5; // Aqu ponemos el cdigo que queramos }

public void otroMetodo() { // Si definimos otro mtodo, ste no podra llamarse // remotamente al no ser de la interfaz remota }

public static void main(String[] args) { try { MiInterfazRemota mir = new MiClaseRemota(); java.rmi.Naming.rebind("//" + java.net.InetAddress.getLocalHost().getHostAddress() + ":" + args[0] + "/PruebaRMI", mir); } catch (Exception e) { } } }

DESARROLLO DE SISTEMAS DISTRIBUIDOS Como se puede observar, la clase MiClaseRemota implementa la interfaz MiInterfazRemota que hemos definido previamente. Adems, hereda de UnicastRemoteObject, que es una clase de Java que podemos utilizar como superclase para implementar objetos remotos. Luego, dentro de la clase, definimos un constructor (que lanza la excepcin RemoteException porque tambin la lanza la superclase UnicastRemoteObject), y los mtodos de la/las interfaz/interfaces que implemente. Finalmente, en el mtodo main, definimos el cdigo para crear el objeto remoto que se quiere compartir y hacer el objeto remoto visible para los clientes, mediante la clase Naming y su mtodo rebind(...). Nota: Hemos puesto el mtodo main() dentro de la misma clase por comodidad. Podra definirse otra clase aparte que fuera la encargada de registrar el objeto remoto.

Compilar y ejecutar el servidor


Ya tenemos definido el servidor. Ahora tenemos que compilar sus clases mediante los siguientes pasos: Compilamos la interfaz remota. Adems lo agrupamos en un fichero JAR para tenerlo presente tanto en el cliente como en el servidor: javac MiInterfazRemota.java jar cvf objRemotos.jar MiInterfazRemota.class Luego, compilamos las clases que implementen las interfaces. Y para cada una de ellas generamos los ficheros Stub y Skeleton para mantener la referencia con el objeto remoto, mediante el comando rmic: set CLASSPATH=%CLASSPATH%;.\objRemotos.jar;. javac MiClaseRemota.java rmic -d . MiClaseRemota Observamos en nuestro directorio de trabajo que se han generado automticamente dos ficheros.class (MiClaseRemota_Skel.class y MiClaseRemota_Stub.class) correspondientes a la capa stub-skeleton de la arquitectura RMI. Para ejecutar el servidor, seguimos los siguientes pasos: Se arranca el registro de RMI para permitir registrar y buscar objetos remotos. El registro se encarga de gestionar un conjunto de objetos remotos a compartir, y buscarlos ante las peticiones de los clientes. Se ejecuta con la aplicacin rmiregistry distribuida con Java, a la que le podemos pasar opcionalmente el puerto por el que conectar (por defecto, el 1099). En el caso de Windows, se debe ejecutar:
6

DESARROLLO DE SISTEMAS DISTRIBUIDOS start rmiregistry 1234 Y en el caso de Linux: rmiregistry & Por ltimo, se lanza el servidor: java -Djava.rmi.server.hostname=127.0.0.1 MiClaseRemota 1234 Crear un cliente RMI Vamos ahora a definir un cliente que acceder a el/los objeto/s remoto/s que creemos. Para ello seguimos los siguientes pasos: Definir la clase para obtener los objetos remotos necesarios La siguiente clase obtiene un objeto de tipo MiInterfazRemota, implementado en nuestro servidor: public class MiClienteRMI {

private MiClienteRMI() { }

public static void main(String[] args) { try { MiInterfazRemota mir = (MiInterfazRemota) java.rmi.Naming.lookup("//" + args[0] + ":" + args[1] + "/PruebaRMI");

// Imprimimos miMetodo1() tantas veces como devuelva miMetodo2() for (int i = 1; i <= mir.miMetodo2(); i++) { mir.miMetodo1(); } } catch (Exception e) { e.printStackTrace(); } } }
7

DESARROLLO DE SISTEMAS DISTRIBUIDOS Como se puede observar, simplemente consiste en buscar el objeto remoto en el registro RMI de la mquina remota. Para ello usamos la clase Naming y su mtodo lookup(...). Compilar y ejecutar el cliente Una vez que ya tenemos definido el cliente, para compilarlo hacemos: set CLASSPATH=%CLASSPATH%;.\objRemotos.jar;. javac MiClienteRMI.java Luego, para ejecutar el cliente hacemos: java MiClienteRMI 127.0.0.1 1234 Se debe poder acceder al fichero Stub de la clase remota. Para ello, o bien lo copiamos al cliente y lo incluimos en su CLASSPATH, o lo eliminamos del CLASSPATH del servidor e incluimos su ruta en el java.rmi.codebase del servidor (si no se elimina del CLASSPATH del servidor, se ignorar la opcin java.rmi.codebase, y el cliente no podr acceder al Stub).. Si echamos un vistazo a la ventana donde est ejecutndose el servidor RMI, veremos como se ha encontrado el objeto remoto y ejecutado sus mtodos:

DESARROLLO PRCTICO
OperacionesServidor.java
import java.rmi.RMISecurityManager; import java.rmi.RemoteException; public class OperacionesServidor { public static void main(String[] args){ System.setSecurityManager(new RMISecurityManager()); try{ OperacionesImplementacion implementation = new OperacionesImplementacion("//:4000/ OperacionesImplementacion "); System.out.println("Server ready"); }catch(RemoteException e){ e.printStackTrace(); } } }

Operaciones.java
import java.rmi.Remote; import java.rmi.RemoteException; public interface Operaciones extends Remote { public int suma(int[] numeros) throws RemoteException; public double promedio(int[] numeros) throws RemoteException;
8

DESARROLLO DE SISTEMAS DISTRIBUIDOS


public int mayor(int[] numeros) throws RemoteException; public int menor(int[] numeros) throws RemoteException; public int[] burbuja(int[] numeros) throws RemoteException; public int[] seleccion(int[] numeros) throws RemoteException; public int valorEncontrado(int[] numeros, int value) throws RemoteException; }

OperacionesImplementacion.java
import import import import java.net.MalformedURLException; java.rmi.Naming; java.rmi.RemoteException; java.rmi.server.UnicastRemoteObject;

public class OperacionesImplementacion extends UnicastRemoteObject implements Operaciones{ public OperacionesImplementacion (String url) throws RemoteException { super(); try{ Naming.rebind(url, this); }catch(RemoteException | MalformedURLException e){ e.printStackTrace(); } } @Override public int suma(int[] numeros) throws RemoteException { int resultado = 0; for(int numeros: numeros){ resultado += numeros; } return resultado; } @Override public double promedio(int[] numeros) throws RemoteException { return suma(numbers)/numeros.length; } @Override public int mayor(int[] numeros) throws RemoteException { int resultado = Integer.MIN_VALUE; for(int numero: numeros){ if(numero > resultado){ resultado = numero; } } return resultado; }
9

DESARROLLO DE SISTEMAS DISTRIBUIDOS

@Override public int menor(int[] numeros) throws RemoteException { int resultado = Integer.MAX_VALUE; for(int numero: numeros){ if(numero < resultado){ resultado = numero; } } return resultado; } @Override public int[] burbuja(int[] numbers) throws RemoteException { boolean swapped; int j = 0; int tmp; do{ swapped = false; j++; for(int i = 0; i < numbers.length-j; i += 1){ if(numbers[i] > numbers[i+1]){ tmp = numbers[i]; numbers[i] = numbers[i+1]; numbers[i+1] = tmp; swapped = true; } } }while(swapped); return numbers; } @Override public int[] seleccion(int[] numbers) throws RemoteException { int smaller, position, tmp; for(int i = 0; i < numbers.length-1; i += 1){ smaller = numbers[i]; position = i; for(int j = i+1; j < numbers.length; j += 1){ if(numbers[i] < smaller){ smaller = numbers[i]; position = j; } } if(position != i){ tmp = numbers[i];
10

DESARROLLO DE SISTEMAS DISTRIBUIDOS


numbers[i] = numbers[position]; numbers[position] = tmp; } } return numbers; } @Override public int valorEncontrado(int[] numbers, int value) throws RemoteException { for(int i = 0; i < numbers.length; i += 1){ if(numbers[i] == value){ return i; } } return -1; } }

OperacionesCliente.java

import import import import import import

java.io.BufferedReader; java.io.IOException; java.io.InputStreamReader; java.rmi.Naming; java.rmi.NotBoundException; java.rmi.RMISecurityManager;

public class OperacionesCliente { public static void main(String[] args) { System.setSecurityManager(new RMISecurityManager()); BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in)); boolean salir = true; int opcion; int valor; int[] numeros; int[] resultado; String[] aux; try{ Operaciones operacion = (Calculator)Naming.lookup("rmi://127.0.0.1:4000/OperacionesImplementacion "); while(exit){ System.out.println("Calculadora RMI"); System.out.println("1) Suma"); System.out.println("2) Promedio"); System.out.println("3) Mayor"); System.out.println("4) Menor"); System.out.println("5) Valor encontrado"); System.out.println("6) Burbuja");
11

DESARROLLO DE SISTEMAS DISTRIBUIDOS


System.out.println("7) Seleccion"); System.out.println("8) Salir"); System.out.print("Opcion: "); opcion = Integer.parseInt(teclado.readLine()); switch(opcion){ case 1: System.out.print("Numeros: "); aux = teclado.readLine().split(","); numeros = new int[aux.length]; for(int i = 0; i < aux.length; i += 1){ numeros[i] = Integer.parseInt(aux[i]); } System.out.println("Resultado: " + operaciones.suma(numeros)); break; case 2: System.out.print("Numeros: "); Aux = teclado.readLine().split(","); numeros = new int[aux.length]; for(int i = 0; i < aux.length; i += 1){ numeros[i] = Integer.parseInt(aux[i]); } System.out.println("Resultado: " + operaciones.promedio(numeros)); break; case 3: System.out.print("Numeros: "); aux = teclado.readLine().split(","); numeros = new int[aux.length]; for(int i = 0; i < aux.length; i += 1){ numeros[i] = Integer.parseInt(aux[i]); } System.out.println("Resultado: " + operaciones.mayor(numeros)); break; case 4: System.out.print("Numeros: "); aux = teclado.readLine().split(","); numeros = new int[aux.length]; for(int i = 0; i < aux.length; i += 1){ numeros[i] = Integer.parseInt(aux[i]); } System.out.println("Resultado: " + operaciones.menor(numeros)); break; case 5: System.out.print("Numeros: "); aux = teclado.readLine().split(","); numeros = new int[aux.length]; for(int i = 0; i < aux.length; i += 1){ numeros[i] = Integer.parseInt(aux[i]); } System.out.print("Valor: "); valor = Integer.parseInt(teclado.readLine());
12

DESARROLLO DE SISTEMAS DISTRIBUIDOS


System.out.println("Resultado: " + operaciones.valorEncontrado(numeros, valor)); break; case 6: System.out.print("Numeros: "); aux = teclado.readLine().split(","); numeros = new int[aux.length]; for(int i = 0; i < aux.length; i += 1){ numeros[i] = Integer.parseInt(aux[i]); } resultado = operaciones.burbuja(numeros); System.out.print("Resultado: "); for(int i = 0; i < resultado.length; i += 1){ System.out.print(resultado[i] + " "); } System.out.print("\n"); break; case 7: System.out.print("Numeros: "); aux = teclado.readLine().split(","); numeros = new int[aux.length]; for(int i = 0; i < aux.length; i += 1){ numeros[i] = Integer.parseInt(aux[i]); } result = operaciones.seleccion(numeros); System.out.print("Resultado: "); for(int i = 0; i < resultado.length; i += 1){ System.out.print(resultado[i] + " "); } System.out.print("\n"); break; case 8: salir = false; break; } } }catch(IOException | NotBoundException e){ e.printStackTrace(); } } }

Java.policy

grant{ permission java.security.AllPermission; };

13

DESARROLLO DE SISTEMAS DISTRIBUIDOS

Capturas de pantalla
Servidor

Cliente

14

DESARROLLO DE SISTEMAS DISTRIBUIDOS

15

DESARROLLO DE SISTEMAS DISTRIBUIDOS

Calculadora WEB Probar la calculadora en diferentes paquetes y ahora con cliente web.

Ilustracin 1.RMI Servidor

Ilustracin 2.RMI Cliente WEB

16

DESARROLLO DE SISTEMAS DISTRIBUIDOS

Ilustracin 3.Servidor Funcionando

17

DESARROLLO DE SISTEMAS DISTRIBUIDOS

18

DESARROLLO DE SISTEMAS DISTRIBUIDOS

Conclusiones
En el presente ejercicio se hizo uso de RMI, el cual es un mecanismo que permite que una aplicacin en este caso se comunique con objetos que residen en programas que se ejecutan en mquinas remotas, tambin al probar RMI en diferentes folders se observ que no importaba y segua funcionando. Por ultimo para corroborar el funcionamiento de RMI se prob el funcionamiento en diferentes paquetes (Cliente y Servidor) agregando al servidor una interfaz web.

Bibliografa
http://es.wikipedia.org/wiki/Java_Remote_Method_Invocation

19

También podría gustarte