上月我們探討了為何選擇 CORBA 與 Java 技術。本月將通過一個簡單可用的示例,帶領您探索 CORBA 技術的核心領域。我們的目標是構建一個分布式應用:客戶端駐留於一台計算機,向運行於另一台計算機的服務發出請求,無需關心硬件或作業系統細節,只需服務能響應請求即可。
CORBA 的所有結構始於接口。正如汽車的標準化介面(方向盤、油門、剎車)讓駕駛者無需適應即可上路,CORBA 通過接口定義語言 (IDL) 定義客戶端如何向服務發出請求,實現跨語言、跨平台的互操作。
module corbasem {
module gen {
module calcsimpl {
interface calculator {
long add(in long x, in long y);
};
};
};
};
package,編譯後生成對應子目錄interface,定義通訊契約而非實現intout (服務端→客戶端) 和 inout (雙向)明確參數方向讓 ORB (Object Request Broker) 能高效處理參數打包、解包與內存管理。

IDL 編譯器是實現 CORBA 2.3 規範中 IDL 到 Java 語言映射的程序,自動生成 Stub、Skeleton 及支援文件,處理網絡「管道」代碼,強制封裝規範,避免手工編寫的繁瑣與錯誤。
jidl --output-dir c:\_work\corbasem calculator.idl
生成六個核心文件:
| 文件 | 角色 | 說明 |
|---|---|---|
| calculator.java | 標記接口 | 擴展 IDLEntity,提供類型標記供其他接口方法聲明使用 |
| calculatorOperations.java | 操作接口 | 包含映射的操作簽名,標記接口擴展此接口 |
| calculatorHelper.java | 輔助類 | 含關鍵 narrow() 方法,將 org.omg.CORBA.Object 縮窄為具體類型引用 |
| calculatorHolder.java | 持有者類 | 用於通過引用傳遞參數,本示例暫不使用 |
| calculatorPOA.java | Skeleton 類 | 提供請求-響應管道核心,基於繼承實現 (預設) |
| _calculatorStub.java | Stub 類 | 客戶端調用代理,處理參數打包與網絡通訊 |

SimpleCalcServant extends calculatorPOA {
public int add(int x, int y) {
return x + y;
}
}
實現類擴展生成的 calculatorPOA,請求經 ORB → Skeleton → Servant 處理並響應。
Properties props = System.getProperties();
props.put("org.omg.CORBA.ORBClass", "com.ooc.CORBA.ORG");
props.put("org.omg.CORBA.ORBSingletonClass", "com.ooc.CORBA.ORBSingleton");
ORB orb = ORB.init(args, props);
指定 ORB 實現類 (此處為 Orbacus)。理想情況下應外部化配置,便於切換 ORB 供應商無需重編碼。
POA rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
POAManager manager = rootPOA.the_POAManager();
POA 取代了供應商各異的 BOA,提供標準化的對象生存環境管理。本例直接使用根 POA 簡化演示。
SimpleCalcServant calcSvt = new SimpleCalcServant();
calculator calc = calcSvt._this(orb); // 獲取 CORBA 對象引用
PrintWriter refstr = new PrintWriter(new FileWriter("calcref.ior"));
refstr.println(orb.object_to_string(calc)); // 寫入文件供客戶端獲取
refstr.close();
manager.activate(); // 激活 POA,開始排隊請求
System.out.println("SimpleCalcSvr is running!");
orb.run(); // 進入事件循環接收請求
客戶端與服務端結構鏡像:打包參數→發送請求→解包響應。關鍵差別在於如何定位服務對象。
Properties props = System.getProperties();
props.put("org.omg.CORBA.ORBClass", "com.ooc.CORBA.ORG");
props.put("org.omg.CORBA.ORBSingletonClass", "com.ooc.CORBA.ORBSingleton");
ORB orb = ORB.init(args, props);
必須使用支援 IIOP (Internet Inter-ORB Protocol) 的 ORB 才能跨供應商互操作。
BufferedReader in = new BufferedReader(new FileReader("calcref.ior"));
String ior = in.readLine();
in.close();
calculator calc = calculatorHelper.narrow(orb.string_to_object(ior));
System.out.println(calc.add(2, 3));
calculatorHelper.narrow() 將通用對象引用縮窄為計算器類型,隨後即可像本地對象一樣調用 add()。
客戶端完全隔離於服務端實現細節:不知硬體、OS、語言、線程模型、甚至物理位置。只知調用 calc.add() 會得到預期響應。這如同撥打電話——只在乎通話接通,不在乎光纖還是衛星傳輸。
下月我們將深入探討表象之下 IIOP 的神奇力量。