本文討論如何讓用 CORBA 支持的任何語言編寫的客戶端能夠訪問 Enterprise JavaBeansTM 組件 (“EJBTM 組件”)。本文針對深入了解 JavaTM 2 Platform, Enterprise Edition ("J2EETM") 和公共對象請求代理結構(Common Object Request Broker Architecture,CORBA)的程序員。
J2EE 技術簡化了企業應用程序,因為它將它們建立在標準、模塊化和可重用組件的基礎上,而該組件又基于 Enterprise JavaBeansTM (EJBTM) 體系結構,它也提供了完整的一組針對于那些組件的服務,并自動處理應用程序行為的許多細節。通過自動化應用程序開發的許多耗時且困難的任務,J2EE 技術使企業開發人員能夠將重點放在增值上,也就是增強業務邏輯,而不是放在構建基礎結構上。
EJBTM 服務器端組件模型簡化了事務型、可伸縮和可移植的中間件組件的開發。Enterprise JavaBeans 服務器減少了中間件開發的復雜程度,因為它為諸如事務、安全、數據庫連接等中間件服務提供了支持。
CORBA 是一個對象管理組織(Object Management Group,OMG)標準,它是一個開放的、供應商無關的體系結構和基礎結構,計算機應用程序可以使用它來通過網絡一起工作。由于使用了標準的 Internet Inter-ORB Protocol,(IIOP),因些來自任何供應商的基于 CORBA 的程序可以與來自相同或其他供應商的基于 CORBA 程序進行互操作,前一程序可以在幾乎所有的計算機、操作系統、編程語言和網絡上,后一程序可以在幾乎所有的其他計算機、操作系統、編程語言和網絡上。 要進一步學習 CORBA,請訪問 http://www.omg.org/gettingstarted/gettingstartedindex.htm。
CORBA 技術補充了 Java 平臺,因為它提供了分布式對象框架、支持此框架的服務以及與其他語言的互操作性。CORBA 技術是 Java 2 平臺的主要部分,它正用于 Enterprise JavaBeans 組件、 運行在 Internet Inter-ORB 協議上的Java 遠程方法調用 API ("Java RMI-IIOP"),以及 Java IDL API ("Java IDL")。
OMG 接口定義語言(Interface Definition Language,IDL)可用于描述一些接口,該接口由遠程對象實現。IDL 可用于定義接口的名稱,以及定義每個屬性和方法的名稱。一旦創建 IDL 文件,就可以在任何語言中,使用 IDL 編譯器來生成客戶端存根模塊 (stub) 和服務器骨架語句 (server skeleton),OMG已經為此定義了這種語言映射的規范。要進一步了解 OMG IDL,請訪問 http://www.omg.org/gettingstarted/omg_idl.htm。
Java IDL 使得分布式 Java 應用程序能夠透明地調用遠程網絡服務上的操作,而該服務使用對象管理組織 (http://www.omg.org/) 定義的行業標準 OMG IDL 和 IIOP。運行在 IIOP API 上的 Java RMI 使得可以通過 javax.rmi
API 來對 CORBA 服務器和應用程序進行編程。
編寫 EJB 組件的開發人員可以遵循 Java RMI 編程模型,并將它用于他們的分布式對象模型,在該模型中,跨越所有應用程序服務器常見的所需傳輸是 Java RMI-IIOP。在異構服務器環境中,到 CORBA 的 EJB 體系結構的標準映射使得能夠進行下述的互操作:
- 使用來自某一供應商 ORB 的客戶端可以訪問駐留在服務器上的企業 bean,而該服務器支持由另一供應商提供的 Enterprise JavaBeans 技術(“EJB 服務器”)。
- 一臺 EJB 服務器上的企業 bean 可以訪問另一臺 EJB 服務器上的企業 bean。
- 除了Java 編程語言之外,用某一語言編寫的 CORBA 客戶端可以訪問任何 EJB 組件,前提是要有一個從 OMG IDL 到那種編程語言的映射。
本文檔的其余部分提供了 CORBA 客戶端應用程序的例子,該應用程序訪問了企業 bean 對象。在本文檔中,CORBA 客戶端就是使用 CORBA 支持的任何語言編寫的客戶端應用程序,這些編程語言包括 Java 編程語言、C++、C、Smalltalk、COBOL、Ada、Lisp 或 Python。雖然本例中的 Java 代碼特定于企業 bean,但開發 CORBA 的客戶端的過程是相同的,并且開發的 CORBA 客戶端可以訪問使用 Java RMI-IIOP API 創建的服務器。
可以在 鏈接到類似例子 中找到一些鏈接,它們指向其他實現了 J2EE 技術的供應商提供的類似應用程序。
開發訪問 Enterprise JavaBean 組件的 CORBA 客戶端
這是一個關于如何開發 CORBA 客戶端應用程序以便訪問 EJB 組件的例子。在本例中,客戶端是用 C++ 編程語言編寫的,但客戶端可以是由 CORBA 支持的任何語言編寫的。
下面的幾節展示了 CORBA 客戶端的一般開發過程,開發完的 CORBA 客戶端可以訪問企業 bean:
- 編寫 Enterprise JavaBean 組件
- 生成 CORBA IDL
- 創建 CORBA 客戶端
- 部署 Enterprise JavaBean 組件
- 運行客戶端可執行文件
本文檔也包括:
為了使例子變得簡單,我們采取了一些捷徑。有關構建更加高級的解決方案的信息,請參閱 針對復雜接口的技巧。
第 1 部分:編寫 Enterprise JavaBean 組件
下面的一些例子展示了企業 bean 的代碼,它將從 Java RMI-IIOP 和 CORBA 客戶端接收發送給應用程序服務器的字符串日志消息。企業 bean 將在服務器上把它們與當前服務器時間一起打印出來。
- 在
/Java/src/ejbinterop
目錄中創建如下文件:Logger.java
、LoggerHome.java
、LoggerEJB.java
和 LogMessage.java。
Logger.java
Logger.java
文件是企業 bean 的遠程接口,因此,它擴展了 EJBObject
。遠程接口提供了 EJB 對象的遠程客戶端視圖,并定義了可由遠程客戶端調用的 business 方法。
//Code Example 1: Logger.java
package ejbinterop;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
/**
* Accepts simple String log messages and prints
* them on the server.
*/
public interface Logger extends EJBObject
{
/**
* Logs the given message on the server with
* the current server time.
*/
void logString(String message) throws RemoteException;
}
LoggerHome.java
LoggerHome.java
文件擴展了 EJBHome
。EJBHome
接口必須由所有 EJB 組件的遠程 home 接口來擴展。home 接口定義了一些方法,使得遠程客戶端可以創建、查找和刪除 EJB 對象,以及創建、查找和刪除不針對 EJB 實例的 home business 方法。
//Code Example 2: LoggerHome.java
package ejbinterop;
import java.rmi.RemoteException;
import javax.ejb.EJBHome;
import javax.ejb.CreateException;
public interface LoggerHome extends EJBHome
{
Logger create() throws RemoteException, CreateException;
}
LoggerEJB.java
LoggerEJB.java
文件包含了會話 bean 的代碼。會話 bean 是一種企業 bean,它由客戶端創建,并且通常只在一個客戶/服務器會話期間存在。會話 bean 執行像計算或訪問客戶端數據庫這樣的操作。在本例中,企業 bean 從客戶端接收簡單的字符串日志消息,并在服務器上打印它們。
//LoggerEJB.java
package ejbinterop;
import javax.ejb.*;
import java.util.*;
import java.rmi.*;
import java.io.*;
/**
* Accepts simple String log messages and prints
* them on the server.
*/
public class LoggerEJB implements SessionBean {
public LoggerEJB() {}
public void ejbCreate() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sc) {}
/**
* Logs the given message on the server with
* the current server time.
*/
public void logString(String message) {
LogMessage msg = new LogMessage(message);
System.out.println(msg);
}
}
LogMessage.java
LogMessage.java
文件取得當前的日期和時間,然后創建格式化字串來顯示消息,并將消息打印到服務器。
//LogMessage.java
package ejbinterop;
import java.io.Serializable;
import java.util.Date;
import java.text.*;
/**
* Simple message class that handles pretty
* printing of log messages.
*/
public class LogMessage implements Serializable
{
private String message;
private long datetime;
/**
* Constructor taking the message. This will
* take the current date and time.
*/
public LogMessage(String msg) {
message = msg;
datetime = (new Date()).getTime();
}
/**
* Creates a formatted String showing the message.
*/
public String toString() {
StringBuffer sbuf = new StringBuffer();
DateFormat dformat
= DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.LONG);
FieldPosition fpos = new
FieldPosition(DateFormat.DATE_FIELD);
dformat.format(new Date(datetime), sbuf, fpos);
sbuf.append(": ");
sbuf.append(message);
return sbuf.toString();
}
}
- 編譯本節編寫的文件,例如:
javac -classpath $J2EE_HOME/lib/j2ee.jar:.. *.java
這些命令在當前目錄中為所有的 .java 文件創建了類文件。這個命令和本文中的其他命令假定已經正確設置了 J2EE_HOME 環境變量。使用 $J2EE_HOME 是 Unix? 操作系統的規定。當在 Microsoft Windows 操作環境中,請替換 %J2EE_HOME%。
第 2 部分:生成 CORBA IDL
本節討論如何從 Java 類文件中生成接口定義語言(Interface Definition Language,IDL),并且假定 Java 類文件已在前一節中生成。在本例中,我們將使用 rmic
編譯器,以便將 Java 代碼映射到 IDL。IDL 提供了純聲明性的、編程語言無關的方式來指定對象的 API。
- 針對 Java 類文件運行
rmic
編譯器,該 Java 類文件已在前一步驟中生成,其命令如下: rmic -idl -noValueMethods -classpath
$J2EE_HOME/lib/j2ee.jar:<path_to_ejbinterop_dir>
-d <path_to_where_idl_files_should_be_generated>
ejbinterop.Logger ejbinterop.LoggerHome
在前面的例子中,我們包括了 .jar 文件和 ejbinterop
文件的目錄,.jar 文件中包含有 javax.ejb
包的定義。如果您正在使用 JavaTM 2 Platform, Enterprise Edition (J2EETM), version 1.3 Reference Implementation (RI),那么 .jar
文件就位于 $J2EE_HOME/lib/j2ee.jar
。
在上面的 rmic
命令行中,我們推薦了一種捷徑——使用 noValueMethods
選項。這個選項告訴 rmic
跳過具有參數或返回類型的任何方法,這里的返回類型將被映射到 CORBA 值類型。有利的方面在于它將防止我們生成許多不必要的 IDL,在 C++客戶端中,我們可能必須實現這些 IDL。不利的方面在于我們只能使用原始的數據類型、數組和字符串,而不能使用自己的 Java 類類型來作為參數或返回類型。 有關進一步信息,請閱讀 針對復雜接口的技巧。
在 Java 類文件上運行 rmic
編譯器會生成下面的一些文件,文件所處的目錄由上面 rmic
語句的 -d 選項指出:
java/lang/Ex.idl
java/lang/Exception.idl
java/lang/Object.idl
java/lang/Throwable.idl
java/lang/ThrowableEx.idl
javax/ejb/CreateEx.idl
javax/ejb/CreateException.idl
javax/ejb/EJBHome.idl
javax/ejb/EJBMetaData.idl
javax/ejb/EJBObject.idl
javax/ejb/Handle.idl
javax/ejb/HomeHandle.idl
javax/ejb/RemoveEx.idl
javax/ejb/RemoveException.idl
ejbinterop/Logger.idl
ejbinterop/LoggerHome.idl
- 注意:許多生成文件包含了只能在 Java 編程環境中使用的 API 。 例如,目前
EJBMetaData
實現特定于每個應用程序服務器,因此很難開發等效設施,以便在除 Java 平臺外的平臺上繼續超時工作。一種選擇是將它們從 IDL 中刪除,但如果這樣做,那么每次改變 Java 接口,并從 rmic
編譯器中重生成 IDL 文件時,就必須從 IDL 中刪除它們。
-
注意: 由于 CORBA 異常不支持繼承,因此針對 IDL 映射的 Java 語言創建了 Ex
類,它包含了代表實際 Java 異常的 CORBA 值類型。在這個基本的例子中,不必過多擔心異常支持。有關異常的進一步信息,請參閱 http://java.sun.com/j2se/1.4.2/docs/guide/idl/jidlExceptions.html
。
- 使用 C++ 供應商的“IDL to C++”編譯器來編譯 IDL 文件,以便生成對應于 IDL 的 C++ 代碼。不同的供應商之間,這個過程的步驟會有區別,因此有必要參考產品文檔,取得針對供應商的特定步驟。
第 3 部分:創建 CORBA 客戶端
客戶端應用程序可以使用 CORBA 支持的任何語言編寫。下面的例子提供了針對于 C++ 客戶端的代碼,只要給予對象請求代理人( Object Request Broker,簡稱 ORB)和 LoggerHome
對象的 corbaname
URL,它就會在服務器上將簡單字符串消息記錄到日志中。您必須根據 C++ ORB 供應商的庫來調整 include
語句,并修改注冊值工廠的代碼。本例是針對 ORBacus for C++ 4.0.5 編寫的,因此本例中的一些 C++ 代碼是特定于該產品的。
corbaname
URL 是可閱讀的 URL 格式,它允許您訪問 CORBA 對象。它用于從特定命名上下文解析字符串化的名稱。這是 J2EE v 1.3 平臺中的新特性,它作為 CORBA 互操作命名服務(Interoperable Naming Service,簡稱 INS)的一部分。INS 是 CORBA 對象服務(CORBA Object Services,簡稱COS)命名服務的擴展,在以前版本的 J2EE 平臺中已經交付使用。為了進一步了解 INS,請訪問 http://java.sun.com/j2se/1.4.2/docs/guide/idl/jidlNaming.html#INS。
在本例中,客戶端代碼執行下面的一些操作:
- 創建對象請求代理(ORB)。ORB 將對象請求服務連接到提供它們的對象。
- 注冊值工廠。
- 在命名上下文中查找
corbaname
URL 指向的 LoggerHome
對象。
- 從返回給
LoggerHome
對象的對象中執行安全的向下轉換。
- 創建
LoggerEJB
對象引用。
- 在日志中記錄消息。
- 告訴應用程序服務器不再使用 EJB 引用。
- 使用類似于下面的 C++ 代碼來創建客戶端。準確的代碼可能與 C++ 實現有關。這些代碼是針對于 ORBacus for C++ 4.0.5 編寫的,因此本例中的一些 C++ 代碼可能特定于該產品。
//Code Example: Client.cpp
#include <fstream.h>
// C++ ORB Vendor specific include files
// These are from C++ ORBacus 4.0.5
#include <OB/CORBA.h>
#include <OB/OBORB.h>
// Include files generated from our IDL
#include <java/lang/Exception.h>
#include <java/lang/Throwable.h>
#include <javax/ejb/CreateException.h>
#include <javax/ejb/RemoveException.h>
#include <ejbinterop/Logger.h>
#include <ejbinterop/LoggerHome.h>
/**
* Given an ORB and a corbaname URL for a LoggerHome
* object, logs a simple string message on the server.
*/
void
run(CORBA::ORB_ptr orb, const char* logger_home_url)
{
cout << "Looking for: " << logger_home_url << endl;
// Look up the LoggerHome object in the naming context
// pointed to by the corbaname URL
CORBA::Object_var home_obj
= orb->string_to_object(logger_home_url);
// Perform a safe downcast
ejbinterop::LoggerHome_var home
= ejbinterop::LoggerHome::_narrow(home_obj.in());
assert(!CORBA::is_nil(home));
// Create a Logger EJB reference
ejbinterop::Logger_var logger = home->create();
CORBA::WStringValue_var msg =
new CORBA::WStringValue((const CORBA::WChar*)L"Message
from a C++ client");
cout << "Logging..." << endl;
// Log our message
logger->logString(msg);
// Tell the application server we won't use this
// EJB reference any more
logger->remove();
cout << "Done" << endl;
}
/**
* Simple main method that checks arguments, creates an
* ORB, and handles exceptions.
*/
int
main(int argc, char* argv[])
{
int exit_code = 0;
CORBA::ORB_var orb;
try {
// Check the arguments
if (argc != 2) {
cerr << "Usage: Client <corbaname URL of LoggerHome>" << endl;
return 1;
}
// Create an ORB
orb = CORBA::ORB_init(argc, argv);
// Register value factories
// NOTE: This is overkill for the example since we'll never
// get these exceptions. Also, the _OB_id method is a
// proprietary feature of ORBacus C++ generated code.
CORBA::ValueFactory factory = new java::lang::Throwable_init;
orb -> register_value_factory(java::lang::Throwable::_OB_id(),
factory);
factory -> _remove_ref();
factory = new java::lang::Exception_init;
orb -> register_value_factory(java::lang::Exception::_OB_id(),
factory);
factory -> _remove_ref();
factory = new javax::ejb::CreateException_init;
orb -> register_value_factory(javax::ejb::CreateException::_OB_id(),
factory);
factory -> _remove_ref();
factory = new javax::ejb::RemoveException_init;
orb ->
register_value_factory(javax::ejb::RemoveException::_OB_id(),
factory);
factory -> _remove_ref();
// Perform the work
run(orb, argv[1]);
} catch(const CORBA::Exception& ex) {
// Handle any CORBA related exceptions
cerr << ex._to_string() << endl;
exit_code = 1;
}
// Release any ORB resources
if (!CORBA::is_nil(orb)) {
try {
orb -> destroy();
} catch(const CORBA::Exception& ex) {
cerr << ex._to_string() << endl;
exit_code = 1;
}
}
return exit_code;
}
- 使用 C++ 編譯器來編譯所有的 C++ 文件,包括 Client.cpp 文件,創建客戶端可執行文件。不同平臺之間,這樣的一些工具的區別甚大,因此有必要參考產品文檔,獲得它的說明。
第 4 部分:部署 Enterprise JavaBean 組件
- 使用滿意的應用程序服務器部署企業 bean。下面的一些步驟描述了如何部署
LoggerEJB
組件,它使用了 J2EE 1.3 Reference Implementation (RI)。
- 通過鍵入如下命令,從終端窗口或命令行提示中啟動 RI 應用程序:
$J2EE_HOME/bin/j2ee -verbose
- 當 J2EE 1.3 RI 指出“J2EE 啟動完成”時,鍵入如下命令,從另一終端窗口或命令提示中運行部署工具:
$J2EE_HOME/bin/deploytool
- 從部署工具中,選擇
File
->
New
->
Application。
- 在 Application File Name 字段中,輸入
Logger.ear
,以指出要在其中創建應用程序的文件。
- 在 Application Display Name 字段中,輸入
Logger。
- 選擇 OK 來保存設置,關閉這個對話窗口。
- 從部署工具中,選擇
File
->
New
->
Enterprise Bean。
- 如果出現 Introduction 屏幕,選擇 Next,否則繼續。
- 在 New EnterpriseBean Wizard 中,在 Contents 框中選擇 Edit。
- 擴展 Available Files 列表,添加下面的 4 個
.class
文件,它們來自 ejbinterop
包:Logger.class
、LoggerHome.class
、LoggerEJB.class
和 LogMessage.class
。選擇 OK,然后選擇 Next。
- 選擇
Stateless
Session
Bean
Type。
- 選擇
ejbinterop.LoggerEJB
用于 Enterprise
Bean
Class
。
- 選擇
ejbinterop.LoggerHome
用于 Remote
Home
Interface
。
- 選擇
ejbinterop.Logger
用于 Remote
Interface
。
- 選擇 Next 按扭,直到看到
Security
Settings
頁。
- 選擇
Deployment
Settings
按扭。
- 選擇
Support
Client
Choice
.
- 選擇 OK 保存設置并關閉這個對話窗口。
- 選擇 Finish.
- 從部署工具中,選擇
Tools
->
Deploy。
- 如果只運行 Java RMI-IIOP 客戶端,選擇 Return Client JAR。
- 選擇 Next。
- 在
JNDI
Name
for our LoggerEJB 字段中輸入 ejbinterop/logger
。
- 選擇 Finish。
- 選擇 File -> Exit 來退出部署工具。
現在已經部署了具有 LoggerEJB
組件的 Logger 應用程序,它準備接收消息。
第 5 部分:運行客戶端可執行文件
- 運行客戶端可執行文件。運行客戶端可執行程序的一種方法是,切換到包含可執行客戶端文件的目錄,然后在終端窗口中輸入下面的 URL:
Client corbaname:iiop:1.2@localhost:1050#ejbinterop/logger
在這個 URL 中,
Client
是要運行的應用程序的名稱。
corbaname
指出將從特定的命名上下文中解析字符串化的名稱。
iiop:1.2
告訴 ORB 使用 IIOP 協議和 GIOP 1.2。
- 要在其上查找引用的宿主計算機是
localhost
——本地計算機。為了擴展這個例子,以便在兩臺計算機上運行,請輸入計算機的 IP 地址和主機名,而不是 localhost
,服務器要在該計算機上運行。
1050
是端口號,命名服務會在該端口上偵聽請求。 在 J2EE v.1.3 RI 中,默認情況下,命名服務要在其上偵聽的默認端口號是端口 1050。到目前為止,散列標記 (hash mark) 上的引用部分( Client corbaname:iiop:1.2@localhost:1050
) 是某個 URL,它返回根命名上下文。
ejbinterop/logger
是要在命名上下文中解析的名稱。
如果您正在使用 J2EE 1.3 Reference Implementation,應該會看到類似于如下的一條消息,該消息是在應用程序服務器上被打印的:
Sep 21, 2001 3:33:07 PM PDT: Message from a C++ client ejbinterop/
logger
is the name to be resolved from the Naming Service.
第 6 部分:停止 J2EE 服務器
- 停止 J2EE 服務器。為了停止服務器,可以在終端窗口或命令行提示中,輸入這條命令。
$J2EE_HOME/bin/j2ee -stop
不同的操作系統之間,停止運行中進程的過程是不同的,因此如果正在使用不同的服務器,可以參考系統文檔以取得詳細信息。
創建 Java RMI-IIOP 客戶端應用程序
使用相同的例子,可以容易地開發連接到企業 bean 的 Java RMI-IIOP 客戶端,。與使用 C++ 的例子的區別在于:
- 在客戶端 CLASSPATH 中,必須包括客戶端
.jar
文件的位置,該文件是由運行需要的企業 bean 的應用程序服務器創建的。那個 .jar
文件包含了必要的客戶端存根模塊。
- 當使用 J2EE 1.3 RI 部署應用程序時,檢查 Deploy 屏幕第一頁上的 Deploytool 中的
Return Client Jar
框。
下面的代碼是 Java RMI-IIOP 版本的 LoggerEJB
組件客戶端。遵循與 C++ 客戶端例子所展示的相同步驟。當運行客戶端時,使用與 C++ 例子中相同的 URL。
//Code Example: LogClient.java
package ejbinterop;
import java.rmi.RemoteException;
import javax.rmi.*;
import java.io.*;
import javax.naming.*;
import javax.ejb.*;
/**
* Simple Java RMI-IIOP client that uses an EJB component.
*/
public class LogClient
{
/**
* Given a corbaname URL for a LoggerHome,
* log a simple String message on the server.
*/
public static void run(String loggerHomeURL)
throws CreateException, RemoveException,
RemoteException, NamingException
{
System.out.println("Looking for: " + loggerHomeURL);
// Create an InitialContext. This will use the
// CosNaming provider we will specify at runtime.
InitialContext ic = new InitialContext();
// Lookup the LoggerHome in the naming context
// pointed to by the corbaname URL
Object homeObj = ic.lookup(loggerHomeURL);
// Perform a safe downcast
LoggerHome home
= (LoggerHome)PortableRemoteObject.narrow(homeObj,
LoggerHome.class);
// Create a Logger EJB reference
Logger logger = home.create();
System.out.println("Logging...");
// Log our message
logger.logString("Message from a Java RMI-IIOP client");
// Tell the application server we won't use this
// EJB reference anymore
logger.remove();
System.out.println("Done");
}
/**
* Simple main method to check arguments and handle
* exceptions.
*/
public static void main(String args[])
{
try {
if (args.length != 1) {
System.out.println("Args: corbaname URL of LoggerHome");
System.exit(1);
}
LogClient.run(args[0]);
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}
}
使用 Java RMI-IIOP 客戶端運行應用程序
當使用 Java RMI-IIOP 客戶端,而不是 C++ 客戶端運行示例應用程序時,請遵循這些步驟:
- 使用下面的命令,在
ejbinterop
/ 目錄中編譯 . java
文件:javac -classpath $J2EE_HOME/lib/j2ee.jar:<ejbinterop_directory> *.java
- 像 部署 Enterprise JavaBean 組件中所描述的那樣部署 Enterprise JavaBean 組件。當運行 Java RMI-IIOP 客戶應用程序時,記得在 Tools -> Deploy 頁中選擇 Return Client JAR 。 Deployment 主題中的一些命令指導您啟動 J2EE RI 或其他應用程序服務器。
- 使用類似于如下命令運行客戶應用程序:
java -classpath $J2EE_HOME/lib/j2ee.jar:
<path to LoggerClient.jar>/LoggerClient.jar:
<directory_above_ejbinterop>:<ejbinterop_directory>
ejbinterop.LogClient
corbaname:iiop:1.2@localhost:1050#ejbinterop/logger
在 J2EE RI 正在運行的窗口中,將會看到:
Jan 31, 2002 2:27:47 PM PST: Message from a Java RMI-IIOP client
在運行客戶端的窗口中,將會看到:
Looking for: corbaname:iiop:1.2@localhost:1050#ejbinterop/logger
Logging...
Done
- 停止 J2EE 服務器。
超越基本應用程序
本部分包括下述信息:
如何增強應用程序
要增強應用程序,您可以:
針對復雜接口的技巧
對于運用不同語言的客戶端和服務器之間的通信,接口是關鍵。為了在這方面獲得成功,應該考慮下面的建議:
- 避免將復雜的 Java 類,比如
java.util
中的集合,用于方法參數或返回類型。
在將這些類開映射到 IDL 后,將強制您使用客戶端編程語言實現它們。此外,由于 Java Object Serialization 和 RMI-IIOP API 使得類的線路格式和內部表示能夠隨時間不斷發展,因此您的 CORBA 客戶端應用程序可能在不同的 JavaTM 2 Platform, Standard Edition (J2SETM) 實現或版本上不兼容。
- 從 IDL 開始。
您可能想在返回類型或方法參數中使用復雜的數據結構。在本例中,試著從 IDL 開始。在 IDL 中定義數據結構,甚至定義異常,然后將它們用在 EJB 接口中。這將可以防止逆向映射的產出物進入 CORBA 接口。
例如,剛開始試著在 IDL 中定義 LogMessage
類,然后在 Logger EJB 組件中,將 IDL 編譯的 Java 語言結果類用作方法參數。
- 避免重載 EJB 接口。
CORBA IDL 不支持方法重載,符合 IDL 映射規范的 Java 語言解決了這一點,其方式是創建 IDL 方法定義,將方法名與它的所有 IDL 參數類型組合起來。對于使用非 Java 編程語言的開發人員來說,這帶來了非常不友好的方法名。
- 考慮使用橋。
如果可用的選項仍然太有限,或者影響到想編寫的代碼,就可以考慮使用服務器端橋。在“鏈接到類似例子”一節列出了一些站點,您可以從這些站點中獲得更多有關如何構建橋的信息。
鏈接到類似例子
實現 J2EE 技術的幾個供應商都有一些優秀的例子和技巧,用于集成 CORBA 和 Enterprise JavaBeans 技術:
posted on 2005-02-04 11:28
jacky 閱讀(256)
評論(0) 編輯 收藏