将 Enterprise JavaBeans 与 Liberty 上的远程接口配合使用

当 Enterprise Bean 由另一个 Java 虚拟机 (JVM) 或同一 JVM 中的另一个应用程序托管时,您可以使用远程接口远程访问 Enterprise Bean (EJB) 方法。 WebSphere® Application Server 使用 RMI-IIOP 技术实现远程企业 Bean 接口。 您可以使用 ejbRemote-3.2enterpriseBeansRemote-4.0 功能部件来启用远程企业 Bean 支持。

有关此任务

要配置 Liberty 服务器以在启用远程企业 Bean 支持的情况下运行应用程序,必须设置 ejbRemote-3.2enterpriseBeansRemote-4.0 功能部件。

使用远程企业 Bean 接口时,请查看以下注意事项:

命名
使用 java: 名称空间
企业 Bean 规范要求将远程接口绑定到 java: 名称空间,该名称空间可供应用程序服务器和应用程序客户机容器使用,如以下示例中所示:
java:global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface    
java:app/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface    
java:module/ExampleBean!com.ibm.example.ExampleRemoteInterface

在 V 20.0.0.12 和更高版本中,企业 Bean 组件同时绑定到缺省名称空间和 ejblocal: Java 命名和目录接口 (JNDI) 名称空间,如 WebSphere® Application Server Traditional中所示。 在这些版本中,对于在同一服务器中托管的企业 Bean 组件, @EJB ibm-*-bnd.xml/xmi 文件中的查找和绑定可以使用 WebSphere Application Server Traditional中的 java: 名称空间或传统名称空间。 对于在另一服务器中托管的企业 Bean 组件,查找和绑定可以使用 corbaname URL。 在 V 20.0.0.12之前,企业 Bean 组件未绑定到缺省 JNDI 名称空间,并且必须将 java: 名称用于同一服务器中托管的企业 Bean 组件。

使用 corbaname URL
这些接口还会绑定至 java:global 名称空间中所使用接口的类似上下文中的 ORB CosNaming 名称服务。 通过使用 corbaname URL,可借助 JNDI 访问这些接口;例如:
corbaname::test.ibm.com:2809#ejb/global/ExampleApp/ExampleModule/ExampleHomeBean!com.ibm.example.ExampleEJBHome
corbaname:rir:#ejb/global/ExampleApp/ExampleModule/ExampleHomeBean!com.ibm.example.ExampleEJBHome

在服务器上,URL 的 rir: 形式使用本地名称服务。 在客户机上,它使用缺省的或已配置的远程名称服务。

corbaname URL 进行转义

按照对象管理组 (OMG) 命名服务规范,必须对 corbaname URL 中的某些字符进行转义。 Liberty 尝试确定是否需要对派生自 java:global 名称空间的 corbaname URL 进行转义,然后自动对其进行转义。 不能在所有情况下进行转义。 例如,如果名称包含单个点 (.) 并且没有无效字符,那么它不能自动转义。 要强制以特定方式解释名称,必须手动对 URL 进行转义,如 OMG 命名服务规范中所述。

对于企业 bean,考虑以下 java:global 名称:
java:global/TestApp/TestModule/TestBean!test.TestRemoteInterface
corbaname URL 的简单形式无法自动转义,因为它表示不同但是有效的位置。 因此,以下 URL 不会按预期工作:
corbaname:rir:#ejb/global/TestApp/TestModule/TestBean!test.TestRemoteInterface
反而必须按以下方式对此 URL 进行手动转义:
corbaname:rir:#ejb/global/TestApp/TestModule/TestBean!test%5c.TestRemoteInterface
并非所有客户机和应用程序服务器实现都支持在 JNDI 名称中使用 %5c 来表示转义字符。 对于这些实现,包括 WebSphere Application Server Traditional,反斜杠 ( \ ) 可以直接使用字符。 因为反斜杠在 Java 字符串中必须转义,所以可以手动对 URL 进行转义,如以下示例中所示:
corbaname:rir:#ejb/global/TestApp/TestModule/TestBean!test\\.TestRemoteInterface

OMG 命名服务规范中完整描述了用于对 corbaname URL 进行转义的语法。

通过程序使用 JNDI 名称
可通过程序从 InitialContext 查找这些示例中的所有 URL 和 JNDI 名称。 查找 java: 名称时,产生的对象可直接转型为预期类型;例如:
Object found = new InitialContext().lookup("java:global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface");
ExampleRemoteInterface bean = (ExampleRemoteInterface) found;
但是,使用 corbaname URL 来检索对象时,必须使用 RMI 样式的强制类型转换(称为收缩);例如:
Object found = new InitialContext().lookup("corbaname:rir:#ejb/global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface");
ExampleRemoteInterface bean = (ExampleRemoteInterface)PortableRemoteObject.narrow(found, ExampleRemoteInterface.class);
如果使用同一上下文从同一远程服务器查找多个企业 Bean ,那么可以在创建 InitialContext 类时使用 corbaloc 值,如以下示例中所示:
        Properties p = new Properties();
        p.put(Context.PROVIDER_URL, "corbaloc::test.ibm.com:2809");
        InitialContext c = new InitialContext(p);
        Object found = c.lookup("ejb/global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface");
        ExampleRemoteInterface bean = (ExampleRemoteInterface)PortableRemoteObject.narrow(found, ExampleRemoteInterface.class);
互操作性
打包在带有 V2.0 部署描述符的 EJB JAR 模块中时,支持 IIOP 协议的任何产品可调用一些企业 bean,这些企业 bean 将 EJB 2.x 远程编程模型与 EJBHomeEJBObject 配合使用。 WLP_INSTALL_DIR/clients/ejbRemotePortable.jar 文件必须包含在远程客户机的类路径上。 此文件包含与 Liberty 服务器通信所需的系统值类。 从 WebSphere Application Server LibertyWebSphere Application Server Traditional远程访问企业 Bean 组件时,不需要此文件。 在 Liberty 上使用 EJB 3 远程编程模型的企业 Bean 组件可由 WebSphere Application Server 进程远程访问。 Liberty 不提供瘦客户机来从独立 Java 进程启动企业 Bean 组件。 Liberty 不会为远程企业 Bean 组件提供工作负载管理或故障转移功能,包括当您启动从 WebSphere Application Server Traditional托管的企业 Bean 组件时。
存根类
当您启动在 WebSphere Application Server上托管的远程企业 Bean 时,客户机必须包含存根类。 在某些情况下,如果客户机为 WebSphere Application Server,那么该产品自动生成正确的存根类:
  • 如果客户机应用程序启动包含在同一应用程序中的远程企业 Bean ,那么 Liberty 会自动生成存根类。
  • 如果目标企业 Bean 正在单独的应用程序中运行,并且正在将 EJB 2.x 远程编程模型与 EJBHomeEJBObject配合使用,那么客户机必须在其类路径中包含存根类。 如果 EJB 在 WebSphere Application Server Traditional上托管,那么在 ejbdeploy 命令处理 EJB 客户机 JAR 之后,可以从 EAR 中的应用程序复制 EJB 客户机 JAR。 如果企业 Bean 托管在 Liberty上,那么必须使用 Java SDK 随附的 rmic 程序为目标企业 Bean 生成存根类,然后必须将存根类包含在客户机中。
  • 如果目标企业 Bean 在单独的应用程序中运行并且正在使用 EJB 3 远程编程模型,那么客户机 LibertyWebSphere Application Server Traditional 进程会自动生成存根类。 在 Liberty 上使用 EJB 3 远程编程模型的企业 Bean 组件只能由 WebSphere Application Server 或 WebSphere Application Client 进程远程访问。
事务传播
Liberty 不支持出站或入站事务传播。 此外, Enterprise Beans 规范要求即使产品支持出站事务传播,它仍必须发送空事务上下文。 使用 Required (缺省值) , MandatorySupports 事务属性的企业 Bean 组件必须拒绝此上下文。 如果客户机或服务器位于 Liberty中,那么具有活动全局事务的客户机无法启动具有缺省事务属性的企业 Bean。 如果将企业 Bean 更改为使用 RequiresNewNotSupported 事务属性,那么客户机可以启动企业 Bean。 但是,企业 Bean 完成的事务工作不会作为客户机事务的一部分落实。
异步方法
企业 Bean 远程接口可以具有类型为 Future的返回值的异步方法。 服务器会将 Future 对象返回至客户机,用于检索该值。 建议不要使用远程异步方法,因为未声明结果的累积可能耗尽内存。 为了缓解此问题,如果客户机在 24 小时内未检索结果或最大未声明结果数超过 1000,那么服务器结果将到期。 可在 server.xml 文件中调整这些值;例如:
<ejbContainer>        
     <async maxUnclaimedRemoteResults="10"unclaimedRemoteResultTimeout="10m"/>    
</ejbContainer>

过程

  1. 要启用此功能,请更新 server.xml 文件以添加 ejbRemote-3.2 功能部件; 例如:
    <featureManager>
         <feature>ejbRemote-3.2</feature>
    </featureManager>
    
  2. 配置应用程序绑定文件 ibm-*-bnd.xml 文件,以用于已在部署描述符 <ejb-ref> 或使用源代码注释 @EJB定义的远程企业 Bean 引用。
    对于在注释上或部署描述符中提供查找名称的 EJB 引用,绑定不是必需的。 在绑定文件中,可以使用 EJB 的其中一个 java: 名称或其中一个 corbaname: 名称来绑定 EJB 引用; 例如:
    对于 EJB 引用:
    @EJB(name="TestBean")
       TestRemoteInterface testBean;
    已定义绑定:
     <ejb-ref name="TestBean" binding-name="corbaname:rir:#ejb/global/TestApp/TestModule/TestBean!test\\.TestRemoteInterface"/>
    
  3. 配置应用程序客户机以包含存根类。
  4. (可选) 通过在远程客户机的类路径上添加 WLP_INSTALL_DIR/clients/ejbRemotePortable.jar 文件,为支持 IIOP 协议的应用程序配置互操作性以使用 EJB 远程接口。