版權聲明:本文為部落客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.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.PortableServer.POA;
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源碼】:
public class BillingClient {
static Billing billingImpl;
System.out.println("ORB initialised");
// 獲得根命名上下文
// 使用NamingContextExt代替命名上下文,它是互操作命名服務的一部分
// 在命名中解析對象引用
billingImpl = BillingHelper.narrow(ncRef.resolve_str(name));
System.out.println("Obtained a handle on server object: "+billingImpl);
System.out.println(billingImpl.successBilling());
billingImpl.shutdown();
System.out.println("ERROR: "+e);
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