Esercizio 7: Server RMI esportato contemporaneamente su JRMP e IIOP.
In questo esercizio esporteremo un server remoto DualServer.java
su entrambi i protocolli JRMP e IIOP.
Come al solito creeremo un package che chiameremo iiop all'interno di javarmi sia nel server
che nel client.
1) L'interfaccia remota RMIInterface.java
contiene 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 aggiungiamo 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("Fatta
la bind sul registro RMI alla porta 2222");
// BINDING SUL COSNaming
// Notare che differentemente da 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("Fatta bind
col CosNaming alla porta 5555");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
2) Compiliamo tali sorgenti nel server.
3) Dopodiche' 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:
Fatta la bind sul registro RMI
alla porta 2222
Fatta la 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 directory
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.