Java&CORBA程式設計例項

chszs發表於2009-07-16
版權宣告:本文為博主chszs的原創文章,未經博主允許不得轉載。 https://blog.csdn.net/chszs/article/details/4353478

Java&CORBA程式設計例項

 

Java IDL技術在Java平臺上新增了CORBA(Common Object Request Broker Architecture)功能,提供了基於標準的互操作能力和連線性。Java IDL技術使得分散式的Java Web應用能夠通過使用工業標準的IDL和IIOP(Internet Inter-ORB Protocol)來透明地呼叫遠端網路服務的操作。執行時元件(Runtime Components)包括了一個用於分散式計算且使用IIOP通訊的Java ORB.

可移植物件介面卡(Portable Object Adapter,POA)
CORBA物件的負責分隔伺服器端遠端呼叫控制程式碼(handler)到遠端物件和它的服務者(servant)。物件由遠端呼叫所暴露,而服務者包含實際處理這些請求的方法。每個物件都可以選擇服務者為靜態的(一次)或動態的(每個遠端呼叫),在這兩種情況下,都允許呼叫轉移到另一臺伺服器。
在伺服器端,POA形成了類似樹狀的結構,每個POA都負責一到多個服務的物件。樹的分支可以是獨立活動的、或鈍化的,服務者呼叫有不同的程式碼和不同的請求處理策略。

API規範
    * org.omg.CORBA 包 – 提供了OMG CORBA APIs到Java程式語言的對映
    * org.omg.CosNaming 包 – 為Java IDL提供命名服務
    * org.omg.PortableServer 包 – 為建立伺服器端的可移植的、跨越多ORB的應用程式提供類和介面
    * org.omg.PortableInterceptor 包 – 提供了註冊ORB鉤子的機制,此鉤子通過ORB服務能擷取正常的ORB執行流
    * org.omg.DynamicAny 包 – 提供了使得任何值都能被動態解釋(或遍歷)和通過DynAny物件構造出來的類和介面
    * org.omg.CORBA.ORB – 為CORBA ORB功能的API

分散式物件之間的關係有兩方面:客戶端和伺服器。
伺服器提供遠端介面,客戶端呼叫遠端介面。
在客戶端,應用程式包括遠端物件的引用。該物件引用有stub方法,它是獨立的遠端方法。stub方法實際連線到ORB,因此呼叫它實際上轉發呼叫到伺服器。
在伺服器端,ORB使用skeleton程式碼翻譯遠端呼叫為本地物件的方法呼叫。Skeleton把呼叫轉換成指定實現的格式,並在方法中呼叫。當方法返回時,Skeleton程式碼轉換方法呼叫的結果或錯誤,經ORB送回客戶端。

Java IDL開發過程
1)定義遠端介面
使用IDL語言為遠端物件定義介面。
【Billing.idl原始碼】如下:

// 宣告CORBA IDL模組
module BillingApp{
// 宣告介面
interface Billing{
string successBilling();
oneway void shutdown();
};
};

2)編譯遠端介面
使用idlj編譯器生成Java語言的stub和skeleton原始檔。
idlj編譯器預設只生成客戶端的binding程式碼。如果同時需要客戶端的bindings和伺服器端的skeletons,必須加上-fall選項。
使用POA(Portable Object Adaptor)的優點:
· 允許程式設計者構建物件在不同ORB產品之間的可移植實現
· 支援帶持久化標識的物件
· 對物件的透明活動提供支援
· 允許單個servant支援多種物件同時標識
注意:確定jdk/bin目錄下有:idlj、java、javac、orbd
命令:
 idlj -fall Billing.idl
在當前目錄下生成BillingApp目錄,包含如下六個檔案:
· Billing.java    ————> 此介面包含IDL介面的Java版本。它繼承自org.omg.CORBA.Object,提供標準的CORBA物件功能。
· BillingHelper.java    ————> 此類提供輔助功能,Helper類負責讀寫資料型別到CORBA流,以及插入和提取資料型別。
· BillingHolder.java    ————> This final class holds a public instance member of type Billing.
· BillingOperations.java    ————> 此介面包含successBilling()和shutdown()方法。
· BillingPOA.java    ————> 此抽象類是基於流的伺服器Skeleton,為伺服器提供基本的CORBA功能。它繼承org.omg.PortableServer.Servant,實現了InvokeHandler介面和BillingOperations介面。伺服器類BillingServant繼承BillingPOA。
· _BillingStub.java    ————> 此類是客戶端stub,為客戶端提供CORBA功能。它繼承org.omg.CORBA.Object,提供標準CORBA物件功能。還擴充套件了BillingOperations介面和org.omg.CORBA.portable.IDLEntity介面。

3)實現伺服器端
一旦使用idlj編譯器後,就可以使用它產生的Skeleton裝配伺服器應用程式了。另外要實現遠端介面方法,伺服器程式碼應包含啟動ORB和等待遠端客戶端呼叫的機制。
伺服器端由兩個類組成,一個是servant,另一個是Server。
servant是BillingImpl類,是Billing IDL介面的實現,每個Billing例項均由BillingImpl例項實現。servant是BillingPOA的子類。
servant包含了IDL定義的所有方法,與通常的Java方法類似。
server類含伺服器的main()方法,它:
· 建立和初始化ORB例項
· 獲得根POA的引用並啟用POAManager
· 建立一個Servant例項(CORBA的Billing物件的實現)並通知ORB
· 獲得根命名上下文
· 在命名上下文用“Billing”名註冊新物件
· 等待客戶端呼叫此新物件

【BillingImpl.java原始碼】:
import org.omg.CORBA.ORB;
import BillingApp.*;
class BillingImpl extends BillingPOA{
private ORB orb;
public void setORB(ORB orb_val){
this.orb = orb_val;
}
/**
* 實現successBilling()方法
*/
public String successBilling() {
return “/nBilling success!!/n”;
}
/**
* 實現shutdown()方法
*/
public void shutdown(){
orb.shutdown(false);
}
}

 

【BillingServer.java原始碼】:
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.PortableServer.POA;
import BillingApp.*;
public class BillingServer {
public static void main(String args[]){
try{
// 建立和初始化ORB
ORB orb = ORB.init(args, null);
// 獲得根POA的引用並啟用POAManager
POA rootpoa = (POA)orb.resolve_initial_references(“RootPOA”);
rootpoa.the_POAManager().activate();
// 建立servant並註冊到ORB
BillingImpl billingImpl = new BillingImpl();
billingImpl.setORB(orb);
// 從servant獲得物件引用
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(billingImpl);
Billing href = BillingHelper.narrow(ref);
// 得到根命名上下文
org.omg.CORBA.Object objRef = orb.resolve_initial_references(“NameService”);
// 使用命名上下文,它是互操作命名服務規範的一部分
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
// 在命名中繫結物件引用
String name = “Billing”;
NameComponent path[] = ncRef.to_name(name);
ncRef.rebind(path, href);
System.out.println(“BillingServer is ready and waiting…”);
// 等待客戶端呼叫
orb.run();
}catch(Exception e){
System.err.println(“ERROR:”+e);
e.printStackTrace(System.out);
}
System.out.println(“BillingServer Exiting …”);
}
}

 

4)實現客戶端
與第三步類似,可以使用idlj產生的stub作為客戶端應用程式的基礎。客戶端程式碼建立於stub之上,啟動ORB,使用伺服器提供的命名服務查詢,獲得遠端物件的引用,呼叫其方法。
【BillingClient.java原始碼】:
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import BillingApp.*;
public class BillingClient {
static Billing billingImpl;
public static void main(String args[]){
try{
// 建立和初始化ORB
ORB orb = ORB.init(args, null);
System.out.println(“ORB initialised”);
// 獲得根命名上下文
org.omg.CORBA.Object objRef = orb.resolve_initial_references(“NameService”);
// 使用NamingContextExt代替命名上下文,它是互操作命名服務的一部分
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
// 在命名中解析物件引用
String name = “Billing”;
billingImpl = BillingHelper.narrow(ncRef.resolve_str(name));

System.out.println(“Obtained a handle on server object: “+billingImpl);
System.out.println(billingImpl.successBilling());
billingImpl.shutdown();
}catch(Exception e){
System.out.println(“ERROR: “+e);
e.printStackTrace(System.out);
}
}
}

5)啟動應用程式
要執行伺服器和客戶端,必須先啟動命名服務,再啟動伺服器,最後執行客戶端。
此例用到命名服務,它使得servant物件的操作對客戶端有效。伺服器需要命名服務的物件引用,命名服務可以釋出物件引用實現各種介面。客戶端使用物件引用來呼叫方法。
Java SE 1.4以上提供了兩種可選的命名服務:
· tnameserv
一種透明的命名服務
· orbd
包含自啟動服務、透明的命名服務、持久化命名服務和命名管理器的後臺處理程式。
本例使用orbd。

5.1)啟動orbd
注意:Solaris系統執行要求root許可權並以1024埠開始程式。因此,對所有OS,可以選用大於或等於1024的埠以實現統一。
-ORBInitialPort選項用於指定埠(非預設狀態)。
例如:假定使用1050埠的Java ORB Daemon(orbd),命令如下:
start orbd -ORBInitialPort 1050 -ORBInitialHost localhost

5.2)開始Billing伺服器
start java BillingServer -ORBInitialPort 1050 -ORBInitialHost localhost
注:如在同一臺主機上執行,可省略-ORBInitialHost localhost

5.3)執行客戶端應用程式
java BillingClient -ORBInitialPort 1050 -ORBInitialHost localhost


相關文章