本節摘要:本節介紹一個corba服務的開發過程,包含服務端和客戶端,實現一個打印Hello World的功能。
preparation
1.開發背景介紹
最近項目中一直在做corba的這塊東西,項目中是在第三方的產品vbroker的產品上做的開發,再者我也主要是做客戶端的調用,服務端用的是C++來實現的,具體的發布和部署過程也不清楚。那我就”不爽啊”,為啥咱就不能寫一個corba服務,從定義idl文件到開發再到發布?說來咱就來,當然是從最簡單的來了,最開始學習java的時候,第一個程序是打印Hello World。OK,come on,咱就用corba寫一個服務,輸出Hello World然后打印出來瞧瞧。搜集了網上相關資料,並加以整理和理解,咱的第一個corba服務(采用corba靜態調用的方式)就問世了。
至於什么是corba,咱就不介紹了,網上一網一籮筐,corba太高深的咱也介紹不了,就不班門弄斧了。
2.IDL介紹
全稱:Interface Description Language
使用Java(TM)編寫的API提供基於標准的和CORBA的交互性和連接性。
用於描述接口,類似於PRC的.x文件。接口定義語言類似一個協議,來規定接入對象的行為。
用RPC / COM / CORBA技術來編寫分布式系統時都需要接口定義語言(IDL)。
特點:
1、IDL是一種規范語言。
2、IDL看上去很像C語言。
3、OMG IDL的目的是定義接口和精簡分布對象的過程。
4、IDL分離對象的接口與其實現。
5、IDL剝離了編程語言和硬件的依賴性。
6、使用IDL定義接口的客戶機程序員不知道接口背后的實現細節。
7、IDL提供一套通用的數據類型,並以這些數據類型來定義更為復雜的數據類型。
IDL的語法需要的話可以專門的去學習,這里不是我介紹的重點。
3.idlj命令介紹
idlj命令是把idl文件生成java代碼,此命令在JDK的安裝目錄的bin目錄下可以找到
idlj命令的使用語法如下:
idlj [選項] <idl文件>
其中,<idl 文件> 是包含 IDL 定義的文件的名稱,而[選項] 是以下所列選項的任一組合。這些選項是可選的,並且可以以任意順序顯示;<idl 文件> 是必須的並且必須顯示在最后。
選項:
當然,也有把idl文件生成C++代碼的,這里我就不關心了。
還有一些軟件公司提供的有實現這種轉換的產品,比如borland。
4.idlj生成的樁和骨架介紹
因為我要客戶端和服務端都自己來實現,所以我使用的idlj命令的選項為-fall
我使用的idl文件名稱為Hello.idl(后面會把詳細的idl文件內容列出來),那么我運行的命令為 idlj –fall Hello.idl
idl生成java文件的步驟:
1.打開cmd窗口
2.切換到JDK安裝目錄下的bin目錄
3.把Hello.idl文件拷貝到JDK的bin目錄下
4.運行idlj命令,由idl文件生成相應的java文件
運行完成,會在JDK的bin目錄下生成一個HelloApp文件夾,HelloApp文件夾包含以下6個java文件:
_HelloStub.java
Hello.java
HelloHelper.java
HelloHolder.java
HelloOperations
HelloPOA.java
5.orbd命令介紹
orbd是用來使客戶能夠透明地查找和調用持久對象在服務器上應用環境,各個參數如下:
sun關於orbd的介紹文檔地址如下:http://download.oracle.com/javase/1.4.2/docs/guide/idl/orbd.html
6.netstat命令介紹
netstat命令是在內核中訪問網絡及相關信息的程序,它能提供TCP連接,TCP和UDP監聽,進程內存管理的相關報告。
7.開發環境
system:win7 myeclipse:6.5 JDK:1.5 project:java project
8.項目結構
start
1.定義idl文件
文件名稱:HelloApp.idl
文件內容:
module HelloApp{
interface Hello{
string sayHello();
};
};
2.生成樁和骨架文件
根據前面介紹的步驟,生成java文件,把生成的HelloApp文件夾拷貝到工程的src目錄;
這里生成的文件就不貼出來了,后面會把整個工程上傳上去;
3.實現服務端
(1)實現sayHello方法
HelloImpl.java

1 package server; 2 3 import HelloApp.HelloPOA; 4 5 /** 6 * 7 *Module: HelloImpl.java 8 *Description: 服務端實現sayHello()方法 9 *Company: 10 *Version: 1.0.0 11 *Author: pantp 12 *Date: Jul 8, 2012 13 */ 14 public class HelloImpl extends HelloPOA { 15 16 public String sayHello() { 17 return "\nHello World\n"; 18 } 19 20 }
(2)開發啟動ORB以及等待遠程客戶機調用的代碼
HelloServer.java

1 package server; 2 3 import org.omg.CORBA.ORB; 4 import org.omg.PortableServer.POA; 5 import org.omg.PortableServer.POAHelper; 6 import HelloApp.Hello; 7 import HelloApp.HelloHelper; 8 import org.omg.CosNaming.NamingContextExt; 9 import org.omg.CosNaming.NamingContextExtHelper; 10 import org.omg.CosNaming.NameComponent; 11 12 /** 13 * 14 *Module: HelloServer.java 15 *Description: 啟動服務端的服務 16 *Company: 17 *Version: 1.0.0 18 *Author: pantp 19 *Date: Jul 8, 2012 20 */ 21 public class HelloServer { 22 23 //啟動ORB以及等待遠程客戶機的調用的代碼 24 public static void main(String args[]) throws Exception { 25 // -ORBInitialPort 1050 26 args = new String[2]; 27 args[0] = "-ORBInitialPort"; 28 args[1] = "1050";//端口 29 30 // 創建一個ORB實例 31 ORB orb = ORB.init(args, null); 32 System.out.println("server--->11111"); 33 34 // 得到一個RootPOA的引用,並激活POAManager 35 org.omg.CORBA.Object obj=orb.resolve_initial_references("RootPOA"); 36 POA rootpoa = POAHelper.narrow(obj); 37 rootpoa.the_POAManager().activate(); 38 39 System.out.println("server--->22222"); 40 41 // 創建一個HelloImpl實例 42 HelloImpl helloImpl = new HelloImpl(); 43 44 System.out.println("server--->33333"); 45 46 // 從服務中得到對象的引用 47 org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl); 48 Hello href = HelloHelper.narrow(ref); 49 50 System.out.println("server--->44444"); 51 52 // 得到一個根名稱的上下文 53 org.omg.CORBA.Object objRef = orb 54 .resolve_initial_references("NameService"); 55 NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); 56 57 System.out.println("server--->55555"); 58 59 // 在命名上下文中綁定這個對象 60 String name = "Hello"; 61 NameComponent path[] = ncRef.to_name(name); 62 ncRef.rebind(path, href); 63 64 System.out.println("server--->66666"); 65 66 // 啟動線程服務,等待客戶端調用 67 orb.run(); 68 } 69 }
4.實現客戶端
以樁作為客戶端應用程序的基礎,客戶機建立在樁之上,通過Java IDL提供的名字服務查詢服務器,獲得遠程對象的引用,然后調用遠程對象中的方法;
HelloClient.java

1 package client; 2 3 import HelloApp.Hello; 4 import HelloApp.HelloHelper; 5 import org.omg.CORBA.ORB; 6 import org.omg.CORBA.ORBPackage.InvalidName; 7 import org.omg.CosNaming.NamingContextExt; 8 import org.omg.CosNaming.NamingContextExtHelper; 9 import org.omg.CosNaming.NamingContextPackage.CannotProceed; 10 import org.omg.CosNaming.NamingContextPackage.NotFound; 11 12 /** 13 * 14 *Module: HelloClient.java 15 *Description: 客戶端的初始化以及調用的代碼 16 *Company: 17 *Version: 1.0.0 18 *Author: pantp 19 *Date: Jul 8, 2012 20 */ 21 public class HelloClient { 22 23 static Hello helloImpl; 24 25 static { 26 System.out.println("客戶端的初始化配置開始......." + System.currentTimeMillis()); 27 28 // -ORBInitialHost 127.0.0.1 -ORBInitialPort 1050 29 String args[] = new String[4]; 30 args[0] = "-ORBInitialHost"; 31 args[1] = "127.0.0.1";// 服務端的IP地址 32 args[2] = "-ORBInitialPort"; 33 args[3] = "1050";// 服務端的端口 34 35 // 創建一個ORB實例 36 ORB orb = ORB.init(args, null); 37 38 // 獲取根名稱上下文 39 org.omg.CORBA.Object objRef = null; 40 try { 41 objRef = orb.resolve_initial_references("NameService"); 42 } catch (InvalidName e) { 43 e.printStackTrace(); 44 } 45 NamingContextExt neRef = NamingContextExtHelper.narrow(objRef); 46 47 String name = "Hello"; 48 try { 49 helloImpl = HelloHelper.narrow(neRef.resolve_str(name)); 50 } catch (NotFound e) { 51 e.printStackTrace(); 52 } catch (CannotProceed e) { 53 e.printStackTrace(); 54 } catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) { 55 e.printStackTrace(); 56 } 57 58 System.out.println("客戶端的初始化配置結束......." + System.currentTimeMillis()); 59 } 60 61 public static void main(String args[]) throws Exception { 62 // init(); 63 sayHello(); 64 } 65 66 // 客戶端的初始化配置 67 /* public static void init() throws Exception { 68 System.out.println("客戶端的初始化配置開始......." + System.currentTimeMillis()); 69 70 // -ORBInitialHost 127.0.0.1 -ORBInitialPort 1050 71 String args[] = new String[4]; 72 args[0] = "-ORBInitialHost"; 73 args[1] = "127.0.0.1";//服務端的IP地址 74 args[2] = "-ORBInitialPort"; 75 args[3] = "1050";//服務端的端口 76 77 // 創建一個ORB實例 78 ORB orb = ORB.init(args, null); 79 80 // 獲取根名稱上下文 81 org.omg.CORBA.Object objRef = orb 82 .resolve_initial_references("NameService"); 83 NamingContextExt neRef = NamingContextExtHelper.narrow(objRef); 84 85 String name = "Hello"; 86 helloImpl = HelloHelper.narrow(neRef.resolve_str(name)); 87 88 System.out.println("客戶端的初始化配置結束......." + System.currentTimeMillis()); 89 }*/ 90 91 // 調用corba服務的方法 92 public static void sayHello() { 93 String str = helloImpl.sayHello(); 94 System.out.println(str); 95 } 96 }
5.啟動應用程序
1.運行startorbd.bat文件,啟動orbd服務
startorbd.bat文件內容如下:
@rem 切換到JDK安裝路徑下的bin目錄 根據本機的環境做相應的更改
cd/d "D:\Program Files\Java\jdk1.5.0_06\bin"
@rem 只有端口和IP是可以變化的,這里的端口和IP是根據HelloServer中的設置來定義的
@rem 1050為命名服務器監聽的端口,對應HelloServer中的端口;
@rem 127.0.0.1為服務啟動的IP地址,對應HelloServer中的IP地址
orbd -ORBInitialPort 1050 -ORBInitialHost 127.0.0.1
運行批處理文件的截圖如下:
2.運行服務端程序
運行HelloServer.java的main方法,console窗口打印的信息如下:
說明:運行本來是沒有日志的,是我人為的在代碼中加入了一些打印語句
3.運行客戶端程序
運行HelloClient.java的main方法,console窗口打印的信息如下
以上完成了corba靜態調用的整個過程;
再把 說明.txt 貼出來吧: