MokaByte 75 - Giugno 2003 
Integrazione di applicazioni Enterprise
III parte
di
Stefano Rossini & Alberto D'Angeli
Nello scorso articolo (vedere [INT2]) si è visto come permettere la comunicazione con EJB utilizzando ORB diversi. In questo articolo si vedrà come esporre oggetti accessibili da remoto attraverso il protocollo IIOP. Nello specifico si vedrà come è possibile sfruttare l'interoperabilità offerta dal protocol-lo IIOP per fare comunicare client CORBA con EJB e client Java con CORBA Server.

RMI o RMI IIOP ?
In [INT2] si è visto come l'integrazione Object/RPC implichi l'invocazione RPC dei metodi degli oggetti distributi (EJB, CORBA, DCOM, …).
Si è visto come comunicare con l'EJB Facade (installato sull'Application Server JBoss) me-diante il protocollo JNP e di come l'EJB Facade comunichi a sua volta con l'EJB Calculator (installato su Weblogic) mediante il protocollo T3.
Entrambi sono protocolli proprietari che offrono vantaggi in termini di prestazioni. Per utiliz-zarli bisogna referenziare gli opportuni jar: per T3 è necessario il weblogic.jar e per JNP i jar jboss.jar,jboss-j2ee.jar e jnpserver.jar.

 

RMI
RMI è un insieme di API potente e semplice, che permette di sviluppare applicazioni distribui-te (vedere [MOKA_RMI-1,MOKA_RMI-2,…]).
Nell'ottica di questo articolo bisogna tenere presente che oggetti che utilizzano l'ORB di RMI potranno colloquiare solo con altri oggetti che utilizzino il medesimo ORB.

 

CORBA
Un'altra soluzione di sviluppo di architetture distribuite ad oggetti è CORBA.
CORBA ha una connotazione completamente opposta rispetto a RMI: maggiore interoperabili-tà pagata al prezzo di una maggiore complessità (vedere [MOKA_IIOP-3]). Con CORBA un'applicazione client Java può interagire con una serie di oggetti remoti scritti in altri lin-guaggi (C++, C, Delphi, Java o altri per i quali sia disponibile un mapping IDL) e viceversa. L'IDL (Interface Definition Language) è il metalinguaggio standard del mondo CORBA usato per descrivere le interfacce degli oggetti remoti e le strutture dati di scambio.
Mentre il "contratto" tra client e server in Corba è definito tramite un'interfaccia IDL, in RMI è "stipulato" mediante un'interfaccia Java. Questo implica che per usare RMI non occorre cono-scere 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 esclusiva-mente in Java) e quindi non è in grado di comunicare con applicazioni distribuite scritte in lin-guaggi diversi. Esportare EJB con protocolli RMI porta vantaggi in termini di prestazioni ma preclude ogni strada all'interoperabilità con altre tecnologie.
Se ad esempio un client CORBA C++ avesse bisogna del servizio di calcolo della lunghezza della stringa non potrebbe usufruirne non essendo in grado di utilizzare il protocolo T3 o JNP.
Il discorso è valido anche al contrario: se esistono servizi sviluppati in CORBA un client Java non è in grado di invocarli nè con RMI, né con JNP e neanche con T3.
Complicando lo scenario dello scorso articolo potremmo introdurre un'applicazione CORBA che ha bisogno del servizio di calcolo della lunghezza della stringa (l'EJB Calculator).
Il nuovo scenario diventa il seguente:


Figura 1 - nuovo possibile scenario d'integrazione

In questo scenario bisogna permettere l'invocazione dell'EJB mediante protocollo IIOP.
IIOP
La specifica CORBA introduce un protocollo GIOP (General Inter-ORB Protocol) che defini-sce 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. GIOP si appoggia a sua volta ad un qualunque protocollo di trasporto, purchè orientato alla connessione, per portare a desti-nazione i suoi messaggi.
Una particolare implementazione del protocollo GIOP, chiamata IIOP (Internet Inter-ORB Pro-tocol), si avvale del protocollo TCP/IP per la realizzazione dello strato di trasporto dei messag-gi tra oggetti remoti.
IIOP quindi è una sorta di "collante" che si appogia su TCP/IP tra gli oggetti distribuiti su ORB diversi tra loro.

 

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 attraverso il protocollo proprieta-rio Sun JRMP, ma anche con il protocollo IIOP.
Tramite l'utilizzo di RMI-IIOP è possibile "gettare un ponte" tra RMI e CORBA
Vediamo quindi come esporre un EJB al fine di essere invocabile mediante protocollo IIOP.
Riprendendo l'esempio del client dell'EJB Calculator dello scorso articolo

public class CalculatorTestClient {
. . . . .
public void test(String jndiName) {
try {
Context ctx = new InitialContext();
//look up jndi name
Object ref = ctx.lookup(jndiName);
Object obj = PortableRemoteObject.narrow(ref, CalculatorHome.class);
CalculatorHome home = (CalculatorHome) obj;
Calculator calculator = home.create();
System.out.println("Risultato: " + calculator.getStringLength("Ciao a tutti!"));
……

Per esporre un EJB mediante IIOP nel caso di Weblogic, bisogna specificare il flag -iiop come opzione dell'utility weblogic.ejbc (l'utility Bea che permette di compilare ed effettuare il de-ploy degli EJB). In questo modo vengono generati gli stub per il protocollo IIOP e non per T3.
Il client può quindi invocare l'EJB mediante IIOP specificando le seguenti proprietà JNDI:

  • java.naming.factory.initial= com.sun.jndi.cosnaming.CNCtxFactor
  • java.naming.provider.url= corbaloc::<<SERVER>>:7001
    (dove con <<SERVER>> si indica il nome o l'indirizzo IP del Server)

A partire dalla versione 3 è possibile esportare un EJB in IIOP anche con JBoss che integra l'ORB di JacORB (vedere [JACORB]).
Con la 3.0.x bisogna specificare nel file DD proprietario il tag <configuration-name> specifi-cando come valore IIOP Stateless SessionBean.

<session>
<ejb-name>CalculatorBean</ejb-name>
<jndi-name>MokaCalculator</jndi-name>
<configuration-name>IIOP Stateless SessionBean</configuration-name>
</session>

Con la versione 3.2.x invece bisogna specificare l'attributo <invoker-proxy-binding-name>.

<session>
<ejb-name> CalculatorBean </ejb-name>
<jndi-name> MokaCalculator </jndi-name>
<configuration-name>Standard Stateless SessionBean</configuration-name>
<invoker-bindings>
<invoker>
<invoker-proxy-binding-name>iiop</invoker-proxy-binding-name>
</invoker>
</invoker-bindings>
</session>


Il client può quindi invocare l'EJB mediante IIOP specificando le seguenti proprietà JNDI:
· java.naming.factory.initial= com.sun.jndi.cosnaming.CNCtxFactor
· java.naming.provider.url= corbaloc::<<SERVER>>:3528/JBoss/Naming/root

Di default il client utilizza l'ORB si SUN.
E' possbile fare in modo che il client utilizzi un diverso ORB mediante le proprietà org.omg.CORBA.ORBClass e org.omg.CORBA.ORBSingletonClass.
Ad esempio per utilizzare l'ORB di JacORB (sempre a partià di bytecode!) si deve includere nel classpath il jar di JacORB e specificare le seguenti proprietà:

  • java.naming.factory.initial= com.sun.jndi.cosnaming.CNCtxFactor
  • java.naming.provider.url= corbaloc::<<SERVER>>:3528/JBoss/Naming/root
  • -Dorg.omg.CORBA.ORBClass=org.jacorb.orb.ORB
  • -Dorg.omg.CORBA.ORBSingletonClass=org.jacorb.orb.ORBSingleton

E' inoltre necesario configurare il Security Manager sul client specificando le proprietà di sicu-rezza java.security.manager e java.security.policy al fine di permettere al network classloader lo scaricamento degli stub (di default il network classloader è disabilitato causando un Clas-sCastException con il PortableRemoteObject.narrow())
Il file di policy usato per gli esempi non pone nessun vincolo di sicurezza per semplicità.

// Standard extensions get all permissions by default
grant codeBase "file:${java.home}/lib/ext/-" {
permission java.security.AllPermission;
};
// default permissions granted to all domains
grant {
permission java.security.AllPermission;
};

Ora vediamo i benefici che derivano dalla scelta di aver esportato il nostro oggetto remoto at-traverso un protocollo interoperabile quale IIOP. Si vuole realizzare un semplice client COR-BA scritto in linguaggio C++ che comunichi con l'EJB Calculator installato su JBoss.
Per fare questo verrà utilizzato l'implementazione CORBA Open Source chiamata MICO (ve-dere [MICO]).
Si è scelto MICO come implementazione di CORBA/C++, sia per la sua semplicità che per il fatto che è liberamente disponibile per una grande varietà di piattaforme software/hardware.
Il nostro scenario di integrazione presenta rispetto ad una applicazione "pure Corba" la seguen-te "singolarità": di norma infatti, il punto di partenza di una qualunque applicazione Corba è la definizione in linguaggio IDL delle interfacce degli oggetti remoti che vengono esposti attra-verso CORBA. Tuttavia nel nostro caso, già disponiamo delle interfacce dell'oggetto remoto EJB Calculator, precisamente si tratta della Home Interface e della Remote Interface definite (in linguaggio Java) per il nostro EJB. La prima cosa da fare sarà quindi trasformare queste de-finizioni di interfacce Java nelle corrispondenti definizioni IDL che useremo per realizzare il nostro client Corba C++. Tale trasformazione si basa su una recente aggiunta alle specifiche Corba che stabilisce appunto la mappatura java-to-idl necessaria per tradurre le specifiche degli oggetti remoti del mondo Java (RMI, EJB) nelle equivalenti interfacce IDL.

Vediamo in dettaglio la sequenza delle operazioni necessarie per la realizzazione del Client C++:

  • si parte dai files .class delle interfacce Home e Remote del nostro Calculator EJB
  • questi file .class vengono dati in ingresso ad un compilatore java-to-idl, come ad esempio l'rmic (disponibile con il JDK) avviato con l'opzione -idl.

rmic -idl -noValueMethods -classpath ${J2EE_JAR}:. -d . it.mokabyte.eai.my.ejb.Calculator it.mokabyte.eai.my.ejb.CalculatorHome

  • si ottengono così numerosi files idl, che contengono oltre alle interfacce corrispondenti alla home e remote interface dell EJB, anche le definizioni IDL di alcuni tipi di dati fon-damentali definiti in java.lang, come Throwable ed Exception, nonché di alcune interfacce fondamentali defnite in javax.ejb, come ad esempio EJBOBject.
  • si utilizza il compilatore idl-to-c++ fornito con MICO per compilare tutti i files IDL sud-detti

$MICO_HOME/idl/idl -I. -I${MICO_HOME}/include/mico -DprimaryKey=_primaryKey it/mokabyte/eai/my/ejb/Calculator.idl
$MICO_HOME/idl/idl -I. -I${MICO_HOME}/include/mico -DprimaryKey=_primaryKey it/mokabyte/eai/my/ejb/CalculatorHome.idl
...

· i files oggetto ottenuti dalla compilazione si linkano insieme unitamente ad una semplice funzione main come la seguente:

//Code Example: mainClient.cc
#include <fstream>

#include <unistd.h>
#include <stdlib.h>

// Inclusione dei file generate dall'IDL
#include <it/mokabyte/eai/my/ejb/Calculator.h>
#include <it/mokabyte/eai/my/ejb/CalculatorHome.h>

using namespace std;

void run(CORBA::ORB_ptr orb, const char* home_url)
{
// Look up dell'EJB Home specificato dal corbaname URL
CORBA::Object_var home_obj = orb->string_to_object(home_url);

assert(!CORBA::is_nil(home_obj));

// effettuo la narrow
it::mokabyte::eai::my::ejb::CalculatorHome_var home =
it::mokabyte::eai::my::ejb::CalculatorHome::_narrow(home_obj.in());

assert(!CORBA::is_nil(home));

// ottengo il remote reference
it::mokabyte::eai::my::ejb::Calculator_var calc = home->create();

CORBA::String_var home_ior = orb->object_to_string(calc);
// stampo lo IOR
cout << "Calculator IOR is: " << home_ior << endl;

CORBA::WStringValue* msg1 = new CORBA::WStringValue(L"Hello CORBA World");

// invoco il metodo remoto
wcout << L"Lunghezza del messaggio: " << msg1->_boxed_in() << L" = " << calc->getStringLength(msg1) << endl;

// NOTA: Per interoperare con le stringhe Java (contenenti
// caratteri a 16 bit) è necessario utilizzare anche in C++
// le stringhe Wide. Si noti inoltre che per stamparle bisogna utilizzare lo stream wcout anziché cout.

calc->remove();
}

// funzione main
int main(int argc, char* argv[])
{
int exit_code = 0;
CORBA::ORB_var orb;

try {
// Inizializzo l'ORB
orb = CORBA::ORB_init(argc, argv);
run(orb, argv[1]);

} catch(const CORBA::Exception& ex) {
….
}
return exit_code;
}

 

CORBA Servant C++
Fino ad ora si è analizzato come è possibile interrogare EJB mediante il protocollo IIOP svi-luppando sia client Java RMI-IIOP che CORBA C++.
Analizziamo adesso il caso duale, cioè supponiamo che il servizio di calcolo della lunghezza di una stringa, precedentemente esposto con un EJB (CalculatorBean) sia disponibile mediante un Servant CORBA scritto in C++.

<< figura_2.jpg - Figura 2: Servizio esposto mediante Server CORBA C++ >>

Il vantaggio offerto dall'architettura CORBA si manifesta infatti nella possibilità di far intero-perare programmi realizzati in linguaggi di programmazione diversi su piattaforme eterogenee. Uno scenario di questo tipo non rappresenta affatto un puro esercizio accademico, ma viene incontro a necessità molto sentite nel mondo aziendale.

Alcuni motivi che inducono ad utlizzare un approccio multilinguaggio sono i seguenti:

  • facilmente si incontra il caso in cui una società disponga già 'in casa' di alcune librerie scritte in C/C++, già abbondantemente testate ed impiegate all'interno di sistemi esistenti, e non si abbia nessuna intenzione di riscrivere (testare nuovamente!) questo codice in Java
  • è possibile che ad utilizzare linguaggi diversi da Java siano altri fornitori o partner che per vari motivi realizzano in C++ dei sottosistemi che è necessario integrare col proprio siste-ma
  • è possibile realizzare in C/C++ alcune parti del proprio sistema che prevedano una elebo-razione computazionalmente molto intensiva

Negli esempi allegati è disponibile il "gemello" del Servant C++ scritto in linguaggio Java per coloro che non sono pratici di C++ o che semplicemente sono interessati al lato client del no-stro scenario di integrazione (magari perché gli oggetti CORBA C++ sono già stati realizzati oppure vengono realizzati da qualcun altro). Questo server CORBA Java può quindi essere uti-lizzato per le vostre prove di integrazione esattamente come se fosse il server C++.
Il client CORBA è infatti del tutto inconsapevole del linguaggio scelto sul lato server per im-plementare un oggetto CORBA.
Indipendentemente dal fatto che il Server CORBA venga implementato in Java o in C++, il punto di partenza è costituito dalla definizione dell'interfaccia che dovrà avere l'oggetto che dobbiamo rendere disponibile attraverso CORBA. Tale interfaccia viene descritta in linguaggio IDL come segue:


// file calcolatrice.idl
module eai
{
interface Calcolatrice
{
short strlen_calc(in string msg);
};
};

Una volta definita l'interfaccia IDL del nostro oggetto, dobbiamo compilarla attraverso un ap-posito compilatore IDL ottenendo così alcuni files nel linguaggio di programmazione desidera-to (Java, C++..) contenenti definizioni di classi di supporto che ci permetteranno di esportare l'oggetto. A titolo esemplificativo, riportiamo nella tabella seguente alcuni estratti dei files ge-nerati dalla compilazione IDL nel caso della traduzione in C++ e in Java.

IDL (calcolatrice.idl) C++ ottenuto dal compilatore IDL di MICO Java ottenuto dall'IDLJ
module eai{ interface Calcolatrice { short strlen_calc(in string msg); };}; namespace eai {class Calcolatrice : virtual public CORBA::Object {virtual CORBA::Short Calcolatrice::strlen_calc(const char* msg) throw (CORBA::SystemException) =0;} package eai;public interface CalcolatriceOperations { short strlen_calc (String msg);}

Il costrutto IDL module si mappa nel costrutto Java package e nel costrutto C++ namespace.
Ciascuna operazione definita in modo language independent nell'interface IDL Calcolatrice viene mappata in una omonima member function C++ ed analogamente in un metodo Java co-me esemplificato nella tabella precedente per strlen_calc. Esistono per ogni linguaggio regole precise che prescrivono come mappare ciascun parametro delle operazioni IDL nei diversi lin-guaggi di programmazione, a seconda del suo tipo e della direzione in cui viene passato (in, out, inout, return).
Per quanto riguarda il nostro esempio, al valore di ritorno (di tipo IDL short) corrisponde il tipo Java short e il tipo C++ CORBA::Short.
Per quanto riguarda invece il parametro d'ingresso al tipo IDL string corrisponde la classe Java String e un puntatore a caratteri per C++.
Per eseguire la compilazione dell'interfaccia IDL in MICO, si deve eseguire il comando:

$MICO_HOME/idl/idl calcolatrice.idl

Questo produrrà come risultato i files calcolatrice.h e calcolatrice.cc che contengono le classi Stub e Skeleton da linkare insieme nell'eseguibile. In aggiunta a questi sarà a carico nostro rea-lizzare una classe C++ (nella terminologia CORBA è detta 'Servant') che implementi le opera-zioni definite nell'interfaccia IDL ed una funzione main() che faccia le opportune inizializza-zioni, crei il servant e si ponga in attesa di richieste per l'oggetto creato.

Per realizzare l'eseguibile del CORBA server C++ è dunque necessario compilare e linkare in-sieme i seguenti files:

  • mainServer.cc: contiene il main () del programma
  • calcolatrice.cc: è il file generato dal compilatore IDL
  • CalcolatriceImpl.cc: contiene l'implementazione del nostro oggetto CORBA

Una semplice classe C++ che realizza l'interfaccia IDL Calcolatrice è mostrata di seguito:

// file CalcolatriceImpl.h
#include "calcolatrice.h"

class CalcolatriceImpl: public POA_eai::Calcolatrice
{
public:
CalcolatriceImpl(){};
virtual ~CalcolatriceImpl(){};
virtual CORBA::Short strlen_calc(const char* msg) throw (CORBA::SystemException) ;
};

// file CalcolatriceImpl.cc
#include <cstring>
#include "CalcolatriceImpl.h"

CORBA::Short CalcolatriceImpl::strlen_calc(const char* msg) throw (CORBA::SystemException)
{
return (strlen(msg));
}

Riportiamo quindi il codice della funzione main() che provvede a inizializzare l'ORB e a "pubblicare" il nostro oggetto Corba.

//file mainServer.cc
#include <CORBA.h>
#include <coss/CosNaming.h>
#include "CalcolatriceImpl.h"
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char* argv[])
{
try {
// Inizializzazione dell'ORB
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

// ottengo un reference al root POA
CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var rootPOA = PortableServer::POA::_narrow(obj.in());

// ottengo il POA Manager
PortableServer::POAManager_var poa_manager = rootPOA->the_POAManager();

// ottengo un reference al context root del Naming Service
CosNaming::NamingContext_var rootContext =
CosNaming::NamingContext::_narrow(
orb->resolve_initial_references("NameService"));

// creo il servant
CalcolatriceImpl servant;

// attivo l'oggetto CORBA
PortableServer::ObjectId_var oid = rootPOA->activate_object(&servant);

// ottengo il reference all'oggetto CORBA
CORBA::Object_var ref = rootPOA->id_to_reference(oid.in());

// creo il Naming Context di nome logico "eai" e effettuo il bind
CosNaming::Name name;
name.length(1);
name[0].id = (const char *) "eai";
name[0].kind = (const char *) "";

CosNaming::NamingContext_var nc1;
try
{
nc1 = rootContext -> bind_new_context(name);
}
catch(const CosNaming::NamingContext::AlreadyBound&)
{
CORBA::Object_var obj = rootContext->resolve(name);
nc1 = CosNaming::NamingContext::_narrow(obj.in());
}

// effettuo il bind dell'oggetto remoto
name.length(2);
name[0].id = (const char *) "eai";
name[0].kind = (const char *) "";
name[1].id = (const char *) "calcolatrice";
name[1].kind = (const char *) "";
rootContext->rebind(name, ref.in());

// attivo il POA Manager
poa_manager->activate();
// mi mettoin attesa di richieste
orb->run();
}
catch(const CORBA::Exception& e) {
cout << "eccezione!!! " << endl;
return 1;
}
return 0;
}

Una volta effettuate le necessarie compilazioni possiamo avviare il Naming Service ed il nostro server Corba: per fare questo utilizziamo le seguenti istruzioni:

$MICO_HOME/coss/naming/nsd -ORBGIOPVersion 1.2 -ORBIIOPVersion 1.2 -ORBIIOPAddr inet:<<SERVER>>:1666 &

./server -ORBIIOPAddr inet:$HOST_D:1777 -ORBGIOPVersion 1.2 -ORBIIOPVersion 1.2 -ORBInitRef NameService=corbaloc:iiop:<<SERVER>>:1666/NameService

Così facendo abbiamo messo in ascolto il Naming Service sulla porta 1666 ed il nostro server Corba sulla porta 1777.
Ora che il server Corba è pronto per essere contattato, abbiamo bisogno di un client.

 

Il Client CORBA Java
Analogamente a quanto visto con MICO, bisogna compilare l'interfaccia IDL utilizzando ad esempio il compilatore IDLJ presente nel JDK.

idlj -fclient calcolatrice.idl

Tale compilazione genera le seguenti classi Java necessarie al client:

  • _CalcolatriceStub.java: la classe stub che permette al client di comunicare con l'ORB
  • CalcolatriceHelper.java: fornisce funzionalità ausiliarie come il metodo narrow() che permette la conversione dell'Oggetto CORBA al tipo appropriato
  • CalcolatriceHolder.java: viene utilizzata nei casi di paramtri IDL out o inout
  • Calcolatrice.java,CalcolatriceOperations.java: insieme forniscono "traduzione" Java dell'interfaccia IDL

Ottenuti i Java bisogna provvedere alla lora compilazione.
Si riporta di seguito il codice del client:

public class CalculatorTestClient {
. . . . .
public void test(String args[]) {
try{
// create and initialize the ORB
ORB orb = ORB.init(args, null);
// si ricava il root naming context(NameService=persistente TNameService=transient)
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

// nome logico dell'oggetto remoto
NameComponent nc[] = { new NameComponent("eai", ""),
new NameComponent("calcolatrice", "")
};
// Lookup + narrow dell'oggetto remoto
Calcolatrice obj= CalcolatriceHelper.narrow(ncRef.resolve(nc));

// invocazione del metodo remoto
System.out.println("Risultato: " + obj.strlen_calc("Hello!"));

} catch (Exception e) {
...

A questo punto è possibile compilare il client e mandarlo in esecuzione.
Per specificare dove trovare il Naming Server e su quale porta TCP è in ascolto è possibile usa-re la modalità proprietaria SUN mediante le proprietà ORBInitialPort e ORBInitialHost.
Nella modalità standard CORBA invece bisogna avvalersi della proprietà ORBInitRef:

%JAVA_HOME%\bin\java -classpath %CLASSPATH%
it.mokabyte.eai.my.client.corba.CalculatorTestClient
-ORBInitRef NameService=corbaloc:iiop:<<SERVER>>:1666/NameService


E' utile infine notare come sia possibile utilizzare le API JNDI per localizzare l'oggetto CORBA invece della API del CORBA Naming Service.
Per fare questo si deve specificare specificando oltre alla proprietà java.naming.factory.initial e java.naming.provider.url precedentemente spiegate, anche la proprietà java.naming.corba.orb inizializzata con l'oggetto ORB che si utilizza.
Di conseguenza la relativa narrow può essere eseguita mediante il metodo javax.rmi.PortableRemoteObject.narrow() al posto del metodo narrow della classe Helper CalcolatriceHelper.narrow().

ORB orb = ORB.init(args, null);
properties = new Properties();
properties.put("java.naming.corba.orb", orb);
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.cosnaming.CNCtxFactor");
properties.put(Context.PROVIDER_URL, "corbaloc::<<SERVER>>:3528/JBoss/Naming/root");
Context ctx = new InitialContext(properties);
// Lookup + narrow dell'oggetto remoto
Object obj = PortableRemoteObject.narrow(ctx.lookup("eai/calcolatrice"), CalcolatriceHome.class);
// invocazione del metodo remoto
System.out.println("Risultato: " + obj.strlen_calc("Hello!"));

 

Conclusioni
In questo articolo si è visto è possibile sfruttare l'interoperabilità offerta dal protocollo IIOP per la comunicazione tra applicazioni eterogenee.

 

Risorse
Scarica gli esempi descritti nell'articolo

 

Bibliografia

[INT1] S.Rossini: Integrazione di applicazioni Enterprise (I) MokabyteN.71-Aprile 2003
[INT1] S.Rossini: Integrazione di applicazioni Enterprise (II) MokabyteN.72-Maggio 2003
[MOKA_RMI-1] G.Puliti: "Remote Method Invocation",Mokabyte N16 Febbraio 1998
[MOKA_RMI-2] S.Rossini:"Networking in Java Parte V: RMI",Mokabyte N43, Luglio 2000
[MOKA_GIOP] A.Bemporad: "GIOP/IIOP l'autostradaCorba",Mokabyte N.25,10mbre 1998
[MOKA_CORBA]L.Bettini:"Java+IDL=CORBA", Mokabyte N.22, Settembre 1998
[MOKA_IIOP-1] S. Rossini: "RMI-IIOP I parte", Mokabyte N.44, Settembre 2000
[MOKA_IIOP-2] S. Rossini: "RMI-IIOP II parte", Mokabyte N.45, Ottobre 2000
[MOKA_IIOP-3] G. Puliti: "RMI over IIOP", Mokabyte N.70, Gennaio 2003
[JACORB] http:// www.jacorb.org
[MICO] http://www.mico.org

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