J2EE应用部署(三):高级篇 |
作者:佚名 发布时间:2005-04-02 来源:不详
|
在前面两篇文章中,我 看看几个可能遇到的问题。
|
们了解了J2EE应用封装和部署的
|
基本概念和实践操作,下面我们来
|
J2EE规范没有对EAR文 有明确规定部署模块的次序 可能会带来问题。
|
件内的J2EE模块应该如何部署作 。如果一个模块中的某个组件要
|
出任何规定。特别地,J2EE规范没 用到另一个待部署模块的组件,它
|
因此,必须注意大多数应用服务器以如下步骤部署EAR文件: |
EAR文件内的所有资源 部署次序就是它们在applic
|
适配器作为基本连接器部署。如 ation.xml部署描述器中列出的
|
果存在多个资源适配器,则它们的 次序。
|
部署所有EJB模块。由于EJB可能在初 源适配器之后。如果存在多个EJB模块, 的次序。
|
始化期间用到某些资源适配器,所以EJB的部署在资 它们的部署次序将是它们在application.xml中列出
|
部署所有Web应用模块。由于Web应用 在这两者之后部署。如果存在多个Web应 中列出的次序。
|
初始化期间可能用到资源适配器和EJB,所有Web应用 用模块,它们部署次序就是它们在application.xml
|
在J2EE应用封装和部署 EJB应用时,这些库应该放 向过程)的能力,这种能力 入应用服务器的标准类路径 应用要更新某个库的版本, 重新部署。在这种情形下, 应用和EJB应用时,都要重
|
过程中,最常见的问题出现在工 在哪里?Web应用和EJB应用一般 由部署时装入它们的类装载器支 ,这些类很可能完全失去被卸出 重新部署Web应用或EJB应用时, 把工具类放入应用服务器标准类 新启动整个应用服务器,这显然
|
具类和支持类上。封装Web应用或 都有被“卸出”(这里指装入的反 持。如果我们把工具类和支持类放 的能力。这样,如果Web应用或EJB 包含工具类和支持类的依赖库也要 路径很不方便,因为每次部署Web 不是理想的选择。
|
那么,在J2EE标准定义中,假定依赖 ?有两个简单的方案,但从根本上来说两
|
库放在哪里才能实现运行时的重新部署(热部署)呢 者都不甚合理:
|
以JAR文件形式封装的 WEB-INFlib目录基本上只 。如果工具类库只供一个We ,如果EJB组件、JMS消费者 不再有效,因为对于它们来
|
依赖库可以放入Web应用的WEB-I 用来存放Servlet,JSP页面和Se b应用的JSP页面和Servlet使用 、启动应用的类和关闭应用的类 说,WEB-INFlib目录是不可见
|
NFlib目录。一般地, rvlet会在读取新类时寻找该目录 ,应该说这个方案已经足够。然而 也要用到同一工具类库,这种方案 的。
|
除了把工具类库放入WE 的拷贝。部署EJB时,EJB类 其他已部署EJB应用的JAR文 类库,则在每一个JAR文件 库的热部署能力,但它明显 把同一个类文件放入多个JA 应用的体积。最后,即使只 杂化。
|
B-INFlib目录之外,同时在每 装载器将只在它自己的JAR文件 件和WEB-INFlib目录。如果有 中放入该类库的一份拷贝就能解 地不够完善。封装JAR文件的目 R包正好是背其道而行之。此外 改变一个库,每一个JAR文件也
|
一个EJB JAR文件中包含一份完整 中寻找被引用的工具类,不去查看 几个EJB应用都要用到同一个工具 决问题。虽然这种方案实现了依赖 的是为了提高应用的模块化程度, ,多次复制同一组类无谓地加大了 都要重新构造,从而使构造过程复
|
要解决这个问题,一种 聚集成单个包。EJB 2.0规 实体EJB使用本地引用,因
|
可能的方案是在J2EE中避免使用 范正在推动几个项目进行这方面 此参与关系的各个EJB必须封装
|
多个JAR文件,把所有EJB和工具类 的工作。这个规范要求参与关系的 到同一个JAR文件。
|
由于新的规范要求避免使用远程关系 JAR文件合并的工具。这些工具能够读取 合并成单个统一的包。但应当注意的是, 了在多个EJB之间复制依赖库,但如果Web 要依赖库的副本。
|
,因此,许多供应商正在考虑提供能够把多个EJB 两个合法的EJB JAR文件,把它们的类和部署描述器 即使所有EJB组件都聚合到了单个JAR文件里面,避免 应用也要用到依赖库,则WEB-INFlib目录下仍旧需
|
此外,对EJB应用模块化的需求仍旧 署一个JAR文件时,该JAR文件内的每一个 部署过程中就会出现许多不必要的操作。
|
存在,许多人希望能够单个地部署EJB。因为重新部 EJB都将重新部署,如果实际要部署的只是单个EJB,
|
随着JDK 1.3的发布,S 支持两方面功能:
|
un重新定义了支持可选包必不可
|
少的“扩展机制”。这个扩展机制
|
类装载器经过了修改,能够在可选的包和应用路径中搜索类。 |
J2EE 1.3规范要求应用 有通过扩展机制定义的可选 时卸出或重新部署那些通过 有依赖库的卸出或重新部署
|
服务器必须提供这方面的支持。 库。它同时也意味着,如果一个 扩展机制使用库的EJB应用,那 。
|
这就要求部署描述工具能够装载所 应用服务器或部署工具能够在运行 么,该应用服务器或工具也支持所
|
这种扩展机制为Web应用WAR文件和EJ 的依赖库提供了一种标准化的方法。那么 都有一个manifest(意为载货单、旅客名 是manifest.mf。JAR文件可以在manifest JAR文件。我们可以手工编辑manifest.mf 实际上,许多供应商提供的EJB封装工具 manifest.mf文件,使这个文件包含正确
|
B应用JAR文件指定自己需要哪些企业应用EAR文件中 ,这种扩展机制是如何工作的呢?每一个JAR文件里 单)文件,这个文件由jar工具自动创建,默认名字 文件中加入一个Class-Path属性,引用它所依赖的 文件,在原有内容的基础上,添加Class-Path属性。 会在封装过程中处理依赖类,自动创建合适的 的Class-Path属性。
|
如果在创建EJB JAR文 的EJB应用文件时,应用服 6.1下,如果EJB JAR已经在 生成新EJB应用时保存这个 的工具还没有出现,所以这
|
件时修改了manifest.mf,引入 务器提供的容器生成工具必须保 manifest.mf文件中包含Class-P 值。当前,专门用来创建Class- 个工作有时还需要通过手工编辑
|
了Class-Path属性,在生成一个新 存这个值。在WebLogic Server ath属性,weblogic.ejbc工具会在 Path属性并把它插入manifest.mf JAR文件的manifest文件进行。
|
Class-Path属性的值是 Class-Path属性的组件(而 个manifest文件可以包含多
|
用来搜索工具类库的相对URL。 不是EAR文件的根)。单个Class 个Class-Path属性。Class-Path
|
这个URL总是相对于包含 -Path属性内可以指定多个URL,一 属性的一般格式是:
|
Class-Path: 列出用空格分隔的多个JAR文件名字 |
Class-Path: mylog4j.jar xmlnew.j
|
ar foo/bar/myutil.jar
|
在J2SE应用中使用这种 都包含在JAR文件中的J2EE 文件中,Class-Path属性声
|
扩展机制时,Class-Path属性可 应用,Class-Path属性只能引用 明必须在一个独立的行上,以便
|
以引用目录。然而,对于全部内容 其他JAR文件。此外,在manifest 与其他属性声明区分。
|
这种扩展机制的功能非常强大。特别 有类的统一类路径,它能够方便地解决循 解析的是MyEJB1.jar。MyEJB1.jar引用了
|
地,通过创建一个以解析次序为最终次序的、包含所 环引用问题。例如,在下面这个例子中,假设首先被 :
|
Class-Path: jaxp1.ja
|
r MyEJB2.jar ..xmlnew.jar
|
此时,类装载器将解析MyEJB2.jar。MyEJB2.jar引用了: |
Class-Path: jaxp1.jar MyEJB1.jar |
Class-Path: jaxp1.ja
|
r MyEJB2.jar ..xmlnew.jar M
|
yEJB1.jar
|
下面这个例子示范了一个企业应用各 Web应用,以及在这些应用之间多个共享 从不同应用装载各个类的过程。当应用运 以了解:是否所有的类都通过单个类装载 个类装载器装入,这些装载器有什么关系
|
种可能的类装载情形。它示范了多个EJB模块、多个 的依赖库。通过这个例子,我们可以了解应用服务器 行时,通过输出不同类的类装载器层次关系,我们可 器装入,还是通过不同的类装载器装入;如果通过多 。
|
这个例子包含两个EJB EAR文件的结构如下:
|
模块、两个Web应用模块、七个
|
在不同情形下使用的依赖类库。
|
每一个“MyDepend?-container”JAR TestServlet的Servlet。每一个工具类库 装载器的层次关系。这个例子测试了EAR
|
文件包含一个EJB。每一个Web应用中包含一个名为 包含一个类,这个类有一个方法,它的功能是输出类 文件内许多不同的类装载情形,其中包括:
|
当一个EJB用到一个依赖库,且在EJB 的?
|
manifest里面的类路径中引用它时,它是如何装载
|
当不同EJB模块内的多 指定时,它是如何装载的?
|
个EJB共享一个依赖库,且依赖
|
库通过各个EJB的manifest类路径
|
当Web应用引用一个依 何装载的?
|
赖库,且通过Web应用模块的man
|
ifest路径引用依赖库时,它是如
|
当Web应用引用一个依赖库,且依赖 如何装载的?
|
库保存在Web应用模块的WEB-INFlib目录下时,它是
|
当一个EJB模块和一个Web应用都在它 何装载的?
|
们的manifest路径中引用一个依赖库时,依赖库是如
|
要执行这个例子,请先 然后运行各个Web应用的Tes 依赖库中类的方法。下面是
|
把MyDepend.ear文件(从本文后 tServlet。TestServlet将调用 执行两个Servlet的URL:
|
面下载源文件)部署到服务器上, 适当的EJB方法,EJB的方法又调用
|
http://<服务器名字>:<端口>/web1/testservlet/ |
http://<服务器名字>:<端口>/web2/testservlet/ |
WebLogic Server 6.1控制台输出如下: |
Inc.//DTD J2EE Application 1.2//EN' 'http://java.sun.com/j2ee/dtds/application_1_2.dtd'> |
第一个EJB模块的manifest声明的Class-Path属性是: |
Class-Path: TestUtil
|
1.jar TestUtil3.jar TestUtil
|
6.jar TestUtil7.jar
|
其他EJB模块和Web应用 个依赖库的不同组合。Web 参见各个组件的源代码。
|
模块的manifest类路径声明都有 应用中包含的各个Servlet提供
|
所不同,它们是EAR文件包含的七 有关执行过程的详细信息,具体请
|
毫无疑问,manifest.m 技术时,我们可以通过一种 为另一个JAR文件:
|
f文件里面声明的类路径有助于 简单的模式确定哪些EJB应该封
|
提高J2EE应用的模块化。使用这种 装为一个JAR文件,哪些应该封装
|
标识出一个参与CMR(C 以从这个源实体EJB通过CMR 为每一组独立的实体EJB关
|
ontainer-Managed Relationshi 关系到达的实体EJB。把这个关 系重复这个过程。
|
p)关系的实体EJB。标识出所有可 系图中的EJB封装为一个EJB JAR。
|
分析业务和技术方面的需求,如果有 个EJB时重新部署多个EJB是可接受的,则
|
必要的话,把多个JAR文件合并成一个。如果修改单 可以用单个JAR文件封装多个EJB。
|
每一个EJB JAR文件必 解决循环引用和重复引用问 库。但是,虽然存在这种重
|
须通过manifest的Class-Path列 题。例如,在前面演示依赖关系 复引用,EAR类装载器只装载该
|
出其依赖关系。类装载器将自动地 的例子中,多个EJB引用了第三个 库一次。
|
本文示例源程序:J2EE
|
Deployment_code.zip。请参见r
|
eadme.txt。
|
IBM WebSphere Application Server |
|
|
|
|
|