JBoss AS 7类加载说明

这是示例章节,摘自Francesco Marchioni编辑的JBoss AS 7 Configuration Deployment and Administration一书,该书正在运行一个名为mastertheboss.com的JBoss门户。

根据Java EE规范的要求,理想情况下,应用程序服务器应为其部署的应用程序提供使用任何实用程序库和任何版本的自由,而不必考虑要使用同一库的并发应用程序的存在。

这也称为名称空间隔离(Java EE 5规范,EE.8.4节)。 但是,从不同名称空间加载类可能会引起一些不易解决的问题:例如,如果我在应用程序中打包了新版本的实用程序库,而应用程序加载了同一个库的旧版本,将会发生什么情况?服务器? 或者,如何在应用程序服务器的同一实例中同时使用同一实用程序库的两个不同版本? 多年来,JBoss AS类加载策略已经发生了明智的变化:基本上,应用服务器的4.x版本使用UnifiedClassLoader ,其目的是减少运行的应用程序之间的通信开销,因为类数据可以通过引用或简单副本共享。

使用UnifiedClassLoader无法解决的主要未解决问题之一是类加载依赖项。 这样的想法是,如果一个应用程序(A)使用另一个应用程序(B)的类,则系统应该知道在重新部署B时重新部署A,否则它将引用陈旧的类。 实际上,有两种尝试来使这项工作有效,而无需用户进行任何配置。 两种尝试均未真正奏效,并且均被放弃。 自从JBoss AS 5.0引入以来,基于新的虚拟文件系统(VFS)的新类加载器。 实施VFS是为了简化和统一应用程序服务器中的文件处理。 新的类加载器名为VFS类加载器,它使用VFS查找JAR和类文件。 即使这表示在JBoss AS 5.0中如何加载类,也发生了重大变化,但是所产生的行为与JBoss AS以前的版本非常相似。

错误的常见来源是在部署中包括由容器提供的API类。 这会导致创建该类的多个版本,并且部署无法正确部署。 AS7中的类加载标志着与以前的尝试大相​​径庭。 现在,类加载基于JBoss模块项目,并且所部署的任何应用程序实际上都是模块。 肯定的读者会提出一些疑问:分配给已部署应用程序的模块名称是什么? 而且,AS如何处理模块之间的依赖关系? 让我们在单独的部分中回答每个问题:

了解模块名称

了解模块名称不是学术活动。 实际上,我们可以在模块之间建立依赖关系,因此在许多情况下,需要知道分配给应用程序的模块名称是哪一个。 因此,打包为顶级归档文件(例如WAR,JAR和SAR)的应用程序将获得以下模块名称:

deployment.[archive name]

例如,将部署一个名为WebExample1.war的Web应用程序作为模块名称:

deployment.WebExample1.war

另一方面,在包含嵌套模块的应用程序(例如EAR归档文件)上,将使用以下分类为每个单个归档文件分配模块名称:

deployment.[ear archive name].[sub deployment archive name]

因此,如果将相同的Web应用程序包含在存档EnterpriseApp.ear中 ,则将使用以下名称进行部署:

deployment.EnterpriseApp.ear.WebExample1.war

查找隔离级别

第2章“配置应用程序服务”中 ,我们有意部署了使用log4j Api的应用程序,并将log4j库添加到WEB-INF / lib文件夹中。 该应用程序的部署很顺利,省去了一个问题:为什么我们需要添加已经作为模块包含在应用程序服务器中的库? (在我们的例子中,在modules \ org \ apache \ log4j \ main路径中)。

一般规则是,在JBoss AS 7上,每个已部署的应用程序模块都与其他模块隔离开来。 这意味着,默认情况下,它在AS模块上不可见,在AS模块上也不对应用程序可见。

但是,使用应用程序服务器模块非常容易,并且可以用一句话来概括:将依赖项添加到所需模块中,AS就会使用它。 应用程序服务器会自动添加依赖项,或者它们需要由用户发出信号:

  • 核心模块库(即企业类)被视为隐式依赖项,因此当部署者检测到它们的使用时,它们会自动添加到您的应用程序中
  • 用户需要在应用程序的MANIFEST文件或定制的JBoss部署文件jboss-deployment-structure.xm l中明确声明其他模块库(有关更多信息,请参见“高级部署策略”部分)。

隐式依赖:

指出企业应用程序通常使用的Api依赖项可能很麻烦。 因此,正如我们预期的那样,应用程序服务器会自动为您添加它们。 当应用服务器检测到某些该模块的典型注释或配置文件时,将添加一些注释或配置文件。 例如,添加beans.xml文件会触发自动焊接依赖。

以下思维导图显示了隐式添加到应用程序中的模块的综合视图:

该图像的含义很简单:如果您的应用程序使用了所示的任何核心模块,那么您无需指定任何依赖项,因为应用程序服务器能够自动链接该模块。 显式依赖项不能被定义为隐式依赖项的模块需要由用户声明。 在最初的示例中,未将log4j库作为隐式依赖项提及,因此我们不得不将log4j JAR与应用程序打包在一起。 但是,我们可以指示部署者使用log4j库,该库捆绑在应用程序服务器分发中。 实现它的最简单且推荐的方法是在META-INF / MANIFEST.MF中包括Dependencies:[module]声明。 在我们的情况下,要使您的应用程序依赖于log4j,只需在清单文件中包含以下代码:

依赖项:org.apache.log4j

请注意,模块名称并不总是与库的软件包名称匹配。 实际的模块名称由module元素的name属性在module.xml文件中指定。

用户通常将使用Eclipse(或任何其他IDE)来更新清单文件,而无需执行任何繁琐的存档更新:

您不仅限于单个依赖项,还可以添加多个以逗号分隔的依赖项。 例如,为了同时添加对log4j和Apache Velocity Api的依赖,可以使用以下命令:

依赖项:org.apache.log4j,org.apache.velocity

您甚至可以通过添加export关键字将一个应用程序模块使用的依赖项导出到其他应用程序。 例如,在较早的应用程序中,我们现在将依赖项导出到其他模块:

标为依赖于Deployment.WebApp.war模块的应用程序还将有权访问其依赖项:

export参数还可以用于将依赖项导出到耳朵中包含的所有子部署。 因此,如果从耳朵的顶层(或通过ear / lib目录中的jar)导出依赖关系,则该依赖关系也将对所有子部署单元可用。

在META-INF / MANIFEST.MF中,您还可以指定其他命令,这些命令可以修改服务器部署程序的行为。 例如,可以添加可选属性,以指定如果在部署时未找到模块,则部署不会失败。

最后,当指定了services关键字时,部署者将尝试加载放置在归档文件的META-INF / services中的服务。

服务Api已在Java SE 6中公开。服务可以定义为一组编程接口和类,它们提供对某些特定应用程序功能或特性的访问。 服务提供者接口(SPI)是服务定义的一组公共接口和抽象类。

您可以通过实现服务提供商API来定义服务提供商。 通常,您将创建一个JAR文件来保存您的提供程序。 要注册您的提供程序,您必须在JAR文件的META-INF / services目录中创建一个提供程序配置文件。 将services属性添加到META-INF / MANIFEST.MF时,您实际上将能够加载META-INF / services目录中包含的服务。

有关SPI Api的出色介绍,请访问:http://java.sun.com/developer/technicalArticles/javase/extensible。

设置全局模块

该选项与用于加载公共库的旧AS方法有点类似,您曾经将它们放置在文件夹JBOSS_HOME / common / lib中。 如果在standalone.xml / domain.xml中定义了名为global-modules的部分,则将使该模块可被其他AS模块访问。 例如,您可以选择使用以下部分来代替声明对log4j的依赖关系:

<subsystem xmlns="urn:jboss:domain:ee:1.0"><global-modules><module name="org.apache.log4j" /></global-modules>
</subsystem>

尽管通常不建议使用这种方法,但是由于它使我们回到了单片应用服务器的概念,因此它仍然可以带来一些好处。 例如,如果您要迁移一些较旧的应用程序,并且您不希望或者根本无法将依赖关系指定到存档中。

进阶部署策略

到目前为止,我们所学的知识足以配置许多类型的应用程序。 如果您使用的是复杂的归档配置,例如具有多个模块和依赖项的EAR归档,那么在单个文件中定义类加载策略将很有用。

配置文件jboss-deployment-structure.xml可以做到这一点。 使用此文件的优点有很多:

  • 您可以在一个文件中定义所有应用程序模块的依赖关系
  • 您可以通过包含/排除所有或部分模块来使用更细粒度的方式加载模块类
  • 您可以为打包在企业归档中的应用程序定义类加载隔离策略

让我们看一些实际的例子,jboss-deployment-structure.xml可以为您做什么。

设置单个模块依赖性

我们已经学习了如何使用归档文件的MANIFEST文件中的Dependencies属性来激活log4j依赖关系。 使用jboss-deployment-structure.xml文件可以达到相同的效果。 让我们回顾一下存档结构,它基本上是由一个名为WebApp.war的Web应用程序组成的。

如您所见,文件jboss-deployment-structure.xml需要放置在EAR的META-INF文件夹中。

其内容如下:

<jboss-deployment-structure><sub-deployment name="WebApp.war"><dependencies><module name="org.apache.log4j" /></dependencies></sub-deployment>
</jboss-deployment-structure>

文件jboss-deployment-structure并非专用于EAR。 实际上,您也可以将其放置在WebApp应用程序中,方法是将其放置在存档的WEB-INF文件夹中。 但是,它仅适用于顶级归档。 因此,如果将jboss-deployment-structure.xml放在WAR的WEB-INF文件夹中,并且将WAR打包在EAR归档中,则将忽略jboss-deployment-structure.xml。

该文件的相关部分是sub-deployment元素,该元素引用Web应用程序(包括其中的依赖项)。 预期的结果是应用程序服务器将触发对log4j Api的依赖关系,因此我们的Web应用程序将看到该依赖关系。

排除服务器自动依赖项

在本章的前面,我们已经展示了当满足某些条件时,应用程序服务器如何能够自动触发某些依赖关系。 例如,如果部署JSF应用程序(包含faces-config.xml文件),那么将自动添加JSF 2.1 Api实现。

例如,这可能并不总是所需的选项,因为您要为该模块提供另一个发行版实现。 您可以使用jboss-deployment-structure.xml中的排除部分轻松实现此目标,如下所示:

<jboss-deployment-structure><deployment><exclusions><module name="javax.faces.api" /><module name="com.sun.jsf-impl" /></exclusions> <dependencies><module name="javax.faces.api" slot="1.2"/> <module name="com.sun.jsf-impl" slot="1.2"/></dependencies> </deployment>
</jboss-deployment-structure>

注意,在“依赖项”部分中,我们添加了备用JSF 1.2实现,您的应用程序将使用该实现。 实际上,此JSF实现随slot属性指定的文件夹下的应用程序服务器分发以及javax.faces.api模块路径一起提供。 在我们的例子中,这对应于JBOSS_HOME / modules / javax / faces / api / 1.2文件夹。

隔离子部署

假设您有一个由Web应用程序,EJB模块和包含实用程序类的JAR文件组成的应用程序。 所有子部署均位于存档的根目录,因此它们将能够彼此看到。 但是,假设您的Web应用程序自身包含相同EJB的某些实现,这可能会很方便。 这是绝对可能的,因为Java EE 6规范允许您的Web应用程序在WEB-INF / classes或WEB-INF / lib文件夹中包括EJB类。

类加载器如何解决此冲突? 加载用于避免已加载类之间的任何冲突的类时,应用程序服务器类加载器具有优先级列表。

  • 容器(包括Java EE API)自动将模块的最大优先级赋予模块。 包含在modules文件夹中的库在此类别中。
  • 然后,用户在打包档案的MANIFEST.MF中将其指示为Dependencies(或在jboss-deployment-structure.xml文件中)。
  • 接下来,打包在应用程序内部的库,例如WEB-INF / lib或WEB-INF / classs中包含的类。
  • 最后,打包在同一EAR归档文件中的库(在EAR的lib文件夹中)。

因此,在此示例中,位于WEB-INF文件夹中的EJB库将“隐藏” EJB.jar顶级部署的实现。 无论这是否是容器中所需的操作,您仍然可以覆盖它:

<jboss-deployment-structure> <ear-subdeployments-isolated>false</ear-subdeployments-isolated> <sub-deployment name="WebApp.war"><dependencies><module name="deployment.App.ear.EJB.jar" />   </dependencies></sub-deployment>
</jboss-deployment-structure>

在此示例中,我们向EJB.jar添加了一个依赖关系,该依赖关系位于存档的根目录,它将覆盖Web应用程序中打包的实现。

请注意, ear-subdeployments-isolated元素位于文件顶部。 通过设置EAR隔离级别,您将能够指示子部署模块是否彼此可见。

此属性的默认值为false ,这意味着子部署模块将能够看到彼此。 如果将隔离设置为true,则每个模块将由不同的类加载器接收,因此,在我们的示例中,Web应用程序将无法找到EJB.jarUtility.jar库中包含的类。

如果要使部署保持隔离状态,但允许其中一些可见,则可以选择以下几种方法:

  • 将库移至EAR / lib文件夹,以便将其作为单独的模块使用
  • 使用依赖关系或调用应用程序的MANIFEST.MF文件中的类路径指定依赖关系

从以下屏幕截图中,您可以看到如何通过将公共库放置在lib文件夹中并向EJB类添加依赖项来正确设置EAR:

这是jboss-deployment-structure.xm l中所需的相应配置:

<jboss-deployment-structure> <ear-subdeployments-isolated>true</ear-subdeployments-isolated>      <sub-deployment name="WebApp.war"><dependencies><module name="deployment.App.ear.EJB.jar" /> </dependencies></sub-deployment>
</jboss-deployment-structure>

可以使用共享库中的打包库,因为Java EE 5通常用于保存EAR的所有模块所使用的JAR文件。

共享库的默认名称是lib,但是您可以随时使用META-INF / application.xml文件中的library-directory元素覆盖它。 例如,假设您要使用公用文件夹来保存共享库,则可以将其添加到application.xml中

<library-directory>common</library-directory>

作为附带说明,我们建议您避免在共享文件夹中放置声明组件的注释(例如EJB3),因为它可能对部署过程产生意想不到的不良后果。 因此,我们强烈建议您仅将实用程序类放在共享库文件夹中。

使用类路径声明解决依赖关系:

到目前为止,我们已经使用JBoss的方法解决了模块之间的依赖关系,我们显然建议将其作为首选。 尽管如此,我们也应该考虑Java引用EAR文件中包含的一个或多个库的可移植方式。

可以使用模块的MANIFEST.MF文件中的Class-Path属性来完成此操作,该属性需要引用另一个应用程序无法看到的库(请看前面的示例,带有隔离集的部署单元)为true )。

例如,假设您需要从Web应用程序中引用Utility.jar应用程序,然后只需将以下内容添加到META-INF / MANIFEST.MF中:

  • 清单版本:1.0
  • 类路径:Utility.jar

实际上,您可以在Class-Path中包含多个库,并以逗号分隔它们,这与使用JBoss的Dependencies属性的方式非常相似。 与Dependencies属性不同,Class-Path属性指向引用依赖库的实际JAR文件名(而不是模块名)。

在类路径方法和JBoss的Dependencies方法之间进行选择,取决于应用程序的结构:通过使用JBoss的Dependencies,您可以购买到更多的选项,尤其是将Dependencies导出到其他部署的能力。较早。 支持JBoss的Dependencies方法的另一点是引用模块的能力,这些模块实际上并未打包在应用程序中。 例如,我们已经了解了如何向服务器分发的一部分log4j Api添加依赖项。

另一方面,类路径方法的主要优点取决于应用程序的可移植性。 因此,如果您将全便携式解决方案作为优先事项,则可以考虑切换到Class-Path清单属性。

这是示例章节,摘自Francesco Marchioni编辑的JBoss AS 7 Configuration Deployment and Administration一书,该书正在运行一个名为mastertheboss.com的JBoss门户。


翻译自: https://www.javacodegeeks.com/2012/09/jboss-as-7-classloading-explained.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/371416.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打印机 共享 问题

1 用户提报无法打印&#xff0c;经查被共享打印机无法联网&#xff0c;先检查网线是否正常&#xff08;换其他电脑是否能行&#xff09;&#xff0c;再检查交换机是否正常&#xff0c;经查交换机需要重启&#xff0c;然后解决问题。 2 被共享机器为32位操作系统&#xff0c;其余…

CoordinatorLayout 中ToolBar遮挡RecyclerView的内容

解决方法:在RecyclerView中添加 app:layout_behavior"string/appbar_scrolling_view_behavior"参考资料:http://stackoverflow.com/questions/32855889/content-behind-coordinatorlayout-appbarlayout 转载于:https://www.cnblogs.com/niluogege/p/6511094.html

兵团职称计算机准考证查询,兵团初级会计准考证打印入口官网

兵团初级会计准考证打印入口官网为财政部会计资格评价中心网(http://kzp.mof.gov.cn)。准考证打印时间在4月16日前公布&#xff0c;考生需要在规定时间登录财政部会计资格评价中心网(http://kzp.mof.gov.cn)下载并打印准考证。未在上述时限内下载打印准考证的&#xff0c;视作放…

用于集成测试的Maven Cargo插件

在项目生命周期中&#xff0c;非常普遍的需求是设置集成测试。 幸运的是&#xff0c;Maven具有针对此确切方案的内置支持&#xff0c;具有默认构建生命周期的以下阶段&#xff08;来自Maven 文档 &#xff09;&#xff1a; 集成前测试 &#xff1a; 执行集成测试之前所需的操作…

jquery-文档操作

1.text() 设置或返回元素的text值 <div id"divname">old text</div> $(#divname).text("new text"); 将改变显示的old为new [1] 参考w3scholl文档操作 转载于:https://www.cnblogs.com/hellokittyblog/p/9128397.html

bzoj 4259: 残缺的字符串

这题好神啊&#xff0c;居然是fft&#xff0c;表示一直在往数据结构上想。 把*当成0&#xff0c;那么两个串可以匹配当且仅当$$\sum (a[i]-b[i])^2\times a[i]\times b[i]0$$ 我们可以把平方拆开&#xff0c;然后就变成了几个乘积相加的形式&#xff0c;那就大力翻转一个串然后…

录屏时计算机休眠,硬盘录像机里硬盘提示休眠,什么意思?

休眠&#xff0c;电脑内存中的数据写入硬盘&#xff0c;关闭电脑。重新启动的时候重新将数据加载到内存中&#xff0c;恢复休眠前状态。睡眠&#xff0c;和休眠一个意思&#xff0c;98系统下叫睡眠。xp系统叫休眠。98系统睡眠时&#xff0c;内存数据写入虚拟内存&#xff0c;xp…

MySQL数据库的基本操作

-- 连接mysql 数据库(前提是配置好MySQL数据库的环境变量&#xff0c;加入path)mysql -uroot -p -- 设置文本的输入输出编码&#xff1a;cmd 使用的是gbk&#xff0c;不然显示乱码set names gbk; -- 创建数据库create database mydatabase charset utf8; -- 创建用户 user001cr…

使用NoSQL实施实体服务–第5部分:使用云提高自治性

在先前的文章中&#xff0c;我讨论了如何通过结合使用Java Web Services &#xff0c; Java EE和CouchDB NoSQL数据库为产品构建SOA“实体”服务。 在本系列的最后一篇文章中&#xff0c;我将利用我已经创建的一些技术资产&#xff0c;并使用一些流行的SOA模式实现一些新的用户…

乐高计算机发展史教程,【乐高产品发展史特别篇】乐高恐龙发展史

—— 写在前面 ——2018年6月22日&#xff0c;《侏罗纪世界2&#xff1a;失落王国》全球上映&#xff1b;4月16日&#xff0c;乐高同名系列套装全球发售。恐龙是一个伴随了乐高产品二十余年的主题&#xff0c;其实在一年以前就有这样一个计划完成乐高恐龙发展史的相关内容&…

mvc 连接数据库但单复值得问题

1. The model backing the ‘MusicStoreDBContext‘ context has changed since the database was created. Consider using Code First Migrations to update the database Movie这个表是用来记录Model的版本号的&#xff0c;你每次重新生成一次数据库它就会重新给ModelHash…

Mybatis处理表关联(懒加载)

1.关系型数据库&#xff1f; 数据库中的表对象之间是有关系的。 一对一&#xff0c;一对多&#xff0c;多对多。 ORM映射。数据库表映射到实体对象。 实体与实体之间是有关系的。 一对多的关系。 比如商品分类表与商品表之间的关系&#xff0c;就是一对多的关系。 入库主表与入…

Spring–设计领域模型和服务层

我们将为时间表管理构建应用程序。 因此&#xff0c;让我们首先考虑一些用例和实体。 让我用几个项目符号写它们&#xff1a; 任务由经理分配给员工。 一项任务可以分配给许多员工。 员工将他在某些任务上工作的小时数填满至系统。 经理/员工查看时间表上的报告&#xff08;时…

如何把很多照片拼成一张照片_一张现场照片引发的中韩之争

来源&#xff1a;渤海新水手聊船专栏前几天&#xff0c;微信群里(造船质量技术高级交流群)一位网友发了一张韩国船厂的现场照片&#xff0c;没想到瞬间引发全群几十位网友的热烈讨论&#xff0c;中韩之争就此上演&#xff01;照片反映出的是国内船厂很难做到的部分——分段预装…

计算机文档设置,电脑这样设置快速的共享文件、分享文档!

原标题&#xff1a;电脑这样设置快速的共享文件、分享文档&#xff01;在日常办公的时候&#xff0c;有时需要共同使用一些文件或者文档或者一些视频资料。那么要怎么方便的使用这些共同的资源呢&#xff1f;当然这时大家可能会说可以用QQ、微信传给对方不就可以了。但是如果文…

关于vue 框架与后台框架的混合使用的尝试

这几天我在研究前台框架和后台框架融合的问题,进行了一些尝试; 我前台选择的是 vue,当然也可以选择 react 等其他 mvvm 框架,不过 vue 对于我来说是最熟悉的; 后台话,我选择的是 php 的 lumen 框架,他是laravel 的简化版,因为比较轻量,所以这也是我的选择; 先说下我这边的环境:…

GitHub上整理的一些工具

GitHub上整理的一些工具 GitHub 2015-11-19 10:10:47 发布您的评价: 0.0 收藏 5收藏技术站点 Hacker News&#xff1a;非常棒的针对编程的链接聚合网站Programming reddit&#xff1a;同上MSDN&#xff1a;微软相关的官方技术集中地&#xff0c;主要是文档类infoq&#x…

服务器 raid 1t硬盘吗,用了4块1T的硬盘,做了raid5,显示有2.7T,但是分区做完系统后,有700多G不能动...

满意答案ouourpt892013.11.14采纳率&#xff1a;46% 等级&#xff1a;12已帮助&#xff1a;13583人出现这种情况是由于创建的硬盘使用的是基本磁盘(MBR)格式&#xff0c;因受MBR磁盘格式技术的限制&#xff0c;MBR磁盘只支持2TB的磁盘容量&#xff0c;所以出现了你所说的情况…

如何编写更好的POJO服务

在Java中&#xff0c;您可以轻松地在Plain Old Java Object&#xff08;POJO&#xff09;类中实现一些业务逻辑&#xff0c;并且可以在高级服务器或框架中轻松运行它们。 有许多服务器/框架&#xff0c;例如JBossAS&#xff0c;Spring或Camel等&#xff0c;它们使您可以部署POJ…

mongo 唯一约束索引_快速掌握mongoDB(三)——mongoDB的索引详解

1 mongoDB索引的管理本节介绍mongoDB中的索引&#xff0c;熟悉mysql/sqlserver等关系型数据库的小伙伴应该都知道索引对优化数据查询的重要性。我们先简单了解一下索引&#xff1a;索引的本质就是一个排序的列表&#xff0c;在这个列表中存储着索引的值和包含这个值的数据(数据…