Ejercicio práctico de RMI: un programa distribuido cliente-servidor que calcula la cuota mensual de una hipoteca de forma remota.
Fundamento matemático
La cuota mensual de un préstamo se calcula según la fórmula:

Ejemplo: para un préstamo de 100.000 € al 4% anual a 20 años con pagos mensuales:


Estructura del proyecto (4 clases)
El proyecto tiene la siguiente estructura:
InterfaceRemota.java— Interfaz remota con el métodocuotaMensual().ObjetoRemoto.java— Implementación del cálculo, extiendeUnicastRemoteObject.Servidor.java— Publica el objeto remoto medianteNaming.rebind().Cliente.java— Obtiene el objeto remoto e invoca el cálculo medianteNaming.lookup().

Código
InterfaceRemota.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
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
// Calcula la cuota mensual de un préstamo dado capital, interés 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
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 barra 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
Cliente.java
package claver.creditos;
import java.rmi.*;
import java.text.*;
/**
* Ejemplo de cliente RMI
*/
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() obtiene el objeto remoto */
InterfaceRemota objetoRemoto = (InterfaceRemota) Naming.lookup("//localhost/ObjetoRemoto");
// Hago cálculo 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
Pasos para compilar y ejecutar
# 1. Compilar todo desde el directorio src
javac claver/creditos/*.java
# 2. Generar el stub con rmic
rmic claver.creditos.ObjetoRemoto
# 3. Copiar los .class del servidor al directorio del servidor
# y los del cliente al directorio del cliente
# 4. Arrancar rmiregistry (desde el directorio con los .class)
rmiregistry
# 5. Ejecutar el servidor
java claver.creditos.Servidor
# 6. Ejecutar el cliente
java claver.creditos.Cliente