JBOSS ClassLoadingConfiguration

 

 

 

Discussion

By default JBoss (prior to version 3.2) uses a flat class loading model that avoids the need to redundantly include classes in different layers. WAR files would only have the web contents and servlets, EJBs their interfaces, implementations and types, etc. Canonical packaging works correctly with this model.

However, if you have applications that cannot share classes because of version conflicts, then you need to isolate the classes from other deployments. Without isolation, common errors seen are ClassCastException ? , IllegalAccessErrors ? , VerifyErrors ? and in general, strange behavior that changes as new deployments are added and removed.

There are two levels of scoping, isolation from other deployments, and isolation that overrides the loading of JBoss server classes. With nested modules, only the top level file may specify class loader scoping. If you have a .ear file containing other modules, only scoping specified in the .ear 's META-INF/jboss-app.xml is used. This also applies for any other deployment which contains sub-deployments. For example, if a .sar contains a .war deployment, only the .sar META-INF/jboss-service.xml scoping has effect.

 

Specifying Isolation

For .ear files, in your jboss-app.xml , add the following descriptor fragment construct to enabled scoped class loading:

<jboss-app>
  <loader-repository>com.example:archive=unique-archive-name</loader-repository>
</jboss-app>

 

 For .war files, in your jboss-web.xml , the following template applies:

<jboss-web>
	<class-loading>
		<loader-repository> com.example:archive=unique-archive-name </loader-repository>
	</class-loading>
</jboss-web>
  

 

Note: As of at least JBoss 4.2.1, the <class-loading> tag appears to no longer be supported as isolation is ignored. Instead, the following configuration appears to accomplish the same goal:

<jboss-web> 
	<loader-repository> com.example:archive=unique-archive-name </loader-repository> 
</jboss-web> 

 

Interestingly enough, 4.0.5 seems to support both configurations.

 

 

For .sar files, in your jboss-service.xml , the following template applies:

<server>
	<loader-repository> com.example:archive=unique-archive-name </loader-repository>
</server>
 
The <loader-repository> elements must be correctly placed within the respective <jboss-app> , <jboss> and <jboss-web> XML elements. Check the corresponding DTD found in the docs/dtd directory of the distribution for the complete content model.

The com.example:archive=unique-archive-name strings are JMX ObjectName strings. These have no particular significance other than that they must be unique. It might be useful to use the same name as used for the .ear , .war , or .sar file. For example, for a petstore.ear file, use: com.example:loader=petstore.ear as the repository name.

The loader-repository ObjectName will appear in the JMX-Console (http://localhost:8080/jmx-console/ ). This MBean is great for debugging any class-loading issues which might arise. The hierarchical loaders created from the repository wll appear together under the loader-repository domain name, com.example in the example.

 


 

Isolation with Overriding Server Classes

Use the following constructs to enabled scoped class loading with the deployment classes overriding the server classes.

For jboss-app.xml :

 

<jboss-app>
	<loader-repository>
		com.example:archive=unique-archive-name
		<loader-repository-config> java2ParentDelegation=false </loader-repository-config>
	</loader-repository>
</jboss-app> 
 For jboss-web.xml :
<jboss-web>
	<class-loading java2ClassLoadingCompliance="false">
		<loader-repository>
			com.example:archive=unique-archive-name
			<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
		</loader-repository>
	</class-loading>
	...
</jboss-web>
  Note: See comment above regarding web class loader isolation.

For jboss-service.xml :

<server>
	...
	<loader-repository>
		com.example:archive=unique-archive-name
		<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
	</loader-repository>
	...
</server>
 The isolated EAR or WAR repository will load its libraries in this order:

 

  1. WEB-INF/lib (for WARs)
  2. libraries in server/default/lib
  3. tomcat-libraries in server/default/deploy/jbossweb-tomcat50.sar (jboss-3.2.6).

The libraries in server/default/lib get mixed together with jbossweb-tomcat50.sar in no specific order (for details look into the loader-repository in the JMX-console).

 

The Web Container

In jboss-3.2.3, the jbossweb-tomcat41.sar is configured to use a unified class loader as the web application class loader. This is controlled by the UseJBossWebLoader attribute in the jbossweb-tomcat41.sar/META-INF/jboss-service.xml descriptor. The use of a unified class loader means that the classes available in the war inside of the WEB-INF/classes and WEB-INF/lib are incorporated into the default shared class loader repository. This may not be what you want as its contrary to the default servlet 2.3 class loading model and can result in sharing of classes/resources between web applications. You can disable this by setting this attribute to false.

 

The Web Container from 4.0.2

From 4.0.2 JBoss has changed to the Servlet spec classloading model, i.e. it uses the Tomcat classloader. See the related JIRA Task

 

Simplified Configuration from 3.2.4

From JBoss-3.2.4 the EAR deployer provides a simplified version of the isolation. You can configure all your ears to be in isolated classloader spaces using call by value for remote interfaces.

The EARDeployer is configured in conf/jboss-service.xml for versions 3.x and in deploy/ear-deployer.xml for versions 4.x+

 

<!-- EAR deployer, remove if you are not using Web layers -->
<mbean code="org.jboss.deployment.EARDeployer" name="jboss.j2ee:service=EARDeployer">
	<!-- Isolate all ears in their own classloader space -->
	<attribute name="Isolated">true</attribute>

	<!-- Enforce call by value to all remote interfaces -->
	<attribute name="CallByValue">true</attribute>
</mbean> 
 Accessing EJBs in isolated ears

If you want to make JNDI lookups across EARs that are isolated, you need to force marshalling of the lookup, e.g. if you have the following ejb-ref in your ejb-jar.xml that references an EJB in an isolated WAR

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
	<enterprise-beans>
		<session>
			<ejb-name>SessionA</ejb-name>
			<home>org.jboss.test.isolation.interfaces.a.SessionAHome</home>
			<remote>org.jboss.test.isolation.interfaces.a.SessionA</remote>
			<ejb-class>org.jboss.test.isolation.ejb.a.SessionAEJB</ejb-class>
			<session-type>Stateless</session-type>
			<transaction-type>Container</transaction-type>
			<ejb-ref>
				<ejb-ref-name>ejb/SessionB</ejb-ref-name>
				<ejb-ref-type>Session</ejb-ref-type>
				<home>org.jboss.test.isolation.interfaces.b.SessionBHome</home>
				<remote>org.jboss.test.isolation.interfaces.b.SessionB</remote>
			</ejb-ref>
		</session>
	</enterprise-beans>
</ejb-jar>

 In jboss.xml use the full scheme to define the lookup:

<?xml version="1.0" encoding="UTF-8"?>
<jboss>
	<enterprise-beans>
		<session>
			<ejb-name>SessionA</ejb-name>
			<ejb-ref>
				<ejb-ref-name>ejb/SessionB</ejb-ref-name>
				<jndi-name>jnp://${jboss.bind.address:localhost}:1099/SessionB</jndi-name>
			</ejb-ref>
		</session>
	</enterprise-beans>
</jboss> 

 You can also use the full scheme in lookups from non-EJB clients such as standalone applications or JSP pages. In this case you would be encoding deployment knowledge into the code - the applications will always use call-by-value even if your needs change. If you are retro-fitting classloader isolation you may also have a lot of lookup code to change, although you should probably have used a constant or lookup service to hold the actual name.

An alternative is to force all JNDI lookups to be call-by-value, which you can do in <server>/deploy/naming-service.xml (This used to reference <server>/conf/jboss-service.xml, which is WRONG for 4.0.3) in the section headed JNDI. Change the jboss:service=Naming bean definition so that the CallByValue ? attribute reads:

 

<mbean code="org.jboss.naming.NamingService" name="jboss:service=Naming" xmbean-dd="resource:xmdesc/NamingService-xmbean.xml">
	...
	<attribute name="CallByValue">true</attribute>
	...
</mbean>

 This is indiscriminate - JBoss will be unable to optimise any JNDI calls any more, but may be appropriate in some circumstances.

 

Performance note - Call By Value

The use of call by value and marshalling is very inefficient. It typically means method invocations take 10 times the cpu. Why? Compare Call By Value with Call By Reference

 

Call By Reference
  1. caller does ejb.someMethod()
  2. invocation is passed through ejb container
  3. container does bean.someMethod()
  4. result is returned to the caller

 

Call By Value
  1. caller does ejb.someMethod()
  2. invocation is marshalled - the parameters are turned into ObjectStream ? (a byte[] )
  3. container with a different classloader unmarshalls - byte[] -> java Objects - including classloading
  4. invocation is passed through ejb container
  5. container does bean.someMethod()
  6. result is marshalled - the return value is turned into ObjectStream ?
  7. result is unmarshalled using the caller's classloader - byte[] -> java Object
  8. result is return to the caller

The marshalling and unmarshalling uses a lot of cpu.

 

Related

JBossClassLoadingUseCases
Preloading classes at startup
Debugging class loading issues

 

Referenced by

GetClassNotFoundExceptionOrNoClassDefFoundError
HowCanIDynamicallyLoadClassesWithinAnMBean
JBoss5AndMyFaces
JBossESBDeploymentStrategies
JBossFrequentlyAskedQuestions
Main
RulesTomcat

cant di this in 3.2.7

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值