Laurent Rieu wrote:
I'm trying to deploy Merlin as an embeded container running in a J2EE environment. For the moment I'm boostrapping the Kernel in the Web tier, passing it the context classloader as both Merlin common loader (urn:merlin:classloader.common) and Merlin system (urn:merlin:classloader.system) loader.
What is the exact role of these two classloaders (common and system) ?
Preparation for the future - i.e. the common load is not actually used except as a parent to the system loader (but read on). The current implementation basically builds a simple classloader hierarchy within which containment and component classes for a given container partition share the same classloader.
Context
|
Common
|
System
| partition
#######################################################
# | #
# EngineClassLoader <-- context classloader for #
# containment & components #
# #
#######################################################
|
|--------|-------|
| |
############ ###########
# # # #
############ ###########The purpose of the common versus system classloader is to provide a separation of "containement" classes from "component" classes.
I should explain what I mean by "containment" versus "component" classes. Containment classes include things like lifecycle extension handlers, custom context handlers, custom appliance implementations, etc. Component classes include things like your component class, the framework interfaces, etc.
The objective is to have something like the following:
Context partition | ################################# | # # Common <----------------# Component context classloader # | # | # ContainmentSPI <---------# Containment classloader # | # # | ################################# | | | |--------|-------| | | | | ############ ########### | # # # # | ############ ########### | Merlin Internal classloader
Where is Merlin looking for component to be deployed ? I mean, if I declare a given component in the block file, where should that component be located ?
A component is represented by the appliance that manages it. Appliances are associated with an appliance repository. Every partition has an appliance repository. Each repository has a parent (except the root). When attempting to locate a component (an action initiated inside the engine), the appliance is resolved relative to the local repository. A collection of all candidate appliance instances is established and passed to an appliance selector for selection. The candidates reflect all potential appliances from the local and all parent repositories.
I guess there are different locations available, but I cannot figure them
out from the documentation. I thought Merlin would scan all available jars
using the different loaders it is given, but this seems to go wrong in a
J2EE context...
Merlin will scan all of the jars, however, there is a restriction concerning URLs to unpacked jar files. This is a restriction in the JVM - the URL classloader implementation will not accept jar files inside jar files (the war case). The workaround it to reference external jar files - or use an alternative repository implementation that creates a cache of packaged jar files). This is why the Merlin repository model is presented as an interface - to enable alternative jar repository strategies.
The real solution to the JVM restriction on emedded jar files is to write your own classloader (which is what tomcat has done).
I had to explicitely declare the extended classpath in the
block.xml file, otherwise the DefaultTypeRepository could not find the
component type. As the block file contains the classname of the component, I
expected Merlin to ba able to load both the component definition and the
class with the classloader it is provided. So what is the exact process when
Merlin tries to populate its type registry with component types, and how
does it relate to the classloaders it is given during bootstrap and the
extended classpath of each container ?
1. each block has a engine classloader
2. the engine has a set of repositories (service, type, profile, appliance)
3. the engine is presented with a set of URLs (via constructor and/or classpath directive)
4. all jars are scanned by an engine for type and service definitions
5. all jars are checked for extension dependencies
6. extension dependencies are also scanned and loaded
7. for every type, the engine loads available packaged profiles
8. if no packaged profile - an implicit profile is created
9. components are created based explicit profiles declared in the block.xml
10. components may be instantiated automatically to service dependencies based on the package and implicit profiles, or explicit profiles declaring in the containment hierarchy (explicit takes priority over packaged takes priority over implicit - unless you define your own profile selector).
Cheers, Steve.
--
Stephen J. McConnell mailto:[EMAIL PROTECTED] http://www.osm.net
Sent via James running under Merlin as an NT service. http://avalon.apache.org/sandbox/merlin
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
