CORBA基本介紹
CORBA(公用對象請求代理體系)是OMG(對象管理組織)于1991年提出的基于對象技術(shù)的分布計算應(yīng)用軟件體系結(jié)構(gòu)。CORBA標(biāo)準(zhǔn)主要分為三個部分:接口定義語言(IDL)、對象請求代理(ORB),以及ORB之間的互操作協(xié)議IIOP,核心是對象請求代理。CORBA可以抽象系統(tǒng)平臺、網(wǎng)絡(luò)通訊及編程語言的差異。通過在CORBA技術(shù)規(guī)范中定義多種類型的服務(wù),如名字服務(wù)(Naming Service)、事務(wù)服務(wù)(Transaction Service)、對象生命期服務(wù)(LifeCycle Service)、并發(fā)控制服務(wù)(Concurrency Control Service)、時間服務(wù)(Time Service)等功能,為應(yīng)用軟件開發(fā)者提供一個全面、健壯、可擴(kuò)展的分布對象計算平臺,使面向?qū)ο蟮膽?yīng)用軟件在分布異構(gòu)環(huán)境下方便地實(shí)現(xiàn)可重用、易移植和互操作。
與RMI比較
與RMI 不同,CORBA 不屬于Java 平臺本身。OMG(Object Management Group,對象管理組織)發(fā)明了CORBA 規(guī)范,CORBA 被設(shè)計成與平臺和語言無關(guān)。因此,CORBA對象可以運(yùn)行于任何平臺之上,位于網(wǎng)絡(luò)的任何位置,還可以用任何語言(包括 Java、C、C++和Smalltalk 等)編寫,只要該語言具有IDL(Interface Definition Language,接口定義語言)的映射。
與RMI 相比,CORBA 是為更大、可伸縮更強(qiáng)的系統(tǒng)準(zhǔn)備的,在這些系統(tǒng)中可能有數(shù)千個對象;CORBA 的編程和部署比RMI 更復(fù)雜,但允程序員開發(fā)需要事務(wù)、安全性等支持的企業(yè)級系統(tǒng);CORBA 的命名服務(wù)也比RMI 命名注冊功能更強(qiáng)大和靈活。
CORBA 的實(shí)現(xiàn)稱為ORB(Object Request Broker,對象請求代理)。Java IDL 即是CORBA 的一個實(shí)現(xiàn),它是JDK1.3 或更高版本的核心軟件包之一,定義在org.omg.CORBA及其子包中。在Java IDL 的支持下,開發(fā)人員可以使用如下兩種方法將Java 和CORBA 集成在一起:
· ??創(chuàng)建Java 對象并使之可在CORBA ORB 中展開,
· ??創(chuàng)建Java 類并作為和其它ORB 一起展開的CORBA 對象的客戶。這種方法提供了另外一種途徑,通過它Java 可以被用于將你的新的應(yīng)用和以前遺留的系統(tǒng)相集。
采用Java創(chuàng)建CORBA應(yīng)用
CORBA對象服務(wù)的實(shí)現(xiàn)方式分為兩種:對象的命名引用方式和字符串化對象引用方式。不論采用何種高級語言,創(chuàng)建CORBA應(yīng)用程序的過程大體如下:
● 編寫IDL接口定義文件;
● 將接口定義文件編譯為相應(yīng)高級語言源代碼,產(chǎn)生服務(wù)器框架與客戶端存根;
● 基于服務(wù)器框架,編寫服務(wù)對象實(shí)現(xiàn)程序;
● 基于客戶端存根,編寫客戶對象調(diào)用程序;
● 分別編譯客戶對象和服務(wù)對象程序;
● 運(yùn)行服務(wù)對象和客戶對象程序;
CORBA對象服務(wù)的實(shí)現(xiàn)方式分為兩種:對象的命名引用方式和字符串化對象引用方式。不論采用何種高級語言,創(chuàng)建CORBA應(yīng)用程序的過程大體如下:
● 編寫IDL接口定義文件;
● 將接口定義文件編譯為相應(yīng)高級語言源代碼,產(chǎn)生服務(wù)器框架與客戶端存根;
● 基于服務(wù)器框架,編寫服務(wù)對象實(shí)現(xiàn)程序;
● 基于客戶端存根,編寫客戶對象調(diào)用程序;
● 分別編譯客戶對象和服務(wù)對象程序;
● 運(yùn)行服務(wù)對象和客戶對象程序;
CORBA實(shí)例分析
下面通過一個實(shí)例,描述如何通過Java創(chuàng)建CORBA應(yīng)用程序。
下面通過一個實(shí)例,描述如何通過Java創(chuàng)建CORBA應(yīng)用程序。
1. 接口定義 (Hello.idl)
Hello.idl
|
module HelloApp { interface Hello { string sayHello(in string message); }; }; |
通過Sun提供的將IDL文件編譯成Java源代碼的工具idlj(jdk1.3.0_01以上版本),為接口定義文件生成客戶端存根和服務(wù)器框架。具體操作如下:
idlj -oldImplBase -fall Hello.idl
編譯后將在 HelloApp 子目錄中形成以下六個文件:
n
_HelloImplBase.java
該抽象類是一個服務(wù)器 skeleton,它可為服務(wù)器提供基本的 CORBA 功能。它實(shí)現(xiàn) Hello.java 接口。服務(wù)器類 HelloServant 擴(kuò)展 _HelloImplBase。
該抽象類是一個服務(wù)器 skeleton,它可為服務(wù)器提供基本的 CORBA 功能。它實(shí)現(xiàn) Hello.java 接口。服務(wù)器類 HelloServant 擴(kuò)展 _HelloImplBase。
n
_HelloStub.java
該類是客戶機(jī) stub,可為客戶機(jī)提供 CORBA 功能。它實(shí)現(xiàn) Hello.java 接口。
該類是客戶機(jī) stub,可為客戶機(jī)提供 CORBA 功能。它實(shí)現(xiàn) Hello.java 接口。
n Hello.java
該接口含有 IDL 接口的 Java 版本。Hello.java 接口擴(kuò)展 org.omg.CORBA.Object 并提供標(biāo)準(zhǔn)的 CORBA 對象功能。
n HelloHelper.java
這是一個終態(tài)類,可以提供輔助功能,特別是提供將 CORBA 對象引用轉(zhuǎn)換為適當(dāng)類型所需的 narrow() 方法。
n HelloHolder.java
這是一個終態(tài)類,其中含有 Hello 類型的公有實(shí)例成員。它可為“out” 和 “inout” 變量提供操作。CORBA 有這些變量,但不容易映射為 Java 的語義。
n
HelloOperations.java
這是一個接口類,其中含有方法 sayHello()。
要完成該應(yīng)用程序,只需在文件 HelloServer.java 和 HelloClient.java 中提供服務(wù)器和客戶機(jī)的實(shí)現(xiàn)即可。
2. 接口實(shí)現(xiàn)
HelloImpl.java是Hello IDL 接口的實(shí)現(xiàn);每個Hello實(shí)例都由一個HelloImpl實(shí)例來實(shí)現(xiàn)。HelloImpl是_HelloImplBase的子類,_HelloImplBase是由 idlj編譯器從示例 IDL 中生成的。
HelloImpl.java
|
/* * @author javamxj (CSDN Blog) 創(chuàng)建日期 2004-12-27 */ import HelloApp . * ; public class HelloImpl extends _HelloImplBase { /* 構(gòu)造函數(shù) */ public HelloImpl() { super (); } /* 實(shí)現(xiàn)接口聲明方法sayHello */ public String sayHello( String message) { System .out.println( "我在CORBA的服務(wù)器端,客戶端正在調(diào)用'sayHello'方法。 " ); System .out.println( "Hello " + message); return message; } } |
3. 服務(wù)器
服務(wù)器類含有服務(wù)器的main()方法,可完成以下任務(wù):
·
創(chuàng)建一個 ORB 實(shí)例
·
創(chuàng)建一個HelloImpl實(shí)例(CORBA Hello對象的實(shí)現(xiàn))并通知 ORB
·
獲取一個命名上下文的 CORBA 對象引用,在該命名上下文中注冊新 CORBA 對象
·
在命名上下文中將新對象注冊在“Hello”名下
·
等待對新對象的調(diào)用
HelloSever.java
|
/* * @author javamxj (CSDN Blog) 創(chuàng)建日期 2004-12-27 */ import org . omg . CosNaming . * ; import org . omg . CORBA . * ; public class HelloServer { public static void main( String args[]) { try { /* 創(chuàng)建和初始化 ORB */ ORB orb = ORB.init(args, null ); System .out.println( "開始 ORB Server ..." ); /* 創(chuàng)建一個實(shí)例并將其向 ORB 注冊 */ HelloImpl helloImpl = new HelloImpl(); orb.connect(helloImpl); System .out.println( "將實(shí)例注冊到ORB " ); /* 獲取根命名上下文 */ org.omg.CORBA. Object objRef =orb.resolve_initial_references( "NameService" ); NamingContext ncRef = NamingContextHelper.narrow(objRef); /* 綁定命名中的對象引用 */ NameComponent nc = new NameComponent( "Hello" , "" ); NameComponent path[] = { nc }; ncRef.rebind(path, helloImpl); /* 等待來自客戶機(jī)的調(diào)用 */ java.lang. Object sync = new java.lang. Object (); synchronized (sync) { sync.wait(); } System .out.println( "等待CORBA客戶端調(diào)用..." ); } catch ( Exception e) { System .err.println( "錯誤: " + e); e.printStackTrace( System .out); } } } |
4. 客戶端
下面的應(yīng)用程序客戶機(jī)將完成以下任務(wù):
·
創(chuàng)建一個 ORB
·
獲取一個指向命名上下文的引用
·
在命名上下文中查找 "Hello" 并獲得指向該 CORBA 對象的引用
·
調(diào)用對象的 sayHello() 操作并打印結(jié)果
HelloClient.java
|
|
CORBA Server/Client的編譯與運(yùn)行
·
把上面4個文件復(fù)制到D:\CorbaSample目錄下,在此目錄下建立Client和Server目錄,假設(shè)它們分別為客戶端和服務(wù)端。
· 編譯Hello.idl
D:\CorbaSample>idlj -oldImplBase -fall Hello.idl
這會生成一個HelloApp的目錄
·
編譯所有java文件:
D:\CorbaSample>javac *.java HelloApp/*.java
·
分別在Client和Server目錄下建立HelloApp子目錄,將D:\CorbaSample\HelloApp目錄中的
_HelloStub.class
Hello.class
HelloHelper.class
HelloHolder.class
HelloOperations.class
復(fù)制到D:\CorbaSample\Client\HelloApp目錄下,再將D:\CorbaSample目錄中的HelloClient.class復(fù)制到D:\CorbaSample\Client目錄下。
將D:\CorbaSample\HelloApp目錄中的
_HelloImplBase.class
Hello.class
HelloOperations.class
復(fù)制到D:\CorbaSample\Server\HelloApp目錄下, 再將D:\CorbaSample目錄中的HelloServer.class和 HelloImpl.class 復(fù)制到D:\CorbaSample\Server目錄中
(
注意:
當(dāng)然,你可以不必建立Server和Client目錄及以上復(fù)制文件的操作,可以直接在D:\CorbaSample目錄中進(jìn)行操作,我這樣做的目的主要是為了區(qū)分客戶端和服務(wù)端
)
·
確保名字服務(wù)器處于運(yùn)行狀態(tài):
D:\CorbaSample\Server>tnameserv -ORBInitialPort 1050
·
啟動 Hello 服務(wù)器:
D:\CorbaSample\Server>java HelloServer -ORBInitialPort 1050
·
CORBA客戶端調(diào)用CORBA服務(wù):
D:\CorbaSample\Client>java HelloClient -ORBInitialPort 1050
(本地調(diào)用,不需要用-ORBInitialHost參數(shù)來指定遠(yuǎn)程的IP地址)
D:\CorbaSample\Server>java HelloClient -ORBInitialHost localhost -ORBInitialPort 1050
(遠(yuǎn)程調(diào)用CORBA服務(wù),可以將localhost替換成遠(yuǎn)程的IP地址)
圖1. 客戶端沒有調(diào)用CORBA服務(wù)之前
圖2. 客戶端調(diào)用CORBA服務(wù)之后
一點(diǎn)補(bǔ)充:
不知道大家注意到?jīng)]有,在JDK1.4編譯idl文件時使用的idlj -oldImplBase -fall Hello.idl
這個命令帶有“-oldImplBase”參數(shù),表示這是一個老版本的實(shí)現(xiàn)。而JDK1.4版本下,可以直接使用
idlj-fall Hello.idl命令,這樣
idlj
編譯器對服務(wù)器端生成的是輕便對象適配器(
POA
)。
(直接再命令行敲入idlj可以得到其使用說明)
這里我就不作詳細(xì)說明了,操作基本上與上一個例子相似。
首先在 D:\CorbaSample2 目錄下編寫下面4個文件,然后依次進(jìn)行如下操作:
D:\CorbaSample2>idlj -fall Hello.idl
D:\CorbaSample2>javac *.java HelloApp/*.java
D:\CorbaSample2>tnameserv -ORBInitialPort 1050
D:\CorbaSample2>java HelloServer -ORBInitialPort 1050
D:\CorbaSample2>java HelloClient -ORBInitialPort 1050
(
注意
:這里為了方便.我沒有再劃分客戶端和服務(wù)端。進(jìn)行對比,你可以發(fā)現(xiàn)這次idlj編譯器生成的文件與上例中生成的文件有和不同。)
Hello.idl
|
module HelloApp { interface Hello { string sayHello(in string message); }; }; |
HelloImpl.java
|
/* * @author javamxj (CSDN Blog) 創(chuàng)建日期 2004-12-27 */ import org . omg . CORBA . * ; import HelloApp . HelloPOA ; public class HelloImpl extends HelloPOA { private ORB orb; public void setORB(ORB orb_val) { orb = orb_val; } /* 實(shí)現(xiàn)接口聲明方法sayHello */ public String sayHello( String message) { System .out.println( "我在CORBA的服務(wù)器端,客戶端正在調(diào)用'sayHello'方法。 " ); System .out.println( "Hello " + message); return message; } } |
HelloServer.java
|
/* * @author javamxj (CSDN Blog) 創(chuàng)建日期 2004-12-27 */ import HelloApp . * ; import org . omg . CosNaming . * ; import org . omg . CORBA . * ; import org . omg . PortableServer . * ; import org . omg . PortableServer . POA ; public class HelloServer { public static void main( String args[]) { try { /* 創(chuàng)建和初始化 ORB */ ORB orb = ORB.init(args, null ); /* 獲取對RootPOA的引用,啟動POAManager */ POA rootpoa = POAHelper.narrow(orb .resolve_initial_references( "RootPOA" )); rootpoa.the_POAManager().activate(); /* 創(chuàng)建一個實(shí)例并將其向 ORB 注冊 */ HelloImpl h = new HelloImpl(); h.setORB(orb); System .out.println( "將實(shí)例注冊到ORB " ); /* 獲取對服務(wù)端的對象引用 */ org.omg.CORBA. Object ref = rootpoa.servant_to_reference(h); Hello href = HelloHelper.narrow(ref); /* 從名稱服務(wù)中獲取根元素名稱上下文 */ org.omg.CORBA. Object objRef = orb .resolve_initial_references( "NameService" ); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); /* 在Hello名稱下注冊新對象 */ String name = "Hello" ; NameComponent path[] = ncRef.to_name(name); ncRef.rebind(path, href); /* 等待客戶端的調(diào)用。 */ orb.run(); System .out.println( "等待CORBA客戶端調(diào)用..." ); } catch ( Exception e) { System .err.println( "ERROR: " + e); e.printStackTrace( System .out); } System .out.println( "HelloServer Exiting ..." ); } } |
HelloClient.java
|
/* * @author javamxj (CSDN Blog) 創(chuàng)建日期 2004-12-27 */ import HelloApp . * ; import org . omg . CosNaming . * ; import org . omg . CORBA . * ; public class HelloClient { public static void main( String args[]) { try { /* 創(chuàng)建和初始化 ORB */ ORB orb = ORB.init(args, null ); /* 獲取根命名上下文 */ org.omg.CORBA. Object objRef = orb .resolve_initial_references( "NameService" ); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); /* 在名稱上下文中查找Hello對象,獲取對它的引用。 */ String name = "Hello" ; Hello h = HelloHelper.narrow(ncRef.resolve_str(name)); System .out.println( "我在客戶端,開始調(diào)用CORBA服務(wù)器端的'sayHello'方法" ); System .out.println( "歡迎, " + h.sayHello( "javamxj blog" )); } catch ( Exception e) { System .out.println( "錯誤 : " + e); e.printStackTrace( System .out); } } } |
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
