类加载器 jboss_JBoss AS 7类加载说明
類加載器 jboss
這是示例章節(jié),摘自Francesco Marchioni編輯的JBoss AS 7 Configuration Deployment and Administration一書,該書正在運行一個名為mastertheboss.com的JBoss門戶。根據(jù)Java EE規(guī)范的要求,理想情況下,應(yīng)用程序服務(wù)器應(yīng)為其部署的應(yīng)用程序提供使用任何實用程序庫和任何版本的自由,而不必考慮要使用同一庫的并發(fā)應(yīng)用程序的存在。
這也稱為名稱空間隔離(Java EE 5規(guī)范,EE.8.4節(jié))。 但是,從不同名稱空間加載類可能會引起一些不易解決的問題:例如,如果我在應(yīng)用程序中打包了新版本的實用程序庫,而應(yīng)用程序加載了同一個庫的舊版本,將會發(fā)生什么情況?服務(wù)器? 或者,如何在應(yīng)用程序服務(wù)器的同一實例中同時使用同一實用程序庫的兩個不同版本? 多年來,JBoss AS類加載策略已經(jīng)發(fā)生了明智的變化:基本上,應(yīng)用服務(wù)器的4.x版本使用UnifiedClassLoader ,其目的是減少運行的應(yīng)用程序之間的通信開銷,因為類數(shù)據(jù)可以通過引用或簡單副本共享。
使用UnifiedClassLoader無法解決的主要未解決問題之一是類加載依賴項。 這樣的想法是,如果一個應(yīng)用程序(A)使用另一個應(yīng)用程序(B)的類,則系統(tǒng)應(yīng)該知道在重新部署B(yǎng)時重新部署A,否則它將引用陳舊的類。 實際上,有兩種嘗試來使這項工作有效,而無需用戶進行任何配置。 兩種嘗試均未奏效,但均被放棄。 自從引入JBoss AS 5.0以來,一個基于新虛擬文件系統(tǒng)(VFS)的新類加載器。 實施VFS是為了簡化和統(tǒng)一應(yīng)用程序服務(wù)器中的文件處理。 新的類加載器名為VFS類加載器,它使用VFS查找JAR和類文件。 即使這表示在JBoss AS 5.0中如何加載類,已經(jīng)發(fā)生了重大變化,但是產(chǎn)生的行為與JBoss AS的先前版本非常相似。
錯誤的常見來源是在部署中包括由容器提供的API類。 這可能會導(dǎo)致創(chuàng)建該類的多個版本,并且部署無法正確部署。 AS7中的類加載標志著與以前的嘗試完全不同。 現(xiàn)在,類加載基于JBoss模塊項目,并且所部署的任何應(yīng)用程序?qū)嶋H上都是模塊。 肯定的讀者會提出一些疑問:分配給已部署應(yīng)用程序的模塊名稱是什么? 而且,AS如何處理模塊之間的依賴關(guān)系? 讓我們在單獨的部分中回答每個問題:
了解模塊名稱
了解模塊名稱不是學術(shù)活動。 事實上,我們可以在模塊之間建立依賴關(guān)系,因此在許多情況下,需要知道分配給應(yīng)用程序的模塊名稱是哪個。 因此,打包為頂級歸檔文件(例如WAR,JAR和SAR)的應(yīng)用程序?qū)@得以下模塊名稱:
deployment.[archive name]例如,將部署一個名為WebExample1.war的Web應(yīng)用程序作為模塊名稱:
deployment.WebExample1.war另一方面,在包含嵌套模塊的應(yīng)用程序(例如EAR歸檔文件)上,將使用以下分類為每個單個歸檔文件分配模塊名稱:
deployment.[ear archive name].[sub deployment archive name]因此,如果將相同的Web應(yīng)用程序包含在存檔EnterpriseApp.ear中 ,則將使用以下名稱進行部署:
deployment.EnterpriseApp.ear.WebExample1.war查找隔離級別
在第2章,配置應(yīng)用程序服務(wù)中 ,我們有意部署了一個使用log4j Api的應(yīng)用程序,將log4j庫添加到WEB-INF / lib文件夾中。 該應(yīng)用程序的部署很順利,省去了一個問題:為什么我們需要添加已經(jīng)作為模塊包含在應(yīng)用程序服務(wù)器中的庫? (在我們的例子中,在modules \ org \ apache \ log4j \ main路徑中)。
一般規(guī)則是,在JBoss AS 7上,每個已部署的應(yīng)用程序模塊都與其他模塊隔離開來。 這意味著,默認情況下,它在AS模塊上不可見,而AS模塊在應(yīng)用程序上也不可見。
但是,使用應(yīng)用程序服務(wù)器模塊非常容易,并且可以用一句話來概括:將依賴項添加到所需模塊中,AS就會使用它。 應(yīng)用程序服務(wù)器會自動添加依賴項,或者它們需要由用戶發(fā)出信號:
- 核心模塊庫(即Enterprise類)被視為隱式依賴項,因此當部署者檢測到它們的使用時,它們會自動添加到您的應(yīng)用程序中
- 用戶需要在應(yīng)用程序的MANIFEST文件或自定義的JBoss部署文件jboss-deployment-structure.xm l中明確聲明其他模塊庫(有關(guān)更多信息,請參見“高級部署策略”部分)。
隱式依賴:
指出企業(yè)應(yīng)用程序通常使用的Api依賴項可能很麻煩。 因此,正如我們預(yù)期的那樣,應(yīng)用程序服務(wù)器會自動為您添加它們。 當應(yīng)用服務(wù)器檢測到某些該模塊的典型注釋或配置文件時,將添加一些注釋或配置文件。 例如,添加beans.xml文件會觸發(fā)自動焊接依賴關(guān)系。
以下思維導(dǎo)圖顯示了隱式添加到應(yīng)用程序中的模塊的綜合視圖:
該圖像的含義很簡單:如果您的應(yīng)用程序使用了所示的任何核心模塊,那么您無需指定任何依賴項,因為應(yīng)用程序服務(wù)器能夠自動鏈接該模塊。 顯式依賴項不能由隱式依賴項限定的模塊需要由用戶聲明。 在最初的示例中,未將log4j庫作為隱式依賴項提及,因此我們不得不將log4j JAR與我們的應(yīng)用程序打包在一起。 但是,我們可以指示部署者使用log4j庫,該庫捆綁在應(yīng)用程序服務(wù)器分發(fā)中。 實現(xiàn)它的最簡單且推薦的方法是在META-INF / MANIFEST.MF中包括Dependencies:[module]聲明。 在我們的情況下,要使您的應(yīng)用程序依賴于log4j,只需在清單文件中包含以下代碼:
依賴項:org.apache.log4j
請注意,模塊名稱并不總是與庫的軟件包名稱匹配。 實際的模塊名稱由module元素的name屬性在module.xml文件中指定。
用戶通常將使用Eclipse(或任何其他IDE)來更新清單文件,而無需執(zhí)行任何繁瑣的存檔更新:
您不限于單個依賴項,因為您可以添加多個用逗號分隔的依賴項。 例如,為了同時添加對log4j和Apache Velocity Api的依賴,可以使用以下命令:
依賴項:org.apache.log4j,org.apache.velocity
您甚至可以通過添加export關(guān)鍵字將一個應(yīng)用程序模塊使用的依賴項導(dǎo)出到其他應(yīng)用程序。 例如,在較早的應(yīng)用程序中,我們現(xiàn)在將依賴項導(dǎo)出到其他模塊:
標記為依賴于Deployment.WebApp.war模塊的應(yīng)用程序還將有權(quán)訪問其依賴項:
export參數(shù)還可以用于將依賴項導(dǎo)出到耳朵中包含的所有子部署。 因此,如果從耳朵的頂層(或通過ear / lib目錄中的jar)導(dǎo)出依賴關(guān)系,則該依賴關(guān)系也將對所有子部署單元可用。
在META-INF / MANIFEST.MF中,您還可以指定其他命令,這些命令可以修改服務(wù)器部署程序的行為。 例如,可以添加可選屬性,以指定如果在部署時未找到模塊,則部署不會失敗。
最后,當指定了services關(guān)鍵字時,部署者將嘗試加載放置在歸檔文件的META-INF / services中的服務(wù)。
服務(wù)Api已在Java SE 6中公開。服務(wù)可以定義為一組編程接口和類,它們提供對某些特定應(yīng)用程序功能或特性的訪問。 服務(wù)提供者接口(SPI)是服務(wù)定義的一組公共接口和抽象類。
您可以通過實現(xiàn)服務(wù)提供商API來定義服務(wù)提供商。 通常,您將創(chuàng)建一個JAR文件來保存您的提供程序。 要注冊您的提供程序,您必須在JAR文件的META-INF / services目錄中創(chuàng)建一個提供程序配置文件。 將services屬性添加到META-INF / MANIFEST.MF時,您實際上將能夠加載META-INF / services目錄中包含的服務(wù)。
有關(guān)SPI Api的出色介紹,請訪問:http://java.sun.com/developer/technicalArticles/javase/extensible。
設(shè)置全局模塊
該選項與用于加載公共庫的舊AS方法有點類似,您曾經(jīng)將它們放置在文件夾JBOSS_HOME / common / lib中。 如果在standalone.xml / domain.xml中定義了名為global-modules的部分,則將使該模塊可被其他AS模塊訪問。 例如,您可以選擇使用以下部分來代替聲明對log4j的依賴關(guān)系:
<subsystem xmlns="urn:jboss:domain:ee:1.0"><global-modules><module name="org.apache.log4j" /></global-modules> </subsystem>盡管通常不建議使用這種方法,但是由于它使我們回到了單片應(yīng)用服務(wù)器的概念,因此它仍然可以帶來一些好處。 例如,如果您要遷移一些較舊的應(yīng)用程序,并且您不希望或者根本無法將依賴關(guān)系指定到存檔中。
進階部署策略
到目前為止,我們所學的知識足以配置多種應(yīng)用程序。 如果您使用的是復(fù)雜的歸檔文件配置,例如具有多個模塊和依賴項的EAR歸檔文件,那么在單個文件中定義類加載策略將很有用。
配置文件jboss-deployment-structure.xml可以做到這一點。 使用此文件的優(yōu)點有很多:
- 您可以在一個文件中定義所有應(yīng)用程序模塊的依賴關(guān)系
- 您可以通過包含/排除所有或部分模塊來使用更精細的方式加載模塊類
- 您可以為打包在企業(yè)歸檔中的應(yīng)用程序定義類加載隔離策略
讓我們看一些實際的例子,jboss-deployment-structure.xml可以為您做些什么。
設(shè)置單個模塊依賴性
我們已經(jīng)學習了如何使用歸檔文件的MANIFEST文件中的Dependencies屬性來激活log4j依賴關(guān)系。 使用jboss-deployment-structure.xml文件可以達到相同的效果。 讓我們回顧一下歸檔結(jié)構(gòu),該結(jié)構(gòu)基本上是由一個名為WebApp.war的Web應(yīng)用程序組成的。
如您所見,文件jboss-deployment-structure.xml需要放置在EAR的META-INF文件夾中。
其內(nèi)容如下:
<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應(yīng)用程序中。 但是,它僅適用于頂級歸檔。 因此,如果將jboss-deployment-structure.xml放在WAR的WEB-INF文件夾中,并且將WAR打包在EAR檔案中,則將忽略jboss-deployment-structure.xml。
該文件的相關(guān)部分是sub-deployment元素,該元素引用Web應(yīng)用程序(包括其中的依賴項)。 預(yù)期的結(jié)果是應(yīng)用程序服務(wù)器將觸發(fā)對log4j Api的依賴關(guān)系,因此我們的Web應(yīng)用程序?qū)⒖吹皆撘蕾囮P(guān)系。
排除服務(wù)器自動依賴項
在本章的前面,我們已經(jīng)展示了當滿足某些條件時,應(yīng)用程序服務(wù)器如何能夠自動觸發(fā)某些依賴關(guān)系。 例如,如果部署JSF應(yīng)用程序(包含faces-config.xml文件),那么將自動添加JSF 2.1 Api實現(xiàn)。
例如,這可能并不總是所需的選項,因為您要為該模塊提供另一個發(fā)行版實現(xiàn)。 您可以使用jboss-deployment-structure.xml中的排除部分輕松實現(xiàn)此目標,如下所示:
<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實現(xiàn),您的應(yīng)用程序?qū)⑹褂迷搶崿F(xiàn)。 實際上,此JSF實現(xiàn)隨slot屬性指定的文件夾下的應(yīng)用程序服務(wù)器分發(fā)以及javax.faces.api模塊路徑一起提供。 在我們的例子中,這對應(yīng)于JBOSS_HOME / modules / javax / faces / api / 1.2文件夾。
隔離子部署
假設(shè)您有一個由Web應(yīng)用程序,EJB模塊和包含實用程序類的JAR文件組成的應(yīng)用程序。 所有子部署均位于存檔的根目錄,因此它們將能夠彼此看到。 但是,假設(shè)您的Web應(yīng)用程序自身包含同一EJB的某些實現(xiàn),這可能會很方便。 這是絕對可能的,因為Java EE 6規(guī)范允許您的Web應(yīng)用程序在WEB-INF / classes或WEB-INF / lib文件夾中包含EJB類。
類加載器如何解決此沖突? 加載用于避免已加載類之間的任何沖突的類時,應(yīng)用程序服務(wù)器類加載器具有優(yōu)先級列表。
- 容器(包括Java EE API)自動為模塊賦予最大優(yōu)先級。 包含在modules文件夾中的庫在此類別中。
- 然后,用戶在打包檔案的MANIFEST.MF中將其表示為Dependencies(或在jboss-deployment-structure.xml文件中)。
- 接下來,打包在應(yīng)用程序內(nèi)部的庫,例如WEB-INF / lib或WEB-INF / classs中包含的類。
- 最后,打包在同一EAR歸檔文件中的庫(在EAR的lib文件夾中)。
因此,在此示例中,位于WEB-INF文件夾中的EJB庫將“隱藏” EJB.jar頂級部署的實現(xiàn)。 無論這是否是容器中所需的操作,您仍然可以覆蓋它:
<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添加了一個依賴關(guān)系,該依賴關(guān)系位于存檔的根目錄下,它將覆蓋Web應(yīng)用程序中打包的實現(xiàn)。
請注意, ear-subdeployments-isolated元素位于文件頂部。 通過設(shè)置EAR隔離級別,您將能夠指示子部署模塊是否彼此可見。
此屬性的默認值為false ,這意味著子部署模塊將能夠看到彼此。 如果將隔離設(shè)置為true,則每個模塊將由不同的類加載器接收,因此,在我們的示例中,Web應(yīng)用程序?qū)o法找到EJB.jar和Utility.jar庫中包含的類。
如果要使部署保持隔離狀態(tài),但允許其中一些可見,則可以選擇以下幾種方法:
- 將庫移至EAR / lib文件夾,以便將其作為單獨的模塊使用
- 使用依賴關(guān)系或調(diào)用應(yīng)用程序的MANIFEST.MF文件中的類路徑指定依賴關(guān)系
從以下屏幕截圖中,您可以看到如何通過將公用庫放在lib文件夾中并向EJB類添加依賴項來正確設(shè)置EAR:
這是jboss-deployment-structure.xm l中所需的相應(yīng)配置:
<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元素覆蓋它。 例如,假設(shè)您想使用公用文件夾來保存共享庫,則可以將其添加到application.xml中 :
<library-directory>common</library-directory>附帶說明一下,我們建議您避免在共享文件夾中放置聲明組件的注釋(例如EJB3),因為它可能對部署過程產(chǎn)生意想不到的不良后果。 因此,我們強烈建議您僅將實用程序類放在共享庫文件夾中。
使用類路徑聲明來解決依賴關(guān)系:
到目前為止,我們已經(jīng)使用JBoss的方法解決了模塊之間的依賴關(guān)系,我們顯然建議將其作為首選。 盡管如此,我們還應(yīng)該考慮Java引用EAR文件中包含的一個或多個庫的可移植方式。
可以使用模塊的MANIFEST.MF文件中的Class-Path屬性來完成此操作,該屬性需要引用其他應(yīng)用程序無法看到的其他庫(考慮到前面的示例,帶有隔離集的部署單元為true )。
例如,假設(shè)您需要從Web應(yīng)用程序中引用Utility.jar應(yīng)用程序,然后只需將以下內(nèi)容添加到META-INF / MANIFEST.MF中:
- 清單版本:1.0
- 類路徑:Utility.jar
實際上,您可以在類路徑中包含多個庫,并以逗號分隔它們,這與使用JBoss的Dependencies屬性的方式幾乎相同。 與Dependencies屬性不同,Class-Path屬性指向引用依賴庫的實際JAR文件名(而不是模塊名)。
在類路徑方法和JBoss的Dependencies方法之間進行選擇取決于應(yīng)用程序的結(jié)構(gòu):通過使用JBoss的Dependencies,您可以購買到更多的選項,尤其是將Dependencies導(dǎo)出到其他部署的能力。較早。 支持JBoss的Dependencies方法的另一點是引用模塊的能力,這些模塊實際上并未打包在應(yīng)用程序中。 例如,我們已經(jīng)看到了如何向服務(wù)器分發(fā)中的log4j Api添加依賴項。
另一方面,類路徑方法的主要優(yōu)點取決于應(yīng)用程序的可移植性。 因此,如果您將全便攜式解決方案作為優(yōu)先事項,則可以考慮切換到Class-Path清單屬性。
這是示例章節(jié),摘自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
總結(jié)
以上是生活随笔為你收集整理的类加载器 jboss_JBoss AS 7类加载说明的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 淘宝电脑客户端登录不上去(淘宝电脑客户端
- 下一篇: OPPO 与索尼合作推出新一代 LYTI