类加载器 jboss

这是示例章节,摘自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就会使用它。 应用程序服务器会自动添加依赖项,或者它们需要由用户发出信号:

  • 核心模块库(即Enterprise类)被视为隐式依赖项,因此当部署者检测到它们的使用时,它们会自动添加到您的应用程序中
  • 用户需要在应用程序的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。 实际上,您也可以通过将其放置在存档的WEB-INF文件夹中,将其部署在WebApp应用程序中。 但是,它仅适用于顶级归档。 因此,如果将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

实际上,您可以在类路径中包含多个库,并以逗号分隔它们,这与使用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

类加载器 jboss

类加载器 jboss_JBoss AS 7类加载说明相关推荐

  1. java 扩展类加载器_java实现自定义类加载器

    各类加载器虽然以父子相称,但是没有继承关系 (视频教程推荐:java课程) 点入ClassLoader的源码查看样例:* * class NetworkClassLoader extends Clas ...

  2. 1.类加载:什么是类加载???什么是类加载器???类加载器有哪三种类型???如何获取类加载器???

    1.类加载:什么是类加载???什么是类加载器???类加载器有哪三种类型???如何获取类加载器??? 学习:第7遍 1.什么是类加载??? 将class文件读取到内存中的过程,称为类加载 2.什么是类加 ...

  3. 类加载器系列一:类加载器有几种以及它们之间的关系?

    大家好,我是骄阳. 今天我们聊一下类加载器. 一.类加载器的种类 1.引导类加载器 负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar.charsets.jar等 思考一下: ...

  4. OSGi 规范和框架 OSGi框架类加载机制 Java默认类加载器机制和OSGI类加载器机制比较

    一.OSGi 规范 OSGi(Open Service Gateway Initiative) 技术是 Java 动态化模块化系统的一系列规范.OSGi 一方面指维护 OSGi 规范的 OSGi Al ...

  5. java的类加载器以及如何自定义类加载器

    ClassLoader作用 类加载流程的"加载"阶段是由类加载器完成的. 类加载器结构 结构:BootstrapClassLoader(祖父)–>ExtClassLoader ...

  6. java类加载器 架构 设计_类加载器(DexClassLoader)与插件化(动态加载)

    类加载器与插件化解析 2.1 类装载器 DexClassLoader 首先,我们需要了解关于java代码本地import的一些知识: import中所引用的类有两个特点: 1.必须存在于本地,当程序运 ...

  7. java 获取类加载器_java-如何从类加载器获取类路径?

    更新:我下面的原始答案很不充分,因为我花了三年的时间开发FastClasspathScanner,并提交了大量关于某些类路径环境无法使用该库的错误报告. FastClasspathScanner现在可 ...

  8. java基础类加载器_Java基础之类加载器

    1. 什么是类加载器? 加载类的工具. 2. Java虚拟机中可以安装多个类加载器,系统默认三个主要的类加载器,每个类负责加载特定位置的类: BootStrap,ExtClassLoader,AppC ...

  9. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

最新文章

  1. network-manager
  2. JS中setTimeout()的使用方法具体解释
  3. Pgcli—自动完成和语法高亮的Postgres命令行工具
  4. linux mysql 5.7.20_linux MySQL 5.7.20安装教程
  5. 敏捷开发流程的8个步骤_敏捷开发——个体和互动高于流程和工具
  6. (转)Spring Boot(六):如何优雅的使用 Mybatis
  7. linux g 链接,图解linux系统的软连接和硬链接
  8. java ajax cookies_HttpOnly cookie如何处理AJAX请求?
  9. Linux 进程间通信的六种机制
  10. 【微信小程序】自己的小程序跳转到京东小程序商品详情页
  11. 电子凸轮设计之数学基础设计
  12. 不为环境所动就能成功——职场人士寓言(3)
  13. VisualEffectGraph概述
  14. mysql中rand的用法_MySQL RAND()用法及代码示例
  15. CAD 二次开发 图层操作(1)创建图层
  16. Qt笔记11:qt如何设置应用程序图标和可执行程序图标
  17. 证券业上云内参: 深圳证券信息
  18. eset找不到服务器更新失败,eset nod32无法更新的解决办法-整理常见的nod32更新问题!...
  19. java p2p技术内幕.pdf_JavaP2P技术内幕 PDF
  20. 优维科技应用CMDB在招商基金的案例分享

热门文章

  1. Java IO: Reader和Writer
  2. Java 正则表达式匹配模式[贪婪型、勉强型、占有型]
  3. 面象对象设计6大原则之三:里氏替换原则
  4. Java多线程神器:join使用及原理
  5. C/C++输入输出流
  6. 越努力越幸运,三年了!!!
  7. 2020蓝桥杯省赛---java---B---8(数字三角形)
  8. 时间格式转换2020-04-09T23:00:00.000+08:00
  9. IDEA导入Maven项目,pom.xml文件中 有inspects a maven model for resolution problems报错 !!!!!!!!!!有用
  10. python数据分析架构_Python数据分析