[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 編程技術 > Java > 正文
CORBA 及Java IDL應用編程
本文出自: 作者: (2001-08-03 15:00:00)
CORBA是一個分布式的面向對象應用架構規范,它是由OMG研究組在80年代末提出,在90年代逐步完善,形成現在被軟件行業普遍認可的標準CORBA/IIOP 規范2.3。CORBA的開發者OMG最初由3Com、American Airlines、Canon、Data General、Hewlett-Packard、Philips、 Sun 和Unisys等八家公司在1989年組建,專門從事公共軟件平台的研究和行業標準的制訂, 目前已經有800多個成員單位加入OMG。
  CORBA的核心是開放軟件總線ORB,它提供了網絡環境無關性、操作系統無關性和開發語言無關性的公共平台。在面向對象的應用環境中,CORBA對象(本文所說的“對象”是面向對象系統中的術語,是指一個實體)的請求者不必知道它所請求的對象是在哪裡,是如何實現的,而是由ORB來負責跨平台的運作管理,無須應用系統的開發者幹預。CORBA所具有的跨平台、分布式、面向對象的這些優點使它具有廣闊的應用前景,日益受到軟件行業的重視。
  CORBA是一個中間件規范並不是一個實體軟件。軟件開發者通過使用第三方的ORB工具或IDL語言來定義CORBA對象,實現ORB功能。
  
  一、CORBA應用模型
  
  下圖展示了CORBA在分布式面向對象應用中,從客戶端發出請求直到服務端實現CORBA對象的一個流轉過程。
  CORBA對象的客戶有一個對該對象的“對象引用”,客戶使用“對象引用”來請求“對象方法”。如果服務端不在本地(不在同一機器的同一應用系統中或不在同一機器中),則“對象引用”指向stub功能(在Java 中,stub和skeleton都是類來實現),stub利用ORB機制將請求帶到服務端的對象。stub通過ORB來確定運行對象的服務端的機器,並請求該機器的ORB連接到對象的服務端去。stub同ORB建立連接,向該機的skeleton發送“對象引用”及相關參數,再由skeleton功能連接到目標對象的“對象實現”上。skeleton將請求和參數轉換成規定格式然調用該對象。最,“對象實現”的結果沿著來的路徑傳送回客戶請求端。
  以上是CORBA實現對象應用的全過程。在這個操作過程中,客戶並不知道CORBA對象的位置、它的實現細節,也不必知道所使用的ORB是什。在ORB之間通過建立在TCP/IP標準之上的IIOP-Internet InterORB Protocol進行通信聯系,相互傳送信息。客戶只是使用CORBA對象的接口來調用對象的方法,CORBA對象的接口則使用IDL語言來定義。對象的接口定義了對象的類型,對象的方法和引用參數以及對象方法可能返回的異常結果。IDL編譯器將把CORBA對象的定義轉換成特定的編程語言。IDL還對每個對象生成相應的stub文件(類)和skeleton文件(類),通過它們實現應用系統同ORB的連接。
  
  二、Java IDL應用編程
  
  Java JDK 1.2提供了對CORBA的支持,Java IDL即idltojava編譯器就是一個ORB,可用來在Java語言中定義、實現和訪問CORBA對象。Java IDL支持的是一個瞬間的CORBA對象,即在對象服務器處理過程中有效。實際上,Java IDL的ORB是一個類庫而已,並不是一個完整的平台軟件,但它對Java IDL應用系統和其他CORBA應用系統之間提供了很好的底層通信支持,實現了OMG定義的ORB基本功能。
  下面將以“中國,早上好!”客戶/服務應用為例,詳細說明Java IDL的實際編程方法。在本例中,客戶端向服務端提出服務請求,服務端回送“中國,早上好!”,然在客戶端的屏幕上顯示出來。
  1定義並編譯對象接口
  定義IDL接口文件China.idl內容如下:
  module ChinaApp
  {
   interface China
   {
   string MorningChina();
   };
  };
  然運行Java IDL編譯器來編譯該接口文件:
   idltojava China.idl
  經idltojava 編譯自動建立了一個文件目錄ChinaApp,並在該目錄下生成五個Java語言文件:
  _ChinaImplBase.java就是服務端的skeleton類,它實現了服務端的China.java接口,為服務端對象提供了CORBA服務功能。
  _ChinaStub.java 是客戶端的stub類,為客戶端提供CORBA服務功能,它實現了客戶端的China.java接口。
  _China.java 是IDL接口的Java語言實現,是方法MorningChina()的實現。
  _ChinaHelper.java類提供了許多輔助功能的方法,主要是narrow()方法它為CORBA對象引用轉化成適合的類型。
  _ChinaHolder.java 提供了有關參數操作的實現,這些參數在CORBA中使用但Java語言中沒有直接的對應。
  下面將要利用這五個編寫實際應用的Java程序。
  2編寫客戶端應用程序
  (1)引入要使用的包:
  import ChinaApp.*; // 本應用的stub類
  import org.omg.CosNaming.*; // 要使用CORBA的名字服務
  import org.omg.CORBA.*; // 使用CORBA服務
  (2)聲明客戶應用類:
  public class ChinaClient {
  // main方法
  }
  (3)定義客戶應用類的main方法:
  public static void main(String args []){
   try {
   // 方法功能碼
   } catch (Exception e) {
   System.out.println("ERROR : " + e);
   e.printStackTrace(System.out);
   }
  } // main()
  以下幾步將編寫try塊中的內容。
  (4)建立ORB對象:
  ORB orb = ORB.init(args, null); // args為客戶程序啟動時的命令行參數
  (5)使用ORB的名字服務尋找China對象:
  org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); // 啟動
  NamingContext ncRef = NamingContextHelper.narrow(objRef); // 類型變換
  NameComponent nc = new NameComponent("China", "");// 注冊服務類
  NameComponent path[]= {nc};
  China ChinaRef = ChinaHelper.narrow(ncRef.resolve(path));
  (6)調用MorningChina操作,把服務端返回的內容顯示在屏幕上:
  String China = ChinaRef.MorningChina();
  System.out.println(China);
  完整的客戶應用Java程序ChinaClient如下:
  import ChinaApp.*;
  import org.omg.CosNaming.*;
  import org.omg.CORBA.*;
  public class ChinaClient {
   public static void main(String args[]){
   try {
   ORB orb = ORB.init(args, null);
   org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
   NamingContext ncRef = NamingContextHelper.narrow(objRef);
   NameComponent nc = new NameComponent("China", "");
   NameComponent path[]= {nc};
   China ChinaRef = ChinaHelper.narrow(ncRef.resolve(path));
   String China = ChinaRef.MorningChina();
   System.out.println(China);
   } catch(Exception e) {
   System.out.println("ERROR : " + e);   e.printStackTrace(System.out);
   }
   } // main()
  } // ChinaClient
  3編寫服務端應用程序
  (1)引入要使用的包:
  import ChinaApp.*; // 本應用的stub類
  import org.omg.CosNaming.*; // 要使用CORBA的名字服務
  import org.omg.CORBA.*; // 使用CORBA服務
  import org.omg.CosNaming.NamingContextPackage.* // 名字服務的例外處理;
  (2)聲明服務應用類:
  public class ChinaServer {
  // main方法
  }
  (3)定義服務應用類的main方法:
  public static void main(String args[]) {
   try {
   // 方法功能碼
   } catch (Exception e) {
   System.out.println("ERROR : " + e);
   e.printStackTrace(System.out);
   }
  } // main()
  然,開始編寫服務端main方法中try塊的內容。
  (4)建立ORB對象:
  ORB orb = ORB.init(args, null);
  ChinaServant ChinaRef = new ChinaServant();  orb.connect(ChinaRef);
  (5)使用ORB的名字服務尋找China對象(在main()方法的try塊中):
  org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); // 啟動
  NamingContext ncRef = NamingContextHelper.narrow(objRef); // 類型變換
  NameComponent nc = new NameComponent("China", ""); // 注冊服務類
  NameComponent path[]= {nc};
  ncRef.rebind(path, ChinaRef);
  (6)等待客戶調用(在main()方法的try塊中):
  java.lang.Object sync = new java.lang.Object();
  synchronized(sync) { sync.wait();}
  (7)定義MorningChina服務類(獨立在ChinaServer類之外)。該類實現本例的服務內容,它向客戶端返回“中國,早上好!”:
  class ChinaServant extends _ChinaImplBase {
   public String MorningChina() { return "\n\n中國,早上好!\n\n"}
  }
  下面是完整的服務應用Java程序ChinaServer:
  import ChinaApp.*;
  import org.omg.CosNaming.*;
  import org.omg.CosNaming.NamingContextPackage.*;
  import org.omg.CORBA.*;
  public class ChinaServer
  {
   public static void main(String args[]){
   try{
   ORB orb = ORB.init(args, null);
   ChinaServant ChinaRef = new ChinaServant();
   orb.connect(ChinaRef);
   org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
   NamingContext ncRef = NamingContextHelper.narrow(objRef);
   NameComponent nc = new NameComponent("China", "");
   NameComponent path[]= {nc};
   ncRef.rebind(path, ChinaRef);
   java.lang.Object sync = new java.lang.Object();
   synchronized(sync){ sync.wait(); }
   } catch(Exception e) {
   System.out.println("ERROR: " + e);
   e.printStackTrace(System.out);
   }
   } // main()
  } // ChinaServer
  class ChinaServant extends _ChinaImplBase{
   public String MorningChina() { return "\n\n中國,早上好!\n\n; }
  }
  4編譯和運行應用程序
  (1)編譯應用程序
   編譯客戶程序:
   javac ChinaClient.java ChinaApp*.java
   編譯服務程序:
   javac ChinaServer.java ChinaApp*.java
  (2)運行應用系統
  啟動名字服務器:
   tnameserv -ORBInitialPort nameserverport
  其中,nameserverport 是ORB名字服務器的服務端口號,可以自選,如1234(在UNIX系統下,非root用戶只能使用大1024的服務端口號)。
  啟動服務程序:
   java ChinaServer -ORBInitialHost nameserverhost -ORBInitialPort nameserverport
  其中,nameserverhost是ORB名字服務器所在主機名。
  啟動客戶程序:
   java ChinaClient-ORBInitialHost nameserverhost -ORBInitialPort nameserverport
   客戶程序啟動,將會在屏幕上顯示:
   中國,早上好!
  從上例可以看出,與傳統的客戶/服務應用開發完全不同,使用CORBA,開發人員再不必關心客戶和服務之間的通信問題,也不必處理客戶和服務之間的協調問題,客戶系統和服務系統可以在不同的機器系統中運行,並且可以用不同的語言來實現(如本例中的服務端程序完全可以用C++來編寫),這些都由CORBA負責解決,對應用開發者來說都是透明的。
  通過上面這一簡單的面向對象的客戶/服務應用實例,我們可以將CORBA應用到更復雜、更大型的分布式系統中。
(http://www.fanqiang.com)
    進入【UNIX論壇

相關文章
 

★  樊強制作 歡迎分享  ★