MokaByte Numero  44  - Settembre 2000
RMI IIOP 
I parte: un po’ di teoria
di 
Stefano Rossini
Panoramica introduttuva su  RMI IIOP
Il primo punto d'incontro tra RMI e Corba 

Con RMI i progettisti della sun hanno aggiunto a Java un potente strumento per la realizzazione di applicazioni distribuite. Caratteristica principale di RMI è la semplicità  suo punto di forza ma anche maggiore limitazione. 
La possibilità di interfacciarsi con ORB di tipo CORBA è sicuramente una delle caratteristiche più interessanti del nuovo RMI IIOP

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.
Chi volesse mettersi in contatto con la redazione può farlo scrivendo a mokainfo@mokabyte.it