Cos’è
l’ORB ?
ORB
in inglese vuole dire globo e, nel contesto della programmazione distribuita,
rappresenta l’ossatura su cui si basa la comunicazione fra gli oggetti
distribuiti.
L’acronimo
ORB significa Object Request Broker, ovvero un agente di scambio di messaggi
fra oggetti e svolge il duplice scopo di gestire la comunicazione tra stub
e skeleton e di nascondere al client l' allocazione della macchina fisica
sulla quale sono in esecuzione gli oggetti remoti. In questo modo il client
ha la sensazione che non ci sia differenza tra la chiamata ai metodi di
oggetti locali o remoti.
L’OMG
(Object Management Group) ha definito un’architettura comune per gli ORB
permettendo così la nascita della specifica CORBA.
Esistono
ORB non conformi allo standard CORBA, come RMI(Javasoft) e DCOM(Microsoft),
e altri invece conformi come JavaIDL(Javasoft), Visibroker(Inprise) e Orbix(Iona).
Stub e Skeleton
Per
potersi agganciare ad un ORB un oggetto ha bisogno di uno strato di software
aggiuntivo che si chiama per convenzione stub dalla parte client e skeleton
dalla parte server.
Lo
stub è il proxy locale del client che effettua le chiamate all'interfaccia
privata del core dell'ORB per innoltrare le richieste del client all'oggetto
remoto.
Lo
Skeleton è l'analogo dello stub sulla parte server e viene utilizzato
dall'ORB per invocare i metodi dell'oggetto.
Sia
RMI, RMI-IIOP che Corba permettono di generare automaticamente questo strato
di software.
Il Repository
ed il Naming service
Quando
si avvia un server come prima cosa registra nel repository l'insieme delle
istanze degli oggetti che gestisce.
Per
ottenere il riferimento ad un oggetto remoto si interroga una sorta di
database posizionato sulla macchina in cui è in esecuzione l'oggetto
remoto. Questo database usa come chiave di accesso un nome assegnato all'oggetto
in fase di registrazione e ritorna un riferimento per quell'oggetto.
In
generale il server, al suo avvio, istanzia e registra i suoi oggetti nel
repository, assegnandogli un certo nome; il client interroga il repository
fornendo il nome dell'oggetto e ottenendo il relativo riferimento.
Il
servizio che permette l'associazione di nomi ad oggetti è detto
naming service, mentre il server che gestisce tale servizio (e quindi il
repository) è il naming server.
Ogni
nome è unico all'interno di un contesto (naming context) che contiene
le associazioni dei nomi agli oggetti.
L’operazione
di registrazione di un oggetto e di associazione di un nome logico
è datta bind mentre l'operazione relativa all’ottenimento del
riferimento all'oggetto remoto mediante il nome logico associato è
detta di lookup.
Corba
mette a disposizone dei servizi (security, naming e transactions) che complementano
e aumentano le funzionalità dell'ORB; tali servizi, si chiamano
COS e non sono altro che interfacce IDL (Services Objects) .
Il
servizio di Naming si chiama CosNaming e permette di localizzare
gli oggetti agganciati all'ORB.
Per
attivare il NameServer nella piattaforma Java 2 si esegue l'applicazione
tnameserv che attiva un demone in ascolto sulla porta TCP 900.
Il
servizio di naming di RMI-JRMP permette di associare nomi o URL agli oggetti
distribuiti mediante i metodi statici (bind/lookup) della classe Naming
mentre la funzione di namimg server è svolta dall’RmiRegistry.
Nel
caso di RMI-IIOP si utilizza JNDI (Java Naming Directory Interface) che
offre la possibilità di utilizzare diversi servizi di nomi e directory
tra i quali CORBA-IIOP, RMI-JRMP e LDAP.
La comunicazione
client-server in ambito distribuito
In
generale il funzionamento di applicazioni in ambito distribuito è
il seguente :
-
La prima
operazione da eseguire è l’attivazione del namimg server (tnameserv
per Corba e Rmi-IIOP, RmiRegistry per Rmi-JRMP)
-
Successivamente
si manda in esecuzione il server che effettua la registrazione dell’oggetto
remoto associandogli un nome logico (operazione di bind).
-
Il client
invoca un metodo di un oggetto remoto.
-
Lo strato
di interfaccia verso l' ORB (Stub), localizza l' oggetto (tramite nome
logico) e ottiene la definizione della sua interfaccia tramite il
repository (operazione di lookup)
-
Utilizzando
IDL nel caso di Corba, Java per RMI, i parametri di input del metodo vengono
in un formato standard che viene utilizzato per compilare il messaggio
di request.
-
Il messaggio
di request viene consegnato all' ORB che provvede a dispacciarlo all' object
adapter (BOA), oppure al PortableObjectAdapter (POA) del nodo di rete che
ospita l' implementazione dell'oggetto in questione.
-
L’OA decodifica
il dati nel formato locale e li consegna ai componenti di interfaccia dell'
implementazione (Skeleton ) il quale rispondono con un messaggio di reply
ripetendo al contrario il percorso (codifica,invio,decodifica).
-
La reply
viene recapitata al client e la sua elaborazione continua.
CORBA
CORBA
(Common Object Request Broker Architecture) è uno standard aperto,
non legato ad alcun particolare produttore, che definisce l'architettura
per la realizzazione di applicazioni distribuite orientate agli oggetti.
Per
una trattazione specifica dell’argomento rimando agli articoli di MokaByte.
Mi preme ricordare che CORBA è più potente (e complicato)
rispetto ad RMI e non è legato ad uno specifico linguaggio di sviluppo
permettendo così l'interfacciamento con sistemi eterogenei anche
non Java.
Corba
porta la definizione di ORB a un livello di astrazione tale da permettere,
ai vari implementatori degli ORB che rispettino tale specifica, di agganciare
a un ORB "oggetti" scritti in linguaggi differenti, come per esempio C,
C++, Cobol, SmallTalk, Ada e Java, e di farli colloquiare fra loro.
IDL
L’indipendenza
dal linguaggio utilizzato in Corba la si ottiene grazie all’ IDL.
L'IDL
(Interface Description Language) è un linguaggio che definisce cosa
fa un oggetto (ma non come) offrendo un meccanismo indipendente dal linguaggio
di programmazione utilizzabile per l’implementazione dei metodi dell’oggetto.
Il
mapping tra IDL e il linguaggio d'implementazione avviene tramite un opportuno
compilatore IDL.
Ad
ogni statement IDL viene associato il relativo costrutto del linguaggio
utilizzato per lo sviluppo.
Nella
tabella 1 viene riportato il mapping IDL in Java e IDL in C++.
IDL
|
Java
|
C++
|
module
|
package
|
namespace
|
interface
|
interface
|
Abstract
class
|
operation
|
method
|
Member
function
|
exception
|
exception
|
exception
|
Tabella
1
Volendo
sviluppare il concatenatore di stringhe trattato in [1] in chiave Corba
bisogna innanzitutto creare il file IDL :
//
File : ConcatApp.idl
module
hellopackage {
interface
MyServerInterface {
string concat(in string a, in string b);
};
};
Utilizzando
il compilatore IDL idltojava di Javasoft, tramite il comando
idltojava
-fno-cpp ConcatApp.idl
si
ottiene la directory hellopackage con i seguenti files :
_MyServerInterfaceImplBase
_MyServerInterfaceStub
MyServerInterface
MyServerInterfaceHelper
MyServerInterfaceHolder
Dove
il file MyServerInterface.java contiene il codice dell'interfaccia Java
per il concatenamento delle due stringhe ricevute in ingresso:
package
hellopackage;
public
interface MyServerInterface
extends org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity {
String concat(String a, String b);
}
A questo
punto si crea il Servant che estende da _MyServerInterfaceImplBase
:
import
hellopackage.*;
class
ConcatServant extends _MyServerInterfaceImplBase {
public
String concat(String a, string b) { return "CORBA:"+ a + b; }
}
ed
un server che effettua la registrazione dell'oggetto ConcatServant con
il nome logico MyService :
.
. .
//
mediante il metodo statico init della classe org.omg.CORBA.ORG
//
otteniamo un'istanza dell'ORB
ORB
orb = ORB.init(args, null);
ConcatServant
ref = new ConcatServant();
//
istanzio l'oggetto remoto ConcatServant
orb.connect(ref);
//
connetto il Servant all'ORB
//
recupero il root naming context
org.omg.CORBA.Object
objRef = orb.resolve_initial_references("NameService");
//
utilizzo il metodo statico narrow della classe Helper e ottengo un NamingContext
NamingContext
ncRef = NamingContextHelper.narrow(objRef);
//
Assegno il nome logico
NameComponent
nc = new NameComponent("MyService", "");
NameComponent
path[] = {nc};
//
Registro l'oggetto objRef con nome logico MyService
ncRef.rebind(path,
ref);
//
Attesa di richieste dal client
java.lang.Object
sync = new java.lang.Object();
synchronized
(sync) { sync.wait(); }
.
. .
Il
client può così ottenere il riferimento dell'oggetto remoto
mediante il nome logico MyService ed invocare su tale riferimento i metodi
dell’oggetto remoto.
. .
ORB
orb = ORB.init(args, null); // crea e inizializza l'ORB
//
Otteniamo un reference al NameService
org.omg.CORBA.Object
objRef = orb.resolve_initial_references("NameService");
//
Otteniamo un NamingContext mediante downcast tramite
//
il metodo narrow della classe Helper
NamingContext
ncRef = NamingContextHelper.narrow(objRef);
//
Specifichiamo il nome logico dell'oggetto remoto desiderato
NameComponent
nc = new NameComponent("MyService", "");
NameComponent
path[] = {nc};
//
Ottenimento del reference dell'oggetto remoto mediante
//
il metodo resolve del NamingContext
//
Il metodo resolve restituisce un oggetto org.omg.CORBA.Object
//
che viene perfezionato in un reference
//
di MyServerInterface mediante il cast del metodo narrow()
//
della classe NamingContextHelper
MyServerInterface
HelloRef = MyServerInterfaceHelper.narrow(ncRef.resolve(path));
System.out.println(HelloRef.concat("Hello","
Corba World!"));
//
invocazione metodi dell'oggetto remoto
.
. . .
Guardano
il file ConcatApp.idl ed il file MyServerInterface.java si nota che il
compilatore IDL ha effettuato il seguente mapping tra i due linguaggi :
IDL
Statement
|
Java
Statement
|
module
hellopackage
|
package
hellopackage;
|
interface
MyServerInterface
|
public
interface MyServerInterface
|
string
concat(in string a, in string b);
|
String
concat(String a, String b);
|
Per
un esempio completo di applicazione Corba vedere [2]
RMI
RMI
e un' insieme di API potente e semplice, che permette di sviluppare applicazioni
distribuite in rete.
Su
MokaByte l’argomento è stato ampiamente trattato. Va puntualizzato
che, nell’ottica di questo articolo, RMI ha un proprio ORB che non risponde
alle specifiche CORBA. Questo significa che oggetti che utilizzano l'ORB
di RMI potranno solo colloquiare con oggetti che utilizzano il medesimo
ORB.
Il
protocollo proprietario della Javasoft su cui si base RMI si chiama JRMP
(Java Remote Method Protocol).
Inoltre
il "contratto" tra client e server che in Corba è definito dal modulo
IDL, in RMI è "stipulato" dall'interfaccia Java. Questo implica
che per usare RMI non occorre conoscere IDL perchè l'unico linguaggio
di sviluppo è eclusivamente Java.
Fondamentalmente
RMI è una tecnologia semplice ma chiusa, sia il client che il server
devono essere scritti esclusivamente in Java.
La
figura 1 schematizza il codice ed i passi che sono stati affrontati nell’esempio
proposto nell’articolo [1].
|
Figura
1
RMI o Corba ?
Dopo
questa panoramica veloce su RMI e CORBA, la questione è :quale utilizzare
?
L’utilizzo
di RMI è consigliabile nel caso in cui si debba implementare una
struttura a oggetti distribuiti full-java.
Se
invece ci si trova nella necessità di dover realizzare applicazioni
distribuite in cui esistono già dei pezzi realizzati con linguaggi
differenti, la scelta ideale può essere l’utilizzo di Corba.
La
maggiore libertà d’implementazione, (C,C++,Smalltalk oppure Java
stesso) richiede come contropartita la conoscenza dell’IDL.
Nella
tabella 2 si riassumono le caratterisitche di RMI e CORBA.
|
CORBA
|
RMI
|
ORB
|
Multi-vendor
|
Javasoft
Non
rispetta specifiche Corba
Utilizzo
del protocollo proprietario JRMP
|
IDL
|
SI
|
NO
|
Definizione
contratto client-server
|
ConcatApp.idl
|
MyserverInterface.java
|
Compilatore
IDL
|
Multi-vendor
(idltojava-Javasoft)
|
rmic
|
File
generati dal compilatore
|
_MyServerInterfaceImplBase.java
(Servant)
_MyServerInterfaceStub.java
MyServerInterface.java
MyServerInterfaceHelper.java
MyServerInterfaceHolder.java
|
MyServerImpl_Stub.class
MyServerImpl__Skel.class
(solo
per JDK 1.1)
|
Stub
|
_MyServerInterfaceStub.java
|
MyServerImpl_Stub.class
|
Skeleton
|
_MyServerInterfaceImplBase.java
|
MyServerImpl__Skel.class
|
Servant
extends
|
_MyServerInterfaceImplBase
|
UnicastRemoteObject
|
Servant
implements
|
|
MyServerInterface
|
Naming
service
|
CosNaming
|
RmiRegistry
|
Start
Namimg Server
|
tnameserv
|
rmiregistry
|
TCP
default port
|
900
|
1099
|
Registrazione
Oggetto remoto
|
NamingContextHelper.narrow()
NamingContext.rebind()
|
Naming.rebind()
|
Ottenimento
riferimento all'oggetto remoto
|
NamingContextHelper.narrow()
NamingContext.resolve()
|
Naming.lookup();
|
Tabella
2
RMI – IIOP
RMI-IIOP
è stato sviluppato da Sun e IBM che hanno collaborato con l'OMG
per sviluppare una nuova versione di RMI in grado di comunicare non
solo con il protocollo proprietario Sun JRMP, ma anche con il protocollo
IIOP.
La
specifica CORBA introduce un protocollo GIOP (General Inter-ORB Protocol)
che definisce il formato dei messaggi e la rappresentazione dei dati per
tutte le comunicazioni tra oggetti distribuiti su uno stesso ORB, o su
ORB di produttori differenti al fine di permettere l'interoperabilità
tra ORB diversi.
GIOP
si appoggia a sua volta ad un qualunque protocollo di trasporto, purché
orientato alla connessione, per portare a destinazione i suoi messaggi.
Una
particolare implementazione del protocollo GIOP, chiamata IIOP (Internet
Inter-ORB Protocol), si avvale del protocollo TCP/IP per la realizzazione
dello strato di trasporto dei messaggi tra oggetti remoti.
IIOP
quindi è una sorta di “collante” che si appoggia su TCP/IP tra gli
oggetti distribuiti su ORB diversi tra loro.
Tramite
l’utilizzo di IIOP vedremo come è possibile gettare un ponte tra
RMI e CORBA.
RMI-IIOP è
compatibile con RMI
La
nuova versione di RMI (RMI-IIOP) utilizza IIOP rappresentando di fatto
il primo punto d'incontro tra RMI e CORBA, fino a questo momento incompatibili
tra di loro.
RMI-IIOP
è completamente compatibile con RMI-JRMP e permette di comunicare
(con delle limitazioni) con applicativi CORBA.
Mediante
l'utilizzo di API JNDI è possibile configurare applicazioni che
utilizzino indifferentemente JRMP o IIOP senza ricompilazione di codice.
JNDI
Java
Naming Directory Interface è un'API che offre servizi di naming
e directory per la comunicazione fra moduli software Java. La caratteristica
importante della API JNDI è quella di potere utilizzare differenti
Naming Service (Lightweight Directory Access Protocol, CORBA COSNaming
Service, RMI Registry) in maniera del tutto trasparente al programmatore.
La
funzione principale di un servizio di Naming è quella di associare
(mapping) nomi logici ad oggetti fisici.
Con
RMI tale mapping avviene mediante invocazione del metodo statico bind della
classe Naming, mentre con JNDI si ottiene mediante il metodo bind della
classe InitalContext; tale metodo non essendo statico richiede che
sia istanziato un oggetto di classe InitialContext.
Un
Naming service adotta una Naming convention cioè un'appropriata
sintassi con cui specificare le risorse.
La
sintassi per gli URL RMI è :
rmi://<host>:<tcp
port>/<nomeLogicoOggettoRemoto>
mentre
nel caso di Rmi-IIOP la convenzione è praticamente analoga:
iiop://<host>:<tcp
port>/<nomeLogicoOggettoRemoto>
Ad
una Naming convention è associato un Contesto, vale a dire un insieme
di coppie nome-oggetto che, risolte con il metodo lookup, permettono di
ottenere il riferimento dell'oggetto desiderato.
Da
osservare che in RMI il metodo lookup della classe Naming è statico,
mentre con JNDI l'invocazione del metodo lookup è da effettuare
su un'istanza di classe InitialContext.
|
Figura
2
La
specifica implementazione del servizio viene decisa mediante l'inizializzazione
opportune proprietà che indicano le classi del servizio che si vuole
utilizzare. Per inizializzare un contesto di naming bisogna fornire la
factory e l'URL del provider: la factory è implementata da una delle
classi contenute nel package delle JNDI scaricato, mentre l'url contiene,
in sequenza, il tipo di comunicazione (RMI), l'indirizzo IP del provider
del servizio ed il numero della porta di comunicazione.
java.naming.factory.initial
Tramite
questa property JNDI si specifica il contesto (a run time !) nel quale
si vuole operare. Esempi di valori di tale proprietà sono :
Protocollo
Ldap ……..…: "com.sun.jndi.ldap.LdapCtxFactory"
Rmi
- protocollo JRMP...: "com.sun.jndi.rmi.registry.RegistryContextFactory"
Corba
- protocollo IIOP..: "com.sun.jndi.cosnaming.CNCtxFactory"
java.naming.provider.url
Specifica
l’URL in formato stringa per configurare il service provider specificato
dalla proprietà java.naming.factory.initial
La
classe InitialContext è il punto iniziale per la creazione di oggetti
JNDI: dopo avere istanziato un oggetto di questa classe al suo interno
possono essere creati oggetti e contesti.
Per
l'inizializzazione delle proprietà JNDI che specificano il protocollo
da utilizzare ed il service provider, si possono seguire due strade :
1.
Via codice
Hashtable
env = new Hashtable();
env.put("java.naming.factory.initial",
"com.sun.jndi.cosnaming.CNCtxFactory");
env.put("java.naming.provider.url","iiop://localhost");
Context
ic = new InitialContext(env);
2.
Parametri
Mediante
parametri di linea di comando per lanciare l’interprete java, lasciando
quindi inalterato il codice dell'applicazione :
java
-Djava.naming.factory.initial=
com.sun.jndi.cosnaming.CNCtxFactory
-Djava.naming.provider.url=iiop://localhost
dove
all’interno del codice myServer.java si effettua :
Context
initialNamingContext = new InitialContext();
initialNamingContext.rebind("MyService",
server);
Oggetti remoti
RMI JRMP e RMI IIOP
Gli
Oggetti remoti RMI-JRMP devono ereditare dalla classe UnicastRemoteObject
mentre gli oggetti remoti RMI-IIOP dalla classe Portable RemoteObject ed
entrambi implementano l'interfaccia dell'oggetto remoto.
Quindi
a parità di interfaccia :
public
interface MyServerInterface extends java.rmi.Remote {
public
String concat(String a, String b) throws java.rmi.RemoteException;
}
la
scelta dell'utilizzo del protocollo avviene a seconda della classe che
si eredita nell'implementazione dell'interfaccia.
RMI-JRMP
public
class MyServerImpl extends UnicastRemoteObject implements MyServerInterface{
public MyServerImpl() throws RemoteException {}
public String concat(String a, String b) throws RemoteException {
return
"JRMP:" + a + b;
}
}
Rmi-IIOP
public
class MyServerImpl extends PortableRemoteObject implements MyServerInterface{
public MyServerImpl() throws RemoteException {}
public String concat(String a, String b)throws java.rmi.RemoteException
{
return "IIOP:" + a + b;
}
}
|
Diagrammi
di classe UML
|
Diagrammi
di classe UML
La
scelta del protocollo può essere rimandata rispetto alla fase di
creazione dell'implementazione non estendendo né UnicastRemoteObject
né PortableRemoteObject :
public
class MyServerImpl implements MyServerInterface{
public MyServerImpl() throws RemoteException {}
public String concat(String a, String b)throws java.rmi.RemoteException
{
return "IIOP:" + a + b;
}
}
sarà
il Server a decidere con quale protocollo esportare l'oggetto mediante
l'invocazione del metodo statico exportObject della classe UnicastRemoteObject
(per utilizare JRMP) o della classe PortableRemoteObject (per utilizzare
IIOP).
La
cosa interessante è che si può effettuare un'operazione di
Dual Export rendendo disponibile il servizio dell'oggetto remoto sia a
client JRMP che a client IIOP contemporaneamente.
…
MyServerImpl
obj = new MyServerImpl();
MyServerImpl
obj2 = new MyServerImpl();
UnicastRemoteObject.exportObject(obj);
// esporto per JRMP
PortableRemoteObject.exportObject(obj2);
// esporto per IIOP
//
Creo 2 InitialContexts ed effettua l'operazione di bind degli oggetti remoti
//
JRMP
Properties
jrmpProps = new Properties();
jrmpProps.put("java.naming.factory.initial",
"com.sun.jndi.rmi.registry.RegistryContextFactory");
InitialContext
jrmpContext = new InitialContext (jrmpProps);
jrmpContext.rebind
("MyService", obj);
System.out.println
(" *** MyService bound in JRMP registry *** ");
//
IIOP
Properties
iiopProps = new Properties();
iiopProps.put("java.naming.factory.initial",
"com.sun.jndi.cosnaming.CNCtxFactory");
InitialContext
iiopContext = new InitialContext (iiopProps);
iiopContext.rebind
("MyService", obj2);
System.out.println
(" ### MyService bound in IIOP registry ### ");
…
Da
notare che si può utilizzare lo stesso nome di servizio (nell'esempio
MyService) visto che deve essere univoco all'interno di uno stesso Contesto.
Generazione Stub
e Skeleton in RMI-IIOP
La
generazione di stub e skeleton nel caso di RMI-IIOP avviene usando
la nuova versione del compilatore rmic utilizzando la flag -iiop.
Nella
tabella 3 si riportano analogie e differenze tra RMI JRMP e RMI-IIOP
|
RMI
|
RMI
IIOP
|
Protocollo
JRMP
|
SI
|
SI
java.naming.factory.initial=
com.sun.jndi.rmi.registry.RegistryContextFactory |
Protocollo
IIOP
|
NO
|
SI
java.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
|
Definizione
contratto client-server
|
MyserverInterface.java
|
ConcatApp.idl
|
Compilatore
IDL
|
Rmic
|
Multi-vendor
(idltojava-Javasoft)
|
File
generati dal compilatore
|
MyServerImpl_Stub.class
MyServerImpl__Skel.class
|
_MyServerImpl_Stub.class
_MyServerImpl__Tie.class
|
Stub
|
MyServerImpl_Stub.class
|
_MyServerImpl_Stub.java
|
Skeleton
|
MyServerImpl__Skel.class
|
MyServerImpl_Tie.java
|
Servant
extends
|
UnicastRemoteObject
|
PortableRemoteObject
|
Servant
implements
|
MyServerInterface
|
MyServerInterface
|
Naming
service
|
RmiRegistry
|
JNDI
|
Registrazione
Oggetto remoto
|
Naming.rebind()
|
InitialContext
ic = new InitialContext();
ic.rebind();
|
Ottenimento
riferimento all'oggetto remoto
|
Naming.lookup();
|
ic.lookup();
PortableRemoteObject.narrow();
|
Tabella
3
RMI IIOP e Corba
Il
mapping delle interfaccie RMI in moduli CORBA IDL è una caratteristica
definita in CORBA 2.3.
Grazie
a questo mapping "al rovescio" rispetto al tradizionale mapping IDL-Java
già definito in CORBA 2.2 è possibile scrivere applicazioni
CORBA (quindi con un qualsiasi linguaggio) partendo da un modulo IDL ricavato
in modo automatico a partire da un'interfaccia RMI scritta (ovviamente)
in Java.
Questa
visione di CORBA "java-centrica" permette di sviluppare applicazioni CORBA
partendo da interfacce Java.
Se
la compatibilità JRMP - IIOP è totale, la comunicazione tra
RMI-IIOP e CORBA ha delle limitazioni. Un client IIOP non è detto
che riesca ad accedere a qualsiasi oggetto CORBA, questo perché
l'IDL di RMI-IIOP è un subset dell'IDL Corba.
RMI
-IIOP mette a disposizione la possibilità di ottenere codice IDL
partendo dall'interfaccia RMI mediante la nuova versione del compilatore
rmic mediante l'uso del flag -iiop.
Dal
file IDL ottenuto è possibile scrivere applicazioni CORBA con qualsiasi
linguaggio e comunicare con tale oggetto sia tramite IIOP.
RMI-IIOP
è in grado di funzionare con ORB che supportano le specifiche CORBA
2.3;questo perché Corba 2.2 non supporta la caratteristica di Objects
by value fondamentale per il funzionamento di RMI su IIOP.
Conclusioni
Dopo
questa panoramica introduttiva su RMI e CORBA, è forse utile fare
un breve riassunto di quella che è la situazione attuale circa la
computazione distribuita in Java. Si delineano quindi tre seguenti
scenari:
-
RMI =
adatto per applicazioni full-java, utilizza JRMP come protocollo di comunicazione
e quindi risulta essere una tecnologia "chiusa" rispetto agli altri ORB.
-
Java IDL
= permette di scrivere applicazioni Java per Corba.
-
Rmi-IIOP=compatibile
con Rmi offre il vantaggio di potere comunicare mediante IIOP con applicazioni
Corba
Le intenzioni
di Sun sono di continuare a supportare tutte e tre i protocolli. Nel prossimo
articolo proseguiremo la trattazione di RMI IIOP, vedendo qualche esempio
pratico. |