Aspectos avanzados de Java: RMI,
JDBC y Extensiones Multimedia
Dr. Antonio LaTorre
e-mail:
[email protected]
Índice
Java RMI
JDBC
Extensiones Multimedia
Java RMI
Java RMI
RMI = Remote Method Invocation
Es la implementación de Java de RPC (Remote Procedure Call)
Permite invocar a métodos de objetos remotos a través del
protocolo TCP/IP
Objetos en la misma máquina
Objetos en máquinas distintas
Arquitectura Cliente/Servidor
Ambos conocen y comparten una interfaz
Comunicación a través de la red transparente
Características de Java RMI
Uso de un Middleware: capa de abstracción para la
comunicación entre procesos remotos. Oculta:
Localización de objetos
Protocolos de comunicación
Transferencia de datos
Hardware subyacente
Sistema Operativo
Recogida de basura distribuida
Orientado a acciones
Hace hincapié en la invocación de métodos
Arquitectura RMI
Service Directory
Arquitectura de un programa RMI
Interfaz
Implementación
Stub
Skeleton
Servidor
Cliente
Servidor de Nombres RMI
Interfaz
Conjunto de métodos que serán implementados por el objeto
remoto y que pueden ser accedidos por el cliente
Especificación de nombre de los métodos y argumentos
No se proporciona una implementación
La interfaz debe extender java.rmi.Remote y ser pública
Todos los métodos declarados deben poder lanzar la
excepción java.rmi.RemoteException
Implementación
Es una clase Java normal
Extiende la clase java.rmi.server.UnicastRemoteObject
Implementa el Interfaz definido anteriormente
Debe proporcionar una implementación para todos los métodos
En el constructor de esta clase hay que llamar al constructor
de la clase UnicastRemoteObject
Hay que usar super()
Stub y Skeleton
Son clases intermedias que abstraen de la comunicación por red
entre cliente y servidor
Cliente Stub
[Red] Skeleton Servidor
Implementan la misma interfaz que “Interfaz”
Antes de Java 1.2
rmic Implementación
Ahora no es necesario...
Skeleton se crea automáticamente a partir de Java 1.2
Stub se crea automáticamente a partir de Java 5
Servidor
Crea el objeto que será accedido remotamente
Instancia el objeto que implementa la interfaz
Registra el objeto remoto (asignándole un nombre) en un
Servidor de Nombres RMI
Sin reemplazo: Naming.bind()
Con reemplazo: Naming.rebind()
rmi://<nombre máquina>:<puerto>/<nombre referencia>
El servidor puede implementarse en una clase aparte o dentro de
la clase Implementación
La instanciación y el registro habría que hacerlos en el main
Cliente
Obtiene una referencia al objeto remoto con el que desea
conectar
Realiza una petición a un Servidor de Nombres RMI
Método Naming.lookup() pasando como argumento el nombre con el
que se registró el objeto remoto (en el mismo formato cualificado)
Una vez recibido el objeto remoto, se pueden invocar sus
métodos como si fuera un objeto local
Los objetos pasados como argumento recibidos como valor de
retorno son serializados (proceso conocido como marshalling)
Servidor de Nombres RMI
Repositorio centralizado de objetos remotos
Los servidores, los registran
Los clientes, los recuperan
Puede iniciarse de dos maneras
Desde consola: rmiregistry [puerto]
Desde el código del servidor LocateRegistry.createRegistry()
Al crearlo hay que decirle en qué puerto debe escuchar (por
defecto, el 1099)
El cliente puede acceder a él de dos formas
A través de Naming
Mediante una instancia del registro:
LocateRegistry.getRegistry()
Arquitectura de un programa RMI
Programando con RMI
Paquetes necesarios
java.rmi
jama.rmi.server
RemoteException
Los métodos de la interfaz y su implementación deben lanzar
Siempre que se invoque a un método remoto o un método del
servicio de nombres hay que capturar sus excepciones
Errores en la comunicación entre los procesos (fallos de acceso o de
conexión)
Fallo en la invocación del objeto remoto (objeto no disponible)
Fallo en el registro de un objeto
Etc.
Desarrollo de aplicaciones RMI
Ejemplo: Hola Mundo (Interfaz)
package hello;
import java.rmi.*;
public interface HelloInterface extends Remote {
public void sendMessage(String msg) throws
RemoteException;
public String getMessage() throws RemoteException;
}
Ejemplo: Hola Mundo (Implementación)
package hello;
import java.rmi.*;
import java.rmi.server.*;
public class HelloImpl extends UnicastRemoteObject implements
public HelloImpl() throws RemoteException {
HelloInterface {
super();
}
public void sendMessage(String msg) throws RemoteException {
System.out.println(msg);
}
public String getMessage() throws RemoteException {
return "Hello from the server";
}
}
Ejemplo: Hola Mundo (Servidor)
package hello;
import java.net.*;
import java.rmi.*;
import java.rmi.server.*;
public class HelloServer {
// ...
Ejemplo: Hola Mundo (Servidor)
//...
public static void main(String args[]) {
HelloImpl obj = new HelloImpl();
Naming.bind("HelloServ", obj);
try {
}
catch (RemoteException e) {
}
catch (AlreadyBoundException e) {
}
catch (MalformedURLException e) {
}
}
}
System.out.println("RemoteException " + e);
System.out.println("AlreadyBoundException");
System.out.println("MalformedURLException");
Ejemplo: Hola Mundo (Cliente)
package hello;
import java.net.*;
import java.rmi.*;
public class HelloClient {
static public void main(String args[]) {
HelloInterface obj = (HelloInterface)
Naming.lookup("HelloServ");
obj.sendMessage("Hello from the client");
System.out.println(obj.getMessage());
try {
}
//...
Ejemplo: Hola Mundo (Cliente)
System.out.println("RemoteException " + e);
System.out.println("AlreadyBoundException");
System.out.println("MalformedURLException");
//...
catch (RemoteException e) {
}
catch (NotBoundException e) {
}
catch (MalformedURLException e) {
}
}
}
Ejemplo: Hola Mundo – Puesta en marcha
Compilación
javac hello/*.java
Generación del Stub (Opcional en Java 5+)
rmic hello.HelloImpl
Ejecución del Servicio de Nombres RMI
rmiregistry <puerto>
Puerto por defecto: 1099
Ejecución del servidor
java hello.HelloServer
Ejecución del cliente
java hello.HelloClient
mostrar el resultado
Ejercicio
Crear una aplicación que implemente una calculadora
La ventana tendrá dos cajas de texto para los operandos y otra para
La operación a realizar se seleccionará de la manera que nos
Sólo se podrá seleccionar una operación si los operandos son
La operación debe realizarse en un servidor local
La interfaz tendrá un método por cada operación válida
El cliente invocará a dichos métodos a través de una instancia
El servidor realizará la operación correspondiente y devolverá el
parezca más oportuna (ComboBox, Buttons, RadioButtons, etc.)
válidos
resultado
Ejercicio
Paso de parámetros: Serialización
La serialización consiste en traducir un objeto en una lista de
bytes
Almacenamiento (persistencia)
Transmisión (invocación de procedimientos remotos)
Procesado en ambos extremos: serialización y deserialización
¿Cómo se pasan los distintos tipos de datos?
Tipos primitivos: por valor
Objetos: por valor (en lugar de por referencia, como se haría
normalmente?
Objeto remoto exportado: se transmite el stub del objeto
Paso de parámetros: Serialización
Un objeto puede ser simple...
... o estar compuesto de otros objetos o tipos primitivos
... o que extienda a una clase base
Es necesario que todos los atributos de un objeto y las clases de las
que hereda sean serializables
¿Cómo se consigue esto?
Los objetos deben implementar la interfaz Serializable
No define ningún método
Es una “marca” que indica que el objeto puede ser convertido en una lista de
bytes
Si se desea, se pueden redefinir los métodos de serialización
Los tipos primitivos y otros objetos de Java ya son serializables
Redefiniendo los métodos de serialización
Hay que implementar los siguientes métodos
private void writeObject (ObjectOutputStream stream) throws IOException
}
private void readObject (ObjectInputStream stream) throws IOException {
{
stream.defaultWriteObject();
...
stream.defaultReadObject();
...
}
Es importante respetar la signatura y, recomendado, llamar a los serializadores
por defecto
Si los redefinimos en una jerarquía de clases, en cada clase sólo hay que
serializar lo correspondiente a dicha clase
Ejercicio
Escribir un programa que trabaje con Personas y Estudiantes
La clase Persona almacena nombre, apellidos y edad
La clase Estudiante extiende la clase Persona y almacena un
vector de Asignaturas
Crear un objeto remoto que devuelva objetos de tipo Persona
y Estudiante por medio de sendos métodos
Imprimir en el cliente las personas y estudiantes devueltos
Recordatorio: Los objetos a enviar deben ser serializables...
Servidor de Nombres RMI
RMI puede utilizar distintos servicios de nombres:
JNDI (Java Naming and Directory Interface)
RMI Registry: servicio sencillo incluido con RMI
Interfaz remota Registry:
Métodos lookup(), bind(), rebind(), unbind() y list()
Asocia objetos a cadenas de caracteres
Clase LocateRegistry
Clase Naming
Permite crear y recuperar objetos que implementan Registry
Invoca métodos de un objeto remoto que implementa Registry
Int
Comentarios de: Aspectos avanzados de Java: RMI, JDBC y Extensiones Multimedia (0)
No hay comentarios