国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

集成EJB和CORBA/CORBA客戶端訪問EJB

2019-11-18 15:07:47
字體:
供稿:網(wǎng)友

  摘要:

EJB與CORBA的集成能力對(duì)于集成基于java或非JAVA的應(yīng)用來說是很重要的。本文描述了如何實(shí)現(xiàn)一個(gè)EJB與一個(gè)CORBA的C++應(yīng)用相集成。它闡述了幾個(gè)重要的集成問題,尤其是那些EJB采用JAVA固有的或是用戶定義的對(duì)象作為參數(shù)或返回值的方法時(shí)涉及的問題。

EJB對(duì)于用JAVA來開發(fā)要害業(yè)務(wù)應(yīng)用程序是非常重要的。但是,業(yè)務(wù)應(yīng)用不是孤立存在的,當(dāng)今,企業(yè)需要集成各種應(yīng)用。從而,把基于EJB的解決方案與現(xiàn)有的應(yīng)用系統(tǒng)集成起來就變得越來越重要了。

在本文中,我將說明如何從一個(gè)非JAVA語言編寫的應(yīng)用中訪問EJB。更加非凡地是,我將討論從一個(gè)CORBA的C++客戶端訪問會(huì)話和實(shí)體Bean(它使用同步的IIOP協(xié)議進(jìn)行通信)。我沒有提到消息驅(qū)動(dòng)Bean,盡管你可能想從其它語言編寫的應(yīng)用中使用MOM產(chǎn)品來訪問它們。

1. RMI-IIOP
會(huì)話Bean和實(shí)體Bean使用遠(yuǎn)程方法調(diào)用(RMI)來進(jìn)行同步通信。J2EE1.3要求JAVA客戶端使用RMI-IIOP。RMI-IIOP采用CORBA的IIOP協(xié)議,這使得RMI-IIOP與CORBA相兼容。換句話說,不是基于JAVA開發(fā)的客戶端可以通過CORBA與EJB進(jìn)行通信。

要實(shí)現(xiàn)這點(diǎn),你必須使用符合J2EE1.3的應(yīng)用服務(wù)器。以前的EJB規(guī)范沒有要求你去用RMI-IIOP協(xié)議。而是,應(yīng)用服務(wù)器采用了RMI-JRMP或是其它私有協(xié)議。另外,你必須使用符合CORBA2.3.1或更高版本的ORB。以前的CORBA版本沒有實(shí)現(xiàn)與RMI-IIOP協(xié)議進(jìn)行互操作所必需的規(guī)范,尤其是后來集成中CORBA規(guī)范和JAVA到IDL的語言映射規(guī)范中的用值傳遞對(duì)象的規(guī)范(可以參看CORBA/IIOP規(guī)范2.6版,在“值類型語義”一章)。

值類型語言增加了用值來傳遞對(duì)象的概念,是由RMI引來,加入到CORBA中的。CORBA最初并不支持這項(xiàng)功能;但是,這個(gè)概念對(duì)于實(shí)現(xiàn)JAVA與CORBA之間的互操作是至關(guān)重要的。

JAVA到IDL語言映射規(guī)范定義了如何把JAVA接口映射到CORBA的IDL語言。這個(gè)定義使CORBA分布對(duì)象可以訪問本來不具有CORBA的IDL的EJB(還有那些RMI-IIOP分布對(duì)象)。非凡的是,這個(gè)規(guī)范定義了一個(gè)JAVA的RMI子集,叫RMI/IDL,它可以讓你

映射到IDL,用IIOP(或是更通用,是GIOP協(xié)議)作為通信的底層協(xié)議。

2. RMI/IDL
許多RMI/IDL數(shù)據(jù)類型遵循一定的約束;我們來看一下那些最重要的類型。更具體的信息,請(qǐng)參看JAVA到IDL的語言映射規(guī)范。

表1顯示了JAVA基本類型到IDL的映射。

表1:JAVA到IDL的映射

Java
OMG IDL

void
void

boolean
boolean

char
wchar

byte
octet

short
short

int
long

long
long long

float
float

double
double


JAVA包映射為IDL的模塊。RMI/IDL中的遠(yuǎn)程接口映射為IDL的接口并具有相對(duì)應(yīng)的名字。但是,那些用JavaBean命名方式用來只讀或讀寫屬性的方法被映射為IDL的屬性。后面我將提到這個(gè)。

JAVA中可序列化的對(duì)象映射為CORBA的值類型。值類型為CORBA提供了用值來進(jìn)行傳遞的語義。值類型是屬于本地的,不能被遠(yuǎn)程調(diào)用。它們不注冊(cè)到ORB中,也不需要標(biāo)識(shí)符,因?yàn)樗鼈兊闹稻褪撬鼈兊臉?biāo)識(shí)符。更具體的信息,請(qǐng)參閱《PRofessional J2EE EAI》和CORBA/IIOP規(guī)范2.6版。

就象我已經(jīng)提到過的,所有的JAVA或序列化的對(duì)象,包括JAVA固有的和用戶定義的,都將映射為值類型。但是,這個(gè)規(guī)則也有一些例外----例如,當(dāng)你想把java.lang.String映射到IDL時(shí)。假如把它定義為常量(final static),這個(gè)對(duì)象將被映射為IDL的wstring。在其它情況下,包括作為方法的參數(shù)或返回值,該對(duì)象都被映射為值類型CORBA::WStringValue。這個(gè)值類型是CORBA模塊的一部分,它的IDL定義如下:

valuetype WStringValue wstring;

這等同于下面的IDL定義:

valuetype WStringValue {

public wstring data;

};

但是,要記住,第一種定義能夠更干凈地映射到JAVA。表2列出其它非凡的映射情況。

表2:其它重要的非凡映射情況

Java
OMG IDL

java.lang.Object
::java::lang::_Object

java.lang.String
::CORBA::WStringValue or wstring

java.lang.Class
::javax::rmi::CORBA::ClassDesc

java.io.Serializable
::java::io::Serializable

java.io.Externalizable
::java::io::Externalizable

java.rmi.Remote
::java::rmi::Remote

org.omg.CORBA.Object
Object


3. 實(shí)現(xiàn)集成
后面我將返回來討論值類型,先討論用戶定義的類,再討論內(nèi)嵌的類,如Vectors、Collections和Enumerations。現(xiàn)在,讓我們看一下CORBA和EJB集成的基本方式。首先,我們需要一個(gè)EJB。在第一個(gè)例子中,我們使用一個(gè)簡(jiǎn)單的會(huì)話Bean,它只使用簡(jiǎn)單的數(shù)據(jù)類型作為方法的參數(shù)和返回值。我們沒有強(qiáng)行去用值類型。(注重:從CORBA客戶端訪問實(shí)體Bean跟訪問會(huì)話Bean的過程一樣。)

這個(gè)方式是最簡(jiǎn)單的;但是,你不能把它用在復(fù)雜的接口上。它的好處是:你可以使用不支持值類型的ORB。許多CORBA產(chǎn)品都是這樣(不支持值類型),尤其是那些不是用C++實(shí)現(xiàn)的產(chǎn)品。

這個(gè)例子中,我將使用C++版本的ORBacus4.1.0作為CORBA的ORB,使用VC++6.0作為編譯客戶端代碼的編譯器。為部署這個(gè)例子中的EJB,我將使用JBoss3.0.0。你可以從網(wǎng)上下載ORBacus4.1.0(也可以從IONA網(wǎng)站上下載)和JBoss3.0.0。

你可以使用任何支持CORBA2.3.1或更高版本的ORB產(chǎn)品(只要它支持到C++的映射)、一個(gè)相對(duì)應(yīng)的C++編譯器和一個(gè)支持J2EE1.3規(guī)范的應(yīng)用服務(wù)器。理論上講不需要修改代碼;但是,假如你使用其它產(chǎn)品,小的改動(dòng)可能是必要的。

4. EJB會(huì)話Bean
讓我們簡(jiǎn)單地看一下這個(gè)名叫CorbaEai的會(huì)話Bean。在我們的第一個(gè)例子中,這個(gè)簡(jiǎn)單的遠(yuǎn)程接口包含一個(gè)計(jì)算兩個(gè)整數(shù)之和的簡(jiǎn)單方法。

package eai;

import java.rmi.RemoteException;

import javax.ejb.EJBObject;

public interface CorbaEai extends EJBObject {

public int sum(int a, int b) throws RemoteException;

}

在你熟悉了集成過程之后,我將告訴你如何擴(kuò)展這個(gè)接口以包含使用用戶定義的對(duì)象和內(nèi)嵌對(duì)象的方法。

要轉(zhuǎn)這個(gè)例子,你必須把會(huì)話Bean部署到一個(gè)應(yīng)用服務(wù)器上。這要求你定義Home接口、實(shí)現(xiàn)這個(gè)Bean的實(shí)現(xiàn)類、定義部署描述器、創(chuàng)建jar文件并最終部署這個(gè)EJB。我不寫這些步驟了,但是你可以下載這個(gè)例子的源碼包。

5. 開發(fā)CORBA客戶端
要開發(fā)CORBA客戶端,我們需要完成以下步驟:

l 從會(huì)話Bean的Home接口和組件遠(yuǎn)程接口生成IDL

l 簡(jiǎn)化生成的IDL

l 編譯IDL接口,生成相應(yīng)的編程語言的代碼----我們這個(gè)例子中是C++----來生成樁及其它必需的映射

l 確定如何使用JNDI作為CORBA的名字服務(wù)

l 開發(fā)C++的客戶端和支持值類型

l 創(chuàng)建客戶端

5.1. 生成IDL
為從JAVA接口生成IDL,你可以使用任何支持JAVA語言到OMG的IDL映射規(guī)范的工具。例如:

l rmic編譯器,由JSDK1.3或更版本提供,使用-idl選項(xiàng);

l java2idl,由VisiBroker提供;

l rmic和ejbc(使用-idl)編譯器,由BEA的WebLogic提供

其它的應(yīng)用服務(wù)器提供類似的工具。需要明確的是,從EJB接口生成IDL接口要比從RMI-IIOP接口生成復(fù)雜得多。首先,EJB接口繼續(xù)于EJBObjec和EJBHome接口,它們定義了一些基本方法。因?yàn)镮DL接口也必須繼續(xù)于這些接口,所以其工具也必須為這些接口生成IDL接口。其次,EJB的home接口中的方法至少拋出CreateException異常,所以其工具也必須把這個(gè)異常和一些其它用戶定義的異常映射到IDL。

這兒我用的是JSDK1.3.1提供的rmic,注重要把包含要映射的接口的jar包包含在classpath中(對(duì)于JBoss來說,要包含$JBOSSHOMEclient jboss-j2ee.jar)。這兒需要映射的是eai.CorbaEai和eai.CorbaEaiHome兩個(gè)類:

rmic -idl -classpath "%classpath%;corbaeai.jar" eai.CorbaEai eai.CorbaEaiHome -d ./idl

rmic編譯器在目錄./idl下生成IDL文件,共有26個(gè)。

5.2. 簡(jiǎn)化生成的IDL的文件
用C++來實(shí)現(xiàn)所有的生成的接口和值類型是很費(fèi)時(shí)間的。但是我們并不需要所有的生成的接口,因?yàn)橛幸恍┓椒ㄎ覀儧]有去用。所以我們可以通過簡(jiǎn)化生成的IDL接口文件來節(jié)省一大部分工作。

對(duì)于這第一個(gè)例子,我們不去用EJBObject和EJBHome兩個(gè)接口上的方法,我們也不需要EJBMetaData。我們也不需要非凡的RemoveException異常,這樣,我們就可以不用RemoteExceprion和RemoteEx兩個(gè)IDL接口。我們還可以除去下列IDL接口:java.io、java.lang和java.rmi。

為進(jìn)一步簡(jiǎn)化IDL文件,我們把所需要的IDL接口放在一個(gè)文件中。經(jīng)過簡(jiǎn)化以后,得到以下IDL文件CorbaEai.idl:

#include "OB/orb.idl" //ORBacus中的orb.idl在OB目錄下。



module javax {

module ejb {

valuetype CreateException {

};



#pragma ID CreateException "RMI:javax.ejb.CreateException:FD98A9711F66DF7F:575FB6C03D49AD6A"



exception CreateEx {

CreateException value;

};

};

};



module eai {



interface CorbaEai {

long sum(

in long arg0,

in long arg1 );

};

#pragma ID CorbaEai "RMI:eai.CorbaEai:0000000000000000"



interface CorbaEaiHome {

::eai::CorbaEai create( ) raises (

::javax::ejb::CreateEx );

};

#pragma ID CorbaEaiHome "RMI:eai.CorbaEaiHome:0000000000000000"

};

5.3. 編譯IDL接口
接下來,我們把IDL接口映射到客戶端的編程語言。我們?cè)诳蛻舳擞肅++,這兒我們用ORBacus的idl編譯器(你可以用任何支持CORBA2.3.1或更高版本規(guī)范的IDL到C++的編譯器)。

假如你仔細(xì)看IDL的文件,你會(huì)發(fā)現(xiàn)它包含了一個(gè)文件orb.idl。在我們的例子中,我們用ORBacus自帶的orb.idl文件,它在$ORBacusHome/idl/OB目錄下。因此,在使用IDL編譯器時(shí),我們要指定包含orb.idl的路徑。我們用ORBacus所帶的IDL編譯器進(jìn)行編譯,因?yàn)槲覀冎皇蔷帉懣蛻舳耍圆恍枰?wù)方的骨架文件:

idl -IE:OOCidl --no-skeletons CorbaEai.idl

會(huì)生成stub文件CorbaEai.h和CorbaEai.cpp。

5.4. 使用JNDI作一個(gè)CORBA名字服務(wù)
在我們開發(fā)C++客戶端之前,先考慮一下如何獲得會(huì)話Bean的Home接口CorbaEaiHome的初始引用。CorbaEaiHome已經(jīng)注冊(cè)到應(yīng)用服務(wù)器的JNDI上,所以C++的客戶端必須訪問JNDI名字服務(wù)。

有一些應(yīng)用服務(wù)器,就象BEA的WebLogic,提供了一個(gè)跟CORBA名字服務(wù)相兼容的接口去訪問JNDI。為測(cè)試這一點(diǎn),我們可以用WebLogic的host2ior工具,它將輸出這個(gè)名字服務(wù)的使用IIOP和IIOP/SSL的IOR。對(duì)我們這個(gè)例子來說,我們只對(duì)非安全的IIOP感愛好。JBoss也提供一個(gè)CORBA名字服務(wù),從JBoss的啟動(dòng)日志中可以看到這個(gè)服務(wù)的IOR。

CORBA名字服務(wù)是一個(gè)有著標(biāo)準(zhǔn)接口的CORBA分布對(duì)象,從技術(shù)上講,它和其它CORBA對(duì)象一樣。因此,我們可以通過IOR直接連接到JNDI。

但是,一個(gè)更好的方法是通過用一個(gè)要害字NameServie析取初始引用來得到名字服務(wù)的引用。在本例中,我們?cè)趩?dòng)客戶端時(shí)指出所要用的名字服務(wù),我們通過命令行實(shí)現(xiàn),在后面將會(huì)提到。

5.5. 開發(fā)C++客戶端
我們開發(fā)一個(gè)簡(jiǎn)單的C++客戶端來調(diào)用會(huì)話Bean CorbaEai上的sum()方法。假定你熟悉CORBA。客戶端的主程序Client.cpp如下:

#include <OB/CORBA.h>

#include <OB/CosNaming.h>



#include <CorbaEai.h>



#ifdef HAVE_STD_IOSTREAM

using namespace std;

#endif



int run(CORBA::ORB_ptr orb, int argc, char* argv[])

{

//

// Get naming service

//

CORBA::Object_var obj;

obj = orb -> resolve_initial_references("NameService");



CosNaming::NamingContext_var nc =

CosNaming::NamingContext::_narrow(obj.in());



//

// Resolve names with the Naming Service

//

CosNaming::Name name;

name.length(1);

name[0].id = CORBA::string_dup("Corba-Eai");

name[0].kind = CORBA::string_dup("");



cout << "Resolved `CorbaEaihome´" << endl;

CORBA::Object_var aObj = nc -> resolve(name);

eai::CorbaEaiHome_var ceaihome = eai::CorbaEaiHome::_narrow(aObj.in());

assert(!CORBA::is_nil(ceaihome.in()));



cout << "Creating a new instance" << endl;

eai::CorbaEai_var ceai = ceaihome->create();



cout << "Result: "<< ceai->sum((CORBA::Long)15,(CORBA::Long)20)<< endl;



return EXIT_SUCCESS;

}



int main(int argc, char* argv[], char*[])

{

int status = EXIT_SUCCESS;

CORBA::ORB_var orb;



try

{

orb = CORBA::ORB_init(argc, argv);

status = run(orb, argc, argv);

}

catch(const CORBA::Exception& ex){

cerr << ex << endl;

status = EXIT_FAILURE;

}



if(!CORBA::is_nil(orb)){

try {

orb -> destroy();

}

catch(const CORBA::Exception& ex){

cerr << ex << endl;

status = EXIT_FAILURE;

}

}

return status;

}

5.6. 建立和運(yùn)行客戶端
我們用VC++6.0建立C++的客戶端。源文件是idl編譯生成的客戶端的stub文件CorbaEai.h和CorbaEai.cpp和主程序文件Client.cpp。生成可執(zhí)行文件CorbaEai.exe。

按照以下步驟運(yùn)行本例子:

l 啟動(dòng)應(yīng)用服務(wù)器,在我們的例子中是JBoss3.0。為了啟動(dòng)IIOP,所以用all模式來啟動(dòng)JBoss3.0.0(可能集群服務(wù)啟動(dòng)不起來,假如起不來,可以先把集群服務(wù)屏蔽掉)。

l 部署會(huì)話Bean CorbaEai到JBoss應(yīng)用服務(wù)器上。

l 使用下面的命令啟動(dòng)C++客戶端程序:

CorbaEai ?CORBInitRef NameService=corbaloc::localhost:8683/JBoss/Naming/root

注重在本例中,EJB應(yīng)用服務(wù)器和客戶端在同一臺(tái)機(jī)器上。假如要進(jìn)行遠(yuǎn)程通信,需要用一個(gè)真正的名字或是ip地址代替localhost。

6.值類型
這個(gè)例子還是十分的不完美。它沒有為Java的可序列化對(duì)象實(shí)現(xiàn)值類型,這就意味著我們不能捕捉到遠(yuǎn)程異常(因?yàn)檎驣DL中所表示的,它們被映射成值類型)。另外,在第一個(gè)例子中我還限制了方法只使用原始的數(shù)據(jù)類型。

為了理解CORBA是如何處理Java的可序列化的類,你必須看一下CORBA的值類型。Java的可序列化對(duì)應(yīng)著值類型。每一個(gè)被作為參數(shù)、返回值或異常傳自于/傳遞到CORBA客戶端的Java可序列化的對(duì)象都應(yīng)該用客戶端的編程語言再實(shí)現(xiàn)一次,在我們的例子中就是C++。這需要一定的工作。不幸的是,我不知道那些對(duì)Java的固有類型,如Remote、Throwable、EJBObject和EJBHome完全支持的CORBA實(shí)現(xiàn)。據(jù)我所知,只有IBM的WebSphere應(yīng)用服務(wù)器提供了一個(gè)值類型的庫,它包含了諸如Integer、Float、Vector、Exception和OutputStream等這些常用的Java類型的C++值類型的實(shí)現(xiàn)。根據(jù)WebSphere4.0應(yīng)用服務(wù)器的文檔,它的值類型庫只支持WebSphere的C++ ORB。

對(duì)每一個(gè)值類型,IDL到C++的編譯器生成一個(gè)指針類型的定義_ptr和一個(gè)_var類。_var類自動(dòng)治理為對(duì)象引用動(dòng)態(tài)分配的內(nèi)存。一個(gè)轉(zhuǎn)換操作符讓你也可以把一個(gè)_var賦給_ptr。還需要提醒的是,原始的Java構(gòu)造器不能映射到IDL。但是,當(dāng)IDL映射到C++時(shí),構(gòu)造器變成工廠類的init方法。

為實(shí)現(xiàn)值類型(比如用C++),你需要:

l 實(shí)現(xiàn)一個(gè)值類型的類,它要繼續(xù)于值類型的基類(由IDL編譯器生成)和缺省的值引用計(jì)數(shù)的基類。對(duì)于值類型,你必須手工實(shí)現(xiàn)引用的計(jì)數(shù)。

l 實(shí)現(xiàn)工廠類和工廠方法。

l 把工廠注冊(cè)到ORB。

讓我們看一下CreateException值類型的例子。首先,我們聲明它的實(shí)現(xiàn)類CreateExceptionImpl:

class CreateExcepionImpl : public virtual ::javax::ejb::OBV_CreateException,

public virtual CORBA::DefaultValueRefCountBase

{

我們至少必須實(shí)現(xiàn)構(gòu)造器和_copy_value()方法,它簡(jiǎn)單地一個(gè)新的值類型類的實(shí)例:

public:

CreateExceptionImpl() : OBV_CreateException() { }

virtual ~CreateExceptionImpl() { }

CORBA::ValueBase* _copy_value() {

return new CreateExceptionImpl();

}

我們也能夠?yàn)槠渌恍┓椒ㄌ峁?shí)現(xiàn),如message()、localizedMessage()和toString():

CORBA::WStringValue* message() {

return new CORBA::WStringValue(CORBA::wstring_dup(L”javax::ejb::CreateException”));

}



CORBA::WStringValue* localizedMessage() {

return new CORBA::WStringValue(CORBA::wstring_dup(L”javax::ejb::CreateException”));

}



CORBA::WStringValue* toString() {

return new CORBA::WStringValue(CORBA::wstring_dup(L”javax::ejb::CreateException”));

}

};

接下來,我們定義工廠類CreateExceptionFactory。我們至少要實(shí)現(xiàn)create_for_unmarshal()方法,但是我們還要實(shí)現(xiàn)create__()方法。這兩個(gè)方法都返回一個(gè)新實(shí)現(xiàn)的類實(shí)例:

class CreateExceptionFactory: public ::javax::ejb::CreateException_init

{

public:

CreateExceptionFactory() { }

virtual ~CreateExceptionFactory() { }

javax::ejb::CreateException* create__() {

return new CreateExceptionImpl();

}

CORBA::ValueBase* create_for_unmarshal() {

return new CreateExceptionImpl();

}

};

最后,我們把工廠注冊(cè)到ORB上。ORB接口提供register_value_factory()方法,它接收庫ID號(hào)和工廠實(shí)例作為參數(shù)。我們可以從IDL中得到庫ID號(hào)(它由#pragma指示)。下面的例子示范了如何注冊(cè)CreateException:

orb->register_value_factory(“RMI:javax.ejb.CreateException:FD98A9711F66DF7F:575FB6C03D49AD6A”, (CORBA::ValueFactory)new CreateExceptionFactory);

我們簡(jiǎn)單地實(shí)現(xiàn)了在CORBA客戶端中所需要的所有值類型。盡管這看起來有些復(fù)雜,但是你將會(huì)發(fā)現(xiàn)這個(gè)過程并不是很難而且你可以定義模板類來自動(dòng)生成它。

7.開發(fā)一個(gè)更高級(jí)的CORBA客戶端
現(xiàn)在你對(duì)CORBA的值類型已經(jīng)熟悉了,你可以為具有更復(fù)雜接口的EJB開發(fā)CORBA客戶端。

在這個(gè)例子中,我們用幾個(gè)使用了用戶自定義對(duì)象和固有的Java對(duì)象的方法來擴(kuò)展CorbaEai會(huì)話Bean的接口。首先,我們添加sumObj()方法來將兩個(gè)Integer對(duì)象相加:

public Integer sumObj(Integer num1, Integer num2) throws RemoteException;

然后我們?yōu)橐粋€(gè)可序列化的類MyType添加一個(gè)getter/setter操作對(duì):

public MyType getMyType() throws RemoteException;

public void setMyType(MyType mt) throws RemoteException;

MyType類非常簡(jiǎn)單,它包含兩個(gè)屬性(為簡(jiǎn)單起見,我沒有列出相對(duì)應(yīng)的getter/setter操作方法):

package eai;

import java.io.Serializable;

public final class MyType implements serializable {

public int a;

public double b;

}

最后,我們添加一個(gè)返回Java向量的方法getVector()和一個(gè)返回Java集合的方法getCollection():

public Vector getVector() throws RemoteException;

public Collection getCollection() throws RemoteException;

這些方法代表了大多數(shù)基于EJB的應(yīng)用中的典型方法。完整的例子可以參見源代碼2。

開發(fā)這個(gè)CORBA客戶端的過程跟第一個(gè)例子相似。首先,我們生成IDL接口。我們使用跟前面一樣的命令;但是,這次我們不再簡(jiǎn)化IDL。

注重,為會(huì)話Bean CorbaEai遠(yuǎn)程組件接口生成的IDL接口遵循RMI/IDL映射屬性訪問方法的規(guī)則。使用JavaBean命名方式來讀寫/只讀屬性的方法沒有映射到IDL操作,而是映射到IDL屬性。在我們的例子中,我們有g(shù)etMyType()和setMyType()讀寫屬性的方法和getVector()、getCollection()的只讀方法。這些方法映射到下面的IDL屬性:

attribute ::eai::MyType myType;

readonly attribute ::java::util::Vector vector;

readonly attritube ::java::util::Collection collection;

為了從C++訪問這些屬性,你必須知道它們是如何從IDL映射到C++(或者你選擇的其它語言)。對(duì)C++,每一個(gè)屬性映射到兩個(gè)重載的和屬性一樣名字的C++函數(shù),一個(gè)用來設(shè)置屬性,一個(gè)用來讀取屬性。只讀屬性只映射到一個(gè)讀取函數(shù)。更具體的信息請(qǐng)參閱C++語言映射。

其它方法,如sum()和sumObj(),都是一對(duì)一地映射:

long sum(in long arg0, in long arg1);

::java::lang::Integer sumObj(in ::java::lang::Integer arg0, in ::java::lang::Integer arg1);

接下來,我們用ORBacus的idl編譯器把IDL接口編譯成C++。你可以一個(gè)一個(gè)地來編譯所有的IDL文件,也可以把所有的IDL文件放在一個(gè)文件中編譯。

現(xiàn)在,我們可以編寫C++客戶端的代碼。第一,按照我前面解釋的,為所有有關(guān)的值類型提供值類型的實(shí)現(xiàn)(值類型的類和工廠類)。在例子中,我們?yōu)橄旅孢@些值類型定義實(shí)現(xiàn):

l MyType

l Integer

l Vector

l CreateException

l RemoveException

我們還要把這些值類型注冊(cè)到ORB。

你也許要希奇為什么我們沒有為Collection定義一個(gè)值類型。你知道,Collection是一個(gè)接口,它由類AbstractCollection實(shí)現(xiàn),提供了一個(gè)框架性的實(shí)現(xiàn)。JavaSDK為更多的特定接口提供了實(shí)現(xiàn),如List。為了理解這種類和接口之間的層次關(guān)系,請(qǐng)看以下的UML圖:



Collection的接口和實(shí)現(xiàn)類層次

你可以把Vector看成Collection接口的一個(gè)可能的實(shí)現(xiàn),所以我們用它來訪問Collection。

實(shí)際上C++用來調(diào)用CorbaEai會(huì)話Bean方法的代碼是比較簡(jiǎn)單的。為調(diào)用sumObj()方法,我們先創(chuàng)建兩個(gè)Integer值類型并插入數(shù)值,然后調(diào)用方法、輸出結(jié)果:

::java::lang::Integer_var javaInt1 = new IntegerImpl();

::java::lang::Integer_var javaInt2 = new IntegerImpl();

javaInt1->value(15);

javaInt2->value(20);

::java::lang::Integer_var javaIntR = ceai->sumObj(javaInt1, javaInt2);

cout << "sumObj(): " << javaIntR->value() << endl;

為了調(diào)用getMyType()和setMyType()方法,回憶一下它們是如何被映射到IDL屬性的。所以,我們用C++重載的方法myType()。下面的代碼調(diào)用會(huì)話Bean上的getMyType()方法:

::eai::MyType_var mt = ceai->myType();

cout << "getMyType(): " << mt << endl;

為了調(diào)用setMyType()方法,我們先創(chuàng)建一個(gè)MyType實(shí)例并填充必要的數(shù)值;剩下的就是調(diào)用它了:

cout << "setMyType()... " << endl;

::eai::MyType_var mt2 = new MyTypeImpl();

mt2->a((CORBA::Long)9);

mt2->b((CORBA::Double)9.9);

ceai->myType(mt2);

注重,這兒的方法名字已經(jīng)變了,因?yàn)槲覀冇玫氖荍avaBean的命名方式(get/set方法)。否則,方法就不會(huì)改變。

對(duì)getVector()方法也是一樣,它被映射到一個(gè)只讀的IDL屬性。所以,我們用C++的vector()方法來訪問它:

::java::util::Vector_ptr vec = ceai->vector();

cout << "getVector(): " << vec << endl;

這個(gè)過程中最有趣的事情也許是我們?nèi)绾卧L問Collection的過程。調(diào)用會(huì)話Bean的getCollection()方法(在C++中是collection())后,我們把它顯式的轉(zhuǎn)換為一個(gè)Vector:

::java::util::Collection_ptr coll = ceai->collection();

::java::util::Vector_ptr cvec = ::java::util::Vector::_downcast(coll);

cout << "Collection: " << cvec << endl;

最后,注重,我們可以應(yīng)用那些從EJBObject繼續(xù)來的遠(yuǎn)程組件接口方法。如最重要的方法remove()。所以,我們可以得出結(jié)論我們的例子中有以下一行:

ceai->remove();

理想的集成

在本文中,我已經(jīng)說明了在CORBA和EJB的的集成是可能的。但是,用非Java開發(fā)一個(gè)EBJ的客戶端并不象你所希望的那么簡(jiǎn)單,尤其是當(dāng)你使用那接收和返回對(duì)象或是用戶定義類型的方法。這是應(yīng)用EJB組件的絕大多數(shù)情況,所以你必須使用CORBA的值類型。最主要的問題是你還要必須實(shí)現(xiàn)Java固有的類型。我希望CORBA的銷售商盡快提供值類型的實(shí)現(xiàn),如IBM的WebSphere應(yīng)用服務(wù)器。我也希望不同的CORBA產(chǎn)品之間的互操作問題能夠盡快解決。

無論如何,當(dāng)你把一個(gè)現(xiàn)有的不是基于Java的應(yīng)用跟新的基于J2EE的方案進(jìn)行集成時(shí),EJB和CORBA之間的互操作是十分重要和有用的。

譯者說明:

l 在第7節(jié)中,采用值類型,當(dāng)用rmic把JAVA接口映射到IDL時(shí),我使用了-noValueMethods,因?yàn)榧偃鐜е搮?shù)編譯出來的IDL文件要多一些,再映射到C++后,很難編譯過去。

l 即使使用-noValueMethods選項(xiàng),最后生成的C++程序還是不能完全進(jìn)行正常地編譯和運(yùn)行(涉及到Java固有的那些類型:Integer、Vector、Collection),所以只好將一些語句屏蔽掉了。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 岳西县| 鸡泽县| 河南省| 上虞市| 阳东县| 濉溪县| 专栏| 锡林郭勒盟| 乌苏市| 伊宁县| 巴彦县| 浮山县| 醴陵市| 虎林市| 盐津县| 定远县| 安庆市| 颍上县| 铁岭市| 准格尔旗| 临邑县| 长宁区| 屏南县| 遂昌县| 额尔古纳市| 宁城县| 大理市| 怀集县| 金华市| 南召县| 敦煌市| 河西区| 襄城县| 牟定县| 邯郸县| 崇礼县| 永福县| 武山县| 乐亭县| 兴城市| 巫溪县|