本文讨论如何让用 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 阅读(253)
评论(0) 编辑 收藏