No es un bug, es una característica no documentada

viernes, 4 de marzo de 2016

Procesos y servicios. RMI (III). El ejercicio de la hipoteca

18:24 Posted by Inazio Claver , No comments
Este ejercicio fue el propuesto en clase de Procesos y Servicios para comprobar si se ha comprendido la sección de RMI. Es decir, vamos a ver como se desarrolla  un RMI básico implementando la teoría vista hasta ahora.

Ejercicio de la Hipoteca

Esta es la fórmula para el cálculo de la cuota mensual de una hipoteca.



Por ejemplo, para calcular la cuota de un préstamo hipotecarío de 100.000 unidades de capital, de 20 años de plazo y un tipo de interés fijo del 4% anual en que los pagos se realizan mensualmente, empleamos los siguientes cálculos.

1. Como los pagos son mensuales, comenzamos calculando el plazo expresados en meses y el tipo de interés mensual.


2. La cuota que debemos ingresar mensualmente será:


Vamos a suponer que realizar estos cálculos es de una gran complejidad computacional por lo que vamos a desarrollar un programa distribuido mediante RMI. Para ello crearemos dos programas, un servidor y un cliente. El servidor tendrá un método remoto que sepa calcular dicha cuota. Un cliente lo invocará pasándole los tres datos iniciales, capital, interés y plazo.

Lo primero será programar la interfaz de nuestro objeto remoto

INTERFAZREMOTA.JAVA

package claver.creditos;

import java.rmi.*;
import java.io.Serializable;

/**
* Interface Remota con métodos para llamada en remoto
*/
public interface InterfaceRemota extends Remote{
     
      public double cuotaMensual(double capital, double interes, double plazo) throws RemoteException;
     
} // Fin InterfaceRemota

Y el siguiente paso es desarrollar el objeto remoto propiamente dicho.
OBJETOREMOTO.JAVA

package claver.creditos;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class ObjetoRemoto extends UnicastRemoteObject implements InterfaceRemota{
     
      // Construye una instancia de ObjetoRemoto
      public ObjetoRemoto() throws RemoteException{
            super();
      } // Fin Constructor
     
      // Métodos
     
      // Calcula la cuota mensual de un prestamo dado capital, interes anual y plazo anual
      public double cuotaMensual(double capital, double interes, double plazo){
            System.out.println("Calculando cuota...");
           
            double plazoMes = plazo / 12.00;
            double interesMes = interes / 12.00;
            return (capital * interes) / (100.00 * (1 - (Math.pow(interesMes / 100.00, plazoMes))));
      } // Fin cuotaMensual
} // Fin ObjetoRemoto

Ahora solo queda desarrollar el Servidor, que será el que esperará que le envíen los datos para calcular.

SERVIDOR.JAVA

package claver.creditos;

import java.rmi.*;

/**
* Servidor para el ejemplo RMI
* Exporta un método para sumar dos enteros y devuelve resultado
*/
public class Servidor{
     
      // Crea nueva instancia de Servidor RMI
      public Servidor(){
            try{
                  /* Indico a rmiregistry donde están las clases.
                  Cambio el path al sitio en el que esté.
                  Hay que mantener la raya al final */
                  System.setProperty(
                        "java.rmi.server.codebase",
                        "file:/C:/ejercicios/primero/src_servidor");
                 
                  // Se publica el objeto remoto
                  InterfaceRemota objetoRemoto = new ObjetoRemoto();
                  Naming.rebind("//localhost/ObjetoRemoto", objetoRemoto);
            }
            catch(Exception e){
                  e.printStackTrace();
            }
      } // Fin Constructor
     
      // Main
      public static void main(String[] args){
            new Servidor();
      } // Fin Main
} // Fin Servidor

Y el cliente, que mandará los datos para su cálculo y los recibirá una vez finalizados.

CLIENTE.JAVA

package claver.creditos;

import java.rmi.*;
import java.text.*;

/**
* Ejemplo de cliente rmi nocivo, para aprovecharse de un servidor
* sin SecurityManager
*/
public class Cliente{
     
      // Crea nueva instancia de Cliente
      public Cliente(){
            try{
                  /* Lugar en el que está el objeto remoto
                   *    Debe reemplazarse "localhost" por el nombre o ip donde
                   *    esté corriendo "rmiregistry".
                   *    Naming.lookup() objtiene el objeto remoto
                   */
                  InterfaceRemota objetoRemoto = (InterfaceRemota)Naming.lookup("//localhost/ObjetoRemoto");
                 
                  // Hago calculo remoto
                  System.out.println("Capital: 20.000 euros");
                  System.out.println("Interes: 6%");
                  System.out.println("Plazo: 5 años");
                  DecimalFormat df = new DecimalFormat("#.##");
                  System.out.println("Cuota mensual: " + df.format(objetoRemoto.cuotaMensual(20000.00, 6.00, 5.00)) + " euros");
            }
            catch(Exception e){
                  e.printStackTrace();
            }
      } // Fin constructor
     
      // Main
      public static void main(String[] args){
            new Cliente();
      } // Fin Main
} // Fin Cliente
Después de haber programado todas nuestras clases, deberemos compilarlo y comenzaremos con el montaje del RMI.

Aquí debo hacer varios apuntes.
El primero es que he programado mi proyecto en el IDE Eclipse, teniendo el Workspace en C:\Users\Inazio\Workspace. Esta ruta es importante porque el .stub y la compilación de las clases la vamos a generar por línea de comandos en vez de aprovechar el autocompilado de Eclipse.

La segunda cosa es que si examináis el código, cuando hago el setProperty del System, estoy colocando los paquetes en dos carpetas.

La parte servidora en C:\ejercicios\primero\src_servidor, donde incluiré Servidor.class, InterfazRemota.class, ObjetoRemoto.class y el .stub generado.
Y la parte cliente estará en C:\ejercicios\primero\src_cliente, y pondremos Cliente.class, InterfazRemota.class y el .stub, que debe estar compartido en las dos carpetas.

Vale. Pues por pasos.

Lo primero será compilar todos los .java. Abrimos una terminal (Ejecutar à cmd) y lo primero es acceder a la ruta donde están nuestros archivos (sin entrar al paquete, nos quedamos en src).

cd  C:\Users\Inazio\workspace\EjercicioRMI\src

Ahora compilaremos todos los .java con el comando javac, colocando la ruta de los paquetes y las clases a compilar.

javac claver\creditos\*.java

Ya estarán compilados, así que procederemos a generar el stub con la herramienta rmic.
Lo primero que haremos será situar el CLASSPATH de nuestra consola en la ruta src de nuestro proyecto (es decir, en la ruta de nuestro proyecto sin contar el paquete) y posteriormente lanzaremos la herramienta rmic con la ruta de nuestro objeto remoto. Esta ruta será como si llamásemos a clases de java, es decir, deberemos separarla por puntos.

set CLASSPATH=C:\Users\Inazio\workspace\EjercicioRMI\src
rmic claver.creditos.ObjetoRemoto

Ya tenemos compilado y generado todo lo necesario para nuestra aplicación. Ahora deberemos trasladar estos compilados a la ruta antes mencionada. Es decir:

En C:\ejercicios\primero\src_cliente
è Cliente.class
è InterfazRemota.class
è ObjetoRemoto_Stub.class

En C:\ejercicios\primero\src_servidor
è Servidor.class
è ObjetoRemoto.class
è InterfazRemota.class
è ObjetoRemoto_Stub.class

De vuelta a la consola de comandos, lanzaremos el servicio rmiregistry para que nuestras aplicaciones cliente y servidor puedan comunicarse entre sí.

Habrá que resetear el CLASSPATH modificado antes a uno vacio y ya lanzar el servicio.

set CLASSPATH=
rmiregistry

Se nos quedará la consola como esperando instrucciones. Bien, es lo que tiene que pasar. Abrimos una segunda terminal y accedemos a la ruta src_servidor y ejecutamos nuestro Servidor.

cd C:\ejercicios\primero\src_servidor
java claver.creditos.Servidor

Y lo mismo con nuestro Cliente

cd C:\ejercicios\primero\src_cliente
java claver.creditos.Cliente

Ahora, el cliente enviará los datos al servidor y este procederá a hacer el cálculo y reenviarlo a Cliente, que en este caso en concreto lo mostrará por pantalla.

Ya tenemos hecho nuestro programa RMI. ¿Sencillo?
Un último apunte. Si decides copiar este ejercicio en tu ordenador, acuérdate de modificar las rutas por las que se ajusten a tu ordenador. Por ejemplo es poco probable que tengas C:\Users\Inazio. Cambialo por otra que se ajuste a tu caso.


0 comentarios:

Publicar un comentario