技术开发 频道

同时托管 J2EE 应用程序的多个版本

  J2EE 应用程序组件的各个版本中的相同类的不同版本之间的类加载冲突,可以通过在相同的 WebSphere 应用程序服务器 JVM 进程中使用不同的类加载器来解决。

  图 4 显示了 WebSphere Application Server 的类加载器的层次。

  图 4. WebSphere 类加载器层次

  应用程序类加载器负责加载 EJB JAR 文件中的 EJB 模块以及封装在相关的 JAR 文件中的实用程序类。不同的应用程序加载类可以使相同的 EJB 类以及 EJB 类使用的实用程序类的不同版本得以分离。J2EE 应用程序中的 Web 模块通过 WAR 类加载器来加载,这个类加载器是企业应用程序中的应用程序类加载器的一个子类。可以设置使用不同的 WAR 类加载器来加载不同版本的 Web 组件类。可以使用不同的封装选择来分隔不同版本的 J2EE 组件,并且这种做法本身就意味着要使用不同的类加载器。

  服务器端组件类的不同版本应该尽量使用不同的类加载器使其分离开来。然而,有时有必要共享客户端类(例如当 EJB stub 属于不同版本的情况),这样可以使不同版本的应用程序访问同一个组件,例如一个 servlet。这种情况可以在应用程序开发阶段通过使用不同的包名来解决。

  servlet 路径冲突

  Web 组件的不同版本可能具有不同的 servlet 上下文根,这就可以使 Web 容器识别出同一个 Web 组件的不同版本,并且可以同时使用不同的 WAR 类加载器加载相同 servlet 类的不同版本。通过这种方式,应用程序版本的粒度可以降到 Web 模块(.war文件)级上。servlet 上下文根是在企业应用程序档案(.ear)文件中的部署描述符中对每个 Web 应用程序进行指定的。样本 1 给出了 EAR 部署描述符指定上下文根的例子。

  静态内容(例如 HTML 页面和 JSP 页面)的不同版本也可以通过 Web 应用程序的不同上下文根来唯一指定。

  样本 1. 在应用程序部署描述符中为 Web 应用程序的不同版本指定不同的上下文根

1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE application PUBLIC
3     "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"
4     "http://java.sun.com/dtd/application_1_3.dtd">
5 <application id="Application_ID">
6     <display-name>MyBankCMPWebEAR</display-name>
7     <module id="WebModule_1071087285887">
8         <web>
9             <web-uri>MyBankCMPWebv1.war</web-uri>
10             <context-root>MyBankCMPWebv1</context-root>
11         </web>
12     </module>
13     <module id="WebModule_1071091542238">
14         <web>
15             <web-uri>MyBankCMPWebCommon.war</web-uri>
16             <context-root>MyBankCMPWebCommon</context-root>
17         </web>
18     </module>
19     <module id="WebModule_1071092618175">
20         <web>
21             <web-uri>MyBankCMPWebv2.war</web-uri>
22             <context-root>MyBankCMPWebv2</context-root>
23         </web>
24     </module>
25 </application>
26

  JNDI 名称空间冲突

  EJB 本地接口是在共享的 JNDI 名称空间中注册的持久性对象引用。J2EE 应用程序的多个版本在一个单一的 WebSphere 域中使用共同的 WebSphere 名称空间。然而,分配给不同版本 EJB 本地接口的 JNDI 名称空间之间会产生冲突。为了避免这种冲突,可以直到部署阶段才将 EJB 本地接口对 JNDI 名称空间的引用绑定。对于 EJB 客户端(例如 Web 应用程序),可以通过 java:comp/env 来引用 EJB,而不是使用硬编码的 JNDI 命名。在 java:comp/env 环境中对 EJB 的引用是在部署描述符中声明的,并且在部署阶段将其绑定到适当的 EJB 本地接口引用版本。

  样本 2 中的代码展示了如何在应用程序的 java:comp/env 中使用 EJB 引用。图 5 展示了在部署阶段如何为 EJB 本地接口指定 JNDI 名,图 6 展示了在部署阶段如何将 java:comp/env 引用绑定到特定版本的 JNDI 名。

  样本 2. 使用 java:comp 来定位 EJB 本地接口

1 Context ctx = new InitialContext();
2          accountHome = (AccountHome)javax.rmi.PortableRemoteObject.narrow(
3              ctx.lookup("java:comp/env/ejb/Account"),AccountHome.class);

  图 5. 在部署阶段为 EJB 本地接口指定 JNDI 名

  图 6. 在部署阶段将 java:comp/env 绑定到 JNDI 名

  下表列出了在样本应用程序 MyBank 中使用的所有 JNDI 名:

版本Account EJB 组件Transfer EJB 组件
最初版本类名com.ibm.mybank.ejb.Accountcom.ibm.mybank.ejb.Transfer
JNDI 名ejb/MyBank/Accountejb/MyBank/Transfer
版本 1类名com.ibm.mybank.ejb.v1.Accountcom.ibm.mybank.ejb.Transfer
JNDI 名ejb/MyBank/v1/Accountejb/MyBank/v1/Transfer
版本 2类名com.ibm.mybank.ejb.v1.Accountcom.ibm.mybank.ejb.Transfer
JNDI 名ejb/MyBank/v2/Accountejb/MyBank/v2/Transfer

  使用 WebSphere Application Server V5 的名称空间转储实用程序可以找到 WebSphere JNDI 名称空间的内容。

0
相关文章