Java RMI Ejemplo básico Arquitectura Cliente Servidor Cliente.java Cliente.java Servidor.java Servidor.java Stub Stub Skeleton Skeleton RMI RMI Internet Arquitectura Cliente Cliente.java Cliente.java Stub Stub Leyenda: manual manual generado generado infraestructra infraestructra (Remote) (Remote) Interface Interface rmic RMI Registry RMI Servidor Servidor.java Servidor.java Skeleton Skeleton RMI Internet El interfaz rmi Métodos con tipos básicos, que implementan Serializable, o que implementan Remote RemoteDate.java RemoteDate.java package p4; import java.rmi.*; import java.util.Date; public interface RemoteDate extends java.rmi.Remote{ /* Constructor */ public Date getRemoteDate() throws java.rmi.RemoteException; /*El nombre del servicio para el registro */ public final static String LOOKUPNAME = "RemoteDate"; } Ojo: no puede tener espacios El cliente package p4; DateClient.java DateClient.java import java.rmi.*; import java.util.Date; public class DateClient { protected static RemoteDate netConn = null; public static void main(String[] args) { try{ netConn = (RemoteDate)Naming.lookup(RemoteDate.LOOKUPNAME); Date fecha = netConn.getRemoteDate(); System.out.println(fecha); }catch (Exception e){ System.err.println("Excepción en RemoteDate: " + e.getMessage()); e.printStackTrace(); } } } El servidor DateServer.java DateServer.java package p4; import java.rmi.*; Crea una nueva instancia de DateServer public class DateServer { public static void main(String[] args) { try{ //Creo una instancia del objeto que será compartido RemoteDateImpl im = new RemoteDateImpl(); System.out.println("Arrancando DateServer..."); //Registro y saco del Registro Naming.rebind(RemoteDate.LOOKUPNAME, im); System.out.println("...OK"); }catch(Exception e){ System.err.println(e); System.exit(1); } } } Da error hasta que exista el stub/skeleton bind da error si el nombre ya estaba definido en el rmiregistry (este es el caso cuando cae el servidor y se arranca de nuevo), así que mejor usar siempre rebind La implementación del servidor package p4; import java.rmi.*; import java.rmi.server.*; import java.util.Date; RemoteDateImpl.java RemoteDateImpl.java Podría sutituirse por: java.rmi.server.UnicastRemoteObject.exportObject(this); public class RemoteDateImpl extends UnicastRemoteObject implements RemoteDate{ public RemoteDateImpl() throws RemoteException {//Por super(); //Deja listas la comunicaciones } Implementar UnicastRemoteObject /** La implementación del interfaz remoto*/ public Date getRemoteDate() throws RemoteException{ return new Date(); } } Implementación del método del interfaz rmi Paso a paso (Windows) Compilamos código de cliente y servidor: javac p4\*.java La opción –d permite generar en el directorio indicado. Si no se Generamos stub y skeleton: indica genera en el dir actual rmic -classpath . p4.RemoteDateImpl (esto genera los ficheros RemoteDateImpl_Stub.class y RemoteDateImpl_Skel.class a partir de RemoteDateImpl.class) Arrancamos el rmiregistry (en el servidor): start rmiregistry rmiregistry debe estar en el PATH Arrancamos el servidor: start java p4.DateServer Arrancamos el/los cliente/s: java p4.DateClient Nota: 1.- se asume que todos los .java están en el mismo directorio 2.- en Java 1.5, rmic no se genera RemoteDateImpl_Skel.class, sino que se crea dinámicamente y se usa cuando se necesita. Usa protocolo rmi 1.2. Para garantizar portabilidad, la opción –vcompat usa el protocolo rmi antiguo Máquinas distintas Si el cliente y el servidor están en máquinas distintas: El rmiregistry corre en la máquina del servidor El .java del cliente cambia Por ejemplo: lookup(arg[0]) hará que el cliente se invoque así: DateClient //x.y.z.k/RemoteDate IP del servidor