|
Page Edited :
SM :
Classloaders
Classloaders has been edited by Torsten Mielke (Jun 04, 2008). Change summary: distinguish self-first configuration for shared libraries and service units ClassloadersThere are several classloaders involved in ServiceMix:
The container class loader contains: JRE + /conf + /lib/*.jar + /lib/optional/*.jar. ServiceMix 3.1, uses Classworlds The components class loaders are defined in the JBI spec and contain the jars referenced in the JBI descriptor (META-INF/jbi.xml). These class loaders can use a parent-first (default) or self-first delegation. When a class is loaded, the class loader will first ask its parent(s) and work back down the classloader hierarchy, or will first load the class from its referenced jars. The service unit class loader is not specified in the JBI spec, because the SU content is specific to each component. In ServiceMix, all XBean based SUs may define their own classloader using the <classpath /> location (though since ServiceMix 3.1 this is no longer necessary, see the last section below). Let's say you deploy a POJO to the servicemix-lwcontainer. When building the configuration, for XBean to find the class, it will ask the SU classloader to do so. So the component may be inside this classloader, or one of its parent (servicemix-lwcontainer, servicemix-shared and the container classloader). However, the component and SL classloaders are not easily modified (you need to repackage the artifact and redeploy it), so you can put this class in the SU or the container. If you put this class in the container, you will need to restart the container after having added the jar in the classpath, which is not what we want. So usually, we put it in the SU. The other benefit of using classloaders is that you can have isolated components. You could deploy two components (or SU) which use different version of the same library without any problems. This is not possible if you put all the dependencies in the container classpath. Self-first delegationThe common delegation mechanism for classloaders is to delegate to the parent first when loading a class. Thus, all classes defined in the container classloader are shared. But when a class references another class (using an import statement in the Java code for example), the referenced classes will be loaded by the same classloader. To avoid such problems, you can use a self-first delegation where classes are loaded from the classloader, and if not found, it will ask its parent. Shared libraries and SMX componentsTo enable self-first delegation for shared libraries and components change the service's POM.XML to include <build> <plugins> <plugin> <groupId>org.apache.servicemix.tooling</groupId> <artifactId>jbi-maven-plugin</artifactId> <configuration> <classLoaderDelegation>self-first</classLoaderDelegation> </configuration> </plugin> </plugins> </build>
For ServiceMix 3.0.x versions, you need to define the classpath manually, as the default does not include any locations. New in ServiceMix 3.2You can now reference Shared Libraries and Components classloaders using the following syntax: <classpath [inverse="true"]> [<nonOverrideable>xxx</nonOverridable>]* [<hidden>xxx</hidden>]* [<location>xxx</location>]* [<library>xxx</library>]* [<component>xxx</component>]* </classpath> For example to reference the "cxf" shared library and the "servicemix-wsn2005" component in addition to the jars inside the SU, you could write: <classpath> <library>cxf</library> <component>servicemix-wsn2005</component> </classpath> |
Unsubscribe or edit your notifications preferences
