1. 概念介绍
UCL : org.jboss.mx.loading.UnifiedClassLoader3 ,它继承标准的java.net.URLClassLoader,覆盖了标准parent delegation模型以使用共享class和资源仓库
仓库(responsitory): org.jboss.mx.loading.UnifiedLoaderRepository3。
平面模型:为了热deploy模块的需要,JBoss实现了自己的类装载器UnifiedClassLoader3,一般来说,一个顶层的deployment就有一个UnifiedClassLoader3实例为之工作。一个deployment所装载的类,其他 deployment是可见的。全局唯一的UnifiedLoaderRepository3实例用于管理这些类,以及装载它们的UnifiedClassLoader3。UnifiedLoaderRepository3实例和UnifiedClassLoader3实例是一对多的关系。
2. jboss classloader机制
name="jboss.management.local:j2eeType=J2EEDomain,name=Manager">
<attribute name="MainDeployer">jboss.system:service=MainDeployer</attribute>
<attribute name="SARDeployer">jboss.system:service=ServiceDeployer</attribute>
<attribute name="EARDeployer">jboss.j2ee:service=EARDeployer</attribute>
<attribute name="EJBDeployer">jboss.ejb:service=EJBDeployer</attribute>
<attribute name="RARDeployer">jboss.jca:service=RARDeployer</attribute>
<attribute name="CMDeployer">jboss.jca:service=ConnectionFactoryDeployer</attribute>
<attribute name="WARDeployer">jboss.web:service=WebServer</attribute>
<attribute name="CARDeployer">jboss.j2ee:service=ClientDeployer</attribute>
<attribute name="MailService">jboss:service=Mail</attribute>
<attribute name="JMSService">jboss.mq:service=DestinationManager</attribute>
<attribute name="JNDIService">jboss:service=Naming</attribute>
<attribute name="JTAService">jboss:service=TransactionManager</attribute>
<attribute name="UserTransactionService">jboss:service=ClientUserTransaction</attribute>
<attribute name="RMI_IIOPService">jboss:service=CorbaORB</attribute>
</mbean>
首先看一下各种类型的deployer。不同的deployer是根据文件的后缀进行区分。MainDeployer起到一个controller的作用,根据不用的后缀分发到不同的deployer进行处理。如果是*.ear,则会由EARDeployer进行载入。
应用的加载时一个 Top Level Deployer + Top Level Ucl。 举个例子,比如发布一个a.ear应用,ear应用中会包含一个*.war。这时候就会涉及deployer选择问题。jboss采取的原则就是按Top Level,根据最顶层的应用选择deployer,继而也有了top level ucl的概念。由*的ucl来加载整个应用。这里需要注意的是war的部署有点特别。它只是将自身添加到ucl的classpath域中,而war下的WEB-INF/lib/*.jar,则是由WebAppClassloader来加载。可调整ear下的 META-INF/jboss-service.xml中的UseJbossWebLoader属性。如果设置为true,故名思义就是用ucl来加载war下的jar包。否则就是采用独立的classloader加载。
再看一下ucl的加载过程,首先会调用仓库去loadclass,仓库在查找无果的情况下会回调各自的UCL去加载本地库。
3. jboss scope配置
ClassLoadingConfiguration一书中描述:
意思是说,scope配置只能是*下的配置,比如一个.sar中包含.war都配置了scope,只有.sar下的 META-INF/jboos-service.xml才有效。这也与前面 TOP level UCL + TOP Devloper相对应。
针对.sar,你可以在jboss-service.xml中,添加如下配置:
<loader-repository> com.example:loader=unique-archive-name </loader-repository>
</server>
针对.ear,你可以在jboss-app.xml添加如下配置:
<loader-repository>com.example:loader=unique-archive-name</loader-repository>
</jboss-app>
针对 .war,你可以在jboss-web.xml添加如下配置:
<class-loading java2ClassLoadingCompliance='true'>
<loader-repository>
com.example:loader=unique-archive-name
<loader-repository-config>
java2ParentDelegaton=true
</loader-repository-config>
</loader-repository>
</class-loading>
</jboss-web>
注意,在最新的4.2.1版本中,<class-loading>标签已经不再使用,你可以直接配置:
<loader-repository> com.example:loader=unique-archive-name </loader-repository>
</jboss-web>
针对这两种方式的配置,4.0.5版本都支持。
针对典型的ear+war应用,*.ear/META-INF/jboos-service.xml,用于调整war的加载方式。
loading model should be used over the servlet 2.3 web container first
model.
-->
<attribute name="Java2ClassLoadingCompliance">false</attribute>
<!-- A flag indicating if the JBoss Loader should be used. This loader
uses a unified class loader as the class loader rather than the tomcat
specific class loader.
The default is false to ensure that wars have isolated class loading
for duplicate jars and jsp files.
-->
<attribute name="UseJBossWebLoader">false</attribute>
配置UseJBossWebLoader为false,则webapp的加载通过独立于jboss的classloader进行加载。