Home   |   Archivio   |   Chi siamo   |   Contatti
Stefano Rossini
RMI IIOP
I parte: un po' di teoria
di
Stefano Rossini
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 - Schema RMI
Figura 1 - Schema RMI

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<br>Non rispetta specifiche Corba<br>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)<br>MyServerInterfaceStub.java<br>MyServerInterface.java<br>MyServerInterfaceHelper.java<br>MyServerInterfaceHolder.java | MyServerImpl_Stub.class<br>MyServerImpl__Skel.class<br>(solo per JDK 1.1) | | Stub | MyServerInterfaceStub.java | MyServerImplStub.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()<br>NamingContext.rebind() | Naming.rebind() | | Ottenimento riferimento all'oggetto remoto | NamingContextHelper.narrow()<br>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 - Architettura JNDI
Figura 2 - Architettura JNDI

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;
  }
}
Figura 3a - Diagrammi di classe UML
Figura 3a - Diagrammi di classe UML
Figura 3b - Diagrammi di classe UML
Figura 3b - 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<br>java.naming.factory.initial=<br>com.sun.jndi.rmi.registry.RegistryContextFactory | | Protocollo IIOP | NO | SI<br>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<br>MyServerImpl__Skel.class | MyServerImplStub.class<br>_MyServerImpl__Tie.class | | Stub | MyServerImplStub.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();<br>ic.rebind(); | | Ottenimento riferimento all'oggetto remoto | Naming.lookup(); | ic.lookup();<br>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.

MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it