分享
 
 
 

J2EE应用部署(三):高级篇

王朝java/jsp·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

提纲:

一、模块次序问题

二、依靠库的问题

2.1 解决方案之一

2.2 解决方案之二

2.3 依靠库应用实例

正文:

在前面两篇文章中,我们了解了J2EE应用封装和部署的基本概念和实践操作,下面我们来看看几个可能碰到的问题。

一、模块次序问题

J2EE规范没有对EAR文件内的J2EE模块应该如何部署作出任何规定。非凡地,J2EE规范没有明确规定部署模块的次序。假如一个模块中的某个组件要用到另一个待部署模块的组件,它可能会带来问题。

因此,必须注重大多数应用服务器以如下步骤部署EAR文件:

EAR文件内的所有资源适配器作为基本连接器部署。假如存在多个资源适配器,则它们的部署次序就是它们在application.XML部署描述器中列出的次序。

部署所有EJB模块。由于EJB可能在初始化期间用到某些资源适配器,所以EJB的部署在资源适配器之后。假如存在多个EJB模块,它们的部署次序将是它们在application.xml中列出的次序。

部署所有Web应用模块。由于Web应用初始化期间可能用到资源适配器和EJB,所有Web应用在这两者之后部署。假如存在多个Web应用模块,它们部署次序就是它们在application.xml中列出的次序。

二、依靠库的问题

在J2EE应用封装和部署过程中,最常见的问题出现在工具类和支持类上。封装Web应用或EJB应用时,这些库应该放在哪里?Web应用和EJB应用一般都有被“卸出”(这里指装入的反向过程)的能力,这种能力由部署时装入它们的类装载器支持。假如我们把工具类和支持类放入应用服务器的标准类路径,这些类很可能完全失去被卸出的能力。这样,假如Web应用或EJB应用要更新某个库的版本,重新部署Web应用或EJB应用时,包含工具类和支持类的依靠库也要重新部署。在这种情形下,把工具类放入应用服务器标准类路径很不方便,因为每次部署Web应用和EJB应用时,都要重新启动整个应用服务器,这显然不是理想的选择。

那么,在J2EE标准定义中,假定依靠库放在哪里才能实现运行时的重新部署(热部署)呢?有两个简单的方案,但从根本上来说两者都不甚合理:

以JAR文件形式封装的依靠库可以放入Web应用的WEB-INF\lib目录。一般地,WEB-INF\lib目录基本上只用来存放Servlet,jsp页面和Servlet会在读取新类时寻找该目录。假如工具类库只供一个Web应用的JSP页面和Servlet使用,应该说这个方案已经足够。然而,假如EJB组件、JMS消费者、启动应用的类和关闭应用的类也要用到同一工具类库,这种方案不再有效,因为对于它们来说,WEB-INF\lib目录是不可见的。

除了把工具类库放入WEB-INF\lib目录之外,同时在每一个EJB JAR文件中包含一份完整的拷贝。部署EJB时,EJB类装载器将只在它自己的JAR文件中寻找被引用的工具类,不去查看其他已部署EJB应用的JAR文件和WEB-INF\lib目录。假如有几个EJB应用都要用到同一个工具类库,则在每一个JAR文件中放入该类库的一份拷贝就能解决问题。虽然这种方案实现了依靠库的热部署能力,但它明显地不够完善。封装JAR文件的目的是为了提高应用的模块化程度,把同一个类文件放入多个JAR包正好是背其道而行之。此外,多次复制同一组类无谓地加大了应用的体积。最后,即使只改变一个库,每一个JAR文件也都要重新构造,从而使构造过程复杂化。

下面我们来看两种较为有效的解决方案。

2.1 解决方案之一

要解决这个问题,一种可能的方案是在J2EE中避免使用多个JAR文件,把所有EJB和工具类聚集成单个包。EJB 2.0规范正在推动几个项目进行这方面的工作。这个规范要求参与关系的实体EJB使用本地引用,因此参与关系的各个EJB必须封装到同一个JAR文件。

由于新的规范要求避免使用远程关系,因此,许多供给商正在考虑提供能够把多个EJB JAR文件合并的工具。这些工具能够读取两个合法的EJB JAR文件,把它们的类和部署描述器合并成单个统一的包。但应当注重的是,即使所有EJB组件都聚合到了单个JAR文件里面,避免了在多个EJB之间复制依靠库,但假如Web应用也要用到依靠库,则WEB-INF\lib目录下仍然需要依靠库的副本。

此外,对EJB应用模块化的需求仍然存在,许多人希望能够单个地部署EJB。因为重新部署一个JAR文件时,该JAR文件内的每一个EJB都将重新部署,假如实际要部署的只是单个EJB,部署过程中就会出现许多不必要的操作。

2.2 解决方案之二

随着JDK 1.3的发布,Sun重新定义了支持可选包必不可少的“扩展机制”。这个扩展机制支持两方面功能:

JAR文件可以声明自己对其他JAR文件的依靠性。

类装载器经过了修改,能够在可选的包和应用路径中搜索类。

J2EE 1.3规范要求应用服务器必须提供这方面的支持。这就要求部署描述工具能够装载所有通过扩展机制定义的可选库。它同时也意味着,假如一个应用服务器或部署工具能够在运行时卸出或重新部署那些通过扩展机制使用库的EJB应用,那么,该应用服务器或工具也支持所有依靠库的卸出或重新部署。

这种扩展机制为Web应用WAR文件和EJB应用JAR文件指定自己需要哪些企业应用EAR文件中的依靠库提供了一种标准化的方法。那么,这种扩展机制是如何工作的呢?每一个JAR文件里都有一个manifest(意为载货单、旅客名单)文件,这个文件由jar工具自动创建,默认名字是manifest.mf。JAR文件可以在manifest文件中加入一个Class-Path属性,引用它所依靠的JAR文件。我们可以手工编辑manifest.mf文件,在原有内容的基础上,添加Class-Path属性。实际上,许多供给商提供的EJB封装工具会在封装过程中处理依靠类,自动创建合适的manifest.mf文件,使这个文件包含正确的Class-Path属性。

假如在创建EJB JAR文件时修改了manifest.mf,引入了Class-Path属性,在生成一个新的EJB应用文件时,应用服务器提供的容器生成工具必须保存这个值。在WebLogic Server 6.1下,假如EJB JAR已经在manifest.mf文件中包含Class-Path属性,weblogic.ejbc工具会在生成新EJB应用时保存这个值。当前,专门用来创建Class-Path属性并把它插入manifest.mf的工具还没有出现,所以这个工作有时还需要通过手工编辑JAR文件的manifest文件进行。

Class-Path属性的值是用来搜索工具类库的相对URL。这个URL总是相对于包含Class-Path属性的组件(而不是EAR文件的根)。单个Class-Path属性内可以指定多个URL,一个manifest文件可以包含多个Class-Path属性。Class-Path属性的一般格式是:

Class-Path: 列出用空格分隔的多个JAR文件名字

下面是一个例子:

Class-Path: mylog4j.jar xmlnew.jar foo/bar/myutil.jar

在J2SE应用中使用这种扩展机制时,Class-Path属性可以引用目录。然而,对于全部内容都包含在JAR文件中的J2EE应用,Class-Path属性只能引用其他JAR文件。此外,在manifest文件中,Class-Path属性声明必须在一个独立的行上,以便与其他属性声明区分。

这种扩展机制的功能非常强大。非凡地,通过创建一个以解析次序为最终次序的、包含所有类的统一类路径,它能够方便地解决循环引用问题。例如,在下面这个例子中,假设首先被解析的是MyEJB1.jar。MyEJB1.jar引用了:

Class-Path: jaXP1.jar MyEJB2.jar ..\xmlnew.jar

此时,类装载器将解析MyEJB2.jar。MyEJB2.jar引用了:

Class-Path: jaxp1.jar MyEJB1.jar

类装载器最终使用的“应用级类路径”将是:

Class-Path: jaxp1.jar MyEJB2.jar ..\xmlnew.jar MyEJB1.jar

2.3 依靠库应用实例

下面这个例子示范了一个企业应用各种可能的类装载情形。它示范了多个EJB模块、多个Web应用,以及在这些应用之间多个共享的依靠库。通过这个例子,我们可以了解应用服务器从不同应用装载各个类的过程。当应用运行时,通过输出不同类的类装载器层次关系,我们可以了解:是否所有的类都通过单个类装载器装入,还是通过不同的类装载器装入;假如通过多个类装载器装入,这些装载器有什么关系。

这个例子包含两个EJB模块、两个Web应用模块、七个在不同情形下使用的依靠类库。EAR文件的结构如下:

MyDepend1-container.jar

MyDepend2-container.jar

MyWebApp1.war

MyWebApp2.war

TestUtil1.jar

TestUtil2.jar

TestUtil3.jar

TestUtil4.jar

TestUtil5.jar

TestUtil6.jar

TestUtil7.jar

META-INF\

application.xml

每一个“MyDepend?-container”JAR文件包含一个EJB。每一个Web应用中包含一个名为TestServlet的Servlet。每一个工具类库包含一个类,这个类有一个方法,它的功能是输出类装载器的层次关系。这个例子测试了EAR文件内许多不同的类装载情形,其中包括:

当一个EJB用到一个依靠库,且在EJB manifest里面的类路径中引用它时,它是如何装载的?

当不同EJB模块内的多个EJB共享一个依靠库,且依靠库通过各个EJB的manifest类路径指定时,它是如何装载的?

当Web应用引用一个依靠库,且通过Web应用模块的manifest路径引用依靠库时,它是如何装载的?

当Web应用引用一个依靠库,且依靠库保存在Web应用模块的WEB-INF\lib目录下时,它是如何装载的?

当一个EJB模块和一个Web应用都在它们的manifest路径中引用一个依靠库时,依靠库是如何装载的?

要执行这个例子,请先把MyDepend.ear文件(从本文后面下载源文件)部署到服务器上,然后运行各个Web应用的TestServlet。TestServlet将调用适当的EJB方法,EJB的方法又调用依靠库中类的方法。下面是执行两个Servlet的URL:

http://:/web1/testservlet/

http://:/web2/testservlet/

下面是Servlet运行时在浏

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有