本文讨论如何让用 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对象的corbanameURL,它就会在服务器上将简单字符串消息记录到日志中。您必须根据 C++ ORB 供应商的库来调整include语句,并修改注册值工厂的代码。本例是针对  ORBacus for C++ 4.0.5 编写的,因此本例中的一些 C++ 代码是特定于该产品的。
 corbanameURL 是可阅读的 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 将对象请求服务连接到提供它们的对象。 
- 注册值工厂。 
- 在命名上下文中查找 corbanameURL 指向的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。
- 选择 StatelessSessionBeanType。
- 选择 ejbinterop.LoggerEJB用于EnterpriseBeanClass。
- 选择 ejbinterop.LoggerHome用于RemoteHomeInterface。
- 选择 ejbinterop.Logger用于RemoteInterface。
- 选择 Next 按扭,直到看到 SecuritySettings页。
- 选择 DeploymentSettings按扭。
- 选择 SupportClientChoice.
- 选择 OK 保存设置并关闭这个对话窗口。 
- 选择 Finish. 
- 从部署工具中,选择 Tools->Deploy。
- 如果只运行 Java RMI-IIOP 客户端,选择 Return Client JAR。 
- 选择 Next。 
- 在 JNDINamefor 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/
loggeris 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 阅读(271) 
评论(0)  编辑  收藏