Esercizio 7: Server RMI esportato contemporaneamente su JRMP e IIOP. 


In questo esercizio esporteremo un server remoto DualServer.java con entrambi i protocolli JRMP e IIOP.
Come al solito creiamo un package che chiameremo iiop all'interno di javarmi sia nel server che nel client.

1) L'interfaccia remota RMIInterface.javacontiene due metodi: Il primo e' una banale invocazione
remota che ritorna una stringa con un messaggio; il secondo metodo invece prevede il passaggio,
e quindi la serializzazione,  di un oggetto di tipo SerClass. Tale oggetto viene modificato dal metodo
remoto e ritornato al chiamante.

1.1) Nel package iiop mettiamo la seguente interfaccia remota RMIInterface.java

package iiop;
 
      import java.rmi.Remote;
      import java.rmi.RemoteException;

public interface RMIInterface extends Remote {
    public String hello() throws RemoteException;
    public SerClass alterClass(SerClass classObject) throws RemoteException;
}

1.2) Mettiamo anche l'oggetto serializzabile SerClass.java:


package iiop;

import java.io.Serializable;
import java.rmi.RemoteException;
   
    public class SerClass implements Serializable {
    // members
    private int x;
    private String myString;
   
    // constructor
    public SerClass(int x, String myString) throws RemoteException {
        this.x=x;
        this.myString=myString;
    }
   
    // some accessor methods
    public int getX() {  return x;}
    public void setX(int x) { this.x=x; }
    public String getString() {  return myString;  }
    public void setString(String str) { myString=str; }
    }


1.3) Infine aggiugniamo il nostro server DualServer.java che esportiamo su entrambi i protocolli.


package iiop;

import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import javax.naming.*;
import java.rmi.server.UnicastRemoteObject;
import javax.rmi.PortableRemoteObject;


public class DualServer implements RMIInterface {
    // ESPORTAZIONE DUALE.
    public DualServer() throws RemoteException {
        UnicastRemoteObject.exportObject(this);
        PortableRemoteObject.exportObject(this);
    }
    // IMPLEMENTAZIONE DEI 2 METODI REMOTI
    public String hello() throws RemoteException {
    return "Ciao, questo e' il metodo remoto hello!!! ";
    }
     public SerClass alterClass(SerClass classObject) throws RemoteException {
    // change the values of SerClass and return it.
    classObject.setX(classObject.getX() + 5 );
    classObject.setString(classObject.getString() + " : Ti ho cambiato!" ); // alter the string
    return classObject;
    }   
    public static void main(String[] args) {
    try {
         DualServer svr = new DualServer();
        //BINDING SUL REGISTRO RMI
        Properties prop1 = new Properties();
        prop1.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
        prop1.put(Context.PROVIDER_URL, "rmi://host-del-server:2222");
        InitialContext cxt1 = new InitialContext(prop1);
        cxt1.rebind("ServerDuale", svr);
            System.out.println("Fatto il bind sul registro RMI alla porta 2222");
        // BINDING SUL COSNaming
        // Notare che differentemetne a quanto fatto prima questa volta
        // uso direttamente le proprieta' di sistema nei comandi put. Lo stesso deve accadere nel client.

        Properties prop2 = new Properties();
        prop2.put("java.naming.factory.initial", "com.sun.jndi.cosnaming.CNCtxFactory");
        prop2.put("java.naming.provider.url", "iiop://host-del-server:5555");
        InitialContext cxt2 = new InitialContext(prop2);
        cxt2.rebind("ServerDuale", svr);
            System.out.println("Fatto il bind col CosNaming alla porta 5555");
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    }
}


2) Compiliamo tali sorgenti nel server.

3) Facciamo la compilazione rmic per ottenere gli stub JRMP:

rmic  -d ~/public_html/common/  iiop.DualServer

4) Facciamo una seconda compilazione rmic per ricavare gli stub ed i tie IIOP:

rmic -iiop  -d ~/public_html/common/  iiop.DualServer

5) Lancio il registro RMI alla porta 2222, adottando le solite precauzioni (unset CLASSPATH) e lo
lancio dalla directory javarmi:

rmiregistry 2222 &

6) Lancio il servizio di COSNaming sulla porta 5555 col seguente comando da javarmi.

tnameserv -ORBInitialPort 5555 &

A questo punto entrambi i servizi di naming su cui registrare il server sono stati lanciati.
Non resta che lanciare il server:

7) Lanciamo il server:

java -classpath :/home/...../public_html/common/ -Djava.security.policy=policy  
         -Djava.rmi.server.codebase=file:///home/....... /public-html/common/   iiop.DualServer

Il risultato sara' una piccola schermata in cui si evidenzia che il server si e' registrato
presso i due servizi di naming:

Fatto il bind sul registro RMI alla porta 2222
Fatto il bind col CosNaming alla porta 5555


8) A questo punto passiamo sulla macchina del client e mettiamo nel package iiop l'interfaccia
remota RMIInterface.java ed anche il codice SerClass.java.

9) Inoltre aggiungiamo il codice di due client simili, che si differiscono solo per il fatto che interagiscono
col server utilizzando protocolli diversi:


ClientJRMP.java:

package iiop;

import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import javax.naming.*;
import javax.rmi.PortableRemoteObject;

public class ClientJRMP {
    public static void main(String[] args) {
    try {
           System.out.println("Questo client usa il protocollo JRMP.");
           System.setSecurityManager(new RMISecurityManager());
           //Setto appriatamente l'Initial Context per fare la lookup sul registro RMI attraverso JNDI.
           Properties pr = new Properties();
            pr.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
            pr.put(Context.PROVIDER_URL, "rmi://host-del-server:2222");
            InitialContext ic = new InitialContext(pr);
            // faccio la lookup
            Object objRef = ic.lookup("ServerDuale");
            System.out.println("Ho fatto con successo la lookup sul registro RMI alla porta 2222. ");
            // faccio la narrow sull'inerrfaccia remota RMIInterface
             RMIInterface ri =
                  (RMIInterface)PortableRemoteObject.narrow(objRef, RMIInterface.class);
            // call the hello method
            System.out.println("Invoco il metodo remoto hello().");
           System.out.println("Ricevuto dal server: "+ri.hello()+"\n"); 
           // now lets try RMI serialization
           SerClass se = new SerClass(7, "Client string! ");
           // pass the class to be altered on the server
           // of course behind the scenes this class is being serialized over IIOP
           se = ri.alterClass(se);
           // now let's see the result
           System.out.println("Risultati della serializzazione :\n"+
                       "Il valore dell'intero era 7 adesso e' "+se.getX()+"\n"+
                   "La stringa era \"Client String! \" adesso e' \""+se.getString()+"\"");
    } catch (Exception e) {
        e.printStackTrace();
    }
    }
}


e  ClientIIOP.java:

package iiop;

import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import javax.naming.*;
import javax.rmi.PortableRemoteObject;

public class ClientIIOP {
    public static void main(String[] args) {
    try {
        System.out.println("Questo client usa il protocollo IIOP.");
        System.setSecurityManager(new RMISecurityManager());
        //Setto appriatamente l'InitialContext per fare la lookup sul COSNaming JNDI.
        Properties pr = new Properties();
        pr.put("java.naming.factory.initial", "com.sun.jndi.cosnaming.CNCtxFactory");
        pr.put("java.naming.provider.url", "iiop://host-del-server:5555");
        InitialContext ic = new InitialContext(pr);
        // faccio la lookup
        Object objRef = ic.lookup("ServerDuale");
        System.out.println("Ho fatto con successo la lookup sul COSNaming alla porta 5555.");
        // faccio la narrow sull'inerfaccia remota RMIInterface
        RMIInterface ri =
        (RMIInterface)PortableRemoteObject.narrow(objRef, RMIInterface.class);
        // call the hello method
        System.out.println("Invoco il metodo remoto hello().");
        System.out.println("Ricevuto dal server: "+ri.hello()+"\n"); 
        // now lets try RMI serialization
        SerClass se = new SerClass(5, "Client string! ");
        //pass the class to be altered on the server
        //of course behind the scenes this class is being serialized over IIOP
        System.out.println("Invoco il metodo remoto alterClass() a cui passo un oggetto serializzabile.");
        se = ri.alterClass(se);
        // now let's see the result
        System.out.println("Risultati della serializzazione :\n"+
                       "Il valore dell'intero era 5 adesso e' "+se.getX()+"\n"+
                "La stringa era \"Client String! \" adesso e' \""+se.getString()+"\"");
       
    } catch (Exception e) {
        e.printStackTrace();
    }
    }
}


10) Compiliamo il codice sorgente presso il client.


11)  Lanciamo il client JRMP digitando da javarmi:

java  -Djava.security.policy=policy  iiop.ClientJRMP

verra' prodotta la seguente schermata:

Questo client usa il protocollo JRMP.
Ho fatto con successo la lookup sul registro RMI alla porta 2222.
Invoco il metodo remoto hello().
Ricevuto dal server: Ciao, questo e' il metodo remoto hello!!!
 
Risultati della serializzazione :
Il valore dell'intero era 7 adesso e' 12
La stringa era "Client String! " adesso e' "Client string!  : Ti ho cambiato!"



12) Similmente, se lanciamo il il client IIOP dalla directory javarmi:

java  -Djava.security.policy=policy  iiop.ClientIIOP

verra' prodotta la seguente schermata:


Questo client usa il protocollo IIOP.
Ho fatto con successo la lookup sul COSNaming alla porta 5555.
Invoco il metodo remoto hello().
Ricevuto dal server: Ciao, questo e' il metodo remoto hello!!!
 
Invoco il metodo remoto alterClass() a cui passo un oggetto serializzabile.
Risultati della serializzazione :
Il valore dell'intero era 5 adesso e' 10
La stringa era "Client String! " adesso e' "Client string!  : Ti ho cambiato!"


13) Provate a nascondere gli stub e tie dei due protocolli nella direcotry condivisa ~/public-html/common/iiop/ .
Noterete che se spostate gli stub di JRMP il ClientJRMP non funzionera' perche' non trova gli stub.
Similmente se spostiamo stub e tie per il ClientIIOP.