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.