Geronimo CORBA

Apache Geronimo 服務器的最新版本 M5(即 Milestone 5,參見 參考資料 中的鏈接),使用 CORBA 對與外部系統的互操作性進行了改進。如果您曾經接觸過 CORBA,就會明白這種能力的重要意義,以及在特定項目中對 J2EE 服務器生存能力的影響。

CORBA 不但是很多遺留計算系統 —— 從大型機到超級計算機 —— 選擇的外部接口機制,還作爲一種分佈式對象機制被大型的實時控制至關重要的電信業、銀行業和國防系統廣泛採用。這些系統中,很多時候需要訪問 J2EE 服務器域中管理的信息和業務邏輯(或者相反)。要平穩地實現這種訪問,而且不需要複雜的自定義編碼,CORBA 和 J2EE 組件之間的互操作性是最基本的要求。

Geronimo 的 CORBA 互操作實現允許 CORBA 客戶機應用程序訪問 Enterprise JavaBeans™ (EJB) 中包含的業務邏輯和 J2EE 業務層管理的數據。

本文示範瞭如何利用 Geronimo M5 的 CORBA 互操作能力。提供了一個完整的 CORBA 客戶機訪問 Geronimo 服務器管理的業務層 EJB 的例子。客戶機利用了 Geronimo 客戶機應用程序容器提供的支持。

CORBA 概述

CORBA 爲分佈式對象間的交互提供了基於標準的基礎設施。它允許運行在不同硬件、不同操作系統上用不同編程語言編寫的軟件組件通過網絡進行通信、協作和執行生產性任務。

CORBA 系統通過將對象之間的交互定義爲明確的接口完成了這一不可思議的任務。要使用分佈式對象的服務,必須通過接口與之交互。客戶機不知道,也不需要知道接口是如何實現的,甚至是在何處實現的。圖 1 說明了典型的 CORBA 系統的工作方式。


圖 1. CORBA 中的對象交互
CORBA 中的對象交互

實現位置透明性

圖 1 中,客戶機代碼通過接口使用服務器對象。事實上,接口是通過客戶機本地的存根對象實現的。對客戶機來說,它僅僅與本地的存根對象交互。在幕後,存根對象實現了和遠程服務器對象同樣的接口。客戶機調用接口方法時,存根對象將調用轉發給稱爲 Object Request Broker (ORB) 的 CORBA 組件。客戶機的調用代碼不需要知道調用實際上是通過存根進行的。

委派給 ORB

ORB 是 CORBA 基礎設施的關鍵一環。它負責本地化服務器對象(無論是否通過網絡)然後把存根的調用發送到服務器。調用完成後,返回值通過網絡返給 ORB,ORB 再交給存根。然後存根返回給客戶機調用。對於客戶機而言,存根對象就是接口的實現者。

在服務器端,ORB 也有重要的作用。它必須接收來自客戶機 ORB 的方法調用,並轉發給基幹(skeleton)對象,後者和客戶端的存根直接對應。從服務器邏輯的角度來看它隱藏了網絡調用,即實現了接口。基幹對象對服務器機器上實現接口的對象進行服務器端本地調用。

不同 ORB 實現進行通信的需要

ORB 的具體實現細節因廠商而異。對於一家廠商來說,ORB 實現可能作爲鏈接到客戶機/服務器可執行文件的庫實現。另一家則可能是庫代碼層和運行在同一機器上的守護進程之間的協作。無論如何,不同廠商的 CORBA ORB 都能夠互相對話,這要感謝 CORBA Internet 通信協議 Internet InterORB Protocol (IIOP) 的標準化。圖 1 說明了 ORB 通過 IIOP 通信的情況。





回頁首


ORB 之間通過 IIOP 的互操作性

IIOP 是 General Inter-ORB Protocol (GIOP) 在 Internet TCP/IP 網絡上的規範。從 CORBA 2.0 開始,該規範就要求不同廠商的 ORB 必須能夠一起工作。目前,IIOP 廣泛用於實現不同 ORB 實現之間、Java Remote Method Invocation (RMI) 和 CORBA 系統之間的互操作。

RMI-IIOP:支持 Java 到 CORBA 互操作

在 Java Development Kit (JDK) 1.4 及以後的版本中,可以選擇使用 IIOP 協議在 Java RMI 對象之間通信。過去,只有私有的 Java Remote Messaging Protocol (JRMP) 用於 RMI。JRMP 和 IIOP 都用於通過網絡發送消息調用信息或者返回數據。RMI 對象能夠使用 IIOP 意味着基於 Java 的 RMI 客戶機可以訪問 CORBA 遠程對象,CORBA 客戶機也可以訪問 RMI 實現的對象。對於讓 Java 對象能夠訪問遺留的基於 CORBA 的資源,以及讓其他 CORBA 客戶機訪問開放的 Java 服務器資源(如 EJB),這種互操作非常重要。





回頁首


CORBA IDL —— 基於接口的遠程對象訪問

CORBA 系統中的對象完全通過接口來訪問。在 CORBA 中,接口用一種標準格式 Interface Definition Language(接口定義語言,IDL)來定義,IDL 獨立於具體的編程語言。圖 2 說明了 IDL 如何將服務器對象和客戶機結合在一起。


圖 2. 從 IDL 生成存根和基幹
從 IDL 生成存根和基幹

對於支持的每種編程語言,都提供了生成原生語言綁定的工具。綁定 通常是用支持的編程語言生成的源代碼(如 Java 綁定是 Java 代碼,C++ 綁定是 C++ 源代碼)。生成的代碼然後被編譯,並與客戶機和源代碼鏈接在一起。雖然綁定是文本源代碼文件,與大多數生成的代碼一樣很容易修改,但是千萬不要這麼做,因 爲重新生成後會清除掉所有的修改。生成的代碼包括客戶端的存根(實現必要的接口)和服務器端的基幹。還包括一些必要的 helper 方法,用於實現相應編程語言數據類型間的轉換。





回頁首


公共 CORBA 服務

CORBA 體系結構提出了對象總線(object bus)的概念。通過 ORB 連接到該總線的任何客戶機或服務器實現都可以交互和使用一組明確定義的、標準化的 CORBA 服務。圖 3 解釋了 CORBA 總線。


圖 3. CORBA 對象總線
CORBA 對象總線

圖 3 中,服務包括命名服務器、接口存儲庫(用於存儲和檢索接口及類型描述)和時間服務。

命名服務

CORBA 中經常使用命名服務。對象管理組(即 OMG,請參閱 參考資料 中的 OMG 鏈接)規定了一種 Interoperable Naming Service (INS)。這種思想非常簡單,與 RMI 類似。簡而言之,服務器創建遠程可訪問對象的實例,使用 ORB 綁定它來接收發來的請求,然後使用衆所周知的或者廣爲宣傳的文本名將該實例的可用性註冊到命名服務器。需要使用服務器上的服務的任何客戶機都能夠與命名服 務聯繫,使用文本名稱查找服務器來獲得遠程對象引用。

使用 JNDI 統一對象引用查找

用 Java 編程語言編寫代碼時,J2EE 和 Java Naming and Directory Interface (JNDI) 的集成允許開發人員編寫可處理不同目錄和命名服務的對象查找代碼。客戶機代碼調用 JNDI,JNDI 在底層通過提供程序實現轉發到可用的服務。JDK 中提供了 CosNaming 提供程序,允許 JNDI 代碼使用 CORBA 命名服務查找對象。圖 4 說明了使用 JNDI 查找遠程 CORBA 對象。


圖 4. 基於 JNDI 的 CORBA 查找
基於 JNDI 的 CORBA 查找

圖 4 還表明,與基於 JNDI 的 CORBA 查找一起使用時,RMI-IIOP 很容易讓開發人員編制一個能同時用於 RMI 和 CORBA 服務器的代碼庫。





回頁首


Geronimo 的 CORBA 互操作實現

Geronimo 的 ORB 選擇

Geronimo M5 依賴於 Sun ORB,這一點限制了 Geronimo 的互操作特性只能用於 Sun Java Virtual Machines (JVM)。目前,Apache Software Foundation 正在評估第三方公司貢獻的 ORB,可能包含到將來的 Geronimo 版本中。如果該捐獻被接受,就可以徹底擺脫對 Sun ORB 的依賴,從而使 Geronimo 的互操作特性可在任何 JVM 上工作。

有了這些基本的瞭解後,現在可以看看如何實現 Geronimo 與外部 CORBA 客戶機和組件的互操作了。圖 5 顯示了常見的幾種互操作。其中包括:

  • Web 層或 EJB 層 Java 客戶機調用外部 CORBA 組件的方法。
  • 通過 IIOP 公開的在 Geronimo 服務器中運行的 EJB 組件供基於 CORBA 的客戶機遠程訪問。
  • 應用程序客戶機使用 Geronimo 客戶機應用程序容器訪問遠程 CORBA 組件。

上述情況下,Geronimo 中的客戶機或服務器代碼都必須通過 IIOP 和 ORB 與外部 CORBA 組件通信。JDK 標準發行版帶有 Sun Microsystems 的 ORB 實現,常常被稱作 Sun ORB。Geronimo M5 利用這種 ORB 進行互操作。


圖 5. Geronimo CORBA 互操作場景
Geronimo CORBA 互操作場景




回頁首


啓用 CORBA 互操作 —— 只需要配置

使用 Geronimo,在部署的時候通過配置可以將 EJB 公開爲 CORBA 服務器。這就是說 EJB 中不需要任何特殊的代碼。事實上,任何已有的 EJB 都能公開爲 CORBA 服務器對象。

我們的例子中,一個簡單的無狀態會話 bean 公開了一個方法來讀取服務器端的時間戳。EJB 接口的代碼如 清單 1 所示。


清單 1. 服務器時間戳無狀態會話 EJB 的 EJB 接口
package com.ibm.dw.geronimo.corba;
public interface ServerTimestamp extends javax.ejb.EJBObject {
public String getTimestamp() throws java.rmi.RemoteException;
}

該 EJB 接口的具體實現在 com.ibm.dw.geronimo.corba.ServerTimestampImpl 類中,如 清單 2 所示。


清單 2. 服務器時間戳 EJB 的實現
package com.ibm.dw.geronimo.corba;
import java.util.Date;
public class ServerTimestampImpl implements javax.ejb.SessionBean {
public String getTimestamp(){
return "This is the current server time " + new Date();
}
private javax.ejb.SessionContext mySessionCtx;
public javax.ejb.SessionContext getSessionContext() {
return mySessionCtx;
}
public void setSessionContext(javax.ejb.SessionContext ctx) {
mySessionCtx = ctx;
}
public void ejbCreate() throws javax.ejb.CreateException {
}
public void ejbActivate() {
}
public void ejbPassivate() {
}
public void ejbRemove() {
}
}

注意,清單 1清單 2 中都沒有特殊的 CORBA 代碼。事實上,即便 EJB 的部署描述符也非常普通。清單 3 顯示了時間戳 EJB 的部署描述符 ejb-jar.xml。


清單 3. 服務器時間戳 EJB 的部署描述符 ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN'
'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
<enterprise-beans>
<session>
<display-name>Server timestamp Stateless Session Bean</display-name>
<ejb-name>ServerTimestampEJB</ejb-name>
<home>com.ibm.dw.geronimo.corba.ServerTimestampHome</home>
<remote>com.ibm.dw.geronimo.corba.ServerTimestamp</remote>
<ejb-class>com.ibm.dw.geronimo.corba.ServerTimestampImpl</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>

清單 3 中普普通通的 ejb-jar.xml 可以讓 EJB JAR 不需要修改就能部署在 Geronimo 或其他 J2EE 1.4 服務器上。

在定製的部署計劃中公開 EJB 以供 CORBA 訪問

爲了配置 EJB 讓 CORBA 訪問,需要爲其創建一個專門的 Geronimo 部署計劃。部署計劃包含在 dp.xml 文件中。清單 4 顯示了該計劃文件的一部分,設置 EJB 以供 CORBA 客戶機訪問。


清單 4. 配置服務器時間戳 EJB 供 CORBA 訪問
<?xml version="1.0" encoding="UTF-8"?>
<application
xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.0"
configId="com/ibm/dw/geronimo/corba/ServerTimestamp"
parentId="org/apache/geronimo/ServerCORBA">
<import>
<uri>org/apache/geronimo/Security</uri>
</import>
<module>
<ejb>dwcorba1-ejbs.jar</ejb>
<openejb-jar
xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.0"
configId="ServerTimestampEJB"
parentId="org/apache/geronimo/ServerCORBA">
<enterprise-beans>
<session>
<ejb-name>ServerTimestampEJB</ejb-name>
<jndi-name>ServerTimestampEJB</jndi-name>
<tss-link>IdentityTokenNoSecurity</tss-link>
</session>
</enterprise-beans>
</openejb-jar>
</module>
...

清單 4 中可以看到,我們把部署的 .ear 文件的父配置設爲 org/apache/geronimo/ServerCORBA 配置。該配置文件包括標準 org/apache/geronimo/Server 配置的全部內容,還有一些 CORBA 專用服務器端 GBeans 的定義。<tss-link> 元素用屬性值 IdentityTokenNoSecurity 指定了安全處理 GBeans 中的一個。下一節介紹該 GBean 的操作。

CORBA 2.3 CSIv2 安全需求的 GBean 實現

Geronimo 的 CORBA 實現和完全遵循 CORBA 2.3。CORBA 2.3 要求實現一個安全層,稱爲 Common Security Interoperability, Version 2 (CSIv2)。在通信之前,該層在 CORBA 客戶機和服務器之間協商需要的安全級別。(在以後的文章中再詳細討論 CSIv2 的細節。)

Geronimo M5 中,CSIv2 特性是作爲一組 GBean 實現的,可以在將 EJB 公開爲 CORBA 訪問時配置。

清單 4 中,<tss-link> 選擇了一種 Target Security Service (TSS) 實現 GBean。它選擇的是 IdentityTokenNoSecurity,這部署在 org/apache/geronimo/ServerCORBA 部署計劃中,以允許不通過身份驗證或加密來進行訪問。

公開 EJB 供 CORBA 訪問需要做的配置就這麼簡單。父配置 org/apache/geronimo/ServerCORBA 在模塊啓動時啓動 CORBA 命名服務並將該 EJB 註冊爲可用的 CORBA 服務器對象。

創建基於 Swing 的 CORBA 客戶機應用程序

要作爲 CORBA 對象訪問 EJB,需要創建一個簡單的 GUI 客戶機應用程序,運行在 Geronimo 應用程序客戶機容器中。該客戶機的源代碼組件如表 2 所示。可以根據代碼發行版交叉參考該表。

表 2. CORBA 客戶機應用程序的組件
代碼組件 說明
TimestampDisplayClient.java 客戶機應用程序的主類,非常簡單,構造 TimestampFrame 的實例並顯示它。
TimestampFrame.java JFrame 子類,使用 JDK 內置的 RMI-IIOP 訪問遠程 CORBA 服務器時間戳對象。它從遠程 CORBA 服務器獲得時間戳然後顯示在自己的 Swing GUI 中。
SecurityCallbackHandler.java Client Security Service (CSS) 處理 GBean 調用該處理程序。當服務器需要用戶名和口令進行身份驗證時,該處理程序通常顯示一個用戶界面來收集這些信息。這裏的例子沒有使用這個處理程序。
com.ibm.dw.geronimo.corba.ServerTimestamp.class
com.ibm.dw.geronimo.corba.ServerTimestampHome.class
正確地編譯 TimestampFrame.java 需要這些 EJB Java 類文件。

TimestampFrame.java 的源代碼如 清單 5 所示。這是調用遠程 EJB/CORBA 對象方法的具體類。


清單 5. TimestampFrame.java 中的 RMI-IIOP 調用
package com.ibm.dw.geronimo.corba.client;
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import com.ibm.dw.geronimo.corba.ServerTimestampHome;
import com.ibm.dw.geronimo.corba.ServerTimestamp;
public class TimestampFrame extends JFrame{
public TimestampFrame(String title) {
super(title);
}
public void init() {
JLabel timeStamp = new JLabel(getTime());
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());
pane.add(timeStamp, BorderLayout.CENTER);
this.getContentPane().add(pane);
}
private String getTime() {
String retval = "";
ServerTimestamp ts = null;
try {
Context ic = new InitialContext();
Object o =
ic.lookup("java:comp/env/ServerTimestampEJB");
ServerTimestampHome home = (ServerTimestampHome)
PortableRemoteObject.narrow(o,
ServerTimestampHome.class);
ts = home.create();
retval = ts.getTimestamp();

} catch (Exception ex) {
ex.printStackTrace();
}
return retval;
}

}

清單 5 中,使用 InitialContext 通過 JNDI 查找來獲得對象引用。得到的對象引用使用 PortableRemoteObject.narrow() 縮小轉換爲 EJB Home 接口。該代碼可以通過 IIOP 訪問遠程 CORBA 對象和遠程 RMI 對象。

動態運行時存根生成

與使用 IDL 生成的常規 Java 綁定(源代碼)不同,Geronimo 可以動態生成二進制形式的 CORBA 存根。客戶機應用程序會利用這種動態存根生成能力;存根是在請求 ORB 時生成的。

圖 6 顯示了對應用程序客戶機和服務器端 EJB 可用的 Geronimo CORBA 支持。


圖 6. Geronimo 的 CORBA 支持
Geronimo 的 CORBA 支持

設置 CORBA 客戶機支持

應用程序客戶機的部署計劃中,配置了一個處理 CSIv2 客戶端的 GBean,稱爲 CSS。deploy.xml 文件指定了和 NosSecurity 名關聯的 CSS 實例。清單 6 說明了應用程序客戶機需要的配置。


清單 6. 配置客戶機應用程序進行 CORBA 訪問
<module>
<java>dwcorba1-clientapp.jar</java>
<application-client xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-client"
configId="client"
clientConfigId="com/ibm/dw/geronimo/corba/ServerTimestampClient"
clientParentId="org/apache/geronimo/ClientCORBA">
<import>
<uri>org/apache/geronimo/ClientSecurity</uri>
</import>
<ejb-ref>
<ref-name>ServerTimestampEJB</ref-name>
<ns-corbaloc>corbaloc::localhost:1050/NameService</ns-corbaloc>
<name>ServerTimestampEJB</name>
<css-link>NoSecurity</css-link>
</ejb-ref>
<realm-name>client-properties-realm</realm-name>
<callback-handler>
com.ibm.dw.geronimo.corba.client.SecurityCallbackHandler
</callback-handler>

</application-client>
</module>

清單 6 中,客戶機應用程序的父配置被設置爲 org/geronimo/corba/ClientCORBA,該文件中配置了安全 GBean 實例。<ns-corbaloc> 元素告訴 Geronimo 客戶機應用程序容器到何處尋找 CORBA 命名服務。<css-link> 標記指定了要使用的安全處理 GBean。<callback-handler> 標記指定了請求身份驗證信息時 CSS GBean 使用的回調方法。

對 EJB 運行 CORBA 客戶機

在 Geronimo 安裝的 bin 目錄中找到 startup.bat 文件。需要做一些修改,如 清單 7 中突出顯示的代碼。其中增加了一個必需的屬性來指定 Geronimo ORB 支持類。(未來的 Geronimo 版本可能會簡化該過程。)


清單 7. startup.bat 文件的修改
for %%z in (%CUR_DIR%) do set CUR_DIR=%%~sz

set CORBA_OPTS=-Dorg.openejb.corba.UtilDelegateClass=
com.sun.corba.se.internal.POA.ShutdownUtilDelegate
-Dorg.omg.CORBA.ORBSingletonClass=com.sun.corba.se.internal.corba.ORBSingleton
-Dorg.omg.CORBA.ORBClass=org.openejb.corba.sunorb.OpenEJBORB
-Djavax.rmi.CORBA.PortableRemoteObjectClass=
com.sun.corba.se.internal.javax.rmi.PortableRemoteObject
-Djavax.rmi.CORBA.UtilClass=org.openejb.corba.util.UtilDelegateImpl

@rem Set the path to the server.jar
set SERVER_JAR="%~dp0server.jar"
for %%z in (%SERVER_JAR%) do set SERVER_JAR=%%~sz
:CheckServerJar
......
:StartServer
echo on

%JAVA% %CORBA_OPTS% -jar %SERVER_JAR% %ARGS%

清單 7 中的選項必須作爲連續的一行輸入。將提供的 startup.bat 文件粘貼到 M5 bin 目錄中可能更簡單。使用這個修改後的 startup.bat 啓動服務器。

本文還提供了構建該例子的 Ant 構建文件。需要根據 Geronimo 安裝目錄對 build.xml 作相應的修改。構建該項目使用下列命令:

ant ear

然後可以在 dist 子目錄中找到 dwcorba1.ear。要將包含 EJB 和客戶機應用程序的 EAR 部署到 Geronimo 中,請在 Geronimo 安裝目錄中運行下列命令:

java -jar bin/deployer.jar --user=system --password=manager deploy dwcorba1.ear deploy.xml

一定要將 dwcorba1.ear 和 deploy.xml 文件移動到同一目錄中。

要運行客戶機應用程序,請在源代碼發行版中運行 runclient.bat 文件。該批處理文件按照和 startup.bat 相同的方式設置 ORB 支持屬性,不過這一次是對客戶機的 Java 虛擬機。runclient.bat 文件包含以下內容:


清單 8. Runclient.bat 文件代碼
java -Djavax.rmi.CORBA.UtilClass=org.openejb.corba.util.UtilDelegateImpl
-Dorg.openejb.corba.UtilDelegateClass=com.sun.corba.se.internal.POA.ShutdownUtilDelegate
-Dorg.omg.CORBA.ORBSingletonClass=com.sun.corba.se.internal.corba.ORBSingleton
-Dorg.omg.CORBA.ORBClass=org.openejb.corba.sunorb.OpenEJBORB
-Djavax.rmi.CORBA.PortableRemoteObjectClass=
com.sun.corba.se.internal.javax.rmi.PortableRemoteObject
-jar bin/client.jar com/ibm/dw/geronimo/corba/ServerTimestampClient

運行該客戶機時,將在 GUI 中顯示服務器的時間戳。該時間戳是從 CORBA 遠程對象獲得的,該對象實際上由遠程 Geronimo EJB 處理。圖 7 顯示了客戶機成功運行後的結果。


圖 7. 顯示服務器時間戳的應用程序客戶機
顯示服務器時間戳的應用程序客戶機

結束語

本文介紹瞭如何集成異構的解決方案和利用已有的遺留系統投資,這是現代企業中經常面臨的一項任務。CORBA 已經證明是一種有效的解決方案,已經部署在很多企業中。Apache Geronimo 組件與 CORBA 組件自由交互的能力,使得我們可以用最新的工具和編程方法論在現代 J2EE 平臺上構建新的應用程序。






回頁首


下載

描述 名字 大小 下載方法
Source code Geronimo CORBA example code.zip 300KB HTTP
關於下載方法的信息


參考資料

學習

獲得產品和技術
  • 使用 IBM 試用軟件 革新您的下一個開放源碼開發項目,可以通過下載或從 DVD 中獲得這些軟件。


討論
 
發佈了29 篇原創文章 · 獲贊 4 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章