[jboss-cvs] JBossAS SVN: r103002 - in projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook: en-US and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Mar 26 00:11:35 EDT 2010


Author: misty at redhat.com
Date: 2010-03-26 00:11:33 -0400 (Fri, 26 Mar 2010)
New Revision: 103002

Added:
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/AOP_Development.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Appendix.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Author_Group.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Book_Info.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Chapter.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Classloading.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Developing_OSGi_Services.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Development_Framework.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Extending_the_Microcontainer.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Getting_Started.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/JBoss_Microcontainer_2.0.0.GA.ent
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/JBoss_Microcontainer_2.0.0.GA.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Legal_Notice.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Managing_Deployments.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/POJO_Development.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Preface.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/fallback_content/
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/fallback_content/Conventions.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/fallback_content/Feedback.xml
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/images/
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/images/deployOutput.png
   projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/images/tuiMenu.png
Log:
Fixing issues that I created with my local SVN repo


Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/AOP_Development.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/AOP_Development.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/AOP_Development.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,53 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+<part>
+  <title>AOP Development</title>
+  <chapter>
+    <title>Introduction</title>
+    
+    <para>
+      
+    </para>
+
+  </chapter>
+  <chapter>
+    <title>Configuration</title>
+    
+    <para>
+      
+    </para>
+
+  </chapter>
+  <chapter>
+    <title>Using Aspects</title>
+    <section>
+      <title></title>
+      <para>
+	
+      </para>
+    </section>
+
+  </chapter>
+  <chapter>
+    <title>Using Lifecycle Callbacks</title>
+    <section>
+      <title></title>
+      <para>
+	
+      </para>
+    </section>
+
+  </chapter>
+  <chapter>
+    <title>AOP Dependencies</title>
+    <section>
+      <title></title>
+      <para>
+	
+      </para>
+    </section>
+
+  </chapter>
+</part>
\ No newline at end of file

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Appendix.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Appendix.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Appendix.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,23 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+<appendix>
+  <title>Additional Resources</title>
+  <section>
+    <title>Wiki</title>
+    
+    <para>
+      
+    </para>
+
+  </section>
+  <section>
+    <title>Forums</title>
+    
+    <para>
+      
+    </para>
+
+  </section>
+</appendix>

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Author_Group.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Author_Group.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Author_Group.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<authorgroup>
+  <author>
+    <firstname>Mark</firstname>
+    <surname>Newton</surname>
+  </author>
+  <author>
+    <firstname>Aleš</firstname>
+    <surname>Justin</surname>
+  </author>
+  <author>
+    <firstname>Kabir</firstname>
+    <surname>Khan</surname>
+  </author>
+  <author>
+    <firstname>Flavia</firstname>
+    <surname>Rainone</surname>
+  </author>
+  <author>
+    <firstname>Thomas</firstname>
+    <surname>Diesler</surname>
+  </author>
+</authorgroup>

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Book_Info.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Book_Info.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Book_Info.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+
+<bookinfo>
+  <title>JBoss Microcontainer 2.0.0.GA</title>
+  <subtitle>User Guide</subtitle>
+  <productname>Documentation</productname>
+  <productnumber>2</productnumber>
+  <edition>0</edition>
+  <pubsnumber>0</pubsnumber>
+  <issuenum> 2.0</issuenum>
+
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Author_Group.xml" />
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Legal_Notice.xml" />
+</bookinfo>

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Chapter.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Chapter.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Chapter.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<chapter id="chap-testbook-Test_Chapter">
+  <title>Test Chapter</title>
+  <para>
+    This is a test paragraph
+  </para>
+  <section id="sect-testbook-Test_Chapter-Test_Section_1">
+    <title>Test Section 1</title>
+    <para>
+      This is a test paragraph in a section
+    </para>
+  </section>
+  
+  <section id="sect-testbook-Test_Chapter-Test_Section_2">
+    <title>Test Section 2</title>
+    <para>
+      This is a test paragraph in Section 2
+      <orderedlist>
+	<listitem>
+	  <para>
+	    listitem text
+	  </para>
+	</listitem>
+      </orderedlist>
+    </para>
+  </section>
+
+</chapter>

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Classloading.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Classloading.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Classloading.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,16 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+
+<part>
+  <title>Classloading</title>
+  <chapter>
+    <title>Defining Policies</title>
+    
+    <para>
+      
+    </para>
+
+  </chapter>
+</part>

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Developing_OSGi_Services.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Developing_OSGi_Services.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Developing_OSGi_Services.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+<part>
+  <title>Developing OSGi services</title>
+  <chapter>
+    <title></title>
+    
+    <para>
+      
+    </para>
+  </chapter>
+</part>

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Development_Framework.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Development_Framework.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Development_Framework.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,1328 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+
+<part>
+  <title>The Deployment Framework</title>
+  <chapter>
+    <title>Introduction</title>
+    <para>JBoss Microcontainer at its core allows POJOs to be deployed into a runtime environment.
+    It does this using a state machine to ensure that any dependencies on classloaders or other
+    POJOs are satisfied before progressing through the various stages of creation and
+    configuration. By design the state machine and dependency mechanisms are generic which means
+    that we can also use them to deploy other types of runtime components such as MBeans or OSGi
+    bundles. In order to do this we need a generic deployment framework to create the relevant
+    metadata, handle different kinds of deployable components, and deal with any nested
+    deployments.</para>
+    <para>To understand why we cannot achieve this using the BasicXMLDeployer let&apos;s take a
+    closer look at what it actually does:</para>
+    <programlisting role="JAVA">public class BasicXMLDeployer extends BasicKernelDeployer
+    {
+    ...
+
+    public KernelDeployment deploy(final URL url) throws Throwable
+    {
+    final boolean trace = log.isTraceEnabled();
+
+    if (url == null)
+    throw new IllegalArgumentException(&quot;Null url&quot;);
+
+    if (trace)
+    log.trace(&quot;Parsing &quot; + url);
+
+    long start = System.currentTimeMillis();
+    
+    Unmarshaller unmarshaller = factory.newUnmarshaller();
+    KernelDeployment deployment = (KernelDeployment) unmarshaller.unmarshal(url.toString(), resolver);
+
+    if (deployment == null)
+    throw new RuntimeException(&quot;The xml &quot; + url + &quot; is not well formed!&quot;); 
+
+    deployment.setName(url.toString());
+
+    if (trace)
+    {
+    long now = System.currentTimeMillis();
+    log.trace(&quot;Parsing &quot; + url + &quot; took &quot; + (now-start) + &quot; milliseconds&quot;);
+    }
+
+    deploy(deployment);
+
+    if (trace)
+    {
+    long now = System.currentTimeMillis();
+    log.trace(&quot;Deploying &quot; + url + &quot; took &quot; + (now-start) + &quot; milliseconds&quot;);
+    }
+
+    return deployment;
+    }
+
+    ...
+    }</programlisting>
+    <para>Once we call the deploy() method with a URL to the XML deployment descriptor an
+    unmarshaller is created to convert the XML into an object representation of type
+    KernelDeployment. We then process the KernelDeployment using the deploy() method of the
+    superclass BasicKernelDeployer: </para>
+    <programlisting role="JAVA">public class BasicKernelDeployer extends AbstractKernelDeployer
+    {
+    ...
+
+    public void deploy(KernelDeployment deployment) throws Throwable
+    {
+    ...
+    super.deploy(deployment);
+    deployments.add(deployment);
+    ...
+    }
+
+    ...
+
+    public void shutdown()
+    {
+    ListIterator iterator = deployments.listIterator(deployments.size());
+    while (iterator.hasPrevious())
+    {
+    KernelDeployment deployment = (KernelDeployment) iterator.previous();
+    undeploy(deployment);
+    }
+    }
+    }</programlisting>
+    <para>As you can see the BasicKernelDeployer simply calls the deploy() method of its
+    superclass AbstractKernelDeployer before adding the deployment to a list.</para>
+    <note>
+      <para>The reason for having BasicKernelDeployer is that it contains a shutdown() method
+      which undeploys all the deployments in reverse order. This allows the microcontainer to
+      shutdown gracefully.</para>
+    </note>
+    <programlisting role="JAVA">public class AbstractKernelDeployer
+    {
+    ...
+    public void deploy(final KernelDeployment deployment) throws Throwable
+    {
+    if (deployment.isInstalled())
+    throw new IllegalArgumentException(&quot;Already installed &quot; + deployment.getName());
+
+    try
+    {
+    deployBeans(controller, deployment);
+    deployment.setInstalled(true);
+    }
+    catch (Throwable t)
+    {
+    undeploy(deployment);
+    throw t;
+    }
+    }
+
+    ...
+
+    protected void deployBeans(KernelController controller, KernelDeployment deployment) throws Throwable
+    {
+    List&lt;BeanMetaData&gt; beans = deployment.getBeans();
+    if (beans != null)
+    {
+    for (BeanMetaData metaData : beans)
+    {
+    KernelControllerContext context = deployBean(controller, deployment, metaData);
+    deployment.addInstalledContext(context);
+    }
+    }
+    }
+
+    protected KernelControllerContext deployBean(KernelController controller, KernelDeployment deployment, BeanMetaData bean) throws Throwable
+    {
+    KernelControllerContext context = new AbstractKernelControllerContext(null, bean, null);
+    if (requiredState != null)
+    context.setRequiredState(requiredState);
+    if (mode != null)
+    context.setMode(mode);
+    // Use any deployment classloader if present and the bean doesn&apos;t have one
+    ClassLoaderMetaData beanClassLoader = bean.getClassLoader();
+    if (beanClassLoader == null &amp;&amp; deployment != null)
+    {
+    ClassLoaderMetaData deploymentClassLoader = deployment.getClassLoader();
+    if (deploymentClassLoader != null)
+    bean.setClassLoader(deploymentClassLoader);
+    }
+    controller.install(context);
+    return context;
+    }
+
+    ...
+    }</programlisting>
+    <para>The deploy() method in AbstractKernelDeployer performs a check to see if the deployment
+    has already been installed before calling deployBeans() to split it up into the individual
+    BeanMetaData instances. These are then deployed into the runtime environment using the
+    deployBean() method which creates a KernelControllerContext for each BeanMetaData and
+    installs it into the controller. It also takes care of deciding which classloader to use
+    based on information contained in the KernelDeployment object. For example if the bean
+    doesn&apos;t declare a classloader of its own then the deployment classloader (if defined)
+    is used instead.</para>
+    <para>The type hierarchy of BasicXMLDeployer restricts it to processing bean deployments of
+    type KernelDeployment where each bean is represented by an instance of BeanMetaData. If we
+    want to deploy other runtime components such as MBeans or OSGi bundles then we need to deal
+    with other types of metadata and find a generic way to represent deployments containing
+    them. Furthermore we need to find a flexibile way to process these deployments since each
+    would have its own set of actions that need to take place. For example MBeans need to be
+    registered with an MBean server before they can be considered &apos;deployed&apos;.</para>
+    <para>It turns out that we can use the state machine to meet these requirements by creating a
+    DeploymentControllerContext to represent a deployment in the same way that a
+    KernelControllerContext represents a POJO. This allows us to associate a number of
+    deployment actions to different stages of the deployment process:</para>
+    <itemizedlist>
+      <listitem>
+	<para>PARSE - convert one or more deployment descriptors into object representations
+	containing metadata</para>
+      </listitem>
+      <listitem>
+	<para>DESCRIBE - determine any dependencies</para>
+      </listitem>
+      <listitem>
+	<para>CLASSLOADER - create classloaders</para>
+      </listitem>
+      <listitem>
+	<para>POST_CLASSLOADER - apply AOP changes together with any other bytecode
+	manipulations</para>
+      </listitem>
+      <listitem>
+	<para>REAL - process the deployment components</para>
+      </listitem>
+    </itemizedlist>
+    <para>As the state machine controller takes a DeploymentControllerContext through each of
+    these stages it calls the associated actions to perform the relevant work. For example we
+    could create multiple parsing actions; one to parse XML files and another to parse Java
+    property files. Depending on the file suffix of the deployment descriptor; .xml or .property
+    we can then choose which one to use during the PARSE stage.</para>
+    <para>Deployments are represented by DeploymentContexts which can be formed into a hierarchy
+    to represent nested deployments of any depth. A reference to the top-level DeploymentContext
+    is contained in the DeploymentControllerContext:</para>
+    <programlisting role="JAVA">public class DeploymentControllerContext extends AbstractControllerContext
+    {
+    /** The deployment context */
+    private DeploymentContext deploymentContext;
+    
+    public DeploymentControllerContext(DeploymentContext context, DeployersImpl deployers)
+    {
+    super(context.getName(), deployers);
+    this.deploymentContext = context;
+    setMode(ControllerMode.MANUAL);
+    }
+
+    public DeploymentContext getDeploymentContext()
+    {
+    return deploymentContext;
+    }
+    }</programlisting>
+    <warning>
+      <para>Be careful not to get confused with the names of these types;
+      DeploymentControllerContext and DeploymentContext, as they are very similar. </para>
+    </warning>
+    <para>As deployment descriptors do not always describe runtime components directly, the notion
+    of a deployment component is defined. For example an EJB deployment descriptor may describe
+    a number of EJB containers from which individual EJBs are created. Here we refer to both the
+    EJB containers and EJBs as <emphasis>deployment components</emphasis> but only the EJBs are
+    thought of as <emphasis>runtime components</emphasis>. Deployment components are represented
+    by an implementation of DeploymentContext called ComponentDeploymentContext which allows
+    them to be hierarchical to any depth. For example an EJB container
+    ComponentDeploymentContext could have multiple child ComponentDeploymentContexts
+    representing its EJBs. Deployment components are added/removed to and from their containing
+    deployment or parent deployment component and retrieved for processing using the following
+    methods:</para>
+    <programlisting role="JAVA">public class ComponentDeploymentContext implements DeploymentContext
+    {
+    ...
+
+    boolean isComponent() {
+    return true;
+    }
+    
+    List&lt;DeploymentContext&gt; getComponents() {
+    return Collections.unmodifiableList(components);
+    }
+
+    void addComponent(DeploymentContext component) {
+    ...
+    components.add(component);
+    }
+
+
+    boolean removeComponent(DeploymentContext component) {
+    ...
+    boolean result = components.remove(component);
+    component.cleanup();
+    return result;
+    }
+
+    ...
+    }</programlisting>
+    <para>The deployment framework is therefore a collection of packages and classes that provides
+    a generic way to represent deployments containing arbitrary <emphasis>deployment
+    components</emphasis>. These could be runtime components such as POJOs, MBeans, and EJBs
+    or non-runtime components such as EJB containers which act as factories for the EJBs.
+    Deployments and deployment components can be nested within one another to any depth
+    providing maximum flexibility during deployment.</para>
+    <para>Consequently it&apos;s possible to use the deployment framework instead of the
+    BasicXMLDeployer to deploy POJO-based services specified with XML deployment descriptors. So
+    why then do we need a BasicXMLDeployer? The answer is because the deployment framework
+    itself a POJO-based service specified with an XML deployment descriptor (usually called
+    <emphasis>bootstrap-beans.xml</emphasis>). We therefore need the BasicXMLDeployer to
+    deploy it when the microcontainer is booted up. Once deployed then the framework is used to
+    deploy everything else including any other POJO-based services.</para>
+    <para>Now that you understand the reasoning for the deployment framework and how it relates to
+    the BasicXMLDeployer the following sections go on the cover the various parts in more
+    detail.</para>
+  </chapter>
+  <chapter>
+    <title>The Virtual File System</title>
+    <para>When you think about it all deployments can be broken down into three types of data: </para>
+    <itemizedlist>
+      <listitem>
+	<para>Deployment descriptors - contain configuration information</para>
+      </listitem>
+      <listitem>
+	<para>Java classes - contain compiled Java bytecode</para>
+      </listitem>
+      <listitem>
+	<para>Resources - any other files that are required at runtime</para>
+      </listitem>
+    </itemizedlist>
+    <para>Sometimes only a single deployment descriptor is required although more often you create
+    a deployment archive containing one or more descriptors together with a number of classes.
+    In the case of a Web Archive (WAR) we also include any resources that are to be hosted by
+    the web server.</para>
+    <para>During development it is convenient to be able to deploy such archives in an unpackaged
+    rather than a packaged state. This means that files can be freely edited in their
+    directories and the deployment processed again without having to re-package everything each
+    time. Packaging is usually more appropriate during the test phase or when going to
+    production as a way of keeping everything together.</para>
+    <para>Depending on the layout of the development, test or production system it&apos;s helpful
+    to allow the deployment of packaged or unpackaged archives both locally, on the
+    computer&apos;s hard drive, or remotely over a network. Support for nested deployments is
+    also important so that related items can be deployed together.</para>
+    <para>To allow all of these concerns to be addressed in a maintainable and extendable way the
+    deployment framework uses a Virtual File System (VFS). This provides a way to represent a
+    deployment as a read-only hierarchical file system regardless of whether it is packaged or
+    not. It also allows deployments to be accessed both locally and remotely using a pluggable
+    design so that new protocols can easily be added to those supplied by default:</para>
+    <itemizedlist>
+      <listitem>
+	<para>File - </para>
+      </listitem>
+      <listitem>
+	<para>JAR - </para>
+      </listitem>
+      <listitem>
+	<para>Memory - </para>
+      </listitem>
+    </itemizedlist>
+    <para>Finally the VFS takes care of generating physical URLs for classloading and debugging.
+    Logical URLs can also be generated for configuration purposes, or codebase protection
+    domains.</para>
+  </chapter>
+  <chapter>
+    <title>Identifying the deployment structure</title>
+    <para>Before we can begin to process a deployment we must first determine its structure. This
+    means finding out if it contains any deployment descriptors and/or classes, and if so where
+    they are located relative to the deployment&apos;s root. Nested deployments must also be
+    detected and their structures determined in the same way. The purpose of this is to help the
+    parsing actions locate the deployment descriptors in a standard way and to assist in the
+    creation of classloaders. Since we wish to use the Virtual File System (VFS) to represent
+    our deployment we must first create a VFSDeployment using the deployment URI or URL:</para>
+    <programlisting role="JAVA">VirtualFile root = VFS.getRoot(deploymentURL);     
+    VFSDeploymentFactory deploymentFactory = VFSDeploymentFactory.getInstance();
+    Deployment deployment = deploymentFactory.createVFSDeployment(root);</programlisting>
+    <para>The deployment framework then determines the structure of the
+    <emphasis>Deployment</emphasis> using classes that implement the
+    <emphasis>StructureDeployer</emphasis> interface:</para>
+    <programlisting role="JAVA">public interface StructureDeployer extends Ordered
+    {
+    boolean determineStructure(VirtualFile root, VirtualFile parent, VirtualFile file, StructureMetaData metaData, VFSStructuralDeployers deployers) throws DeploymentException;
+    }</programlisting>
+    <para>As a deployment can contain nested deployments the determineStructure() method is meant
+    to be called recursively. The <emphasis>root</emphasis> parameter represents the root of the
+    top-level deployment, the <emphasis>file</emphasis> parameter represents the root of the
+    current (possibly nested) deployment being analyzed and the <emphasis>parent</emphasis>
+    parameter its parent (or null if it is the top-level). The <emphasis>deployers</emphasis>
+    parameter represents a class containing a list of all the
+    <emphasis>StructureDeployer</emphasis> implementations and is needed in order to process
+    any nested deployments.</para>
+    <para>As each deployment is found a <emphasis>ContextInfo</emphasis> object is created to
+    store the paths to any deployment descriptors and/or classes. These are then added to the
+    <emphasis>StructureMetaData</emphasis> parameter so that the structure of the entire
+    deployment is recorded. For example if we had a top-level deployment containing 2 nested
+    deployments then we would create 3 <emphasis>ContextInfo</emphasis> objects, one for each
+    deployment, and add these to the <emphasis>StructureMetaData</emphasis> object.</para>
+    <section>
+      <title>Deployment Descriptors</title>
+      <para>Deployment descriptors are files containing configuration information for deployments.
+      They are detected using the <emphasis>FileStructure</emphasis> class by matching the file
+      suffix or using a <emphasis>FileMatcher</emphasis>. Default file suffixes include:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>-beans.xml - contains bean definitions</para>
+	</listitem>
+	<listitem>
+	  <para>-aop.xml - contains aspect definitions</para>
+	</listitem>
+	<listitem>
+	  <para>-service.xml - contains mbean definitions</para>
+	</listitem>
+	<listitem>
+	  <para>-ds.xml - contains JCA datasource definitions</para>
+	</listitem>
+      </itemizedlist>
+      <para>Each <emphasis>FileMatcher</emphasis> must implement the following interface:</para>
+      <programlisting role="JAVA">public interface FileMatcher
+      {
+      boolean isDeployable(VirtualFile file);
+      }</programlisting>
+      <para>Default implementations are:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>BshFileMatcher - checks whether the filename ends with .bsh (Bean Shell)</para>
+	</listitem>
+      </itemizedlist>
+      <para>The purpose of the <emphasis>FileStructure</emphasis> class is to detect deployments
+      that consist of a single deployment descriptor. As such it creates a single
+      <emphasis>ContextInfo</emphasis> object when a known file is found and adds this to the
+      <emphasis>StructureMetaData</emphasis>. Since no classes are present the list of
+      classpaths within the <emphasis>ContextInfo</emphasis> is set to null.</para>
+      <warning>
+	<para>Currently any top-level deployment that consists of a single file is always
+	identified as a known deployment descriptor. This is done to avoid having to specify all
+	of the known file suffixes in a configuration file. The file suffix and FileMatcher
+	checks are only performed for nested deployments.</para>
+	<para>As the FileStructure class has a relative order of Integer.MAX_VALUE it is always
+	called after any other <emphasis>StructureDeployer</emphasis> implementations such as
+	JARStructure. This means that a deployment consisting of a single JAR file will be
+	detected correctly. </para>
+      </warning>
+      <para>Deployment descriptors that form part of a deployment together with other files, such
+      as classes or resources are detected by other implementations of
+      <emphasis>StructureDeployer</emphasis> such as<emphasis>JARStructure</emphasis> which is
+      described next.</para>
+    </section>
+    <section>
+      <title>Java Archives (JARs)</title>
+      <para>The <emphasis>JARStructure</emphasis> class determines whether a deployment, in the
+      form of a file or a directory, represents a packaged or unpackaged JAR archive. If the
+      deployment is a single file then the filename suffix is checked against a list contained
+      in the <emphasis>JarUtils</emphasis> class:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>.zip - a standard archive</para>
+	</listitem>
+	<listitem>
+	  <para>.jar - a java archive (defined by the Java SE specification)</para>
+	</listitem>
+	<listitem>
+	  <para>.ear - an enterprise archive (defined by the Java EE specification)</para>
+	</listitem>
+	<listitem>
+	  <para>.rar - a resource archive (defined by the Java EE specification)</para>
+	</listitem>
+	<listitem>
+	  <para>.war - a web archive (defined by the Java EE specification)</para>
+	</listitem>
+	<listitem>
+	  <para>.sar - a service archive (defined by JBoss)</para>
+	</listitem>
+	<listitem>
+	  <para>.har - a hibernate archive (defined by JBoss)</para>
+	</listitem>
+	<listitem>
+	  <para>.aop - an aspect archive (defined by JBoss)</para>
+	</listitem>
+      </itemizedlist>
+      <para>If the deployment is a directory then the same check is performed using the directory
+      name. If a match is found in either case then the deployment is determined to represent a
+      JAR archive.</para>
+      <note>
+	<para>A top-level directory whose name doesn&apos;t match any of the file suffixes is
+	still considered an unpackaged JAR archive as this allows it to be used as a container
+	for multiple nested deployments.</para>
+      </note>
+      <para>In order to detect nested JAR deployments we iterate through all subdirectories
+      checking whether their names end in a known suffix or if they contain META-INF
+      directories. The check for a META-INF directory is required otherwise every subdirectory
+      without a known filename would be classified as a nested deployment.</para>
+      <para>For each JAR deployment found we create a new <emphasis>ContextInfo</emphasis> object
+      with its metadata path set to META-INF and the classpath set to the deployment
+      root.</para>
+    </section>
+    <section>
+      <title>Nested deployments</title>
+      <para>Nested deployments are found by calling the addAllChildren() method in
+      <emphasis>AbstractStructureDeployer</emphasis> and passing in a reference to the
+      deployment root and the current nested deployment along with the
+      <emphasis>StructureMetaData</emphasis> and <emphasis>VFSStructuralDeployers</emphasis>
+      references: </para>
+      <programlisting role="JAVA">public abstract class AbstractStructureDeployer implements StructureDeployer
+      {
+      ...
+
+      protected void addAllChildren(VirtualFile root, VirtualFile parent, StructureMetaData metaData, VFSStructuralDeployers deployers) throws Exception
+      {
+      addChildren(root, parent, metaData, deployers, null);
+      }
+
+      protected void addChildren(VirtualFile root, VirtualFile parent, StructureMetaData metaData, VFSStructuralDeployers deployers, VisitorAttributes attributes) throws Exception
+      {
+      if (parent == null)
+      throw new IllegalArgumentException(&quot;Null parent&quot;);
+      
+      VirtualFileVisitor visitor = candidateStructureVisitorFactory.createVisitor(root, parent, metaData, deployers, attributes);
+      parent.visit(visitor);
+      }
+
+      ...
+      }</programlisting>
+      <para>This in turn calls the addChildren() method which creates a
+      <emphasis>VirtualFileVisitor</emphasis> that is passed to the virtual file representing
+      the current deployment. Each child file or directory of the current deploment is then
+      visited using the visitor which use the <emphasis>VFSStructuralDeployers</emphasis> object
+      to iterate through the list of <emphasis>StructureDeployers</emphasis>. These then
+      determine whether the child represents a nested deployment. If a nested deployment is
+      found then the process is repeated in order to recurse through the entire directory
+      structure. This happens regardless of whether the deployment is packaged or unpackaged as
+      the Virtual File System takes care of accessing the actual files.</para>
+      <para>Due to this recursive algorithm you can freely nest any type of deployment within any
+      other type of deployment to any level. There is one exection to this with WAR archives
+      which cannot contain nested deployments. All you need to ensure is that you have defined a
+      <emphasis>StructureDeployer</emphasis> implementation capable of recognising your
+      deployment.</para>
+    </section>
+    <section>
+      <title>Declaring a custom deployment structure</title>
+      <para>JBoss Microcontainer provides two <emphasis>StructureDeployer</emphasis>
+      implementations out-of-the-box to recognise the most common forms of deployments;
+      standalone deployment descriptors and packaged/unpackaged JAR archives. In addition it
+      also includes a third implementation called <emphasis>DeclaredStructure</emphasis>.</para>
+      <para><emphasis>DeclaredStructure</emphasis> allows you to specify the structure of a
+      deployment, including any nested deployments, using an XML file called
+      <emphasis>jboss-structure.xml</emphasis> placed in the deployment&apos;s META-INF
+      directory. The contents of this file are:</para>
+      <programlisting role="XML">&lt;structure&gt;
+      &lt;context&gt;
+      &lt;path name=&quot;&quot;/&gt;
+      &lt;metaDataPath&gt;
+      &lt;path name=&quot;OTHER-DIR&quot;/&gt;
+      &lt;/metaDataPath&gt;
+      &lt;classpath&gt;
+      &lt;path name=&quot;&quot;/&gt;
+      &lt;/classpath&gt;
+      &lt;/context&gt;
+      &lt;/structure&gt;</programlisting>
+      <para>This describes a top-level deployment and specifies that deployment descriptors can be
+      found in the <emphasis>OTHER-DIR</emphasis> directory and classes in the root directory.
+      If you want to describe nested deployments then you simply need to create additional
+      &lt;context&gt; elements and specify their paths relative to the root deployment:</para>
+      <programlisting role="XML">&lt;structure&gt;
+      &lt;context&gt;
+      &lt;path name=&quot;&quot;/&gt;
+      &lt;metaDataPath&gt;
+      &lt;path name=&quot;OTHER-DIR&quot;/&gt;
+      &lt;/metaDataPath&gt;
+      &lt;classpath&gt;
+      &lt;path name=&quot;&quot;/&gt;
+      &lt;/classpath&gt;
+      &lt;/context&gt;
+      &lt;context&gt;
+      &lt;path name=&quot;nestedDeployment1&quot;/&gt;
+      &lt;metaDataPath&gt;
+      &lt;path name=&quot;descriptors/xml/&quot;/&gt;
+      &lt;/metaDataPath&gt;
+      &lt;classpath&gt;
+      &lt;path name=&quot;classes&quot;/&gt;
+      &lt;path name=&quot;thirdParty/classes&quot;/&gt;
+      &lt;/classpath&gt;
+      &lt;/context
+      &lt;context&gt;
+      &lt;path name=&quot;utils/nestedDeployment2&quot;/&gt;
+      &lt;metaDataPath&gt;
+      &lt;path name=&quot;META-INF&quot;/&gt;
+      &lt;path name=&quot;config/descs/&quot;/&gt;
+      &lt;/metaDataPath&gt;
+      &lt;classpath&gt;
+      &lt;path name=&quot;lib&quot;/&gt;
+      &lt;/classpath&gt;
+      &lt;/context
+      &lt;/structure&gt;</programlisting>
+      <para>Here we&apos;ve added two nested deployments, one directly underneath the top-level
+      deployment and another in a subdirectory called utils. The first nested deployment has
+      deployment descriptors located in its <emphasis>descriptors/xml</emphasis> directory and
+      classes in either the <emphasis>classes</emphasis> or
+      <emphasis>thirdParty/classes</emphasis> directories. The second nested deployment has
+      deployment descriptors in either the <emphasis>META-INF</emphasis> or
+      <emphasis>config/descs</emphasis> directories and classes in the
+      <emphasis>lib</emphasis> directory.</para>
+      <note>
+	<para>In order to ensure that any JAR files that you add META-INF/jboss-structure.xml to
+	are correctly recognised by <emphasis>DeclaredStructure</emphasis> instead of
+	<emphasis>JARStructure</emphasis> the DeclaredStructure has a relativeOrder of 0 and
+	the JARStructure a relativeOrder of 10000. This means that the DeclaredStructure class
+	will be consulted first when determining the structure of a deployment.</para>
+      </note>
+      <para>If you use the <emphasis>DeclaredStructure</emphasis> approach then you must specify
+      all nested deployments in the <emphasis>META-INF/jboss-structure.xml</emphasis> file. This
+      is because no recursion takes place once the structure has been determined. If you want
+      the ability to nest other kinds of deployments within your custom deployment structure
+      then it may be easier to create your own <emphasis>StructureDeployer</emphasis>
+      implementation. Doing so will allow you to call the addAllChildren() method to perform the
+      recursion. </para>
+    </section>
+    <section>
+      <title>Determining the deployment structure programmatically</title>
+      <para>Using the <emphasis>DeclaredStructure</emphasis> approach is convenient if you have an
+      unusual deployment structure and don&apos;t mind adding the
+      <emphasis>META-INF/jboss-structure.xml</emphasis> file to your deployment. However, if
+      you have many deployments and want to avoid adding this file each time, or you want to
+      nest arbitrary deployments inside your custom structure then you are better off creating
+      your own <emphasis>StructureDeployer</emphasis> implementation.</para>
+      <para>The easiest way to do this is by extending the
+      <emphasis>AbstractStructureDeployer</emphasis> class which already implements the
+      <emphasis>StructureDeployer</emphasis> interface:</para>
+      <programlisting role="JAVA">public abstract class AbstractStructureDeployer implements StructureDeployer
+      {
+      ...
+      }</programlisting>
+      <para>This includes helper methods to see if a VirtualFile represents a file or a directory
+      and whether it corresponds to a top-level deployment. It also has methods to recurse
+      through all of the files within a deployment to find nested deployments and to create
+      <emphasis>ContextInfo</emphasis> objects for each one found. The only method that you
+      need to implement is the one defined by the <emphasis>StructureDeployer</emphasis>
+      interface:</para>
+      <programlisting role="JAVA">public interface StructureDeployer extends Ordered
+      {
+      boolean determineStructure(VirtualFile root, VirtualFile parent, VirtualFile file, StructureMetaData metaData, VFSStructuralDeployers deployers) throws DeploymentException;
+      }</programlisting>
+      <para>If you recognise the structure of the deployment then you must create a
+      <emphasis>ContextInfo</emphasis> object containing the details and add it to the
+      <emphasis>StructureMetaData</emphasis>. If you extend AbstractStructureDeployer then you
+      can use the createContext() and addClassPath() helper methods to help do this. You must
+      then return true to prevent any other <emphasis>StructureDeployer</emphasis> from
+      analysing the deployment again.</para>
+      <para>If you want to control when your <emphasis>StructureDeployer</emphasis> is called you
+      can use the <emphasis>relativeOrder</emphasis> property. By default this is set to
+      <property>Integer.MAX_VALUE</property> in <emphasis>AbstractStructureDeployer</emphasis>.
+      Implementations with a lower value are called before those with a higher value. If two
+      values are the same then the return values of each implementation&apos;s toString() method
+      are compared. The relativeOrder values for the out-of-the-box
+      <emphasis>StructureDeployer</emphasis> implementations are:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>DeclaredStructure - 0</para>
+	</listitem>
+	<listitem>
+	  <para>JARStructure - 10000</para>
+	</listitem>
+	<listitem>
+	  <para>FileStructure - Integer.MAX_VALUE</para>
+	</listitem>
+      </itemizedlist>
+      <para>This means that DeclaredStructure is always called first followed by JARStructure and
+      finally FileStructure.</para>
+    </section>
+  </chapter>
+  <chapter>
+    <title>Creating Deployment Contexts</title>
+    <section>
+      <title>Introduction</title>
+      <para>Once the structure of a deployment has been determined then the next step is to create
+      a number of <emphasis>DeploymentContext</emphasis> objects. A
+      <emphasis>DeploymentContext</emphasis> is required for each deployment, whether
+      top-level or nested, in order to store information such as:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>the location of any deployment descriptors - the metadata path</para>
+	</listitem>
+	<listitem>
+	  <para>the location of any classes - the classpath</para>
+	</listitem>
+	<listitem>
+	  <para>the relative path to the top-level deployment - the relative path</para>
+	</listitem>
+	<listitem>
+	  <para>the deployment name</para>
+	</listitem>
+	<listitem>
+	  <para>the order it should be deployed in relative to other deployments - the relative
+	  order</para>
+	</listitem>
+	<listitem>
+	  <para>a list of deployment types that it represents (including nested deployments) - the
+	  types</para>
+	</listitem>
+	<listitem>
+	  <para>the state of the deployment - whether it is deployed or not</para>
+	</listitem>
+	<listitem>
+	  <para>the deployment class loader</para>
+	</listitem>
+	<listitem>
+	  <para>the deployment resource loader</para>
+	</listitem>
+	<listitem>
+	  <para>dependencies on other deployments or runtime components</para>
+	</listitem>
+	<listitem>
+	  <para>references to any components that it deploys - POJOs, MBeans etc...</para>
+	</listitem>
+	<listitem>
+	  <para>references to any nested (child) deployments or the parent deployment</para>
+	</listitem>
+      </itemizedlist>
+      <para>Since the <emphasis>StructureMetaData</emphasis> object created using the
+      <emphasis>StructureDeployer</emphasis> implementations already contains some of this
+      information we subsequently pass it to a <emphasis>StructureBuilder</emphasis> together
+      with a reference to the original <emphasis>Deployment</emphasis> to populate the
+      deployment with a tree of DeploymentContexts:</para>
+      <programlisting role="JAVA">public interface StructureBuilder
+      {
+      DeploymentContext populateContext(Deployment deployment, StructureMetaData metaData) throws DeploymentException;
+      }</programlisting>
+      <para>During this method call the information contained within the
+      <emphasis>ContextInfo</emphasis> objects, found inside the
+      <emphasis>StructureMetaData</emphasis>, is transferred to new instances of
+      <emphasis>DeploymentContext</emphasis> that are assembled into a hierarchy. A reference
+      to the top-level <emphasis>DeploymentContext</emphasis> is then returned.</para>
+    </section>
+    <section>
+      <title>Accessing a deployment</title>
+      <para>The deployment framework uses <emphasis>DeploymentContext</emphasis> objects to access
+      the internal details of a deployment during processing. However, if you wish to access a
+      deployment yourself then you should use a wrapper called
+      <emphasis>DeploymentUnit</emphasis>.</para>
+      <para>This prevents you from getting or setting the deployment state, changing the
+      deployment classloader if it already exists, changing any parent/child relationships
+      between nested deployments and accessing any exceptions that have occurred during
+      deployment. You are also prevented from calling the visit() method that allows you to
+      visit all of the contexts in the hierarchy or the cleanup() method that removes deployment
+      metadata from the metadata repository.</para>
+    </section>
+    <section>
+      <title>Attaching extra information</title>
+      <para>Since each instance of <emphasis>DeploymentContext</emphasis> contains generic
+      deployment information we need a way to store and retrieve additional information
+      generated during the deployment process. This is done using the
+      <emphasis>DeploymentUnit</emphasis> wrapper which extends the
+      <emphasis>MutableAttachments</emphasis> interface:</para>
+      <programlisting role="JAVA">public interface DeploymentUnit extends MutableAttachments
+      {
+      ...
+      }</programlisting>
+      <programlisting role="JAVA">public interface MutableAttachments extends Attachments
+      {
+      Object addAttachment(String name, Object attachment);
+      &lt;T&gt; T addAttachment(String name, T attachment, Class&lt;T&gt; expectedType);
+      &lt;T&gt; T addAttachment(Class&lt;T&gt; type, T attachment);
+
+      Object removeAttachment(String name);
+      &lt;T&gt; T removeAttachment(String name, Class&lt;T&gt; expectedType);
+      &lt;T&gt; T removeAttachment(Class&lt;T&gt; type);
+
+      void setAttachments(Map&lt;String, Object&gt; map);
+
+      void clear();
+
+      int getChangeCount();
+      void clearChangeCount();
+      }</programlisting>
+      <para>As you can see the <emphasis>MutableAttachments</emphasis> operations allow you to
+      store arbitrary objects (referred to as attachments) inside a map using a
+      <emphasis>String</emphasis> for the key. For convenience you can pass in the type of the
+      object instead of a string and the return value of type.getName() will be used as the key.
+      If you pass in a type for the key, or you specify an expectedType argument, then the
+      return value will be cast to an object of that type.</para>
+      <para>If you wish to retrieve any objects then you can use operations from the
+      <emphasis>Attachments</emphasis> interface:</para>
+      <programlisting role="JAVA">public interface Attachments extends Serializable
+      {
+      Map&lt;String, Object&gt; getAttachments();
+
+      Object getAttachment(String name);
+      &lt;T&gt; T getAttachment(String name, Class&lt;T&gt; expectedType);
+      &lt;T&gt; T getAttachment(Class&lt;T&gt; type);
+      
+      boolean isAttachmentPresent(String name);
+      boolean isAttachmentPresent(String name, Class&lt;?&gt; expectedType);   
+      boolean isAttachmentPresent(Class&lt;?&gt; type);
+
+      boolean hasAttachments();
+      }</programlisting>
+      <para>Again if you pass a type for the key, or specify an expectedType argument, then the
+      return value will be cast to an object of that type. In the case of the
+      isAttachmentPresent() methods the return value is only true if both the object can be
+      located using the key and it can be cast to the specified type.</para>
+      <para><emphasis>DeploymentUnit</emphasis> also contains a convenience method that allows you
+      to retrieve all objects of a particular type from the map of attachments:</para>
+      <programlisting role="JAVA">public interface DeploymentUnit extends MutableAttachments
+      {
+      ...
+      &lt;T&gt; Set&lt;? extends T&gt; getAllMetaData(Class&lt;T&gt; type);
+      ...
+      }</programlisting>
+    </section>
+    <section>
+      <title>Deployment components</title>
+      <para>Deployments usually contain one or more runtime components in addition to
+      configuration information and resource files. By runtime components we mean any classes
+      that require a container in which to run. Containers take care of controlling a
+      component&apos;s lifecycle in addition to providing common behaviours so that component
+      developers do not have to do this themselves. By leveraging the work of the container,
+      components allow you to concentrate on developing the business logic of your application
+      without having to continually write code for common tasks. This typically reduces the time
+      needed to develop systems with advanced behaviour.</para>
+      <para>The simplest example of a component is a POJO. In this case the container controls
+      when the POJO is created based on when a client performs a lookup. It can also take care
+      of wiring different POJOs together based on information in a deployment descriptor so that
+      the developer doesn&apos;t have to hard-code any relationships. This makes configuration
+      of the runtime environment easier to change.</para>
+      <para>Another example is an MBean. Here the container (an MBeanServer) takes care of routing
+      all method calls through a bus so that clients never reference the MBean directly. This
+      allows MBeans to be replaced at runtime without impacting any clients. It also allows the
+      management interface of an MBean, the attributes and operations exposed to clients, to
+      change at runtime without needing to redeploy it.</para>
+      <para>A further example is an OSGi service bundle. Here the container ensures that the
+      classes required by the bundle are available in the runtime before the service is started.
+      It also takes care of making classes within the bundle available to others when deployed
+      and removing them again when undeployed. This makes the runtime environment easier to
+      construct and maintain with fewer classloading issues.</para>
+      <para>In order to provide support for deploying different types of runtime components, JBoss
+      Microcontainer requires that each one is represented by its own
+      <emphasis>ComponentDeploymentContext</emphasis>:</para>
+      <programlisting role="JAVA">public class ComponentDeploymentContext implements DeploymentContext
+      {
+      ...
+      }</programlisting>
+      <para>This is similer to a normal <emphasis>DeploymentContext</emphasis> implementation but
+      with some important differences:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>Components always have a relative order of 0</para>
+	</listitem>
+	<listitem>
+	  <para>Components do not have a metadata path</para>
+	</listitem>
+	<listitem>
+	  <para>Components always use the classloader of the containing deployment</para>
+	</listitem>
+	<listitem>
+	  <para>Components cannot change their parent once constructed</para>
+	</listitem>
+	<listitem>
+	  <para>Components can contain other components</para>
+	</listitem>
+	<listitem>
+	  <para>Components are never considered top-level deployments</para>
+	</listitem>
+      </itemizedlist>
+      <para>In addition ComponentDeploymentContexts delegate to their parent
+      <emphasis>DeploymentContext</emphasis> for information such as:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>simple name</para>
+	</listitem>
+	<listitem>
+	  <para>relative path</para>
+	</listitem>
+	<listitem>
+	  <para>deployment types</para>
+	</listitem>
+	<listitem>
+	  <para>deployment state</para>
+	</listitem>
+	<listitem>
+	  <para>class loader</para>
+	</listitem>
+	<listitem>
+	  <para>Resource class loader</para>
+	</listitem>
+	<listitem>
+	  <para>Deployment Resource Loader</para>
+	</listitem>
+	<listitem>
+	  <para>Dependency Info</para>
+	</listitem>
+	<listitem>
+	  <para>get/setProblem</para>
+	</listitem>
+      </itemizedlist>
+      <para>The reason we use the <emphasis>DeploymentContext</emphasis> interface is so that we
+      can process components together with normal deployments. This ensures that when a
+      deployment is deployed any components that it contains are deployed with it. Similarly
+      undeploying a deployment causes its components to be undeployed at the same time.</para>
+      <important>
+	<para>An additional motivation is that we can easily create separate ControllerContexts
+	for each component which we can then process using the state machine. This allows us to
+	perform a well-defined set of deployment actions to deploy/undeploy each component in
+	and out of the runtime.</para>
+	<para>Having separate ControllerContexts for each component also allows you to manage the
+	components individually, possibly via an Admin console. Furthermore each component can
+	have its own dependencies allowing fine-grained control of how the runtime is
+	constructed and destructed. </para>
+      </important>
+      <para>ComponentDeploymentContexts are added to a <emphasis>DeploymentUnit</emphasis> using
+      the addComponent() method whenever a component is discovered during the deployment
+      process:</para>
+      <programlisting role="JAVA">public class AbstractDeploymentUnit extends AbstractMutableAttachments implements DeploymentUnit
+      {
+      ...
+
+      public DeploymentUnit addComponent(String name)
+      {
+      DeploymentContext component = createComponentDeploymentContext(name, deploymentContext);
+      DeploymentUnit unit = createComponentDeploymentUnit(component);
+      component.setDeploymentUnit(unit);
+      deploymentContext.addComponent(component);
+      return unit;
+      }
+
+      ...
+
+      protected DeploymentContext createComponentDeploymentContext(String name, DeploymentContext parent)
+      {
+      return new ComponentDeploymentContext(name, parent);
+      }
+
+      ...
+      }</programlisting>
+      <para>As components are usually accessed with the <emphasis>DeploymentUnit</emphasis>
+      interface they can also have attachments just like any other deployment:</para>
+      <programlisting role="JAVA">public interface DeploymentUnit extends MutableAttachments
+      {
+      ...
+      }
+
+      public interface MutableAttachments extends Attachments
+      {
+      ...
+
+      Object addAttachment(String name, Object attachment);
+
+      ...
+      }</programlisting>
+      <para>An attachment may well be metadata associated with the component. In this way the
+      metadata can be processed using deployment actions as the component&apos;s
+      <emphasis>ControllerContext</emphasis> passes through the state machine.</para>
+    </section>
+    <section>
+      <title>Deployment dependencies</title>
+      <para>Sometimes a deployment may have dependencies on other deployments or on a runtime
+      component such as a classloader. In these cases we need to be able to define the
+      dependencies so that the state machine can decide whether or not to progress the
+      deployment to the next stage. This is done using the following methods of the
+      <emphasis>DeploymentUnit</emphasis> interface:</para>
+      <programlisting role="JAVA">public interface DeploymentUnit extends MutableAttachments
+      {
+      ...
+
+      DependencyInfo getDependencyInfo();
+      void addIDependOn(DependencyItem dependency);
+      void removeIDependOn(DependencyItem dependency);
+      }</programlisting>
+      <para><emphasis>AbstractDeploymentUnit</emphasis> delegates these calls to the
+      <emphasis>DeploymentContext</emphasis> implementation that it wraps:</para>
+      <programlisting role="JAVA">public class AbstractDeploymentUnit extends AbstractMutableAttachments implements DeploymentUnit
+      {
+      ...
+
+      public void addIDependOn(DependencyItem dependency)
+      {
+      getDependencyInfo().addIDependOn(dependency);
+      }
+
+      public DependencyInfo getDependencyInfo()
+      {
+      return deploymentContext.getDependencyInfo();
+      }
+
+      public void removeIDependOn(DependencyItem dependency)
+      {
+      getDependencyInfo().removeIDependOn(dependency);
+      }
+
+      ...
+      }</programlisting>
+      <para>This in turn delegates them to the corresponding
+      <emphasis>ControllerContext</emphasis> implementation which is stored as an
+      attachment:</para>
+      <programlisting role="JAVA">public class AbstractDeploymentContext extends ManagedObjectsWithTransientAttachmentsImpl implements DeploymentContext
+      {
+      ...
+
+      public DependencyInfo getDependencyInfo()
+      {
+      ControllerContext controllerContext = getTransientAttachments().getAttachment(ControllerContext.class);
+      if (controllerContext != null)
+      return controllerContext.getDependencyInfo();
+      else
+      {
+      DeploymentContext parent = getParent();
+      if (parent == null)
+      throw new IllegalStateException(&quot;Deployment ControllerContext has not been set&quot;);
+      return parent.getDependencyInfo();
+      }
+      }
+
+      ...
+      }</programlisting>
+      <para>If a <emphasis>ControllerContext</emphasis> object is not found within the
+      deployment&apos;s attachments then the parent deployment is tried. In this way
+      DependencyItems are added/removed to the underlying <emphasis>ControllerContext</emphasis>
+      implementation for the deployment. </para>
+    </section>
+  </chapter>
+  <chapter>
+    <title>Processing a deployment</title>
+    <section>
+      <title>Introduction</title>
+      <para>So far we have established the structure of a deployment using
+      <emphasis>StructureDeployer</emphasis> classes and created a corresponding
+      <emphasis>DeploymentContext</emphasis> using a <emphasis>StructureBuilder</emphasis>.
+      Nested deployments have been dealt with by creating additional DeploymentContexts and
+      adding these as children of the parent <emphasis>DeploymentContext</emphasis>.</para>
+      <para>The next step in the deployment framework is to process the deployment. The objective
+      being to extract any metadata from the deployment descriptors and create a classloader.
+      Components must also be identified during this process and a
+      <emphasis>ComponentDeploymentContext</emphasis> created for each one so that they can be
+      deployed into the runtime.</para>
+      <para>The <emphasis>Deployers</emphasis> interface defines the operations that need to take
+      place:</para>
+      <programlisting role="JAVA">public interface Deployers
+      {
+      ...
+      
+      void process(List&lt;DeploymentContext&gt; deploy, List&lt;DeploymentContext&gt; undeploy);
+
+      void checkComplete(Collection&lt;DeploymentContext&gt; errors, Collection&lt;Deployment&gt; missingDeployer) throws DeploymentException;
+
+      void checkComplete(DeploymentContext... contexts) throws DeploymentException;
+
+      void checkStructureComplete(DeploymentContext... contexts) throws DeploymentException;
+      }</programlisting>
+      <para>In the default implementation <emphasis>DeployersImpl</emphasis> the process() method
+      creates new DeploymentControllerContexts for each <emphasis>DeploymentContext</emphasis>
+      in the deploy list and installs them into the microcontainer controller:</para>
+      <programlisting role="JAVA">public class DeployersImpl implements Deployers, ControllerContextActions
+      {
+      ...
+
+      public void process(List&lt;DeploymentContext&gt; deploy, List&lt;DeploymentContext&gt; undeploy)
+      {
+      ...
+
+      // There is something to deploy
+      if (deploy != null &amp;&amp; deploy.isEmpty() == false)
+      {
+      // Create the controller contexts
+      for (DeploymentContext context : deploy)
+      {
+      DeploymentControllerContext deploymentControllerContext = new DeploymentControllerContext(context, this);
+      try
+      {
+      controller.install(deploymentControllerContext);
+      context.setState(DeploymentState.DEPLOYING);
+      ...
+      context.getTransientAttachments().addAttachment(ControllerContext.class, deploymentControllerContext);
+      ...
+      }
+      catch (Throwable t)
+      {
+      // Set the error on the parent
+      context.setState(DeploymentState.ERROR);
+      context.setProblem(t);
+      // Set the children to not deployed
+      setState(context, DeploymentState.UNDEPLOYED, DeploymentState.DEPLOYING);
+      }
+      }
+
+      // Go through the states in order
+      List&lt;ControllerState&gt; states = controller.getStates();
+      for (ControllerState state : states)
+      {
+      for (DeploymentContext context : deploy)
+      {
+      if (DeploymentState.ERROR.equals(context.getState()) == false)
+      {
+      DeploymentControllerContext deploymentControllerContext = context.getTransientAttachments().getAttachment(ControllerContext.class.getName(), DeploymentControllerContext.class);
+      try
+      {
+      controller.change(deploymentControllerContext, state);
+      }
+      catch (Throwable t)
+      {
+      context.setState(DeploymentState.ERROR);
+      context.setProblem(t);
+      }
+      }
+      }
+      }
+      }
+      }
+
+      ...
+      }</programlisting>
+      <para>Notice that a reference to the <emphasis>DeploymentControllerContext</emphasis> is
+      stored as an attachment to the <emphasis>DeploymentContext</emphasis> so that it can be
+      retrieved later and passed to the controller.install() method.</para>
+      <para>Undeployment happens in a similar way. First of all the DeploymentControllerContexts
+      associated with the DeploymentContexts in the undeploy list are extracted into a separate
+      list. The microcontainer controller is then used again to push them through the deployment
+      states in reverse order. Finally the DeploymentControllerContexts are removed from the
+      <emphasis>DeploymentContext</emphasis> attachments where they were initially stored and
+      uninstalled from the controller:</para>
+      <programlisting role="JAVA">public class DeployersImpl implements Deployers, ControllerContextActions
+      {
+      ...
+
+      public void process(List&lt;DeploymentContext&gt; deploy, List&lt;DeploymentContext&gt; undeploy)
+      {
+      // There is something to undeploy
+      if (undeploy != null &amp;&amp; undeploy.isEmpty() == false)
+      {
+      // Build a list in reverse order
+      List&lt;DeploymentControllerContext&gt; toUndeploy = new ArrayList&lt;DeploymentControllerContext&gt;();
+      for (int i = undeploy.size()-1; i &gt;= 0; --i)
+      {
+      DeploymentContext context = undeploy.get(i);
+      if (DeploymentState.ERROR.equals(context.getState()) == false)
+      context.setState(DeploymentState.UNDEPLOYING);
+      ...
+      DeploymentControllerContext deploymentControllerContext = context.getTransientAttachments().getAttachment(ControllerContext.class.getName(), DeploymentControllerContext.class);
+      if (deploymentControllerContext == null)
+      {
+      log.debug(&quot;DeploymentContext has no DeploymentControllerContext during undeploy request, ignoring: &quot; + context);
+      }
+      else
+      {
+      toUndeploy.add(deploymentControllerContext);
+      }
+      }
+
+      // Go through the states in reverse order
+      List&lt;ControllerState&gt; states = controller.getStates();
+      for (int i = states.size()-1; i &gt;= 0; --i)
+      {
+      ControllerState state = states.get(i);
+      for (DeploymentControllerContext deploymentControllerContext : toUndeploy)
+      {
+      DeploymentContext context = deploymentControllerContext.getDeploymentContext();
+      if (ControllerState.ERROR.equals(context.getState()) == false)
+      {
+      try
+      {
+      controller.change(deploymentControllerContext, state);
+      }
+      catch (Throwable t)
+      {
+      ...
+      context.setState(DeploymentState.ERROR);
+      context.setProblem(t);
+      }
+      }
+      }
+      }
+
+      // Uninstall the contexts
+      for (DeploymentControllerContext deploymentControllerContext : toUndeploy)
+      {
+      DeploymentContext context = deploymentControllerContext.getDeploymentContext();
+      context.getTransientAttachments().removeAttachment(ControllerContext.class);
+      try
+      {
+      controller.uninstall(deploymentControllerContext.getName());
+      setState(context, DeploymentState.UNDEPLOYED, null);
+      ...
+      cleanup(context);
+      ...
+      }
+      catch (Throwable t)
+      {
+      ...
+      context.setState(DeploymentState.ERROR);
+      context.setProblem(t);
+      }
+      }
+      }
+
+      ...
+      }
+
+      ...
+      }
+      </programlisting>
+      <note>
+	<para>Undeployments are actually processed before deployments to ensure that we don&apos;t
+	end up in a situation where a deployment that depends on a subsequently undeployed
+	deployment has to be undeployed again straight away.</para>
+      </note>
+      <para>You should hopefully see from this breakdown that each deployment is processed by
+      creating a <emphasis>DeploymentControllerContext</emphasis> that is then installed into
+      the microcontainer controller and pushed through a series of deployment stages. What these
+      stages are and how they are created is the subject of the next section.</para>
+    </section>
+    <section>
+      <title>Deployment stages</title>
+      <para> By default the <emphasis>DeployersImpl</emphasis> class creates the following
+      deployment stages on construction:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>NOT_INSTALLED - the deployment is ready to be installed or has been
+	  uninstalled</para>
+	</listitem>
+	<listitem>
+	  <para>PARSE - deployment descriptors are parsed into deployment metadata</para>
+	</listitem>
+	<listitem>
+	  <para>DESCRIBE - dependencies on other deployments or runtime components are
+	  determined</para>
+	</listitem>
+	<listitem>
+	  <para>CLASSLOADER - a classloader for the deployment is created</para>
+	</listitem>
+	<listitem>
+	  <para>POST_CLASSLOADER - </para>
+	</listitem>
+	<listitem>
+	  <para>REAL - components are deployed into the runtime</para>
+	</listitem>
+	<listitem>
+	  <para>INSTALLED - the deployment is fully deployed</para>
+	</listitem>
+      </itemizedlist>
+      <para>Each <emphasis>DeploymentStage</emphasis> has a name and indicates which stages it
+      comes before and after: </para>
+      <programlisting role="JAVA">public class DeploymentStage
+      {
+      private String name;
+      
+      private String after;
+      
+      private String before;
+
+      ...
+      }</programlisting>
+      <para>This allows a new <emphasis>ControllerState</emphasis> to be created for each
+      <emphasis>DeploymentStage</emphasis> which can then be added in the correct place to the
+      list of ControllerStates associated with the controller:</para>
+      <programlisting role="JAVA">public class DeployersImpl implements Deployers, ControllerContextActions
+      {
+      ...
+
+      public DeployersImpl(AbstractController controller, Set&lt;Deployer&gt; deployers)
+      {
+      if (controller == null)
+      throw new IllegalArgumentException(&quot;Null controller&quot;);
+      this.controller = controller;
+      
+      // Add the standard stages
+      addDeploymentStage(DeploymentStages.NOT_INSTALLED);
+      addDeploymentStage(DeploymentStages.PARSE);
+      addDeploymentStage(DeploymentStages.DESCRIBE);
+      addDeploymentStage(DeploymentStages.CLASSLOADER);
+      addDeploymentStage(DeploymentStages.POST_CLASSLOADER);
+      addDeploymentStage(DeploymentStages.REAL);
+      addDeploymentStage(DeploymentStages.INSTALLED);
+
+      ...
+      }
+
+      ...
+
+      protected synchronized void addDeploymentStage(DeploymentStage stage)
+      {
+      if (stage == null)
+      throw new IllegalArgumentException(&quot;Null stage&quot;);
+      // Already done?
+      String stageName = stage.getName();
+      if (stages.containsKey(stageName))
+      return;
+
+      ControllerState preceeds = null;
+      String before = stage.getBefore();
+      String after = stage.getAfter();
+      if (before != null || after != null)
+      {
+      // Determine where to put the stage
+      List&lt;ControllerState&gt; states = controller.getStates();
+      for (int i = 0; i &lt; states.size(); ++i)
+      {
+      ControllerState state = states.get(i);
+      String stateName = state.getStateString();
+      if (before != null &amp;&amp; before.equals(stateName))
+      {
+      preceeds = state;
+      break;
+      }
+      if (after != null &amp;&amp; after.equals(stateName))
+      {
+      if (i &lt; states.size()-1)
+      {
+      preceeds = states.get(i+1);
+      break;
+      }
+      }
+      }
+      }
+
+      controller.addState(new ControllerState(stageName), preceeds);
+      stages.put(stageName, stage);
+      ...
+      }
+
+      ...
+      }</programlisting>
+      <para>The DeploymentStages are also stored in a map, using the stage name as a key, to
+      prevent duplicate stages from being added.</para>
+    </section>
+    <section>
+      <title>Deployment actions</title>
+      <para />
+    </section>
+    <section>
+      <title>Ordering (Inputs and outputs)</title>
+      <para />
+    </section>
+    <section>
+      <title>Deploying components</title>
+      <para />
+    </section>
+  </chapter>
+  <chapter>
+    <title>Putting it all together</title>
+    <section>
+      <title>Introduction</title>
+      
+      <para>
+	
+      </para>
+
+    </section>
+    <section>
+      <title>Defining the deployment framework</title>
+      
+      <para>
+	
+      </para>
+
+    </section>
+    <section>
+      <title>Defining deployment structures</title>
+      
+      <para>
+	
+      </para>
+
+    </section>
+    <section>
+      <title>Defining deployment actions</title>
+      
+      <para>
+	
+      </para>
+
+    </section>
+  </chapter>
+</part>

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Extending_the_Microcontainer.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Extending_the_Microcontainer.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Extending_the_Microcontainer.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,57 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+<part>
+  <title>Extending the Microcontainer</title>
+  <chapter>
+    <title>Introduction</title>
+    <section>
+      <title></title>
+      <para>
+	
+      </para>
+    </section>
+
+  </chapter>
+  <chapter>
+    <title>Guice Extension</title>
+    <section>
+      <title></title>
+      <para>
+	
+      </para>
+    </section>
+
+  </chapter>
+  <chapter>
+    <title>Identity Extension</title>
+    <section>
+      <title></title>
+      <para>
+	
+      </para>
+    </section>
+
+  </chapter>
+  <chapter>
+    <title>jBPM Extension</title>
+    <section>
+      <title></title>
+      <para>
+	
+      </para>
+    </section>
+
+  </chapter>
+  <chapter>
+    <title>Drools Extension</title>
+    <section>
+      <title></title>
+      <para>
+	
+      </para>
+    </section>
+
+  </chapter>
+</part>
\ No newline at end of file

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Getting_Started.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Getting_Started.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Getting_Started.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,1469 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+<part>
+  <title>Getting Started</title>
+  <chapter id="overview">
+    <title>Introduction</title>
+    <para>The Java platform has traditionally been distributed in 3 editions, each providing a
+    different type of runtime environment: </para>
+    <itemizedlist>
+      <listitem>
+	<para>Java ME (Micro Edition) - Mobile or other embedded devices</para>
+      </listitem>
+      <listitem>
+	<para>Java SE (Standard Edition) - Desktop machines or servers (typically running 2-tier
+	applications)</para>
+      </listitem>
+      <listitem>
+	<para>Java EE (Enterprise Edition) - Servers (typically running 3-tier
+	applications)</para>
+      </listitem>
+    </itemizedlist>
+    <para>Each environment aims to provide a base level of functionality on top of which
+    developers can add their own code to create applications. For example Java SE provides
+    networking and security libraries together with graphical user interface toolkits to
+    facilitate the development of desktop and simple client-server applications. Java EE takes
+    this a stage further by adding a number of &apos;enterprise services&apos; such as
+    transactions, messaging, and persistence that allow much more robust and scalable
+    &apos;enterprise applications&apos; to be developed. These services are typically combined
+    together inside a JEE application server in order to provide a standard runtime environment
+    for enterprise applications but it is often the case that some are never used.</para>
+    <para>Services that are never used are undesirable as they can take up valuable resources such
+    as CPU and memory resulting in lower performance. They may also clutter up the environment
+    with redundant configuration files, complicating maintenance and adding unnecessary
+    complexity. Given these drawbacks it would be better if there was a way to create a custom
+    runtime environment containing only those services that were needed. You would then be able
+    to create your own custom &apos;Java Edition&apos; tailored to your requirements.</para>
+    <para>JBoss Microcontainer aims to provide these capabilities by allowing services, created
+    using Plain Old Java Objects (POJOs), to be deployed into a standard Java SE runtime
+    environment in a controlled manner to create a customized environment for your applications.
+    Dependencies are fully managed to ensure that new services cannot be deployed until services
+    they depend on have first been deployed. Where it makes sense to do so you can even redeploy
+    services at runtime providing that you access them via the microcontainer bus. Undeploying a
+    service causes all dependent services to be undeployed first in order to maintain the
+    integrity of the system. </para>
+    <para>JBoss Application Server 5.0 uses the microcontainer to integrate enterprise services
+    together with a Servlet/JSP container, EJB container, deployers and management utilities in
+    order to provide a standard Java EE environment. If you need additional services then you
+    can simply deploy these on top of Java EE to provide the functionality you need. Likewise
+    you are free to remove any services that you don&apos;t need simply by changing the
+    configuration. You can even use the microcontainer to do this in other environments such as
+    Tomcat and GlassFish since you can plug in different classloading models during the service
+    deployment phase.</para>
+    <para>Since JBoss Microcontainer is very lightweight and deals with POJOs it can also be used
+    to deploy services into a Java ME runtime environment. This opens up new possibilities for
+    mobile applications that can now take advantage of enterprise services without requiring a
+    full JEE application server. </para>
+    <para>In common with other lightweight containers JBoss Microcontainer uses dependency
+    injection to wire individual POJOs together to create services. Configuration is performed
+    using either annotations or XML depending on where the information is best located. Finally
+    unit testing is made extremely simple thanks to a helper class that extends JUnit to setup
+    the test environment, allowing you to access POJOs and services from your test methods using
+    just a few lines of code.</para>
+  </chapter>
+  <chapter>
+    <title>Download and Installing</title>
+    <para>JBoss Microcontainer 2.0.0 is available for download from <ulink
+    url="http://www.jboss.org/jbossmc/downloads">the JBoss Microcontainer downloads</ulink>
+    page. The initial downloads page is split into two sections: <ulink
+    url="http://www.jboss.org/jbossmc/downloads/individual">Individual Projects</ulink>, which
+    contains the jars for the individual projects that make up the JBoss Microcontainer, and
+    <ulink url="http://www.jboss.org/jbossmc/downloads/framework">Frameworks</ulink>, which
+    give you usable distributions containing all the dependencies. The two frameworks shipped
+    are the <ulink url="http://www.jboss.org/jbossmc/downloads/framework/jboss-kernel">JBoss
+    Kernel</ulink> and <ulink
+    url="http://www.jboss.org/jbossmc/downloads/framework/jboss-deployers">JBoss Virtual
+    Deployment Framework</ulink>. The JBoss Kernel distribution contains the core framework,
+    which is discussed in Parts I, II and III. The JBoss Virtual Deployment Framework contains
+    the JBoss Kernel as well as advanced classloading capabilities and deployer functionality,
+    as discussed in Part IV.</para>
+    <para>JBoss Microcontainer 2.0.0 is also available via Maven2. This means that you need to
+    install and configure Maven before you can begin development. Once this is done then you can
+    create a maven project that depends on the JBoss Microcontainer JARs in order to download
+    and install them into your local maven repository. You can then create an assembly for your
+    final application in order to package the relevant JARs into a distributable format.</para>
+    <para>The examples created for this User Guide use Maven2 for their configuration to achieve
+    exactly this so it is highly recommended that you <ulink
+    url="http://labs.jboss.com/file-access/default/members/jbossmc/downloads/userGuide-examples-13112007.zip"
+    >download</ulink> these first and take a look at how they work.</para>
+    <note>
+      <para>To build and run the examples you first need to install and configure Maven 2.0.9
+      available from <ulink url="http://maven.apache.org/"
+      >http://maven.apache.org/</ulink></para>
+      <para>Installation is performed by downloading and unzipping the maven-2.0.9-bin.zip file to
+      a convenient location on your local disk. Configuration consists of adding $MAVEN_HOME/bin
+      to your path and adding the following profile to your ~/.m2/settings.xml file:</para>
+      <programlisting role="XML">&lt;settings&gt;
+      &lt;profiles&gt;
+      &lt;profile&gt;
+      &lt;id&gt;jboss.repository&lt;/id&gt;
+      &lt;activation&gt;
+      &lt;property&gt;          
+      &lt;name&gt;!jboss.repository.off&lt;/name&gt;
+      &lt;/property&gt;
+      &lt;/activation&gt;
+      &lt;repositories&gt;
+      &lt;repository&gt;
+      &lt;id&gt;snapshots.jboss.org&lt;/id&gt;
+      &lt;url&gt;http://snapshots.jboss.org/maven2&lt;/url&gt;
+      &lt;snapshots&gt;
+      &lt;enabled&gt;true&lt;/enabled&gt;
+      &lt;/snapshots&gt;
+      &lt;/repository&gt;
+      &lt;repository&gt;
+      &lt;id&gt;repository.jboss.org&lt;/id&gt;
+      &lt;url&gt;http://repository.jboss.org/maven2&lt;/url&gt;
+      &lt;snapshots&gt;
+      &lt;enabled&gt;false&lt;/enabled&gt;
+      &lt;/snapshots&gt;
+      &lt;/repository&gt;
+      &lt;/repositories&gt;
+      &lt;pluginRepositories&gt;
+      &lt;pluginRepository&gt;
+      &lt;id&gt;repository.jboss.org&lt;/id&gt;
+      &lt;url&gt;http://repository.jboss.org/maven2&lt;/url&gt;
+      &lt;snapshots&gt;
+      &lt;enabled&gt;false&lt;/enabled&gt;
+      &lt;/snapshots&gt;
+      &lt;/pluginRepository&gt;
+      &lt;pluginRepository&gt;
+      &lt;id&gt;snapshots.jboss.org&lt;/id&gt;
+      &lt;url&gt;http://snapshots.jboss.org/maven2&lt;/url&gt;
+      &lt;snapshots&gt;
+      &lt;enabled&gt;true&lt;/enabled&gt;
+      &lt;/snapshots&gt;
+      &lt;/pluginRepository&gt;
+      &lt;/pluginRepositories&gt;
+      &lt;/profile&gt;
+      &lt;/profiles&gt;
+      &lt;/settings&gt;</programlisting>
+      <para>This profile informs maven of the two JBoss repositories (snapshots and releases) that
+      are needed to download the JBoss Microcontainer and dependant JARs.</para>
+    </note>
+    <para>Once you have configured Maven and downloaded the examples then you can go to one of the
+    following subdirectories in the <filename>examples/User_Guide</filename> directory and enter
+    <command>mvn install</command> to perform a build:</para>
+    <itemizedlist>
+      <listitem>
+	<para>gettingStarted - projects for creating and using a service together with AOP</para>
+      </listitem>
+      <listitem>
+	<para>pojoDevelopment - examples of creating and configuring POJOs using XML and
+	annotations</para>
+      </listitem>
+      <listitem>
+	<para>aopDevelopment - examples of using AOP to add behaviour to POJOs</para>
+      </listitem>
+      <listitem>
+	<para>extending - examples of how we created various extensions to the microcontainer by
+	creating new dependencies</para>
+      </listitem>
+    </itemizedlist>
+    <para>Instructions on how to run the individual examples can be found in the corresponding
+    parts of this guide.</para>
+  </chapter>
+  <chapter>
+    <title>Building services</title>
+    <para>Before we talk about building services using POJOs it is necessary to define what we
+    mean by these terms.</para>
+    <para><emphasis role="bold">
+      <emphasis role="underline">POJOs</emphasis>
+    </emphasis></para>
+    <para>The term POJO is an acronym for Plain Old Java Object and was first coined while Rebecca
+    Parsons, Josh MacKenzie, and Martin Fowler were preparing for a talk at a conference in
+    September 2000. It describes the practice of encoding business logic in regular java objects
+    instead of components such as EJB 2.1 Entity Beans. The benefit of this approach is that
+    you&apos;re not required to implement any special interfaces. This not only keeps your code
+    simple but allows it to be used in a wider variety of environments and makes it easy to unit
+    test.</para>
+    <para><emphasis role="bold">Definition:</emphasis>
+    <emphasis role="italic">A POJO declares business methods, which define behaviour, and
+    properties, which represent state. Some properties represent associations to other
+    POJOs.</emphasis></para>
+    <para>For experienced developers this should sound familiar as it mimicks almost exactly the
+    proposals set out in the JavaBeans specification. JavaBeans describes a component model for
+    User Interface development emphasizing simplicity and standardized naming conventions for
+    property accessor methods. The idea was that this would allow automatic discovery of an
+    object&apos;s properties so that an instance could easily be created and populated with
+    state at runtime. The main use case was creating and configuring visual user interface
+    components such as text boxes, buttons, and tables from within an Integrated Development
+    Environment (IDE).</para>
+    <para><emphasis role="bold">Definition:</emphasis>
+    <emphasis role="italic">A Java Bean is a reusable software component that can be manipulated
+    visually in a builder tool.</emphasis></para>
+    <para> Importantly a Java Bean is not required to inherit from any particular base class or
+    interface. Also while Java Beans are primarily targeted at builder tools they are entirely
+    usable by programmers with conventional text editors.</para>
+    <para>Strictly speaking a Java Bean should include support for events and persistence but in
+    many cases developers choose not to implement these features and simply follow the
+    standardized naming conventions for property accessor methods; i.e. get and set. This
+    &apos;lightweight&apos; form of Java Bean is commonly referred to as simply a
+    &apos;bean&apos; and is semantically equivalent to a POJO.</para>
+    <para>The terms POJO and bean are therefore interchangeable and you will encounter both in the
+    microcontainer documentation and configuration files.</para>
+    <para><emphasis role="bold">
+      <emphasis role="underline">Services</emphasis>
+    </emphasis></para>
+    <para>The word &apos;service&apos; has many definitions in the English language but in the
+    context of developing Java applications it is helpful to define it as follows:</para>
+    <orderedlist>
+      <listitem>
+	<para>A service should perform work that is useful to multiple clients, thereby preventing
+	each client from having to perform the work themselves.</para>
+      </listitem>
+      <listitem>
+	<para>A service should have a name that clients can lookup at runtime to gain access. This
+	provides a standard way to access different kinds of services and removes the need for
+	clients to explicitly create them before they can be used. </para>
+      </listitem>
+      <listitem>
+	<para>Internal changes to a service should not affect any clients. In practice this means
+	that clients should access a service using a well defined interface so that the
+	implementation can be changed without having to recompile any clients. </para>
+      </listitem>
+    </orderedlist>
+    <para>Using this definition we can now answer some simple questions:</para>
+    <para>Q) Is a POJO a service?</para>
+    <para>A) No, because although it performs work that is useful to multiple clients you cannot
+    access it using a name. Also clients have to explicitly create a POJO themselves either
+    directly using the <systemitem>new</systemitem> operator or indirectly using a factory. </para>
+    <para>Q) Does a class have to implement an interface in order to provide a
+    &apos;well-defined&apos; interface?</para>
+    <para>A) Not necessarily. Providing that we don&apos;t remove fields or methods from a class,
+    or restrict access to them, we can always change its implementation without needing to
+    recompile any clients. See the section entitled <ulink
+    url="http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html#44524"
+    >Resolution of Symbolic References</ulink> from the Java Language Specification for more
+    details.</para>
+    <para>The &apos;well-defined&apos; interface in this respect is composed from the original
+    class&apos;s fields and methods together with their access modifiers.</para>
+    <note>
+      <para>Implementing an interface is only necessary if we want to allow a client to <emphasis
+      role="bold">choose</emphasis> between <emphasis role="bold">alternative
+      implementations</emphasis>. i.e. if the client is compiled against an interface then we
+      can provide as many different implementations of the interface as we like without having
+      to recompile the client. This is because the interface ensures that the method signatures
+      do not change.</para>
+    </note>
+    <para>What then must we do in order to create a service using a POJO? The answer is to provide
+    a naming mechanism that allows us to register a reference to the POJO instance with a name.
+    Clients can then lookup the POJO reference using the name at runtime and use it to perform
+    work. The POJO class is not required to implement an interface unless it is important that
+    the client can choose between alternative implementations. </para>
+    <para>JBoss Microcontainer provides such a naming mechanism in the form of a Controller so
+    that we can deploy our POJO services into a runtime environment such as Java SE and look
+    them up from within our applications.</para>
+    <para>Since robust implementations of Java EE services are already available from JBoss.org
+    and other communities it is common for companies to focus on creating more
+    &apos;business-oriented&apos; services. For this reason we shall look at creating,
+    configuring and testing a simple Human Resources service that could potentially be used by a
+    number of different applications.</para>
+    <section>
+      <title>Creating POJOs</title>
+      <para>The example that relates to this section can be found in the
+      <filename>examples/User_Guide/gettingStarted/humanResourcesService</filename> directory. The
+      directory layout, as with all of the examples for the User Guide, follows the <ulink
+      url="http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html"
+      >Maven Standard Directory Layout</ulink>.</para>
+      <para>
+	<programlisting>humanResourcesService/pom.xml
+	/src/main/java
+	/test/java
+	/test/resources</programlisting>
+      </para>
+      <para>Java source files are located in packages beneath the src/main/java directory:</para>
+      <para>
+	<programlisting>org/jboss/example/service/Address.java
+	/Employee.java
+	/HRManager.java
+
+	org/jboss/example/service/util/SalaryStrategy.java
+	/AgeBasedSalaryStrategy.java
+	/LocationBasedSalaryStrategy.java</programlisting>
+      </para>
+      <para>Each of these classes represents a simple POJO that doesn&apos;t implement any special
+      interfaces. The most important class is HRManager as this represents the service entry
+      point providing all of the public methods that clients will call.</para>
+      <itemizedlist>
+	<listitem>
+	  <para>addEmployee(Employee employee)</para>
+	</listitem>
+	<listitem>
+	  <para>removeEmployee(Employee employee)</para>
+	</listitem>
+	<listitem>
+	  <para>getEmployee(String firstName, String lastName)</para>
+	</listitem>
+	<listitem>
+	  <para>getEmployees()</para>
+	</listitem>
+	<listitem>
+	  <para>getSalary(Employee employee)</para>
+	</listitem>
+	<listitem>
+	  <para>setSalary(Employee employee, Integer newSalary)</para>
+	</listitem>
+	<listitem>
+	  <para>isHiringFreeze()</para>
+	</listitem>
+	<listitem>
+	  <para>setHiringFreeze(boolean hiringFreeze)</para>
+	</listitem>
+	<listitem>
+	  <para>getSalaryStrategy()</para>
+	</listitem>
+	<listitem>
+	  <para>setSalaryStrategy(SalaryStrategy strategy)</para>
+	</listitem>
+      </itemizedlist>
+      <para>The Human Resources Service is therefore composed of a handful of classes which work
+      together to allow a list of employees, together with details of their addresses and
+      salaries, to be maintained by an HRManger. Thanks to the SalaryStrategy interface it is
+      possible to configure the HRManager so that different salary strategy implementations are
+      used. These place minimum and maximum limits on the salaries that can be awarded to
+      employees depending on various rules.</para>
+      <para>To compile the source code you simply need to enter <command>mvn compile</command> from the
+      <filename>humanResourcesService/</filename> directory. This will create a new directory called
+      <filename>target/classes</filename> containing the compiled code. To clean up the project and
+      remove the <filename>target</filename> directory simply enter <command>mvn clean</command>. </para>
+      <para>Now that we have compiled our classes we need to create instances of them. This is
+      done by creating an XML deployment descriptor that contains a list of beans representing
+      individual instances. Each bean is given a name so that the instance can be looked up at
+      runtime by clients.</para>
+      <programlisting role="XML">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+
+      &lt;deployment xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+      xsi:schemaLocation=&quot;urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd&quot;
+      xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+      &lt;bean name=&quot;HRService&quot; class=&quot;org.jboss.example.service.HRManager&quot;/&gt;
+      
+      &lt;/deployment&gt;</programlisting>
+      <para>Here we have declared that we want to create an instance of the HRManager class and
+      register it with the name HRService. This file is passed to an XML deployer associated
+      with the microcontainer at runtime to perform the actual deployment and instantiate the
+      beans.</para>
+    </section>
+    <section>
+      <title>Wiring POJOs together </title>
+      <para>So far we have seen how to create POJOs and declare instances of them together with
+      names in an XML deployment descriptor. However, individual POJO instances can only provide
+      relatively simple behaviour. Things really get interesting when we combine POJOs together
+      to perform more complex tasks. In our example we know that we can choose different salary
+      strategy implementations for the HRManager so how do we go about wiring the POJOs
+      together?</para>
+      <para>The answer is to use the XML deployment descriptor again as follows:</para>
+      <programlisting role="XML">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+
+      &lt;deployment xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+      xsi:schemaLocation=&quot;urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd&quot;
+      xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+      &lt;bean name=&quot;HRService&quot; class=&quot;org.jboss.example.service.HRManager&quot;&gt;
+      &lt;property name=&quot;salaryStrategy&quot;&gt;<emphasis>&lt;inject bean=&quot;AgeBasedSalary&quot;/&gt;</emphasis>&lt;/property&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;AgeBasedSalary&quot;
+      class=&quot;org.jboss.example.service.util.AgeBasedSalaryStrategy&quot;/&gt;
+      
+      &lt;/deployment&gt;</programlisting>
+      <para>We first need to create an instance of our chosen salary strategy implementation by
+      including an additional &lt;bean&gt; element. Here we have chosen the
+      AgeBasedSalaryStrategy. Next we need to inject a reference to this bean into the instance
+      of HRManager created using the HRService bean. Injection is possible as the HRManager
+      class contains a <methodname>setSalaryStrategy(SalaryStrategy strategy)</methodname> method. Behind
+      the scenes JBoss Microcontainer will call this method on the newly created HRManager
+      instance and pass in a reference to the AgeBasedSalaryStrategy instance.</para>
+      <para>In other words the XML deployment descriptor causes the same sequence of events to
+      occur as if you had written the following code:</para>
+      <programlisting role="JAVA">HRManager hrService = new HRManager();
+      AgeBasedSalaryStrategy ageBasedSalary = new AgeBasedSalaryStrategy();
+      hrService.setSalaryStrategy(ageBasedSalary);</programlisting>
+      <para>In addition to performing injection via property setter methods JBoss Microcontainer
+      can also perform injection via constructor parameters if necessary. For more details
+      please see the &apos;Injection&apos; chapter in Part II &apos;POJO Development&apos;. </para>
+      <note>
+	<para>Although we can create instances of classes using the &lt;bean&gt; element in the
+	deployment descriptor it is not always appropriate to do so. For example we do not need
+	to create instances of the Employee and Address classes since these will be created by
+	the client in response to input from the user. As such they remain part of the service
+	but are not mentioned in the deployment descriptor. </para>
+      </note>
+      <note>
+	<para>Also note that it is possible to define multiple beans within a deployment
+	descriptor providing that each has a unique name. The names are required in order to
+	perform injection as shown above. However this does not mean to say that all of the
+	beans represent services. While a service could be implemented using a single bean it is
+	most often the case that multiple beans are used together as in our example. In these
+	cases there is usually one bean that represents the service entry point containing the
+	public methods intended for the clients to call. In our example this is the HRService
+	bean. Notice that there is nothing in the XML deployment descriptor to say which beans
+	represent a service or indeed which bean if any is the service entry point (a service
+	may run autonomously in which case it is its own client). Care must therefore be taken
+	when creating deployment descriptors to ensure that sufficient comments are included to
+	describe what the beans are used for. Alternatively a naming convention such as ending
+	each bean name that represents a service entry point with &apos;Service&apos; can be
+	used instead, e.g. HRService.</para>
+      </note>
+    </section>
+    <section>
+      <title>Configuring a service</title>
+      <para>Injecting references between POJO instances is one way of configuring a service
+      however we can also inject values into POJO properties. The following deployment
+      descriptor shows how we can configure the HRManager instance to have a hiring freeze and
+      the AgeBasedSalaryStrategy to have new minimum and maximum salary values:</para>
+      <programlisting role="XML">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+
+      &lt;deployment xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+      xsi:schemaLocation=&quot;urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd&quot;
+      xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+      &lt;bean name=&quot;HRService&quot; class=&quot;org.jboss.example.service.HRManager&quot;&gt;
+      <emphasis>&lt;property name=&quot;hiringFreeze&quot;&gt;false&lt;/property&gt;</emphasis>
+      &lt;property name=&quot;salaryStrategy&quot;&gt;&lt;inject bean=&quot;AgeBasedSalary&quot;/&gt;&lt;/property&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;AgeBasedSalary&quot; 
+      class=&quot;org.jboss.example.service.util.AgeBasedSalaryStrategy&quot;&gt;
+      <emphasis>&lt;property name=&quot;minSalary&quot;&gt;1000&lt;/property&gt;
+      &lt;property name=&quot;maxSalary&quot;&gt;80000&lt;/property&gt;</emphasis>
+      &lt;/bean&gt;
+      
+      &lt;/deployment&gt;</programlisting>
+      <para>As with wiring POJOs together the classes need to have public setter methods for the
+      relevant properties so that values can be injected. For example the HRManager class has a
+      <classname>setHiringFreeze(boolean hiringFreeze)</classname> method and the AgeBasedSalaryStrategy
+      class has <classname>setMinSalary(int minSalary)</classname> and <methodname>setMaxSalary(int
+      maxSalary)</methodname> methods.</para>
+      <para>The values in the deployment descriptor are converted from strings into the relevant
+      types (boolean, int etc...) by JavaBean <ulink
+      url="http://java.sun.com/j2se/1.5.0/docs/api/java/beans/PropertyEditor.html"
+      >PropertyEditors</ulink>. A large number of these are provided by default for standard
+      types but you can easily create your own if necessary. See the Properties chapter in Part
+      II &apos;POJO Development&apos; for more details.</para>
+    </section>
+    <section>
+      <title>Testing a service</title>
+      <para>We should now have a good idea about how to create POJOs and configure them using an
+      XML deployment descriptor so how do we go about testing them? Thankfully JBoss
+      Microcontainer makes it extremely easy to unit test individual POJOs as well as POJOs that
+      are wired together through the use of a MicrocontainerTest class.</para>
+      <para>The org.jboss.test.kernel.junit.MicrocontainerTest class inherits from
+      junit.framework.TestCase and as such it sets up each test by bootstrapping JBoss
+      Microcontainer and adding a BasicXMLDeployer. It then looks on the classpath for an XML
+      deployment descriptor with the same name as the test class ending in .xml and residing in
+      a directory structure representing the class&apos;s package name. Any beans found in this
+      file are deployed and can then be accessed using a convenience method called
+      <methodname>getBean(String name)</methodname>. </para>
+      <para>You can see examples of these deployment descriptors in the src/test/resources
+      directory:</para>
+      <programlisting>org/jboss/example/service/HRManagerTestCase.xml
+      /HRManagerAgeBasedTestCase.xml
+      /HRManagerLocationBasedTestCase.xml
+
+      org/jboss/example/service/util/AgeBasedSalaryTestCase.xml
+      /LocationBasedSalaryTestCase.xml</programlisting>
+      <para>The test code is located in the src/test/java directory:</para>
+      <programlisting>org/jboss/example/service/HRManagerTestCase.java
+      /HRManagerAgeBasedTestCase.xml
+      /HRManagerLocationBasedTestCase.xml
+      /HRManagerTest.java
+      /HRManagerTestSuite.java
+
+      org/jboss/example/service/util/AgeBasedSalaryTestCase.java
+      /LocationBasedSalaryTestVase.java
+      /SalaryStrategyTestSuite.java</programlisting>
+      <para>The HRManagerTest class extends MicrocontainerTest in order to set up a number of
+      employees to use as the basis for the tests. Individual test cases then subclass this to
+      perform the actual work. You can also see a couple of TestSuite classes that are used to
+      group individual test cases together for convenience.</para>
+      <para>To run the tests simply enter <command>mvn test</command> from the
+      <filename>humanResourcesService/</filename> directory. You should see some DEBUG log output
+      which shows JBoss Microcontainer booting up and deploying beans from the relevant XML file
+      before running each test. At the end of the test it then undeploys the beans and shuts
+      down the microcontainer.</para>
+      <note>
+	<para>Some of the tests such as HRManagerTestCase, AgeBasedSalaryTestCase and
+	LocationBasedSalaryTestCase simply unit test individual POJOs whilst other tests such as
+	HRManagerAgeBasedTestCase and HRManagerLocationBasedTestCase unit test the whole service
+	consisting of multiple POJOs wired together. Either way the method for conducting the
+	tests remains the same. Thanks to the MicrocontainerTest class it is trivial to set up
+	and conduct comprehensive tests for any part of your code.</para>
+	<para>Finally note that we didn&apos;t unit test the Address or Employee classes here.
+	They were deliberately left out as they only contain trivial logic which is very
+	unlikely to break.</para>
+      </note>
+    </section>
+    <section>
+      <title>Packaging a service</title>
+      <para>Now that we have successfully created and tested our service it is time to package it
+      up so that others can use it. The simplest way to do this is to create a JAR containing
+      all of the classes. You can choose to include the deployment descriptor if there is a
+      sensible default way to configure the service but you are not required to do so.</para>
+      <para>If you do choose to include the deployment descriptor then by convention you should
+      call it <filename>jboss-beans.xml</filename> and put it in a META-INF directory. This helps if you
+      want to later deploy the service in JBoss AS 5 as the JAR deployer recognises this layout
+      by default and will automatically perform the deployment.</para>
+      <para>In our case we will not include it as we want to configure the service by editing the
+      descriptor directly as a separate file. To generate a JAR in the <filename>target</filename>
+      directory containing all of the compiled classes simply enter <command>mvn package</command>
+      from the <filename>humanResourcesService/</filename> directory. </para>
+      <para>To make the JAR available to other maven projects you then need to enter <command>mvn
+      install</command> in order to copy it to your local maven repository.</para>
+      <para>The final layout of the JAR is as follows:</para>
+      <programlisting>org/jboss/example/service/Address.class
+      /Employee.class
+      /HRManager.class
+      org/jboss/example/service/util/AgeBasedSalaryStrategy.class
+      /LocationBasedSalaryStrategy.class
+      /SalaryStrategy.class
+      META-INF/MANIFEST.MF
+      META-INF/maven/org.jboss.microcontainer.examples/humanResourcesService/pom.xml
+      /pom.properties</programlisting>
+      <para>The META-INF/maven directory is automatically produced by maven and is required so
+      that other maven projects can use this JAR as a dependency. If you are not using maven as
+      your build system then you will not have this directory.</para>
+    </section>
+  </chapter>
+  <chapter>
+    <title>Using services </title>
+    <para>In the previous chapter we looked at how to create, configure, test and package a
+    service. It is now time to move on and create a client so that we can use the service to
+    perform actual work.</para>
+    <para>In order to keep things simple the client uses a Text User Interface (TUI) to accept
+    input from the user and output results. In the real-world a Graphical User Interface (GUI)
+    would almost certainly be used but here we are more concerned with demonstrating how the
+    client interacts with the service than showing how to develop a rich desktop
+    application.</para>
+    <para>You will find all of the necessary files in the
+    <filename>examples/User_Guide/gettingstarted/commandLineClient</filename> directory. As with the
+    previous example this follows the Maven Standard Directory Layout: </para>
+    <programlisting>commandLineClient/pom.xml
+    /src/main/assembly
+    /main/config
+    /main/java
+    /main/resources
+    /test/java
+    /test/resources</programlisting>
+    <para>The client consists of 3 classes and 1 interface, located in the
+    <filename>src/main/java</filename> directory:</para>
+    <programlisting>org/jboss/example/client/Client.java
+    /ConsoleInput.java
+    /EmbeddedBootstrap.java
+    /UserInterface.java</programlisting>
+    <para>UserInterface describes methods that the client will call at runtime to request data
+    from the user. ConsoleInput is an implementation of this that creates a TUI allowing the
+    user to operate the client from the command line. The advantage of this design is that we
+    can easily create a Swing implementation of UserInterface at a later date and replace the
+    TUI with a GUI if we decide to improve usability. We can also create a mock implementation
+    for testing purposes that simulates a user entering data. This allows us to check the
+    behaviour of the client automatically using conventional JUnit test cases as demonstrated by
+    the code in the <filename>src/test/java</filename> directory:</para>
+    <programlisting>org/jboss/example/client/ClientTestCase.java
+    /ClientTestSuite.java
+    /MockUserInterface.java</programlisting>
+    <para>To compile the source code, run the unit tests, build a client JAR and assemble a
+    distribution containing all of the necessary files simply type <command>mvn package</command> from
+    the <filename>commandLineClient</filename> directory. </para>
+    <warning>
+      <para>For the build to work you must first have built and installed auditAspect.jar from the
+      <filename>examples/User_Guide/gettingStarted/auditAspect</filename> directory using the
+      <command>mvn install</command> command. This is because we actually create a number of
+      different client distributions including one based on AOP which relies on auditAspect.jar
+      being available in the local maven repositiory.</para>
+      <para>If you previously typed <command>mvn install</command> from the
+      <filename>examples/User_Guide/gettingStarted</filename> directory then you will have already
+      built and installed humanResourcesService.jar together with auditAspect.jar and the client
+      will have already been packaged so this step will not be necessary.</para>
+    </warning>
+    <para>Once you have successfully compiled and packaged the client you will find the following
+    subdirectories in the <filename>commandLineClient/target</filename> directory:</para>
+    <itemizedlist>
+      <listitem>
+	<para>client-pojo.dir - used to call the service without any AOP</para>
+      </listitem>
+      <listitem>
+	<para>client-cl.dir - used to demonstrate classloading features</para>
+      </listitem>
+      <listitem>
+	<para>client-aop.dir - used in Chapter 5. Adding behaviour through AOP</para>
+      </listitem>
+    </itemizedlist>
+    <para>Each of these represents a different distribution containing all of the shell scripts,
+    JARs, and XML deployment descriptors that we need to run the client in different
+    configurations. For the moment we will use the client-pojo distribution which can be found
+    in the client-pojo.dir subdirectory:</para>
+    <programlisting>run.sh
+    client-1.0.0.jar
+    jboss-beans.xml
+    lib/concurrent-1.3.4.jar
+    /humanResourcesService-1.0.0.jar
+    /jboss-common-core-2.0.4.GA.jar
+    /jboss-common-core-2.2.1.GA.jar
+    /jboss-common-logging-log4j-2.0.4.GA.jar
+    /jboss-common-logging-spi-2.0.4.GA.jar
+    /jboss-container-2.0.0.Beta6.jar
+    /jboss-dependency-2.0.0.Beta6.jar
+    /jboss-kernel-2.0.0.Beta6.jar
+    /jbossxb-2.0.0.CR4.jar
+    /log4j-1.2.14.jar
+    /xercesImpl-2.7.1.jar</programlisting>
+    <para>To run the client simply <command>cd</command> into <filename>client-pojo.dir</filename> and type
+    <command>./run.sh</command>. You will then be presented with the following menu of options: </para>
+    <mediaobject>
+      <imageobject>
+	<imagedata align="center" fileref="images/tuiMenu.png" />
+      </imageobject>
+    </mediaobject>
+    <para>To select an option enter the letter shown on the left-hand side and press return. For
+    example to redisplay the menu options enter &apos;m&apos; followed by return. This is useful
+    if they scroll off the top of the screen as you input data and read results. Entering more
+    than one letter or entering an invalid option will result in an appropriate error
+    message.</para>
+    <important>
+      <para>The run.sh script sets up the runtime environment by adding all of the JARs found in
+      the <filename>lib</filename> directory to the classpath using the <filename>java.ext.dirs</filename>
+      system property. It also adds the current directory and the client-1.0.0.jar using the
+      <command>-cp</command> flag so that the jboss-beans.xml deployment descriptor can be found at
+      runtime together with the org.jboss.example.client.Client class which is called to start
+      the application.</para>
+    </important>
+    <section>
+      <title>Bootstrapping the microcontainer</title>
+      <para>Before we use the client to deploy and call our service, lets take a closer look at
+      what happened during its construction:</para>
+      <programlisting role="JAVA">public Client(final boolean useBus) throws Exception {
+      this.useBus = useBus;
+
+      ClassLoader cl = Thread.currentThread().getContextClassLoader();
+      url = cl.getResource(&quot;jboss-beans.xml&quot;);
+
+      // Start JBoss Microcontainer
+      bootstrap = new EmbeddedBootstrap();
+      bootstrap.run();
+
+      kernel = bootstrap.getKernel();
+      controller = kernel.getController();
+      bus = kernel.getBus();
+      }</programlisting>
+      <para>First of all a url representing the jboss-beans.xml deployment descriptor was created.
+      This is required later on by the XML deployer so that we can deploy and undeploy beans
+      declared in the file. Here we have chosen to use the getResource() method of the
+      application classloader as we deliberately placed the jboss-beans.xml file on the
+      classpath. However, this is not a requirement and you are free to call the deployment
+      descriptor anything you like and place it anywhere you want provided that the URL is valid
+      and reachable.</para>
+      <para>Next we created an instance of JBoss Microcontainer together with an XML deployer.
+      This process is called bootstrapping and for convenience a BasicBootstrap class is
+      provided as part of the microcontainer to allow for configuration via system properties.
+      To add an XML deployer we simply extend BasicBootstrap to create an EmbeddedBootstrap
+      class and override the protected bootstrap() method as follows:</para>
+      <programlisting role="JAVA">public class EmbeddedBootstrap extends BasicBootstrap {
+
+      protected BasicXMLDeployer deployer;
+
+      public EmbeddedBootstrap() throws Exception {
+      super();
+      }
+
+      public void bootstrap() throws Throwable {
+      super.bootstrap();
+      deployer = new BasicXMLDeployer(getKernel());
+      Runtime.getRuntime().addShutdownHook(new Shutdown());
+      }
+
+      public void deploy(URL url) {
+      ...
+      deployer.deploy(url);
+      ...
+      }
+
+      public void undeploy(URL url) {
+      ...
+      deployer.undeploy(url);
+      ...
+      }
+
+      protected class Shutdown extends Thread {
+      public void run() {
+      log.info(&quot;Shutting down&quot;);
+      deployer.shutdown();
+      }
+      }
+      }</programlisting>
+      <para>The shutdown hook ensures that when the JVM is exited all of the beans are undeployed
+      in the correct order. The public deploy/undeploy methods simply delegate to the
+      BasicXMLDeployer so that we can deploy and undeploy beans declared in our jboss-beans.xml
+      file.</para>
+      <para>Finally we stored references to the microcontainer controller and bus so that we can
+      lookup bean references by name and access them directly or indirectly as necessary.</para>
+    </section>
+    <section>
+      <title>Deploying the service</title>
+      <para>Once the client has been created we can proceed to deploy the Human Resources service.
+      This is done by entering the &apos;d&apos; option. You should see the following log output
+      indicating that the BasicXMLDeployer has parsed the <emphasis>
+      <property>jboss-beans.xml</property>
+      </emphasis> file using the url and instantiated the beans found within.</para>
+      <mediaobject>
+	<imageobject>
+	  <imagedata align="center" fileref="images/deployOutput.png" />
+	</imageobject>
+      </mediaobject>
+      <note>
+	<para>The microcontainer is able to instantiate the beans as their classes are available
+	in the extension classpath inside the <filename>lib/humanResourcesService.jar</filename> file.
+	We could have equally placed these classes in an exploded directory structure and added
+	this to the application classpath but in general you will package them in a JAR for
+	convenience. </para>
+      </note>
+      <para>Notice that our deployment descriptor is entirely separate from the
+      humanResourcesService.jar file. This is done on purpose so that you can easily edit it and
+      test your changes by redeploying the service. The jboss-beans.xml file in the example
+      contains some commented out fragments of XML that you can uncomment to configure it in
+      different ways:</para>
+      <programlisting role="XML">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+      &lt;deployment xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+      xsi:schemaLocation=&quot;urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd&quot;
+      xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+      &lt;bean name=&quot;HRService&quot; class=&quot;org.jboss.example.service.HRManager&quot;&gt;
+      &lt;!-- &lt;property name=&quot;hiringFreeze&quot;&gt;true&lt;/property&gt;
+      &lt;property name=&quot;salaryStrategy&quot;&gt;&lt;inject bean=&quot;AgeBasedSalary&quot;/&gt;&lt;/property&gt; --&gt;
+      &lt;/bean&gt;
+
+      &lt;!-- &lt;bean name=&quot;AgeBasedSalary&quot; 
+      class=&quot;org.jboss.example.service.util.AgeBasedSalaryStrategy&quot;&gt;
+      &lt;property name=&quot;minSalary&quot;&gt;1000&lt;/property&gt;
+      &lt;property name=&quot;maxSalary&quot;&gt;80000&lt;/property&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;LocationBasedSalary&quot;
+      class=&quot;org.jboss.example.service.util.LocationBasedSalaryStrategy&quot;&gt;
+      &lt;property name=&quot;minSalary&quot;&gt;2000&lt;/property&gt;
+      &lt;property name=&quot;maxSalary&quot;&gt;90000&lt;/property&gt;
+      &lt;/bean&gt; --&gt;
+
+      &lt;/deployment&gt;</programlisting>
+      <important>
+	<para>Depending on how you access the service at runtime you may need to shutdown the
+	application and restart it again to redeploy the service and see your changes. This
+	reduces the flexibility of the application but results in faster performance at runtime.
+	Alternatively you may be able to simply redeploy the service whilst the application is
+	running. This increases flexilibity but results in slower runtime performance. Careful
+	consideration of these tradeoffs must be made before deciding on the approach you will
+	take.</para>
+      </important>
+    </section>
+    <section>
+      <title>Direct access</title>
+      <para>If no parameter is given to the <filename>run.sh</filename> script when the client is started
+      then a reference to the HRService bean is looked up using the microcontainer controller
+      once the service is deployed:</para>
+      <programlisting role="JAVA">private HRManager manager;
+      ...
+      private final static String HRSERVICE = &quot;HRService&quot;;
+
+      ...
+
+      void deploy() {
+      bootstrap.deploy(url);
+      if (!useBus &amp;&amp; manager == null) {
+      ControllerContext context = controller.getInstalledContext(HRSERVICE);
+      if (context != null) { manager = (HRManager) context.getTarget(); }
+      }
+      }</programlisting>
+      <para>Rather than immediately looking up a reference to the bean instance we first lookup a
+      reference to a <systemitem>ControllerContext</systemitem>. We then obtain a reference to the bean
+      instance from the context using the <methodname>getTarget()</methodname> method. The reason for this
+      is because the bean can exist in many states within the microcontainer e.g. NOT_INSTALLED,
+      DESCRIBED, INSTANTIATED, CONFIGURED, INSTALLED. In order to keep track of which state the
+      bean is in we need to wrap it in another object called a context that describes the
+      current state. The name of the context is the same as the bean name. Once a context
+      reaches the INSTALLED state then the bean it represents is considered to be
+      deployed.</para>
+      <para>Now that we have a reference to the bean instance representing our service entry point
+      we can call methods on it to perform work:</para>
+      <programlisting role="JAVA">@SuppressWarnings(&quot;unchecked&quot;)
+      Set&lt;Employee&gt; listEmployees() {
+      if (useBus)
+      ...
+      else
+      return manager.getEmployees();
+      }</programlisting>
+      <para>The client is said to be accessing the service directly since it&apos;s using a
+      reference to the actual bean instance. Performance is good as each method call goes
+      directly to the bean but what happens if we want to reconfigure the service and redeploy
+      it whilst the application is running? </para>
+      <para>Reconfiguration as we know is achieved by making changes to the XML deployment
+      descriptor and saving the file but in order to redeploy the service we must first undeploy
+      the current one. During undeployment the microcontainer controller releases its reference
+      to the bean instance together with any beans that depend on it. The intention is that
+      these beans will subsequently become available for garbage collection as they are no
+      longer required by the application. Deploying the service again creates new bean instances
+      representing the new configuration. Any subsequent lookups from clients will then retrieve
+      references to these new instances and they will be able to access the reconfigured
+      service.</para>
+      <para>The problem is that we cache the reference to the bean instance representing our
+      service entry point in our client when we deploy the service for the first time.
+      Undeploying the service therefore has no affect as the bean instance can still be accessed
+      using the cached reference and it will not be garbage collected until the client releases
+      it. Similarly deploying the service again will not cause another lookup as the client
+      already has a cached reference. It will therefore continue to use the bean instance
+      representing the initial service configuration.</para>
+      <note>
+	<para>You can test this behaviour for yourself by typing &apos;u&apos; followed by return
+	to undeploy the current service. You should still be able to access the service from the
+	client even though it is &apos;undeployed&apos;. Now make some changes to the
+	configuration using the jboss-beans.xml file and deploy it again using the &apos;d&apos;
+	option (remember to save any changes you make to jboss-beans.xml first). Printing out
+	the status of the service using the &apos;p&apos; option should allow you to see that
+	the client is still accessing the initial instance of the service that was
+	deployed.</para>
+      </note>
+      <warning>
+	<para>Even if we change our client so that we lookup a new reference each time the service
+	is redeployed there is nothing to prevent new developers from coming along and
+	mistakedly handing out copies of this reference to other objects. If all of these
+	references are not cleaned up during redeployment then this then puts us in the same
+	situation as before with access to older instances of the service still possible.</para>
+      </warning>
+      <para>To reliably redeploy the reconfigured service you must therefore shutdown the
+      application completely using the &apos;q&apos; option and restart it again using the
+      <filename>run.sh</filename> script. For enterprise services such as transactions, messaging and
+      persistance this is perfectly acceptable since they are generally always in use. As such
+      they cannot be redeployed at runtime and benefit from the high performance given by using
+      direct access. If your service falls into this category then you too should consider using
+      direct access via the microcontainer controller.</para>
+    </section>
+    <section>
+      <title>Indirect access</title>
+      <para>The <filename>run.sh</filename> script can be called with an optional parameter
+      &apos;bus&apos; to specify that calls to the Human Resources service should take place
+      using the microcontainer bus:</para>
+      <programlisting>./run.sh bus</programlisting>
+      <para>Instead of using a direct reference to the bean instance obtained from the
+      microcontainer controller we now call an invoke() method on the bus passing in the bean
+      name, method name, method arguments and method types. The bus takes this information and
+      uses it to call the bean on the client&apos;s behalf.</para>
+      <programlisting role="JAVA">private final static String HRSERVICE = &quot;HRService&quot;;
+
+      ...
+
+      @SuppressWarnings(&quot;unchecked&quot;)
+      Set&lt;Employee&gt; listEmployees() {
+      if (useBus)
+      return (Set&lt;Employee&gt;) invoke(HRSERVICE, &quot;getEmployees&quot;, new Object[] {}, new String[] {});
+      else
+      return manager.getEmployees();
+      }
+
+      private Object invoke(String serviceName, String methodName, Object[] args, String[] types) {
+      Object result = null;
+      try {
+      result = bus.invoke(serviceName, methodName, args, types);
+      } catch (Throwable t) {
+      t.printStackTrace();
+      }
+      return result;
+      }</programlisting>
+      <para>Behind the scenes the bus looks up the reference to the bean instance specified by the
+      bean name and calls the chosen method using reflecton. Since the client never has a direct
+      reference to the bean instance we say that it accesses the service &apos;indirectly&apos;.
+      As the bus does not cache the reference we can safely make changes to our service
+      configuration and redeploy it at runtime. Subsequent calls by the client will then result
+      in the new reference to the service being used as expected. In technical terms we say that
+      the client and service have been decoupled.</para>
+      <note>
+	<para>You can test this behaviour for yourself by deploying the service and using the
+	&apos;p&apos; option to print out the status. Undeploy the service using the
+	&apos;u&apos; option and check that you cannot access it anymore. Now make some changes
+	to the configuration using the jboss-beans.xml file and deploy it again using the
+	&apos;d&apos; option (remember to save any changes you make to jboss-beans.xml first).
+	Printing out the status again using the &apos;p&apos; option should reveal that the
+	client is accessing the new service configuration.</para>
+      </note>
+      <para>As the bus uses reflection to call bean instances it is slower than using direct
+      access. The benefit however is that only the bus has references to the bean instances.
+      This means that when a service is redeployed we can clean up all of the existing
+      references and replace them with new ones, allowing us to reliably redeploy a service at
+      runtime. Services that are not used very often or that are specific to certain
+      applications are good candidates for indirect access using the microcontainer bus. This is
+      either because the reduction in performance does not matter if the service is used rarely
+      or the service can be deployed and undeployed together with the relevant applications to
+      keep the runtime environment clean.</para>
+    </section>
+    <section>
+      <title>Dynamic classloading</title>
+      <para>So far we have been using the extension and application classloaders to load all of
+      the classes in our application. The application classpath was setup by the
+      <filename>run.sh</filename> script using the -cp flag to include the current directory and the
+      client-1.0.0.jar.</para>
+      <programlisting>java -Djava.ext.dirs=`pwd`/lib -cp .:client-1.0.0.jar org.jboss.example.client.Client $1</programlisting>
+      <para>For convenience the JARs in the lib directory were added to the extenion
+      classloader&apos;s classpath using the <filename>java.ext.dirs</filename> system property as this
+      prevents us from having to list the full path to each of the JARs after the -cp flag.
+      Since the extension classloader is the parent of the application classloader our client
+      classes can find all of the microcontainer classes together with the Human Resources
+      service classes at runtime.</para>
+      <note>
+	<para>If you are using Java 6+ then you can use a wildcard to include all JARs in a
+	directory with the -cp
+	flag.<programlisting>java -cp `pwd`/lib/*:.:client-1.0.0.jar org.jboss.example.client.Client $1</programlisting>This
+	means that all of the classes in our application will be added to the application
+	classloader&apos;s classpath and the extension classloader&apos;s classpath will retain
+	its default value.</para>
+      </note>
+      <para>This is all well and good but what happens if we now want to deploy an additional
+      service at runtime? If the new service is packaged in a JAR file then it needs to be
+      visible to a classloader before any of its classes can be loaded. The trouble is we have
+      already setup the classpath for the application classloader (and extension classloader) on
+      startup so we cannot easily add the url of the JAR. The same situation applies if the
+      service classes are contained in a directory structure. Unless the top-level directory is
+      located in the current directory (which is on the application classpath) then the classes
+      will not be found by the application classloader.</para>
+      <para>It&apos;s also possible that we may wish to redeploy an existing service with changes
+      to some of its classes. Since it is forbidden for an existing classloader to reload
+      classes due to security constraints how can this be done?</para>
+      <para>What we need is the ability to create a new classloader that knows the location of the
+      new service&apos;s classes, or that can load new versions of an existing service&apos;s
+      classes, so that we can deploy the service&apos;s beans. JBoss Microcontainer allows us to
+      do this using the &lt;classloader&gt; element in the deployment descriptor.</para>
+      <para>The client-cl distribution in the <filename>commandLineClient/target/client-cl.dir</filename>
+      directory contains the following files that demonstrate how this works: </para>
+      <programlisting>run.sh
+      client-1.0.0.jar
+      jboss-beans.xml
+      lib/concurrent-1.3.4.jar
+      /jboss-common-core-2.0.4.GA.jar
+      /jboss-common-core-2.2.1.GA.jar
+      /jboss-common-logging-log4j-2.0.4.GA.jar
+      /jboss-common-logging-spi-2.0.4.GA.jar
+      /jboss-container-2.0.0.Beta6.jar
+      /jboss-dependency-2.0.0.Beta6.jar
+      /jboss-kernel-2.0.0.Beta6.jar
+      /jbossxb-2.0.0.CR4.jar
+      /log4j-1.2.14.jar
+      /xercesImpl-2.7.1.jar
+      otherLib/humanResourcesService-1.0.0.jar</programlisting>
+      <para>As you can see the humanResourcesService.jar file has been moved to a new subdirectory
+      called <filename>otherLib</filename>. In this location it is no longer available to either the
+      extension or application classloaders whose classpaths are setup in the
+      <filename>run.sh</filename> script:</para>
+      <programlisting>java -Djava.ext.dirs=`pwd`/lib -cp .:client-1.0.0.jar org.jboss.example.client.Client $1</programlisting>
+      <para>We must therefore create a new classloader during the deployment of the service so
+      that we can load in the service classes and create instances of the beans. You can see how
+      this is done by looking at the contents of the jboss-beans.xml file:</para>
+      <programlisting role="XML">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+
+      &lt;deployment xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;            
+      xsi:schemaLocation=&quot;urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd&quot;
+      xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+      &lt;bean name=&quot;URL&quot; class=&quot;java.net.URL&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;file:/Users/newtonm/jbossmc/microcontainer/trunk/docs/examples/User_Guide/gettingStarted/commandLineClient/target/client-cl.dir/otherLib/humanResourcesService-1.0.0.jar&lt;/parameter&gt;
+      &lt;/constructor&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;customCL&quot; class=&quot;java.net.URLClassLoader&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;
+      &lt;array&gt;
+      &lt;inject bean=&quot;URL&quot;/&gt; 
+      &lt;/array&gt;
+      &lt;/parameter&gt;
+      &lt;/constructor&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;HRService&quot; class=&quot;org.jboss.example.service.HRManager&quot;&gt;
+      &lt;classloader&gt;&lt;inject bean=&quot;customCL&quot;/&gt;&lt;/classloader&gt;
+      &lt;!-- &lt;property name=&quot;hiringFreeze&quot;&gt;true&lt;/property&gt;
+      &lt;property name=&quot;salaryStrategy&quot;&gt;&lt;inject bean=&quot;AgeBasedSalary&quot;/&gt;&lt;/property&gt; --&gt;
+      &lt;/bean&gt;
+
+      &lt;!-- &lt;bean name=&quot;AgeBasedSalary&quot; class=&quot;org.jboss.example.service.util.AgeBasedSalaryStrategy&quot;&gt;
+      &lt;property name=&quot;minSalary&quot;&gt;1000&lt;/property&gt;
+      &lt;property name=&quot;maxSalary&quot;&gt;80000&lt;/property&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;LocationBasedSalary&quot; class=&quot;org.jboss.example.service.util.LocationBasedSalaryStrategy&quot;&gt;
+      &lt;property name=&quot;minSalary&quot;&gt;2000&lt;/property&gt;
+      &lt;property name=&quot;maxSalary&quot;&gt;90000&lt;/property&gt;
+      &lt;/bean&gt; --&gt;
+
+      &lt;/deployment&gt;</programlisting>
+      <para>First of all we create an instance of java.net.URL called URL using parameter
+      injection in the constructor to specify the location of the humanResourcesService.jar file
+      on our local filesystem. Then we create an instance of a URLClassLoader by injecting the
+      URL bean into the constructor as the only element in an array. Once this is done then we
+      simply include a &lt;classloader&gt; element in our HRService bean definition and inject
+      the customCL bean. This specifies that the HRManager class needs to be loaded by the
+      customCL classloader.</para>
+      <para>But how do we know which classloader to use for the other beans in the
+      deployment?</para>
+      <para>The answer is that all beans in the deployment use the current thread&apos;s context
+      classloader. In our case the thread that handles deployment is the main thread of the
+      application which has its context classloader set to the application classloader on
+      startup. If you wish, you can choose to specify a different classloader for the entire
+      deployment using a &lt;classloader&gt; element as follows:</para>
+      <programlisting role="XML">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+
+      &lt;deployment xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;            
+      xsi:schemaLocation=&quot;urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd&quot;
+      xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+      &lt;classloader&gt;&lt;inject bean=&quot;customCL&quot;/&gt;&lt;/classloader&gt;
+
+      &lt;bean name=&quot;URL&quot; class=&quot;java.net.URL&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;file:/Users/newtonm/jbossmc/microcontainer/trunk/docs/examples/User_Guide/gettingStarted/commandLineClient/target/client-cl.dir/otherLib/humanResourcesService-1.0.0.jar&lt;/parameter&gt;
+      &lt;/constructor&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;customCL&quot; class=&quot;java.net.URLClassLoader&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;
+      &lt;array&gt;
+      &lt;inject bean=&quot;URL&quot;/&gt; 
+      &lt;/array&gt;
+      &lt;/parameter&gt;
+      &lt;/constructor&gt;
+      &lt;/bean&gt;
+
+      ...
+
+      &lt;/deployment&gt;</programlisting>
+      <para>This would be necessary for example if you wished to reconfigure the service by
+      uncommenting the AgeBasedSalary or LocationBasedSalary beans. As you might expect,
+      classloaders specified at the bean level override the deployment level classloader and if
+      you wish to ignore the deployment level classloader altogether, and use the default
+      classloader for a bean, then you can use the &lt;null/&gt; value as follows:</para>
+      <programlisting role="XML">  &lt;bean name=&quot;HRService&quot; class=&quot;org.jboss.example.service.HRManager&quot;&gt;
+      &lt;classloader&gt;&lt;null/&gt;&lt;/classloader&gt;
+      &lt;/bean&gt;</programlisting>
+      <warning>
+	<para>If you decide to create a new classloader for your service using the deployment
+	descriptor then be aware that you may not be able to access classes loaded by it from
+	the application classloader anymore. In our example this means that the client will no
+	longer be able to cache a direct reference to the bean instance when using the
+	microcontainer controller. You can see this for yourself by starting the client using
+	the <filename>run.sh</filename> command and then trying to deploy the service. You should see
+	that a java.lang.NoClassDefFoundError exception is thrown and the application will then
+	exit.</para>
+	<para>You must therefore use the bus to access the service indirectly and provide access
+	to any classes shared by the client in the application classpath. In our example this
+	means the Address, Employee, and SalaryStrategy classes.</para>
+      </warning>
+    </section>
+  </chapter>
+  <chapter>
+    <title>Adding behaviour with AOP</title>
+    <para>Object Oriented Programming (OOP) contains many useful techniques for software
+    development including encapsulation, inheritance, and polymorphism but does not solve the
+    problem of how to address logic that is often repeated in many different classes. Examples
+    of this include logging, security, and transactional logic which is traditionally hard-coded
+    into each class making the source code difficult to maintain. We call logic of this nature a
+    &apos;cross-cutting concern&apos; as it typically applies across class hierarchies.</para>
+    <para>Aspect Oriented Programming (AOP) provides a solution to this by allowing cross-cutting
+    concerns to be applied to classes after they have been compiled. This keeps the source code
+    free of logic which is not central to the main purpose of the class and aids maintenance.
+    The way it is done varies depending on the AOP implementation. Typically if a class
+    implements an interface then all method calls to an instance of the class first pass through
+    a proxy that implements the same interface and adds in the required behaviour.
+    Alternatively, if an interface is not used, then the java bytecode of the compiled class is
+    modified so that the original methods are renamed and replaced by methods that implement the
+    cross-cutting logic. These new methods then call the original methods after the
+    cross-cutting logic has been executed. The same result can be achieved by modifying the
+    bytecode to create a subclass of the original class that overrides its methods. The
+    overriden methods then execute the cross-cutting logic before calling the corresponding
+    methods of the super class. </para>
+    <para>JBoss AOP is a framework for Aspect-Oriented Programming that allows you to create
+    cross-cutting concerns using conventional java classes and methods. In AOP terminology each
+    concern is represented by an aspect that you implement using a simple POJO. Behaviour is
+    provided by methods within the aspect called advices that follow certain rules for their
+    parameter and return types together with any exceptions that they throw. Other than this you
+    are free to use conventional object-oriented notions such as inheritance, encapsulation, and
+    composition in order to make your cross-cutting concerns as maintainable as possible.
+    Aspects are applied to code using an expression language that allows you to specify which
+    constructors, methods and even fields to target. This means that you can quickly change the
+    behaviour of a number of classes simply by editing a configuration file. </para>
+    <para>In this chapter we are going to look at using JBoss AOP together with the microcontainer
+    to create and apply an auditing aspect to the Human Resources Service. We could choose to
+    place auditing code within the HRManager class but it would detract from the main purpose of
+    the class and add unnecessary complexity. The design of the aspect will ensure that it can
+    also be used with other classes if our requirements change at a later date.</para>
+    <para>We shall also look at how AOP can be used to apply additional behaviour during the
+    deployment phase. Specifically we will show how you can create and bind a proxy to a bean
+    instance into a basic JNDI service so that you can access it using a JNDI lookup instead of
+    the microcontainer controller.</para>
+    <section>
+      <title>Creating an aspect</title>
+      <para>The <filename>examples/User_Guide/gettingStarted/auditAspect</filename> directory contains all
+      the files you need to create the aspect.</para>
+      <programlisting>auditAspect/pom.xml
+      /src/main/java/org/jboss/example/aspect/AuditAspect.java</programlisting>
+      <para>As you can see from the source code below all we need is a simple POJO.</para>
+      <programlisting role="JAVA">public class AuditAspect {
+
+      private String logDir;
+      private BufferedWriter out;
+
+      public AuditAspect() {
+      logDir = System.getProperty(&quot;user.dir&quot;) + &quot;/log&quot;;
+
+      File directory = new File(logDir);
+      if (!directory.exists()) {
+      directory.mkdir();
+      }
+      }
+
+      public Object audit(ConstructorInvocation inv) throws Throwable {
+      SimpleDateFormat formatter = new SimpleDateFormat(&quot;ddMMyyyy-kkmmss&quot;);
+      Calendar now = Calendar.getInstance();
+      String filename = &quot;auditLog-&quot; + formatter.format(now.getTime());
+
+      File auditLog = new File(logDir + &quot;/&quot; + filename);
+      auditLog.createNewFile();
+      out = new BufferedWriter(new FileWriter(auditLog));
+      return inv.invokeNext();
+      }
+
+      public Object audit(MethodInvocation inv) throws Throwable {
+      String name = inv.getMethod().getName();
+      Object[] args = inv.getArguments();
+      Object retVal = inv.invokeNext();
+
+      StringBuffer buffer = new StringBuffer();
+      for (int i=0; i &lt; args.length; i++) {
+      if (i &gt; 0) {
+      buffer.append(&quot;, &quot;);
+      }
+      buffer.append(args[i].toString());
+      }
+
+      if (out != null) {
+      out.write(&quot;Method: &quot; + name);
+      if (buffer.length() &gt; 0) {
+      out.write(&quot; Args: &quot; + buffer.toString());
+      }
+      if (retVal != null) {
+      out.write(&quot; Return: &quot; + retVal.toString());
+      }
+      out.write(&quot;\n&quot;);
+      out.flush();
+      }
+      return retVal;
+      }
+      }</programlisting>
+      <para>The constructor checks for the presence of a <filename>log</filename> directory in the current
+      working directory and creates one if not found. After this we define an advice that will
+      be called whenever the constructor of our target class is called. The purpose of this is
+      to create a new log file within the log directory so that we can record method calls made
+      on different instances of our target class in separate files. Finally we define an advice
+      that will apply to each method call made on the target class. Here we store the method
+      name and arguments together with the return value so that we can construct an audit record
+      and write it to the current log file. Notice how each advice calls
+      <methodname>inv.invokeNext()</methodname>. This is required in order to call the next advice, if
+      more than one cross-cutting concern has been applied, or to call the target
+      constructor/method.</para>
+      <note>
+	<para>Each advice is implemented using a method that takes an invocation object as a
+	parameter, throws Throwable and returns Object. This is necessary as we do not know at
+	design time which constructors or methods our advices will be applied to so the types
+	must be as generic as possible. For more information on creating aspects and advices
+	together with additional examples of how to apply them to various classes please consult
+	the JBoss AOP project documentation.</para>
+      </note>
+      <para>To compile the class and create an auditAspect.jar file that can be used by other
+      examples simply type <command>mvn install</command> from the auditAspect directory.</para>
+    </section>
+    <section>
+      <title>Configuring the microcontainer</title>
+      <para>Before we can apply the audit aspect to our service we must first add a number of JARs
+      to the extension classpath. These can be found in the <filename>lib</filename> subdirectory of the
+      client-aop distribution located in the
+      <filename>examples/User_Guide/gettingStarted/commandLineClient/target/client-aop.dir</filename>
+      directory:</para>
+      <programlisting>run.sh
+      client-1.0.0.jar
+      jboss-beans.xml
+      lib/auditAspect-1.0.0.jar
+      /concurrent-1.3.4.jar
+      /humanResourcesService-1.0.0.jar
+      /javassist-3.6.0.GA.jar
+      /jboss-aop-2.0.0.beta1.jar
+      /jboss-aop-mc-int-2.0.0.Beta6.jar
+      /jboss-common-core-2.0.4.GA.jar
+      /jboss-common-core-2.2.1.GA.jar
+      /jboss-common-logging-log4j-2.0.4.GA.jar
+      /jboss-common-logging-spi-2.0.4.GA.jar
+      /jboss-container-2.0.0.Beta6.jar
+      /jboss-dependency-2.0.0.Beta6.jar
+      /jboss-kernel-2.0.0.Beta6.jar
+      /jbossxb-2.0.0.CR4.jar
+      /log4j-1.2.14.jar
+      /trove-2.1.1.jar
+      /xercesImpl-2.7.1.jar</programlisting>
+      <para>First of all we need to include the <filename>auditAspect</filename> jar as we need to create
+      an instance of our aspect at runtime in order to execute the logic. We then need to
+      include the jar file for JBoss AOP (<filename>jboss-aop</filename>) together with its
+      dependencies; <filename>javassist</filename> and <filename>trove</filename>. Finally we need to add
+      the<filename> jboss-aop-mc-int</filename> jar as this contains an XML schema definition that
+      allows us to define aspects inside our XML deployment descriptor. It also contains
+      integration code to create dependencies between normal beans and aspect beans within the
+      microcontainer so that we can add behaviour during the deployment and undeployment
+      phases.</para>
+      <note>
+	<para>Since we are using Maven2 to assemble the client-aop distribution we can easily add
+	these JAR files by declaring the appropriate dependencies in our <filename>pom.xml</filename>
+	file and creating a valid assembly descriptor. If you are using Ant to perform your
+	build then you will need to do this in a different way.</para>
+      </note>
+    </section>
+    <section>
+      <title>Applying an aspect</title>
+      <para>Now that we have a valid distribution containing everything we need we can configure
+      our jboss-beans.xml file to apply the audit aspect. This can be found in the
+      <filename>examples/User_Guide/gettingStarted/commandLineClient/target/client-aop.dir</filename>
+      directory:</para>
+      <programlisting role="XML">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+
+      &lt;deployment xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+      xsi:schemaLocation=&quot;urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd&quot;
+      xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+      &lt;bean name=&quot;AspectManager&quot; class=&quot;org.jboss.aop.AspectManager&quot;&gt;
+      &lt;constructor factoryClass=&quot;org.jboss.aop.AspectManager&quot;
+      factoryMethod=&quot;instance&quot;/&gt;
+      &lt;/bean&gt;
+
+      &lt;aop:aspect xmlns:aop="urn:jboss:aop-beans:1.0"
+      name="AuditAspect" class="org.jboss.example.aspect.AuditAspect"/&gt;
+      
+      &lt;aop:bind xmlns:aop="urn:jboss:aop-beans:1.0"
+      method="audit" pointcut="execution(public org.jboss.example.service.HRManager->new(..)) OR
+      execution(public * org.jboss.example.service.HRManager->*(..))"&gt;
+      &lt;aop:advice name="audit" aspect="AuditAspect"/&gt;
+      &lt;/aop:bind&gt;
+
+      ...
+
+      &lt;/deployment&gt;</programlisting>
+      <para>Before we can apply our aspect to any classes we need to create an instance of
+      org.jboss.aop.AspectManager using a &lt;bean&gt; element. We use a factory method instead
+      of calling a conventional constructor as we only want one instance of the AspectManager in
+      the JVM at runtime i.e. it is a singleton.</para>
+      <para>Next we declare an aspect called AuditAspect using the &lt;aop:aspect&gt; element.
+      This looks much like the &lt;bean&gt; element as it has <property>name</property> and
+      <property>class</property> attributes that you can use in the same way. However, behind the
+      scenes due to the <systemitem>urn:jboss:aop-beans:1.0</systemitem> namespace this resolves to some
+      other beans which install the aspect into the JBoss Microcontainer and into the JBoss AOP
+      AspectManager.</para>
+      <para>Next we declare a binding called AuditAspect using the &lt;aop:bind&gt; element.
+      Again, this resolves to some other beans which install the binding into the JBoss
+      Microcontainer and into the JBoss AOP AspectManager. The <property>pointcut</property> attribute
+      says this binding should apply to all public constructors and all public methods of the
+      <classname>HRManager</classname> class, and the nested &lt;aop:advice&gt; element specifies that
+      when any of these are called we should invoke the <methodname>audit</methodname> advice method of the
+      aspect called <methodname>AuditAspect</methodname>. We only need to specify one method called audit as
+      we have overloaded this method within our AuditAspect class with different parameters.
+      JBoss AOP knows at runtime which one to select based on whether a constructor or method
+      invocation is being made.</para>
+      <para>This additional configuration is all we need to apply the audit aspect at runtime and
+      add auditing behaviour to the Human Resources service. You can test this out for yourself
+      by running the client using the <filename>run.sh</filename> script. A <filename>log</filename> directory
+      will be created on startup alongside the <filename>lib</filename> directory as the AuditAspect
+      bean is created by the microcontainer. Each deployment of the Human Resources service will
+      then cause a new log file to appear within the <filename>log</filename> directory containing a
+      record of any calls made from the client to the service:</para>
+      <programlisting>log/auditLog-28112007-163902
+      /auditLog-28112007-164055
+      /auditLog-28112007-164108</programlisting>
+      <para>The audit records inside the log files will look something like this:</para>
+      <programlisting>Method: getEmployees Return: []
+      Method: addEmployee Args: (Santa Claus, 1 Reindeer Avenue, Lapland City - 25/12/1860) Return: true
+      Method: getSalary Args: (Santa Claus, null - Birth date unknown) Return: 10000
+      Method: getEmployees Return: [(Santa Claus, 1 Reindeer Avenue, Lapland City - 25/12/1860)]
+      Method: isHiringFreeze Return: false
+      Method: getEmployees Return: [(Santa Claus, 1 Reindeer Avenue, Lapland City - 25/12/1860)]
+      Method: getSalaryStrategy</programlisting>
+      <para>If you wish to remove the auditing behaviour then you can simply comment out the
+      relevant fragments of XML in the deployment descriptor and restart the application.</para>
+      <warning>
+	<para>The order of deployment for aspects declared in this way relative to normal beans
+	matters in the deployment descriptor. Specifically each aspect must be declared before
+	the beans that it applies to so that the microcontainer deploys them in that order. This
+	is because the microcontainer may need to alter the bytecode of the normal bean class in
+	order to add the cross-cutting logic before it creates an instance and stores a
+	reference to it in the controller. If a normal bean instance has already been created
+	then this is not possible. </para>
+      </warning>
+    </section>
+    <section>
+      <title>Lifecycle callbacks</title>
+      <para>In addition to applying aspects to beans that we instantiate using the microcontainer
+      we can also add behaviour during the deployment and undeployment process. As you may
+      recall from the Direct access section of Chapter 4, a bean goes through several different
+      states as it is deployed. These include:<itemizedlist>
+      <listitem>
+	<para>NOT_INSTALLED - the deployment descriptor containing the bean has been parsed
+	along with any annotations on the bean itself.</para>
+      </listitem>
+      <listitem>
+	<para>DESCRIBED - any dependencies created by AOP have been added to the bean and
+	custom annotations have been processed.</para>
+      </listitem>
+      <listitem>
+	<para>INSTANTIATED - an instance of the bean has been created.</para>
+      </listitem>
+      <listitem>
+	<para>CONFIGURED - properties have been injected into the bean along with any
+	references to other beans.</para>
+      </listitem>
+      <listitem>
+	<para>CREATE - the create method, if defined on the bean, has been called.</para>
+      </listitem>
+      <listitem>
+	<para>START - the start method, if defined on the bean, has been called.</para>
+      </listitem>
+      <listitem>
+	<para>INSTALLED - any custom install actions that were defined in the deployment
+	descriptor have been executed and the bean is ready to access.</para>
+      </listitem>
+      </itemizedlist></para>
+      <important>
+	<para>The CREATE and START states are included in order to allow services that used to be
+	implemented as MBeans in JBoss AS 3.x and 4.x to function correctly when implemented as
+	beans in JBoss AS 5.x. If you do not define any corresponding create/start methods in
+	your bean then it will simply pass straight through these states.</para>
+      </important>
+      <para>Together these states represent the bean&apos;s lifecycle and using an additional set
+      of &lt;aop&gt; elements you can define a number of callbacks to be applied to any
+      point:</para>
+      <programlisting>&lt;aop:lifecycle-describe&gt; - applied when entering/leaving the DESCRIBED state
+      &lt;aop:lifecycle-instantiate&gt; - applied when entering/leaving the INSTANTIATED state
+      &lt;aop:lifecycle-configure&gt; - applied when entering/leaving the CONFIGURED state
+      &lt;aop:lifecycle-create&gt; - applied when entering/leaving the CREATE state
+      &lt;aop:lifecycle-start&gt; - applied when entering/leaving the START state
+      &lt;aop:lifecycle-install&gt; - applied when entering/leaving the INSTALLED state</programlisting>
+      <para>Just like the &lt;bean&gt; element and the &lt;aop:aspect&gt; element the
+      &lt;aop:lifecycle-&gt; elements contain <property>name</property> and <property>class</property>
+      attributes. These allow the microcontainer to create an instance of the callback class and
+      give it a name so that it can be used as beans enter/leave the relevant state during
+      deployment and undeployment. You can specify which beans are affected by the callback
+      using the <property>classes</property> attribute:</para>
+      <programlisting role="XML">&lt;aop:lifecycle-install xmlns:aop=&quot;urn:jboss:aop-beans:1.0&quot;
+      name=&quot;InstallAdvice&quot;
+      class=&quot;org.jboss.test.microcontainer.support.LifecycleCallback&quot;
+      classes=&quot;@org.jboss.test.microcontainer.support.Install&quot;&gt;
+      &lt;/aop:lifecycle-install&gt;</programlisting>
+      <para>Here we have specified that additional logic in the LifecycleCallback class should be
+      applied to any bean classes that are annotated with
+      @org.jboss.test.microcontainer.support.Install before they enter and after they leave the
+      INSTALLED state. </para>
+      <para>In order for the callback class to work it must contain <methodname>install</methodname> and
+      <methodname>uninstall</methodname> methods that take ControllerContext as a parameter:</para>
+      <programlisting role="JAVA">import org.jboss.dependency.spi.ControllerContext;
+
+      public class LifecycleCallback {
+
+      public void install(ControllerContext ctx) {
+      System.out.println(&quot;Bean &quot; + ctx.getName() + &quot; is being installed&quot;;
+      }
+
+      public void uninstall(ControllerContext ctx) {
+      System.out.println(&quot;Bean &quot; + ctx.getName() + &quot; is being uninstalled&quot;;
+      }
+      } </programlisting>
+      <para>The install method will be called during the bean&apos;s deployment and the uninstall
+      method during its undeployment.</para>
+      <note>
+	<para>Although we are adding behaviour to the deployment and undeployment process using
+	callbacks we are not actually using AOP to achieve this. The reason we have included
+	them in this section, and the reason why they are part of the aop XML schema, is that
+	they use the pointcut expression functionality of JBoss AOP to determine which bean
+	classes they should apply to. We have already shown how the <property>classes</property>
+	attribute allows you to write a shorthand pointcut expression to target annotated bean
+	classes. Later in Part III - AOP Development we will show how it is possible to use
+	regular pointcut expressions to target classes in a much more powerful way.</para>
+      </note>
+    </section>
+    <section>
+      <title>Adding service lookup through JNDI</title>
+      <para>Until now we have looked up references to bean instances representing services through
+      the microcontainer controller. Whilst there is nothing wrong with this it is not ideal
+      since we must first have a reference to the microcontainer kernel before we can access the
+      controller: </para>
+      <programlisting role="JAVA">private HRManager manager;
+
+      private EmbeddedBootstrap bootstrap;
+      private Kernel kernel;
+      private KernelController controller;
+
+      private final static String HRSERVICE = &quot;HRService&quot;;
+
+      ...
+
+      // Start JBoss Microcontainer
+      bootstrap = new EmbeddedBootstrap();
+      bootstrap.run();
+
+      kernel = bootstrap.getKernel();
+      controller = kernel.getController();
+
+      ...
+
+      ControllerContext context = controller.getInstalledContext(HRSERVICE);
+      if (context != null) { manager = (HRManager) context.getTarget(); }</programlisting>
+      <para>Handing out kernel references to every client that looks up a service represents a
+      significant risk as it provides wide-spread access to the microcontainer configuration. It
+      would be better to apply the ServiceLocator pattern and have a class that performs lookups
+      on behalf of the clients. Better still we could pass the bean references, together with
+      their names, to the ServiceLocator at deployment time using a lifecycle callback so that
+      it could look them up without knowing about the microcontainer at all. Undeployment would
+      subsequently remove the bean references from the ServiceLocator to prevent further
+      lookups. </para>
+      <para>While it would not be too difficult to write our own ServiceLocator implementation we
+      can save time by integrating an existing one such as JBoss Naming Service (JBoss NS). This
+      has the additional benefit of complying to the Java Naming and Directory Interface (JNDI)
+      specification. JNDI enables clients to access different, possibly multiple, naming
+      services using a common API. </para>
+      <para>All that we need to do is create an instance of JBoss NS using the microcontainer and
+      then add a lifecycle callback to perform the binding and unbinding of our bean references
+      during deployment/undeployment. We can then mark the bean classes that we wish to bind
+      references for using annotations and find them at runtime using the shorthand pointcut
+      expression as shown earlier.</para>
+    </section>
+  </chapter>
+  <chapter>
+    <title>Advanced deployment</title>
+    <para>Mention the need for a main deployer and explain how we add various deployers to
+    this.</para>
+    <section>
+      <title>Deployment stages and actions</title>
+      <para>Give example of using aspectized bean deployer and show how it&apos;s the same as the
+      BasicXMLDeployer.</para>
+    </section>
+    <section>
+      <title>Changing the descriptor file format</title>
+      <para>Give an example where we move the jboss-beans.xml file out of the META-INF directory
+      and change the location of the classes.</para>
+    </section>
+    <section>
+      <title>Changing the archive structure</title>
+      <para>Give an example of changing the jboss-beans.xml file for a jboss-beans.properties
+      file.</para>
+    </section>
+    <section>
+      <title>Changing the classloader</title>
+      <para />
+    </section>
+    <section>
+      <title>Adding a deployment action</title>
+      <para />
+    </section>
+  </chapter>
+</part>
\ No newline at end of file

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/JBoss_Microcontainer_2.0.0.GA.ent
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/JBoss_Microcontainer_2.0.0.GA.ent	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/JBoss_Microcontainer_2.0.0.GA.ent	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1 @@
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
\ No newline at end of file

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/JBoss_Microcontainer_2.0.0.GA.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/JBoss_Microcontainer_2.0.0.GA.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/JBoss_Microcontainer_2.0.0.GA.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,18 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+<book>
+  <xi:include href="Book_Info.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="Preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="Getting_Started.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="POJO_Development.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="AOP_Development.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="Development_Framework.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="Managing_Deployments.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="Classloading.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="Developing_OSGi_Services.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="Extending_the_Microcontainer.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="Appendix.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</book>

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Legal_Notice.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Legal_Notice.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Legal_Notice.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,17 @@
+<?xml version='1.0'?>
+<!DOCTYPE legalnotice PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+
+<legalnotice id="Book-Legal_Notice">
+	<title>Legal Notice</title>
+	<para>
+		<address>
+			<street>1801 Varsity Drive</street>
+			<city>Raleigh</city>, <state>NC</state><postcode>27606-2072</postcode><country>USA</country><phone>Phone: +1 919 754 3700</phone>
+			<phone>Phone: 888 733 4281</phone>
+			<fax>Fax: +1 919 754 3701</fax>
+			<pob>PO Box 13588</pob><city>Research Triangle Park</city>, <state>NC</state><postcode>27709</postcode><country>USA</country>
+		</address>
+	</para>
+</legalnotice>
+

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Managing_Deployments.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Managing_Deployments.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Managing_Deployments.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,15 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+
+<part>
+  <title>Managing Deployments</title>
+  <chapter>
+    <title></title>
+    
+    <para>
+      
+    </para>
+  </chapter>
+</part>

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/POJO_Development.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/POJO_Development.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/POJO_Development.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,2375 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+<part>
+  <title>POJO Development</title>
+  <chapter>
+    <title>Introduction</title>
+    <para>In Part I of this guide we looked at a complete use-case showing how to develop a
+    service using POJOs and access it from one or more clients. This should have given you a
+    good overview of how the microcontainer is intended to be used in real applications. In Part
+    II we look more closely at the various features available for creating POJOs, wiring them
+    together, deploying them into the runtime environment, and managing their dependencies. With
+    this knowledge you should be able to create flexible and reusable services that can be
+    integrated together to provide a custom runtime suited to your needs.</para>
+  </chapter>
+  <chapter>
+    <title>Running the examples</title>
+    <para>You can find examples of how to use each of the features described here in the
+    <filename>examples/User_Guide/pojoDevelopment</filename> directory:</para>
+    <programlisting>alias
+    annotations
+    autowiring
+    classloader
+    collections
+    constructor
+    demand
+    factory
+    injection
+    installation
+    javabeans
+    lifecycle
+    locator
+    properties
+    simple
+    spring
+    supply</programlisting>
+    <para>To build these simply <command>cd</command> to this directory and enter <command>mvn
+    package</command>. A <filename>target</filename> directory will then be created in each
+    subdirectory as follows:</para>
+    <programlisting>target/archive-tmp
+    /classes
+    /&lt;exampleName&gt;-1.0.0.jar
+    /&lt;exampleName&gt;-dist.dir</programlisting>
+    <para>The contents of the &lt;exampleName&gt;-dist.dir will be similar for each
+    example:</para>
+    <programlisting>&lt;exampleName&gt;-1.0.0.jar
+    log4j.properties
+    lib/concurrent-1.3.4.jar
+    /jboss-common-core-2.0.4.GA.jar
+    /jboss-common-core-2.2.1.GA.jar
+    /jboss-common-logging-log4j-2.0.4.GA.jar
+    /jboss-common-logging-spi-2.0.4.GA.jar
+    /jboss-container-2.0.0.Beta6.jar
+    /jboss-dependency-2.0.0.Beta6.jar
+    /jboss-kernel-2.0.0.Beta6.jar
+    /jbossxb-2.0.0.CR4.jar
+    /log4j-1.2.14.jar
+    /xercesImpl-2.7.1.jar</programlisting>
+    <para>If you previously used the examples from Part I you will notice that we no longer have a
+    <filename>run.sh</filename> script. Instead we have made &lt;exampleName&gt;-1.0.0.jar executable.
+    This means that it contains a META-INF/MANIFEST.MF file with Main-Class and Class-Path
+    attributes:</para>
+    <programlisting>Main-Class: org.jboss.kernel.plugins.bootstrap.standalone.StandaloneBootstrap
+    Class-Path: .
+    lib/jboss-common-core-2.0.4.GA.jar
+    lib/junit-3.8.1.jar
+    l ib/jboss-common-logging-spi-2.0.4.GA.jar
+    lib/xercesImpl-2.7.1.jar
+    lib /ant-1.6.5.jar
+    lib/jboss-container-2.0.0.Beta6.jar
+    lib/jboss-common-c ore-2.2.1.GA.jar
+    lib/dtdparser121-1.2.1.jar
+    lib/jbossxb-2.0.0.CR4.jar 
+    lib/jboss-aop-2.0.0.beta1.jar
+    lib/jboss-common-logging-log4j-2.0.4.G A.jar
+    lib/activation-1.0.2.jar
+    lib/jboss-test-1.0.4.GA.jar
+    lib/xml-ap is-2.7.1.jar
+    lib/concurrent-1.3.4.jar
+    lib/webdavlib-2.0.jar
+    lib/jboss -profiler-jvmti-1.0.0.CR5.jar
+    lib/jboss-kernel-2.0.0.Beta6.jar
+    lib/jb oss-managed-2.0.0.Beta6.jar
+    lib/jboss-metatype-2.0.0.Beta6.jar
+    lib/co mmons-httpclient-2.0.2.jar
+    lib/javassist-3.6.0.GA.jar
+    lib/jboss-loggi ng-spi-2.0.3.GA.jar
+    lib/log4j-1.2.14.jar
+    lib/jboss-dependency-2.0.0.B eta6.jar
+    lib/ant-junit-1.6.5.jar</programlisting>
+    <note>
+      <para>Certain JAR files included in the Class-Path attribute are not present in the
+      <filename>lib</filename> directory. This is because the maven-jar-plugin is creating the
+      Class-Path value using its internal dependency resolution mechanism and including JARs
+      that are not actually needed at runtime. This is the fault of the pom.xml descriptors in
+      projects such as jbossxb, which the microcontainer depends on, that do not currently mark
+      their dependencies as optional. For clarity we have prevented all of these JARs appearing
+      in the lib directory of the distribution by explicitly listing only those that are
+      required in the <filename>examples/User_Guide/pojoDevelopment/dist.xml</filename>
+      file which is passed to the maven-assembly-plugin. </para>
+      <para>Once we have fixed the pom.xml files in the projects that the microcontainer depends
+      on then this filtering will no longer be necessary. </para>
+    </note>
+    <para>The Main-Class attribute contains the name of a StandaloneBootstrap class that is
+    provided with the microcontainer. This class is very similar to the EmbeddedBootstrap class
+    that we used in Part I with the addition of a main() method so that it can be called from
+    the command line:</para>
+    <programlisting role="JAVA">public class StandaloneBootstrap extends BasicBootstrap
+    {
+    protected BasicXMLDeployer deployer;
+    protected String[] args;
+    
+    public static void main(String[] args) throws Exception {
+    StandaloneBootstrap bootstrap = new StandaloneBootstrap(args);
+    bootstrap.run();
+    }
+
+    public StandaloneBootstrap(String[] args) throws Exception {
+    super();
+    this.args = args;
+    }
+    
+    public void bootstrap() throws Throwable {
+    super.bootstrap();
+    
+    deployer = new BasicXMLDeployer(getKernel());
+    
+    Runtime.getRuntime().addShutdownHook(new Shutdown());
+    
+    ClassLoader cl = Thread.currentThread().getContextClassLoader();
+    for (Enumeration e = cl.getResources(StandaloneKernelConstants.DEPLOYMENT_XML_NAME); e.hasMoreElements(); ) {
+    URL url = (URL) e.nextElement();
+    deploy(url);
+    }
+    for (Enumeration e = cl.getResources(&quot;META-INF/&quot; + StandaloneKernelConstants.DEPLOYMENT_XML_NAME); e.hasMoreElements(); ) {
+    URL url = (URL) e.nextElement();
+    deploy(url);
+    }
+    
+    // Validate that everything is ok
+    deployer.validate();
+    }
+    
+    protected void deploy(URL url) throws Throwable {
+    deployer.deploy(url);
+    }
+    
+    protected void undeploy(URL url) {
+    try {
+    deployer.undeploy(url);
+    }  catch (Throwable t) {
+    log.warn(&quot;Error during undeployment: &quot; + url, t);
+    }
+    }
+    
+    protected class Shutdown extends Thread  {
+    public void run()  {
+    log.info(&quot;Shutting down&quot;);
+    deployer.shutdown();
+    }
+    }
+    }
+    </programlisting>
+    <para>The bootstrap() method also includes code to automatically scan the classpath for files
+    called jboss-beans.xml (the value of StandaloneKernelConstants.DEPLOYMENT_XML_NAME) that may
+    or may not reside in a META-INF directory. If any such files are found then their URLs are
+    passed to the BasicXMLDeployer to deploy any beans declared inside. In our examples we place
+    a jboss-beans.xml file into the META-INF directory of our &lt;exampleName&gt;-1.0.0.jar so
+    that it can be found in this way.</para>
+    <important>
+      <para>To run any of the examples simply <command>cd</command> to the relevant
+      <filename>target/&lt;exampleName&gt;-dist.dir</filename> directory and execute the JAR file
+      using the <command>java -jar &lt;exampleName&gt;-1.0.0.jar</command> command, replacing
+      &lt;exampleName&gt; with the name of the example you are running, .e.g <command>java -jar
+      constructor-1.0.0.jar</command></para>
+    </important>
+    <para>Running an example causes the following sequence of events to occur:</para>
+    <orderedlist>
+      <listitem>
+	<para>The &lt;exampleName&gt;-1.0.0.jar is executed. </para>
+      </listitem>
+      <listitem>
+	<para>The StandaloneBootstrap class defined in the Main-Class attribute of the
+	META-INF/MANIFEST.MF file within the JAR is run which bootstraps the microcontainer and
+	searches the classpath for files called jboss-beans.xml.</para>
+      </listitem>
+      <listitem>
+	<para>The META-INF/jboss-beans.xml file in the &lt;exampleName&gt;-1.0.0.jar is found and
+	the beans declared within it are deployed.</para>
+      </listitem>
+      <listitem>
+	<para>The main() method of the StandaloneBootstrap class ends and the JVM shuts down
+	undeploying the beans in reverse order.</para>
+      </listitem>
+    </orderedlist>
+    <para>If you would like to use the StandaloneBootstrap class within your own applications to
+    deploy beans on startup then you can do so as follows:</para>
+    <programlisting role="JAVA">import org.jboss.kernel.plugins.bootstrap.standalone.StandaloneBootstrap;
+
+    public class MyApp {
+    public static void main(String[] args) throws Exception
+    {
+    StandaloneBootstrap.main(args);
+    // your application code...
+    }
+    }</programlisting>
+    <note>
+      <para>Because the deploy() and undeploy() methods of the StandaloneBootstrap are protected
+      you will not be able to call them from your application after the initial startup. If you
+      wish to deploy and undeploy beans at runtime then the EmbeddedBootstrap class may be a
+      better choice. Alternatively you are free to create your own bootstrap class that uses
+      BasicBootstrap and BasicXMLDeployer to provide whatever functionality you need.</para>
+    </note>
+  </chapter>
+  <chapter>
+    <title>Configuring POJOs</title>
+    <para>In accordance with modern development methods JBoss Microcontainer supports POJO
+    configuration via annotations and/or deployment descriptors. The decision to use one or the
+    other depends on what you are trying to achieve. If there is a sensible default
+    configuration for your POJOs then it may be worthwhile defining this using annotations so
+    that users do not have to maintain a separate deployment descriptor. Since annotations are
+    overriden by deployment descriptors at runtime it is always possible for users to change the
+    default configuration using a descriptor if necessary.</para>
+    <important>
+      <para>Annotations are overriden by deployment descriptors at runtime.</para>
+    </important>
+    <para>If there is no sensible default configuration then it may be worthwhile using a
+    deployment descriptor instead of annotations. This keeps the source code free of potentially
+    redundant information and allows for easy customization since the initial deployment
+    descriptor acts as a template for further changes.</para>
+    <para>Sometimes a mixture of annotations and a deployment descriptor is best. It&apos;s up to
+    you to discover what makes most sense for your particular situation. </para>
+    <section>
+      <title>Using annotations</title>
+      <para>With the notable exception of defining classloaders nearly all of the microcontainer
+      features can be used by adding annotations to your POJO classes. </para>
+      <note>
+	<para>We are not able to define classloaders using annotations for the simple reason that
+	in order to read any annotations we must first load the class. Once the class is loaded
+	we cannot change its classloader so a classloader annotation would be useless.</para>
+      </note>
+      <para>The microcontainer annotations live in the
+      <systemitem>org.jboss.beans.metadata.api.annotations</systemitem> package and to use them you need
+      Java 1.5 or above.</para>
+      <para>Further JBoss Microcontainer allows you to define a subset of the annotations in the
+      XML deployment descriptor. The caveat is that these apply to bean instances instead of
+      bean classes. As with normal annotations you are free to add as many as necessary at a
+      single point. However you must always specify the fully-qualified class name since there
+      is no way to &apos;import&apos; packages in XML. Currently you can place annotations
+      inside the following elements:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>&lt;deployment&gt; -all beans in the deployment inherit this annotation </para>
+	  <programlisting role="XML">&lt;deployment name=&quot;SimpleDeployment&quot; xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+	  &lt;annotation&gt;@org.jboss.test.TestAnnotation&lt;/annotation&gt;
+	  &lt;/deployment&gt;</programlisting>
+	</listitem>
+	<listitem>
+	  <para>&lt;bean&gt;</para>
+	  <programlisting role="XML">&lt;bean name=&quot;example&quot; class=&quot;org.jboss.test.Example&quot;&gt;
+	  &lt;annotation&gt;@org.jboss.test.TestAnnotation1&lt;/annotation&gt;
+	  &lt;annotation&gt;@org.jboss.test.TestAnnotation2&lt;/annotation&gt;
+	  &lt;/bean&gt;</programlisting>
+	</listitem>
+	<listitem>
+	  <para>&lt;constructor&gt;</para>
+	  <programlisting role="XML">&lt;bean name=&quot;example&quot; class=&quot;org.jboss.test.Example&quot;&gt;
+	  &lt;constructor&gt;
+	  &lt;annotation&gt;@org.jboss.test.TestAnnotation&lt;/annotation&gt;
+	  &lt;/constructor&gt;
+	  &lt;/bean&gt; </programlisting>
+	</listitem>
+	<listitem>
+	  <para>&lt;create&gt;, &lt;start&gt;, &lt;stop&gt;, &lt;destroy&gt;</para>
+	  <programlisting role="XML">&lt;bean name=&quot;example&quot; class=&quot;org.jboss.test.Example&quot;&gt;
+	  &lt;create&gt;
+	  &lt;annotation&gt;@org.jboss.test.TestAnnotation&lt;/annotation&gt;
+	  &lt;/create&gt;
+	  &lt;/bean&gt;</programlisting>
+	</listitem>
+	<listitem>
+	  <para>&lt;install&gt;, &lt;uninstall&gt;</para>
+	  <programlisting role="XML">&lt;bean name=&quot;example&quot; class=&quot;org.jboss.test.Example&quot;&gt;
+	  &lt;install method=&quot;someMethod&quot;&gt;
+	  &lt;annotation&gt;@org.jboss.test.TestAnnotation&lt;/annotation&gt;
+	  &lt;/install&gt;
+	  &lt;/bean&gt; </programlisting>
+	</listitem>
+	<listitem>
+	  <para>&lt;incallback&gt;, &lt;uncallback&gt;</para>
+	  <programlisting role="XML">&lt;bean name=&quot;example&quot; class=&quot;org.jboss.test.Example&quot;&gt;
+	  &lt;incallback method="addSubject"&gt;
+	  &lt;annotation&gt;@org.jboss.test.TestAnnotation&lt;/annotation&gt;
+	  &lt;/incallback&gt;
+	  &lt;/bean&gt;</programlisting>
+	</listitem>
+	<listitem>
+	  <para>&lt;property&gt;</para>
+	  <programlisting role="XML">&lt;bean name=&quot;example&quot; class=&quot;org.jboss.test.Example&quot;&gt;
+	  &lt;property name=&quot;PropertyName&quot;&gt;
+	  &lt;annotation&gt;@org.jboss.test.TestAnnotation&lt;/annotation&gt;
+	  &lt;value&gt;123&lt;/value&gt;
+	  &lt;/property&gt;
+	  &lt;/bean&gt;</programlisting>
+	</listitem>
+      </itemizedlist>
+      <important>
+	<para>Annotations declared in XML apply to bean instances instead of bean classes.</para>
+      </important>
+      <para>Examples of how to use both normal and XML annotations will be given in the following
+      sections.</para>
+    </section>
+    <section>
+      <title>Writing deployment descriptors</title>
+      <para>Deployment descriptors externalize the configuration of POJOs into one or more files
+      that are separate from the source code. This means that changes can be made without having
+      to recompile any classes. The usual way to define a deployment descriptor is using the
+      bean-deployer XML schema whose root element is &lt;deployment&gt;. This is used to group
+      multiple beans together so that they are deployed as a unit:</para>
+      <programlisting role="XML">&lt;deployment xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+      xsi:schemaLocation=&quot;urn:jboss:bean-deployer bean-deployer_2_0.xsd&quot;
+      xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+      &lt;!-- Bean definitions --&gt;
+
+      &lt;/deployment&gt;</programlisting>
+      <para>The bean definitions are created using &lt;bean&gt; elements that each describe a
+      single POJO instance. Each bean is given a name so that it can be referenced elsewhere in
+      the deployment descriptor or looked up by a client at runtime.</para>
+      <programlisting role="XML">&lt;deployment xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+      xsi:schemaLocation=&quot;urn:jboss:bean-deployer bean-deployer_2_0.xsd&quot;
+      xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+      &lt;bean name=&quot;Person&quot; class=&quot;org.jboss.example.microcontainer.PersonBean&quot;/&gt;
+
+      &lt;bean name=&quot;Address&quot; class=&quot;org.jboss.example.microcontainer.AddressBean&quot;/&gt;
+
+      &lt;/deployment&gt; </programlisting>
+      <para>The name of the file containing these elements can be anything you like providing that
+      a deployer can access it and parse the contents correctly. By convention it is called
+      jboss-beans.xml as anything that ends in -beans.xml is found by default using the
+      FileStructure deployer.</para>
+      <note>
+	<para>Although deployment descriptors are usually created using the bean-deployer XML
+	schema it is also possible to use other XML schemas or even Java properties as shown in
+	the following sections.</para>
+      </note>
+    </section>
+    <section>
+      <title>Using JavaBean XML</title>
+      <para>Together with the bean-deployer XML schema the microcontainer also contains a javabean
+      XML schema. This is a lightweight version of bean-deployer that allows for the
+      construction and configuration of <ulink url="http://java.sun.com/products/javabeans/"
+      >JavaBeans</ulink> without any advanced features like bean injection, callbacks or
+      dependencies. It is intended to be used in situations where the microcontainer has been
+      customised to remove all of the advanced functionality so that it can be bootstrapped in
+      very small runtime environments. </para>
+      <para>Construction of POJOs is performed using either a normal constructor or a static
+      factory method. In either case constructor or method parameters can be added as necessary: </para>
+      <itemizedlist>
+	<listitem>
+	  <para>Default constructor</para>
+	  <programlisting role="XML">&lt;javabean xmlns=&quot;urn:jboss:javabean:2.0&quot;
+	  class=&quot;org.jboss.test.javabean.support.SimpleBean&quot;/&gt;</programlisting>
+	</listitem>
+	<listitem>
+	  <para>Constructor with parameters</para>
+	  <programlisting role="XML">&lt;javabean xmlns=&quot;urn:jboss:javabean:2.0&quot; 
+	  class=&quot;org.jboss.test.javabean.support.SimpleBean&quot;&gt;
+	  &lt;constructor&gt;
+	  &lt;property name=&quot;ABoolean&quot;&gt;true&lt;/property&gt;
+	  &lt;property name=&quot;ACharacter&quot;&gt;x&lt;/property&gt;
+	  &lt;property name=&quot;AShort&quot;&gt;123&lt;/property&gt; 
+	  &lt;/constructor&gt;
+	  &lt;/javabean&gt;</programlisting>
+	</listitem>
+	<listitem>
+	  <para>Static factory method</para>
+	  <programlisting role="XML">&lt;javabean xmlns=&quot;urn:jboss:javabean:2.0&quot; 
+	  class=&quot;org.jboss.test.javabean.support.SimpleBean&quot;&gt;
+	  &lt;constructor factoryClass=&quot;org.jboss.test.javabean.support.SimpleBeanFactory&quot;
+	  factoryMethod=&quot;newInstance&quot;/&gt;
+	  &lt;/javabean&gt;</programlisting>
+	</listitem>
+	<listitem>
+	  <para>Static factory method with parameters</para>
+	  <programlisting role="XML">&lt;javabean xmlns=&quot;urn:jboss:javabean:2.0&quot; 
+	  class=&quot;org.jboss.test.javabean.support.SimpleBean&quot;&gt;
+	  &lt;constructor factoryClass=&quot;org.jboss.test.javabean.support.SimpleBeanFactory&quot;
+	  factoryMethod=&quot;newInstance&quot;&gt;
+	  &lt;property name=&quot;AString&quot;&gt;StringValue&lt;/property&gt;
+	  &lt;property name=&quot;AByte&quot;&gt;12&lt;/property&gt;
+	  &lt;/constructor&gt;
+	  &lt;/javabean&gt;</programlisting>
+	</listitem>
+      </itemizedlist>
+      <note>
+	<para>JavaBean declarations do not include a <property>name</property> attribute which means that
+	you cannot inject references into other JavaBeans or lookup a reference to a JavaBean
+	instance from a client at runtime.</para>
+      </note>
+      <para>Once a JavaBean has been constructed then simple injection of property values is
+      possible using the &lt;property&gt; element: </para>
+      <programlisting role="XML">&lt;javabean xmlns=&quot;urn:jboss:javabean:2.0&quot; 
+      class=&quot;org.jboss.test.javabean.support.SimpleBean&quot;&gt;
+      &lt;property name=&quot;ADouble&quot;&gt;3.14e12&lt;/property&gt;
+      &lt;property name=&quot;ADate&quot;&gt;Jan 01 00:00:00 CET 2001&lt;/property&gt;
+      &lt;property name=&quot;ABigDecimal&quot;&gt;12e4&lt;/property&gt;
+      &lt;property name=&quot;ABigInteger&quot;&gt;123456&lt;/property&gt;
+      &lt;property name=&quot;abyte&quot;&gt;12&lt;/property&gt; 
+      &lt;/javabean&gt;</programlisting>
+      <para>As with properties defined using the bean-deployer XML schema the string values are
+      converted into objects of the correct type using JavaBean <ulink
+      url="http://java.sun.com/j2se/1.5.0/docs/api/java/beans/PropertyEditor.html"
+      >PropertyEditors</ulink>. For cases where the type is ambiguous, e.g. when defining
+      numbers, you can specify the required type by including a <property>class</property> attribute: </para>
+      <programlisting role="XML">&lt;javabean xmlns=&quot;urn:jboss:javabean:2.0&quot; 
+      class=&quot;org.jboss.test.javabean.support.SimpleBean&quot;&gt;
+      &lt;property name=&quot;ANumber&quot; class=&quot;java.lang.Long&quot;&gt;12345&lt;/property&gt; 
+      &lt;/javabean&gt;</programlisting>
+      <important>
+	<para>Beans created using the bean-deployer XML schema can include JavaBeans created using
+	the javabean XML schema instead of string values. This provides a simple way to inject
+	objects composed of multiple values into a bean property without having to write a
+	complicated property editor:</para>
+	<programlisting role="XML">&lt;bean name=&quot;example&quot; class=&quot;org.jboss.acme.Example&quot;&gt;
+	&lt;property name=&quot;myProperty&quot;&gt;
+        &lt;javabean xmlns=&quot;urn:jboss:javabean:1.0&quot; 
+	class=&quot;org.jboss.test.javabean.support.SimpleBean&quot;&gt;
+	&lt;property name=&quot;ADate&quot;&gt;Jan 01 00:00:00 CET 2001&lt;/property&gt;
+	&lt;property name=&quot;ABigDecimal&quot;&gt;12e4&lt;/property&gt;
+        &lt;/javabean&gt;
+	&lt;/property&gt;
+	&lt;/bean&gt; </programlisting>
+      </important>
+    </section>
+    <section>
+      <title>Using Spring XML</title>
+      <para>Spring like JBoss Microcontainer allows POJOs to be created and configured using an
+      XML schema. As the microcontainer largely supports the same set of features as Spring it
+      is possible to use the spring-beans schema to define beans instead of the bean-deployer
+      schema. This makes migrating services built and tested using Spring to JBoss
+      Microcontainer very straightforward.</para>
+      <para>To define beans using the spring-beans schema you need to include
+      <filename>spring-int.jar</filename> on the microcontainer classpath. You can then create a
+      deployment descriptor containing a &lt;beans&gt; element at the root instead of the usual
+      &lt;deployment&gt; element:</para>
+      <programlisting role="XML">&lt;beans xmlns=&quot;urn:jboss:spring-beans:2.0&quot;&gt;
+      &lt;bean id=&quot;testBean&quot; class=&quot;org.jboss.test.spring.support.SimpleBean&quot;&gt;
+      &lt;constructor-arg index=&quot;2&quot;&gt;
+      &lt;value&gt;SpringBean&lt;/value&gt;
+      &lt;/constructor-arg&gt;
+      &lt;constructor-arg index=&quot;0&quot;&gt;
+      &lt;value&gt;1&lt;/value&gt;
+      &lt;/constructor-arg&gt;
+      &lt;constructor-arg index=&quot;1&quot;&gt;
+      &lt;value&gt;3.14159&lt;/value&gt;
+      &lt;/constructor-arg&gt;
+
+      &lt;property name=&quot;mylist&quot;&gt;
+      &lt;list value-type=&quot;java.lang.String&quot;&gt;
+      &lt;value&gt;onel&lt;/value&gt;
+      &lt;value&gt;twol&lt;/value&gt;
+      &lt;value&gt;threel&lt;/value&gt;
+      &lt;/list&gt;
+      &lt;/property&gt;
+
+      &lt;property name=&quot;myset&quot;&gt;
+      &lt;set value-type=&quot;java.lang.String&quot;&gt;
+      &lt;value&gt;ones&lt;/value&gt;
+      &lt;value&gt;twos&lt;/value&gt;
+      &lt;value&gt;ones&lt;/value&gt;
+      &lt;/set&gt;
+      &lt;/property&gt;
+
+      &lt;property name=&quot;mymap&quot;&gt;
+      &lt;map key-type=&quot;java.lang.String&quot;&gt;
+      &lt;entry&gt;
+      &lt;key&gt;
+      &lt;value&gt;test_key&lt;/value&gt;
+      &lt;/key&gt;
+      &lt;value type=&quot;java.lang.String&quot;&gt;myvalue&lt;/value&gt;
+      &lt;/entry&gt;
+      &lt;/map&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;
+      &lt;/beans&gt;</programlisting>
+      <para>The namespace declaration <systemitem>xmlns=&quot;urn:jboss:spring-beans:2.0&quot;</systemitem>
+      tells the microcontainer that it should interpret the XML according to the spring-bean
+      schema.</para>
+      <para>You can even mix beans declared using the bean-deployer schema with those declared
+      using the spring-beans schema just like we did with the javabean schema. All that you need
+      to do is include the correct namespace declarations in the relevant elements:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>JBoss Microcontainer deployment containing Spring defined beans</para>
+	  <programlisting role="XML">&lt;deployment xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+	  &lt;bean name=&quot;oldBean&quot; class=&quot;org.jboss.test.spring.support.OldBean&quot;&gt;
+	  &lt;property name=&quot;testBean&quot;&gt;
+	  &lt;inject/&gt;
+	  &lt;/property&gt;
+	  &lt;/bean&gt;
+
+	  &lt;bean xmlns=&quot;urn:jboss:spring-beans:2.0&quot; id=&quot;testBean&quot; 
+          class=&quot;org.jboss.test.TestBean&quot;&gt;
+	  &lt;property name=&quot;mylist&quot;&gt;
+	  &lt;list value-type=&quot;java.lang.String&quot;&gt;
+	  &lt;value&gt;onel&lt;/value&gt;
+	  &lt;value&gt;twol&lt;/value&gt;
+	  &lt;value&gt;threel&lt;/value&gt;
+	  &lt;/list&gt;
+	  &lt;/property&gt;
+	  &lt;/bean&gt;
+
+	  &lt;/deployment&gt; </programlisting>
+	</listitem>
+	<listitem>
+	  <para>Spring defined deployment containing JBoss Microcontainer beans</para>
+	  <programlisting role="XML">&lt;beans xmlns=&quot;urn:jboss:spring-beans:2.0&quot;&gt;
+
+	  &lt;bean id=&quot;testBean&quot; class=&quot;org.jboss.test.spring.support.SimpleBean&quot;&gt;
+	  &lt;property name=&quot;refBean&quot;&gt;
+	  &lt;ref bean=&quot;oldBean&quot;/&gt;
+	  &lt;/property&gt;
+	  &lt;/bean&gt;
+
+	  &lt;bean xmlns=&quot;urn:jboss:bean-deployer:2.0&quot; name=&quot;oldBean&quot; class=&quot;org.jboss.test.spring.support.OldBean&quot;&gt;
+	  &lt;property name=&quot;myString&quot;&gt;I&apos;m an old bean&lt;/property&gt;
+	  &lt;/bean&gt;
+
+	  &lt;/beans&gt;</programlisting>
+	</listitem>
+      </itemizedlist>
+      <note>
+	<para>Adding <filename>spring-int.jar</filename> to the microcontainer classpath simply adds the
+	ability to define beans using the spring-beans XML schema. It does not integrate JBoss
+	Microcontainer with Spring libraries.</para>
+      </note>
+    </section>
+    <section>
+      <title>Using Java Properties</title>
+      <para>Using XML schemas to create deployment descriptors provides us wth a powerful way to
+      express complex configuration information. However the XML parsers that are needed to
+      interpret this information are often large in size which doesn&apos;t help when
+      bootstrapping the microcontainer in small runtime environments. For this reason you can
+      also choose to create deployment descriptors using Java properties.</para>
+    </section>
+  </chapter>
+  <chapter>
+    <title>Creating POJOs</title>
+    <section>
+      <title>Defining classloaders</title>
+      <para>In order to create POJO instances we must first load the corresponding POJO classes
+      into the JVM using a classloader. JBoss Microcontainer does this by using the classloader
+      associated with the current thread of execution, i.e. the thread context classloader. But
+      what do we mean by the current thread of execution and who sets its context
+      classloader?</para>
+      <para>In all of our examples so far we have created applications that only use a single
+      thread. This is the &apos;primordial&apos; thread created by the main() function:</para>
+      <programlisting role="JAVA">public static void main(String[] args) {}</programlisting>
+      <para>As the only thread in the application (other than the garbage collecton thread which
+      is created for every Java application) this executes all of the code including calling the
+      deploy() method of our BasicXMLDeployer:</para>
+      <programlisting role="JAVA">public class BasicXMLDeployer extends BasicKernelDeployer
+      {
+      ...
+      public KernelDeployment deploy(final URL url) throws Throwable
+      {
+      ...
+
+      long start = System.currentTimeMillis();
+
+      Unmarshaller unmarshaller = factory.newUnmarshaller();
+      KernelDeployment deployment = (KernelDeployment) unmarshaller.unmarshal(url.toString(), resolver);
+      if (deployment == null)
+      throw new RuntimeException(&quot;The xml &quot; + url + &quot; is not well formed!&quot;);
+      deployment.setName(url.toString());
+
+      if (trace)
+      {
+      long now = System.currentTimeMillis();
+      log.trace(&quot;Parsing &quot; + url + &quot; took &quot; + (now-start) + &quot; milliseconds&quot;);
+      }
+
+      <emphasis>deploy(deployment);</emphasis>
+
+      if (trace)
+      {
+      long now = System.currentTimeMillis();
+      log.trace(&quot;Deploying &quot; + url + &quot; took &quot; + (now-start) + &quot; milliseconds&quot;);
+      }
+
+      return deployment;
+      }
+
+      ...
+      }</programlisting>
+      <para>The deploy() method takes a URL representing the location of an XML deployment
+      descriptor and passes it as a string to an unmarshaller. The unmarshaller parses the XML,
+      converts it into an object representation called a KernelDeployment and sets its name. The
+      KernelDeployment object is then passed to the deploy() method of the superclass
+      BasicKernelDeployer. This iterates through all of the beans in the deployment creating a
+      context for each one which it subsequently passes to the contoller&apos;s install() method
+      to peform the deployment. The controller then performs actions on each context to take the
+      bean from one state to another: NOT_INSTALLED, DESCRIBED, CONFIGURED, INSTANTIATED,
+      CREATE, START, INSTALLED. Once a bean reaches the INSTALLED state then it&apos;s
+      considered to be deployed.</para>
+      <important>
+	<para>During the deployment process, as the controller performs the Instantiate action,
+	the thread context classloader is used to load the bean&apos;s class into the JVM. As
+	all of the controller code is executed by the thread that calls controller.install() we
+	refer to this as the current thread of execution.</para>
+      </important>
+      <para>Therefore when using the BasicXMLDeployer the classloader used to load bean classes is
+      retrieved from the thread that calls the BasicXMLDeployer&apos;s deploy() method as this
+      goes on to call controller.install() which subsequently executes the Instantiate action.
+      For all of our examples this is the primordial thread whose context classloader is set on
+      startup to the classloader that loaded the application, i.e. the application classloader.
+      This means that in our examples the microcontainer can load any bean classes present on
+      the application, extension or boot classpaths.</para>
+      <para>What happens though if we create our own threads in the application and use these to
+      call the deploy() method of our BasicXMLDeployer?</para>
+      <para>If you create a thread then by default its context classloader will be set to the
+      parent thread&apos;s context classloader. As any hierarchy of threads is ultimately rooted
+      at the primordial thread this means that by default they will all use the application
+      classloader. To change this you simply need to call setContextClassLoader() on a thread at
+      runtime. This is typically done on the current thread using
+      <methodname>Thread.currentThread().setContextClassloader()</methodname>.</para>
+      <note>
+	<para>If you choose not to use the BasicXMLDeployer and instead use the equivalent
+	aspectized deployer then the classloader used to load bean classes is taken from the
+	thread that calls the process() method of the MainDeployer. This is because the
+	MainDeployer process() method iterates through all of the registered deployers calling
+	their process() methods which in turn call controller.install() to perform the
+	deployment. </para>
+      </note>
+      <para>Now that we know the default classloader comes from the current thread of execution,
+      which if not set explicitly is set on startup to be the application classloader, how can
+      we change it to load bean classes from other locations?</para>
+      <para>If you are using the BasicXMLDeployer or its equivalent aspectized deployer then you
+      can define classloaders for entire deployments or individual beans by including
+      &lt;classloader&gt; elements within the XML deployment descriptor. To specify a different
+      classloader for all the beans in a deployment you need to include a &lt;classloader&gt;
+      element above all of the &lt;bean&gt; elements:</para>
+      <programlisting role="XML">&lt;deployment&gt;
+      &lt;classloader&gt;&lt;inject bean=&quot;deploymentCL&quot;/&gt;&lt;/classloader&gt;
+
+      &lt;bean name=&quot;Bean1&quot; ... &gt;
+      ...
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;Bean2&quot; ... &gt;
+      ...
+      &lt;/bean&gt;
+
+      &lt;/deployment&gt;</programlisting>
+      <para>If instead you wish to override either the default classloader or a deployment
+      classloader for a particular bean then you need to include a &lt;classloader&gt; element
+      within the &lt;bean&gt; definition itself:</para>
+      <programlisting role="XML">&lt;deployment&gt;
+      &lt;classloader&gt;&lt;inject bean=&quot;deploymentCL&quot;/&gt;&lt;/classloader&gt;
+
+      &lt;bean name=&quot;Bean1&quot; ... &gt;
+      &lt;classloader&gt;&lt;inject bean=&quot;beanCL&quot;/&gt;&lt;/classloader&gt;
+      ...
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;Bean2&quot; ... &gt;
+      ...
+      &lt;/bean&gt;
+
+      &lt;/deployment&gt;</programlisting>
+      <para>Finally you can choose to use the default classloader for a bean instead of the
+      deployment classloader, if one is defined, by including a &lt;classloader&gt; element with
+      a &lt;/null&gt; value:</para>
+      <programlisting role="XML">&lt;deployment&gt;
+      &lt;classloader&gt;&lt;inject bean=&quot;deploymentCL&quot;/&gt;&lt;/classloader&gt;
+
+      &lt;bean name=&quot;Bean1&quot; ... &gt;
+      &lt;classloader&gt;&lt;inject bean=&quot;beanCL&quot;/&gt;&lt;/classloader&gt;
+      ...
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;Bean2&quot; ... &gt;
+      &lt;classloader&gt;&lt;/null&gt;&lt;/classloader&gt;
+      ...
+      &lt;/bean&gt;
+
+      &lt;/deployment&gt;</programlisting>
+      <para>The classloader beans that you inject must be deployed in the runtime environment
+      before bean classes can be loaded. Typically this is done by also declaring them in the
+      XML deployment descriptor:</para>
+      <programlisting role="XML">&lt;deployment xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
+      xsi:schemaLocation=&quot;urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd&quot;
+      xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+      &lt;bean name=&quot;URL&quot; class=&quot;java.net.URL&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;file:/Users/newtonm/jbossmc/microcontainer/trunk/docs/examples/User_Guide/gettingStarted/commandLineClient/target/client-cl.dir/otherLib/humanResourcesService-1.0.0.jar&lt;/parameter&gt;
+      &lt;/constructor&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;customCL&quot; class=&quot;java.net.URLClassLoader&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;
+      &lt;array&gt;
+      &lt;inject bean=&quot;URL&quot;/&gt;
+      &lt;/array&gt;
+      &lt;/parameter&gt;
+      &lt;/constructor&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;HRService&quot; class=&quot;org.jboss.example.service.HRManager&quot;&gt;
+      &lt;classloader&gt;&lt;inject bean=&quot;customCL&quot;/&gt;&lt;/classloader&gt;
+      ...
+      &lt;/bean&gt;</programlisting>
+      <para>If a classloader is not available for a bean when an attempt is made to deploy it then
+      the bean will remain in a pre INSTANTIATED state. Once the classloader is deployed then
+      the bean will automatically continue to deploy. This means that you can define
+      classloaders in the deployment descriptor after beans that depend on them and everything
+      will deploy as expected.</para>
+      <note>
+	<para>User defined classloaders are detected by the microcontainer during the deployment
+	process as the controller performs the Instantiate action. They are used instead of the
+	default classloader by calling setContextClassLoader() on the current thread. In this
+	way they can be subsequently retrieved by code that loads the bean class using
+	Thread.currentThread().getContextClassLoader(). After the bean class has been loaded the
+	default classloader is put back by calling setContexClassLoader() again.</para>
+      </note>
+    </section>
+    <section>
+      <title>Calling constructors</title>
+      <para>Creating POJO instances is performed either by calling a constructor or using a
+      factory method. The &lt;constructor&gt; element is used in both cases and parameters can
+      be passed if necessary using nested &lt;parameter&gt; elements. Annotations also exist for
+      either case with parameter values represented as annotations of the constructor parameters
+      themselves.</para>
+      <important>
+	<para>At present it is not possible to create a POJO instance only using annotations. This
+	is because classes are not automatically loaded and scanned whenever they are added to
+	the classpath. Doing so would significantly reduce the performance of the deployment
+	process as all classes would need to be loaded, even if they were not yet required.
+	Instead you must always define beans using a deployment descriptor as this tells the
+	microcontainer which classes to load. These classes are subsequently scanned for
+	annotations such as @Constructor and @Factory to discover how to create
+	instances.</para>
+	<programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;/&gt;</programlisting>
+      </important>
+      <itemizedlist>
+	<listitem>
+	  <para>Default constructor</para>
+	  <programlisting role="JAVA">@Constructor
+	  public TestConstructorBean() {
+	  ...
+	  }</programlisting>
+	  <programlisting role="XML">&lt;bean name=&quot;Test&quot; class=&quot;org.jboss.example.constructor.TestConstructorBean&quot;/&gt;       </programlisting>
+	</listitem>
+	<listitem>
+	  <para>Constructor with parameters</para>
+	  <programlisting role="JAVA">@Constructor
+	  public TestConstructorBean(@StringValue(&quot;this is a test contructor&quot;) String testString, @StringValue(&quot;25&quot;) int testNumber) {
+	  ...
+	  }</programlisting>
+	  <programlisting role="XML">&lt;bean name=&quot;Test&quot; class=&quot;org.jboss.example.constructor.TestConstructorBean&quot;&gt;
+	  &lt;constructor&gt;
+	  &lt;parameter&gt;this is a test constructor&lt;/parameter&gt;
+	  &lt;parameter&gt;25&lt;/parameter&gt;
+	  &lt;/constructor&gt;
+	  &lt;/bean&gt;</programlisting>
+	</listitem>
+	<listitem>
+	  <para>Choosing between two constructors with the same number of parameters</para>
+	  <programlisting role="JAVA">public TestConstructorBean(String testString, int testNumber) {
+	  ...
+	  }
+
+	  @Constructor
+	  public TestConstructorBean(@StringValue(&quot;this is a test constructor&quot;) String testString, @StringValue(value=&quot;25&quot;, type=Long.TYPE) long testNumber) {
+	  ...
+	  }</programlisting>
+	  <programlisting role="XML">&lt;bean name=&quot;Test&quot; class=&quot;org.jboss.example.constructor.TestConstructorBean&quot;&gt;
+	  &lt;constructor&gt;
+	  &lt;parameter&gt;this is a test constructor&lt;/parameter&gt;
+	  &lt;parameter class=&quot;long&quot;&gt;25&lt;/parameter&gt;
+	  &lt;/constructor&gt;
+	  &lt;/bean&gt;</programlisting>
+	  <note>
+	    <para>You only need to include the <property>class</property> attribute on enough parameters
+	    to resolve the ambiguity.</para>
+	  </note>
+	</listitem>
+      </itemizedlist>
+      <para>You can also specify javabeans as parameters if required using the @JavaBeanValue
+      annotation or &lt;javabean&gt; element. In this particular case the annotation is not very
+      useful as it can only call the default constructor of the javabean class to create an
+      instance. If you want to use a different constructor or inject properties then you should
+      use the XML element instead.</para>
+      <programlisting role="JAVA">@Constructor
+      public TestConstructorBean(@StringValue(&quot;this is a test constructor&quot;) String testString, @JavaBeanValueorg.jboss.test.Person.class) Person testPerson) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;Test&quot; class=&quot;org.jboss.example.constructor.TestConstructorBean&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;this is a test constructor&lt;/parameter&gt;
+      &lt;parameter&gt;
+      &lt;javabean xmlns=&quot;urn:jboss:javabean:2.0&quot; class=&quot;org.jboss.test.Person&quot;&gt;
+      &lt;constructor&gt;
+      &lt;property name=&quot;age&quot;&gt;21&lt;/property&gt;
+      &lt;/constructor&gt;
+      &lt;property name=&quot;firstName&quot;&gt;Mark&lt;/property&gt;
+      &lt;property name=&quot;lastName&quot;&gt;Newton&lt;/property&gt;
+      &lt;/javabean&gt;
+      &lt;/parameter&gt;
+      &lt;/constructor&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>Finally you can inject references to other beans or their properties into constructor
+      parameters giving you complete control of the construction of your POJOs.</para>
+      <programlisting role="JAVA">@Constructor
+      public TestConstructorBean(@Inject(bean=&quot;TestPerson&quot;) Person testPerson, @Inject(bean=&quot;TestAddress&quot;, property=&quot;street&quot;) String street) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;Test&quot; class=&quot;org.jboss.example.constructor.TestConstructorBean&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;
+      &lt;inject bean=&quot;TestPerson&quot;/&gt;
+      &lt;/parameter&gt;
+      &lt;parameter&gt;
+      &lt;inject bean=&quot;TestAddress&quot; property=&quot;street&quot;/&gt;
+      &lt;/parameter&gt;
+      &lt;/constructor&gt;
+      &lt;/bean&gt;</programlisting>
+    </section>
+    <section>
+      <title>Using factories</title>
+      <para>If you have a number of classes that share the same interface then you may want to use
+      a factory to create your POJO instances. JBoss Microcontainer provides support for static
+      or non-static factory methods which can also take parameters if necessary.</para>
+      <itemizedlist>
+	<listitem>
+	  <para>Static factory method</para>
+	  <programlisting role="JAVA">@Factory (factoryClass=&quot;org.jboss.example.MyFactory&quot;,
+          factoryMethod=&quot;newInstance&quot;)
+	  public class SimpleBean {
+	  ...
+	  }</programlisting>
+	  <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+	  &lt;constructor factoryClass=&quot;org.jboss.example.MyFactory&quot;
+	  factoryMethod=&quot;newInstance&quot;/&gt;
+	  &lt;/bean&gt; </programlisting>
+	</listitem>
+	<listitem>
+	  <para>Static factory method with parameters</para>
+	  <programlisting role="JAVA">@Factory (factoryClass=&quot;org.jboss.example.MyFactory&quot;,
+          factoryMethod=&quot;newInstance&quot;,
+          parameters={@Value(string=@StringValue(&quot;a string&quot;)),
+	  @Value(string=@StringValue(&quot;7&quot;))})
+	  public class SimpleBean {
+	  ...
+	  }</programlisting>
+	  <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+	  &lt;constructor factoryClass=&quot;org.jboss.example.MyFactory&quot;
+	  factoryMethod=&quot;newInstance&quot;&gt;
+	  &lt;parameter&gt;a string&lt;/parameter&gt;
+	  &lt;parameter&gt;7&lt;/parameter&gt;
+	  &lt;/constructor&gt;
+	  &lt;/bean&gt; </programlisting>
+	</listitem>
+	<listitem>
+	  <para>Non-static factory method (instance of factory created as JavaBean when
+	  needed)</para>
+	  <programlisting role="JAVA">@Factory (
+	  factory=@Value(javabean=@JavaBeanValue(org.jboss.example.MyOtherFactory.class)),
+	  factoryMethod=&quot;createBean&quot;)
+	  public class SimpleBean {
+	  ...
+	  }</programlisting>
+	  <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+	  &lt;constructor factoryMethod=&quot;createBean&quot;&gt;
+	  &lt;factory&gt;
+	  &lt;javabean xmlns="urn:jboss:javabean:1.0" 
+	  class="org.jboss.example.MyOtherFactory"/&gt;
+	  &lt;/factory&gt;
+	  &lt;/constructor&gt;
+	  &lt;/bean&gt;</programlisting>
+	</listitem>
+	<listitem>
+	  <para>Non-static factory method with parameters (instance of factory installed as a
+	  Microcontainer bean)</para>
+	  <programlisting role="JAVA">@Factory (
+	  factory=@Value(inject=@Inject(bean="Factory"))),
+	  factoryMethod=&quot;createBean&quot;,
+	  parameters={@Value(string=@StringValue(&quot;a string&quot;)),
+	  @Value(string=@StringValue(&quot;7&quot;))})
+	  public class SimpleBean {</programlisting>
+	  <programlisting role="XML">&lt;bean name=&quot;MyOtherFactory&quot; class=&quot;org.jboss.example.MyOtherFactory&quot;/&gt;
+
+	  &lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+	  &lt;constructor factoryMethod=&quot;createBean&quot;&gt;
+	  &lt;factory bean=&quot;MyOtherFactory&quot;/&gt;
+	  &lt;parameter&gt;a string&lt;/parameter&gt;
+	  &lt;parameter&gt;7&lt;/parameter&gt;
+	  &lt;/constructor&gt;
+	  &lt;/bean&gt;</programlisting>
+	</listitem>
+      </itemizedlist>
+      <para>For the special case where a bean implements its own static factory method in order to
+      create itself then you can also use a shorthand notation:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>Bean implementing its own static factory method</para>
+	  <programlisting role="JAVA">public class SimpleBean {
+
+	  @FactoryMethod
+	  public static newInstance(@StringValue(&quot;a string&quot;) String name, @StringValue(&quot;5&quot;) int level) {
+	  ...
+	  }
+	  }</programlisting>
+	  <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+	  &lt;constructor factoryMethod=&quot;newInstance&quot;&gt;
+	  &lt;parameter&gt;a string&lt;/parameter&gt;
+	  &lt;parameter&gt;5&lt;/parameter&gt;
+	  &lt;/constructor&gt;
+	  &lt;/bean&gt; </programlisting>
+	  <para>Note that the @FactoryMethod annotation doesn&apos;t have a parameter attribute as
+	  the method parameters themselves are annotated.</para>
+	</listitem>
+      </itemizedlist>
+      <note>
+	<para>Factory method parameters can also be configured using JavaBeans and injected bean
+	references if necessary just like constructor parameters. </para>
+      </note>
+    </section>
+    <section>
+      <title>Creating bean aliases</title>
+      <para>By default each bean declared in the deployment descriptor has a unique name that is
+      used to inject it into other beans or to provide a reference to clients at runtime.
+      Sometimes however it is useful to define additional names or aliases. This can be done
+      using the @Aliases annotation or &lt;alias&gt; XML element. System property replacement is
+      used by default to change the value of the alias at runtime but you can disable this if
+      required. </para>
+      <itemizedlist>
+	<listitem>
+	  <para>Defining extra bean names</para>
+	  <programlisting role="JAVA">@Aliases({&quot;MyAlias&quot;, &quot;Test: ${test.name}&quot;})
+	  public class SimpleBean {
+	  ...
+	  }</programlisting>
+	  <programlisting role="XML">&lt;bean name=&quot;MyBean&quot; class=&quot;org.acme.SimpleBean&quot;&gt;
+	  &lt;alias&gt;MyAlias&lt;/alias&gt;
+	  &lt;alias&gt;Test: ${test.name}&lt;/alias&gt;
+	  &lt;/bean&gt;</programlisting>
+	</listitem>
+	<listitem>
+	  <para>Disabling System property replacement</para>
+	  <programlisting role="JAVA">@Aliases({&quot;MyAlias&quot;, &quot;Test: ${test.name}&quot;} replace=&quot;false&quot;)
+	  public class SimpleBean {
+	  ...
+	  }</programlisting>
+	  <programlisting role="XML">&lt;bean name=&quot;MyBean&quot; class=&quot;org.acme.SimpleBean&quot;&gt;
+	  &lt;alias&gt;MyAlias&lt;/alias&gt;
+	  &lt;alias replace=&quot;false&quot;&gt;Test: ${test.name}&lt;/alias&gt;
+	  &lt;/bean&gt;</programlisting>
+	</listitem>
+      </itemizedlist>
+      <para>The type of an alias doesn&apos;t have to be a string. If you want to choose a
+      different type then you can specify a <property>class</property> attribute in the &lt;alias&gt;
+      XML element. At present you cannot do this using the @Aliases annotation.</para>
+      <itemizedlist>
+	<listitem>
+	  <para>Choosing a different alias type</para>
+	  <programlisting role="XML">&lt;bean name=&quot;MyBean&quot; class=&quot;org.acme.SimpleBean&quot;&gt;
+	  &lt;alias class=&quot;java.lang.Integer&quot;&gt;12345&lt;/alias&gt; 
+	  &lt;/bean&gt;</programlisting>
+	</listitem>
+      </itemizedlist>
+      <para>Sometimes you may wish to define an alias for a bean after it has been deployed. This
+      can be done using the standalone &lt;alias&gt; element in the deployment descriptor. There
+      is no equivalent annotation in this case as there is no sensible place to put it.</para>
+      <itemizedlist>
+	<listitem>
+	  <para>Defining a standalone alias</para>
+	  <programlisting role="XML">&lt;deployment name=&quot;FirstDeployment&quot; xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+	  &lt;bean name=&quot;Bean1&quot; class=&quot;java.lang.Object&quot;/&gt;
+	  &lt;bean name=&quot;Bean2&quot; class=&quot;java.lang.Object&quot;/&gt;
+
+	  &lt;/deployment&gt;
+
+	  &lt;deployment name=&quot;SecondDeployment&quot; xmlns=&quot;urn:jboss:bean-deployer:2.0&quot;&gt;
+
+	  &lt;bean name=&quot;Xyz1&quot; class=&quot;java.lang.Object&quot;&gt;
+	  &lt;property name=&quot;locker1&quot;&gt;&lt;inject name=&quot;Lock1&quot;&gt;&lt;/property&gt;
+	  &lt;property name=&quot;locker2&quot;&gt;&lt;inject name=&quot;Lock2&quot;&gt;&lt;/property&gt;
+	  &lt;/bean&gt;
+
+	  &lt;alias name=&quot;Bean1&quot;&gt;Lock1&lt;/alias&gt;
+	  &lt;alias name=&quot;Bean2&quot;&gt;Lock2&lt;/alias&gt;
+
+	  &lt;/deployment&gt; </programlisting>
+	</listitem>
+      </itemizedlist>
+      <note>
+	<para>Standalone aliases behave just like normal beans with respect to dependencies.
+	Specifically they won&apos;t be deployed until the beans that they represent have been
+	deployed first. Likewise when a bean is undeployed then any corresponding standalone
+	aliases are undeployed first.</para>
+	<para>Furthermore if any beans depend on a standalone alias then they will not be deployed
+	until the alias is deployed first. Similarly undeploying a standalone alias will cause
+	all dependent beans to be undeployed, regardless of whether the bean that it represents
+	remains deployed. </para>
+      </note>
+    </section>
+  </chapter>
+  <chapter>
+    <title>Injecting properties</title>
+    <section>
+      <title>Using values</title>
+      <para>Once a POJO instance has been created then it can be configured by injecting property
+      values. Like most other features this can be done using either annotations or a deployment
+      descriptor. For each property that you wish to inject the bean must define an appropriate
+      setter method for the microcontainer to call.</para>
+      <programlisting role="JAVA">public class PropertiesBean {
+
+      public void setTitle(@StringValue(&quot;JBoss Microcontainer&quot;) String title) {
+      ...
+      }
+
+      public void setLink(@StringValue(&quot;http://www.jboss.org&quot;) URL link) {
+      ...
+      }
+
+      public void setNumber(@StringValue(&quot;4&quot;) int number) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;PropertiesBean&quot; 
+      class=&quot;org.jboss.example.microcontainer.properties.PropertiesBean&quot;&gt;
+      &lt;property name=&quot;title&quot;&gt;JBoss Microcontainer&lt;/property&gt;
+      &lt;property name=&quot;link&quot;&gt;http://www.jboss.org&lt;/property&gt;
+      &lt;property name=&quot;number&quot;&gt;4&lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>As you have probably noticed we are required to enter all of our values as strings
+      since we are dealing with text files. These strings are converted into objects of the
+      correct type using JavaBean <ulink
+      url="http://java.sun.com/j2se/1.5.0/docs/api/java/beans/PropertyEditor.html"
+      >PropertyEditors</ulink>. If the property takes an interface or abstract class then you
+      can pass a specific implementation using a <property>type</property> or <property>class</property>
+      attribute depending on whether you&apos;re using annotations or XML.</para>
+      <programlisting role="JAVA">public class PropertiesBean {
+      public void setNumber(@StringValue(value=&quot;4&quot;, type=java.lang.Long.class) Number number) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;PropertiesBean&quot; 
+      class=&quot;org.jboss.example.microcontainer.properties.PropertiesBean&quot;&gt;
+      &lt;property name=&quot;number&quot; class=&quot;java.lang.Long&quot;&gt;4&lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>Sometimes you may want to pass in a value that isn&apos;t of the same type as the
+      property but can be progressed into it. Progression is typically used for converting
+      numbers from one type to another, e.g. Short to Int or Float to Double. JBoss
+      Microcontainer by default will automatically perform progression using a
+      <classname>SimpleProgressionConverter</classname> implementation.</para>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.test.SimpleBean&quot;&gt;
+      &lt;property name=&quot;anInt&quot;&gt;
+      &lt;javabean xmlns=&quot;urn:jboss:javabean:2.0&quot; class=&quot;java.lang.Double&quot;&gt;
+      &lt;constructor&gt;
+      &lt;property name=&quot;aDouble&quot;&gt;123.456&lt;/property&gt;
+      &lt;/constructor&gt;
+      &lt;/javabean&gt;
+      &lt;/property&gt;
+      &lt;property name=&quot;aShort&quot;&gt;
+      &lt;javabean xmlns=&quot;urn:jboss:javabean:2.0&quot; class=&quot;java.lang.Float&quot;&gt;
+      &lt;constructor&gt;
+      &lt;property name=&quot;aFloat&quot;&gt;987.6543&lt;/property&gt;
+      &lt;/constructor&gt;
+      &lt;/javabean&gt;
+      &lt;/property&gt;
+      &lt;property name=&quot;aFloat&quot;&gt;
+      &lt;javabean xmlns=&quot;urn:jboss:javabean:2.0&quot; class=&quot;java.lang.Integer&quot;&gt;
+      &lt;constructor&gt;
+      &lt;property name=&quot;anInt&quot;&gt;314159&lt;/property&gt;
+      &lt;/constructor&gt;
+      &lt;/javabean&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>You can replace the default progression converter implementation with one of your own
+      by setting the <property>org.jboss.reflect.plugins.progressionConverter</property> system property
+      using a fully-qualified class name. If you want to prevent progression from occuring
+      altogether then you can use the <property>NullProgressionConverter</property> which is also
+      provided.</para>
+      <programlisting>-Dorg.jboss.reflect.plugins.progressionConverter=org.jboss.reflect.plugins.NullProgressionConvertor</programlisting>
+      <para>If you want to use a null value then you need to use the @NullValue annotation or
+      &lt;null/&gt; element. This is so we can differentiate it from the string
+      &apos;null&apos;.</para>
+      <programlisting role="JAVA">public void setTitle(@NullValue String title) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;PropertiesBean&quot; 
+      class=&quot;org.jboss.example.microcontainer.properties.PropertiesBean&quot;&gt;
+      &lt;property name=&quot;title&quot;&gt;&lt;null/&gt;&lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>Similarly if you want to refer to the current object then you should use the
+      @ThisValue annotation or &lt;this/&gt; element.</para>
+      <programlisting role="JAVA">public void setObject(@ThisValue Object target) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;PropertiesBean&quot; 
+      class=&quot;org.jboss.example.microcontainer.properties.PropertiesBean&quot;&gt;
+      &lt;property name=&quot;target&quot;&gt;&lt;this/&gt;&lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>Property values can also be defined using a longer form of XML if you prefer.</para>
+      <programlisting role="XML">&lt;bean name=&quot;PropertiesBean&quot; 
+      class=&quot;org.jboss.example.microcontainer.properties.PropertiesBean&quot;&gt;
+      &lt;property name=&quot;number&quot;&gt;
+      &lt;value class=&quot;java.lang.Long&quot;&gt;4&lt;/value&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>This is primarily used when configuring values representing collections such as lists,
+      sets and arrays. Elements of a collection are defined by listing annotations or nesting
+      &lt;value&gt; elements as follows:</para>
+      <programlisting role="JAVA">@CollectionValue(elementClass=java.lang.String.class,
+      {@Value(string=@StringValue(&quot;string1&quot;)),
+      @Value(string=@StringValue(&quot;string2&quot;)),
+      @Value(string=@StringValue(&quot;string3&quot;)),
+      @Value(string=@StringValue(&quot;string4&quot;))})
+      public void setCollection(Collection collection) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;property name=&quot;collection&quot;&gt;
+      &lt;collection elementClass=&quot;java.lang.String&quot;&gt;
+      &lt;value&gt;string1&lt;/value&gt;
+      &lt;value&gt;string2&lt;/value&gt;
+      &lt;value&gt;string3&lt;/value&gt;
+      &lt;value&gt;string4&lt;/value&gt;
+      &lt;/collection&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>The <property>elementClass</property> attribute specifies the default class for the values.
+      This can be overriden for individual values using the <property>type</property> or
+      <property>class</property> attributes.</para>
+      <programlisting role="JAVA">@CollectionValue(elementClass=java.lang.String.class,
+      {@Value(string=@StringValue(&quot;string1&quot;)),
+      @Value(string=@StringValue(&quot;string2&quot;)),
+      @Value(string=@StringValue(value=&quot;3.0&quot;, type=&quot;java.lang.Float&quot;)),
+      @Value(string=@StringValue(value=&quot;4&quot;, type=&quot;java.lang.Integer&quot;))})
+      public void setCollection(Collection collection) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;property name=&quot;collection&quot;&gt;
+      &lt;collection elementClass=&quot;java.lang.String&quot;&gt;
+      &lt;value&gt;string1&lt;/value&gt;
+      &lt;value&gt;string2&lt;/value&gt;
+      &lt;value class=&quot;java.lang.Float&quot;&gt;3.0&lt;/value&gt;
+      &lt;value class=&quot;java.lang.Integer&quot;&gt;4&lt;/value&gt;
+      &lt;/collection&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <warning>
+	<para>The type of each value must be specified using either the <property>elementClass</property>
+	or <property>type/class</property> attribute in order for the collection to be created.</para>
+      </warning>
+      <para>Lists, sets and arrays take the same form as the collection annotation and XML
+      element. </para>
+      <programlisting role="JAVA">@ListValue(elementClass=java.lang.String.class,
+      {@Value(string=@StringValue(&quot;my first string&quot;)),
+      @Value(string=@StringValue(&quot;my second string&quot;))})
+      public void setList(List list) {
+      ...
+      }
+
+      @SetValue(elementClass=java.lang.Integer.class,
+      {@Value(string=@StringValue(&quot;50&quot;)),
+      @Value(string=@StringValue(&quot;55&quot;))})
+      public void setSet(Set set) {
+      ...
+      }
+
+      @ArrayValue(elementClass=java.lang.Float.class,
+      {@Value(string=@StringValue(&quot;1.0&quot;)),
+      @Value(string=@StringValue(&quot;2.0&quot;))})
+      public void setArray(Object[] array) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;property name=&quot;list&quot;&gt;
+      &lt;list elementClass=&quot;java.lang.String&quot;&gt;
+      &lt;value&gt;my first string&lt;/value&gt;
+      &lt;value&gt;my second string&lt;/value&gt;
+      &lt;/list&gt;
+      &lt;/property&gt;
+
+      &lt;property name=&quot;set&quot;&gt;
+      &lt;set elementClass=&quot;java.lang.Integer&quot;&gt;
+      &lt;value&gt;50&lt;/value&gt;
+      &lt;value&gt;55&lt;/value&gt;
+      &lt;/set&gt;
+      &lt;/property&gt;
+
+      &lt;property name=&quot;array&quot;&gt;
+      &lt;array elementClass=&quot;java.lang.Float&quot;&gt;
+      &lt;value&gt;1.0&lt;/value&gt;
+      &lt;value&gt;2.0&lt;/value&gt;
+      &lt;/array&gt;
+      &lt;/array&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>They can even be nested within one another if required. </para>
+      <programlisting role="JAVA">@ListValue(elementClass=java.lang.String.class,
+      {@Value(string=@StringValue(&quot;my first string&quot;)),
+      @Value(string=@SetValue(elementClass=java.lang.Integer.class;,
+      {@Value(string=@StringValue(&quot;1&quot;)),
+      @Value(string=@StringValue=&quot;2&quot;))})
+      )})
+      public void setList(List list) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;property name=&quot;list&quot;&gt;
+      &lt;list elementClass=&quot;java.lang.String&quot;&gt;
+      &lt;value&gt;my first string&lt;/value&gt;
+      &lt;value&gt;
+      &lt;set elementClass=&quot;java.lang.Integer&quot;&gt;
+      &lt;value&gt;1&lt;/value&gt;
+      &lt;value&gt;2&lt;/value&gt;
+      &lt;/set&gt;
+      &lt;/value&gt;
+      &lt;/list&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>Maps can also be created using multiple entries of key/value pairs. As we now have two
+      types to consider we must use the <property>keyClass</property> and <property>valueClass</property>
+      attributes to specify the default classes for each entry. Again these can be overriden for
+      individual entries if necessary.</para>
+      <programlisting role="JAVA">@MapValue(keyClass=java.lang.String.class,
+      valueClass=java.lang.String.class;,
+      {@EntryValue(key=@Value(string=@StringValue(&quot;foo.bar.key&quot;)),
+      value=@Value(string=@StringValue(&quot;QWERT&quot;))),
+      @EntryValue(key=@Value(string=@StringValue(&quot;xyz.key&quot;)),
+      value=@Value(string=@StringValue(&quot;QWERTY&quot;)))
+      })
+      public void setMap(Map&lt;String, String&gt; map) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;property name=&quot;map&quot;&gt;
+      &lt;map keyClass=&quot;java.lang.String&quot; valueClass=&quot;java.lang.String&quot;&gt;
+      &lt;entry&gt;
+      &lt;key&gt;foo.bar.key&lt;/key&gt;
+      &lt;value&gt;QWERT&lt;/value&gt;
+      &lt;/entry&gt;
+      &lt;entry&gt;
+      &lt;key&gt;xyz.key&lt;/key&gt;
+      &lt;value&gt;QWERTY&lt;/value&gt;
+      &lt;/entry&gt;
+      &lt;/map&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>So far we have defined collections, lists, sets, arrays and maps but all of these have
+      multiple implementations, e.g. java.util.ArrayList, java.util.LinkedList, so which are we
+      using at runtime? By default JBoss Microcontainer will look for an existing instance using
+      the corresponding getter method for the property. If one is found then it is used, and any
+      values defined in the annotations or xml deployment descriptor will be added to the
+      exisiting values. If not then the type of the property is analysed and providing that it
+      represents a class (not an interface) then this is used to create a new instance. Failing
+      that a default instance will be created as follows:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>Collection - java.util.ArrayList</para>
+	</listitem>
+	<listitem>
+	  <para>List - java.util.ArrayList</para>
+	</listitem>
+	<listitem>
+	  <para>Set - java.util.HashSet</para>
+	</listitem>
+	<listitem>
+	  <para>Array - java.lang.Object[]</para>
+	</listitem>
+	<listitem>
+	  <para>Map - java.util.HashMap</para>
+	</listitem>
+      </itemizedlist>
+      <para>If you want to override this behaviour and specify your own class then you can simply
+      add a <property>clazz</property> attribute to your annotation or <property>class</property> attribute to
+      your XML element containing the fully-qualified class name. This causes the microcontainer
+      to create a new instance using the specified class.</para>
+      <programlisting role="JAVA">@SetValue(clazz=java.util.TreeSet.class,
+      elementClass=java.lang.Integer.class,
+      {@Value(string=@StringValue(&quot;50&quot;)),
+      @Value(string=@StringValue(&quot;55&quot;))})
+      public void setSet(Set set) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot;
+      class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;property name=&quot;set&quot;&gt;
+      &lt;set class=&quot;java.util.TreeSet&quot; elementClass=&quot;java.lang.Integer&quot;&gt;
+      &lt;value&gt;50&lt;/value&gt;
+      &lt;value&gt;55&lt;/value&gt;
+      &lt;/set&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <note>
+	<para>If you don&apos;t specify a <property>clazz/class</property> attribute but you
+	want to ensure that a new instance is created then you can prevent the microcontainer
+	from looking for a existing instance by specifying a <property>preinstantiate</property>
+	attribute in the &lt;property&gt; element. Currently this cannot be achieved using
+	annotations.</para>
+	<programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+	&lt;property name=&quot;list&quot; preinstantiate=&quot;false&quot;&gt;
+        &lt;list elementClass=&quot;java.lang.String&quot;&gt;
+	&lt;value&gt;string1&lt;/value&gt;
+	&lt;value&gt;string2&lt;/value&gt;
+        &lt;/list&gt;
+	&lt;/property&gt;
+	&lt;/bean&gt; </programlisting>
+      </note>
+      <note>
+	<para>If you want to define a <property>clazz/class</property> attribute for an array
+	then you must use the following syntax:</para>
+
+	<screen>[L<replaceable>&lt;fully-qualified class
+	name&gt;</replaceable>;</screen>
+	<variablelist>
+	  <varlistentry>
+	    <term>An array of strings</term>
+	    <listitem>
+	      <para>
+		[Ljava.lang.String;
+	      </para>
+	    </listitem>
+	  </varlistentry>
+	  <varlistentry>
+	    <term>An array of integers</term>
+	    <listitem>
+	      <para>
+		[Ljava.lang.Integer;
+	      </para>
+	    </listitem>
+	  </varlistentry>
+	</variablelist>
+      </note>
+    </section>
+    <section>
+      <title>Calling methods</title>
+      <para>Using PropertyEditors to create instances of objects from strings is fine in many
+      situations but sometimes you need to inject a return value from a method call. As the
+      method is responsible for creating the value we refer to it as a value factory. Hence the
+      @ValueFactory annotation or &lt;value-factory&gt; element can be used in place of
+      @StringValue or &lt;value&gt; to call a method and inject the returned value during
+      deployment.</para>
+      <programlisting role="JAVA">@ValueFactory(bean=&quot;SimpleBean&quot;,
+      method=&quot;getFullName&quot;)
+      public void setName(String name) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;PropHolder&quot; class=&quot;org.jboss.test.kernel.config.support.PropHolder&quot;&gt;
+      &lt;property name=&quot;name&quot;&gt;
+      &lt;value-factory bean=&quot;SimpleBean&quot; method=&quot;getFullName&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>If you need to pass any parameters to the method then you can use multiple @Parameter
+      annotations or nested &lt;parameter&gt; elements. </para>
+      <programlisting role="JAVA">@ValueFactory(bean=&quot;SimpleBean&quot;,
+      method=&quot;getFullName&quot;,
+      parameters={@Parameter(string=@StringValue(&quot;Bob&quot;)),
+      @Parameter(string=@StringValue(&quot;Smith&quot;))})
+      public void setName(String name) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;PropHolder&quot; class=&quot;org.jboss.test.kernel.config.support.PropHolder&quot;&gt;
+      &lt;property name=&quot;name&quot;&gt;
+      &lt;value-factory bean=&quot;SimpleBean&quot; method=&quot;getFullName&quot;&gt;
+      &lt;parameter&gt;Bob&lt;/parameter&gt;
+      &lt;parameter&gt;Smith&lt;/parameter&gt;
+      &lt;/value-factory&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>Alternatively if only one parameter is required then you can use the
+      <property>parameter</property> attribute to create a shorthand version. However this only works
+      for values that can be created from strings.</para>
+      <programlisting role="JAVA">@ValueFactory(bean=&quot;SimpleBean&quot;,
+      method=&quot;getFullName&quot;,
+      parameter=&quot;Bob&quot;)
+      public void setName(String name) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;PropHolder&quot; class=&quot;org.jboss.test.kernel.config.support.PropHolder&quot;&gt;
+      &lt;property name=&quot;name&quot;&gt;
+      &lt;value-factory bean=&quot;SimpleBean&quot; method=&quot;getFullName&quot; parameter=&quot;Bob&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>It is also possible to specify a default value to use in case the method returns null.
+      This is done using the <property>defaultValue/default</property> attribute which like
+      the <property>parameter</property> attribute only accepts values created using strings. </para>
+      <programlisting role="JAVA">@ValueFactory(bean=&quot;SimpleBean&quot;,
+      method=&quot;getFullName&quot;,
+      defaultValue=&quot;Mark Newton&quot;)
+      public void setName(String name) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;PropHolder&quot; class=&quot;org.jboss.test.kernel.config.support.PropHolder&quot;&gt;
+      &lt;property name=&quot;name&quot;&gt;
+      &lt;value-factory bean=&quot;SimpleBean&quot; method=&quot;getFullName&quot; default=&quot;Mark Newton&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+    </section>
+    <section>
+      <title>Using bean references</title>
+      <para>Injecting string-based properties or the return values of method calls into individual
+      beans allows us to perform simple configurations. To create more complex configurations we
+      need to wire beans together by injecting references using the @Inject annotation or
+      &lt;inject&gt; element. </para>
+      <programlisting role="JAVA">@Inject(bean = &quot;Name1&quot;)
+      public void setSimpleBean(SimpleBean bean) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.test.SimpleBean&quot;&gt;
+      &lt;property name=&quot;simpleBean&quot;&gt;
+      &lt;inject bean=&quot;Name1&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>Bean injections can be used anywhere a string value is used but you must ensure that
+      the type of bean being injected is compatible with the type of property being set. It is
+      also possible to inject a property from one bean into another using the
+      <property>property</property> attribute.</para>
+      <programlisting role="JAVA">@Inject(bean = &quot;Name1&quot;, property=&quot;age&quot;)
+      public void setAge(Integer age) {
+      ...
+      } </programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.test.SimpleBean&quot;&gt;
+      &lt;property name=&quot;age&quot;&gt;
+      &lt;inject bean=&quot;Name1&quot; property=&quot;age&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>Although injection is simple to use it provides a very powerful way to create
+      arbitrary relationships between POJO instances. The dependencies that are formed by these
+      relationships are discussed in the next chapter &apos;Defining Dependencies&apos;.</para>
+      <note>
+	<para>Sometimes you may wish to declare a bean simply so that you can inject it into a
+	single property. In this case you can replace the &lt;inject&gt; element with the bean
+	declaration itself to reduce the amount of XML required. This is not possible using
+	annotations as there is no annotation to declare a bean.</para>
+	<programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.test.SimpleBean&quot;&gt;
+	&lt;property name=&quot;testBean&quot;&gt;
+        &lt;bean=&quot;TestBean&quot; class=&quot;org.jboss.test.TestBean&quot;&gt;
+	&lt;property name=&quot;age&quot;&gt;25&lt;/property&gt;
+        &lt;/bean&gt;
+	&lt;/property&gt;
+	&lt;/bean&gt;</programlisting>
+      </note>
+    </section>
+    <section>
+      <title>Injecting context information</title>
+      <para>You may recall that inside the microcontainer each bean is represented by a context
+      which holds amongst other things the bean&apos;s current state. This context information
+      can be injected into bean properties or constructor/factory-method parameters using the
+      @Inject annotation or &lt;inject&gt; element together with a <property>fromContext</property>
+      attribute.</para>
+      <programlisting role="JAVA">@Inject(bean=&quot;otherBean&quot;,
+      fromContext=FromContext.BEANINFO)
+      public void setBeanInfo(BeanInfo beanInfo) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;sndBean&quot; class=&quot;org.jboss.test.NameAwareBean&quot;&gt;
+      &lt;property name=&quot;beaninfo&quot;&gt;
+      &lt;inject bean=&quot;otherBean&quot; fromContext=&quot;beaninfo&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>If you want to inject information about the current bean&apos;s context then you can
+      simply omit the <property>bean</property> attribute.</para>
+      <programlisting role="JAVA">@Inject(fromContext=FromContext.BEANINFO)
+      public void setBeanInfo(BeanInfo beanInfo) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;sndBean&quot; class=&quot;org.jboss.test.NameAwareBean&quot;&gt;
+      &lt;property name=&quot;beaninfo&quot;&gt;
+      &lt;inject fromContext=&quot;beaninfo&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>The <property>fromContext</property> attribute can take the following values from the
+      <systemitem>org.jboss.beans.metadata.api.model.FromContext</systemitem> enum:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>name - the name of the bean</para>
+	</listitem>
+	<listitem>
+	  <para>aliases - a list of the bean&apos;s other names</para>
+	</listitem>
+	<listitem>
+	  <para>metadata - information about the bean from annotations or deployment
+	  descriptors</para>
+	</listitem>
+	<listitem>
+	  <para>beaninfo - information about the bean from the bean class</para>
+	</listitem>
+	<listitem>
+	  <para>scope - the microcontainer scope that the bean belongs to</para>
+	</listitem>
+	<listitem>
+	  <para>id - the internal id of the bean within the microcontainer</para>
+	</listitem>
+	<listitem>
+	  <para>context - the bean context</para>
+	</listitem>
+      </itemizedlist>
+      <important>
+	<para>All context information is wrapped into unmodifiable objects to prevent the user
+	from changing anything outside of the microcontainer&apos;s control. </para>
+      </important>
+    </section>
+    <section>
+      <title>Auto-wiring</title>
+      <para>Having to write large amounts of configuration information just to wire together
+      sometimes trivial beans can often be frustrating. For this reason JBoss Microcontainer
+      provides the ability to autowire beans. Auto-wiring means that a bean&apos;s properties or
+      constructor/factory-method parameters are set by automatically searching for matching
+      beans. The benefit is that you don&apos;t have to specify the names of the beans to inject
+      yourself but the drawback is that this only works reliably for small environments. If you
+      have an environment where more than one bean matches the property or parameter being set
+      then it becomes unclear from the configuration information which one will be chosen during
+      deployment. </para>
+      <para>To use auto-wiring you simply need to specify an @Inject annotation or &lt;inject&gt;
+      element without a <property>bean</property> attribute for the parameter or property that you wish
+      to set.</para>
+      <programlisting role="JAVA">@Inject
+      public class Example(ThreadPool pool) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;paramInj&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter name=&quot;threadPool&quot;&gt;&lt;inject/&gt;&lt;/parameter&gt;
+      &lt;/constructor&gt;
+      &lt;/bean&gt; </programlisting>
+      <programlisting role="JAVA">@Inject
+      public void setThreadPool(ThreadPool pool) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;propInj&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;property name=&quot;threadPool&quot;&gt;&lt;inject/&gt;&lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>By default the microcontainer will search for a bean whose class matches that of the
+      parameter/property. However you can change this behaviour when auto-wiring properties so
+      that the microcontainer searches for a bean whose name matches the property name. This is
+      done using the <property>type</property> attribute of the &lt;inject&gt; element.</para>
+      <programlisting role="JAVA">@Inject(type=AutowireType.By_NAME)
+      public void setThreadPool(ThreadPool pool) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;propInj&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;property name=&quot;threadPool&quot;&gt;&lt;inject type=&quot;ByName&quot;/&gt;&lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>The <systemitem>org.jboss.beans.metadata.api.model.AutowireType</systemitem> enum defines the
+      valid values to use. <property>AutowireType.By_CLASS</property> is the default if using
+      annotations, and <property>ByClass</property> the default when using xml.</para>
+      <para>If no match is found then by default the deployment will fail but for certain
+      properties it may be acceptable for injection to occur after deployment. In these cases
+      you can specify that a property should be set using a callback mechanism whenever a
+      suitable bean becomes available. This is done using the <property>option</property>
+      attribute.</para>
+      <programlisting role="JAVA">@Inject(type=AutowireType.By_NAME, option=InjectOption.CALLBACK)
+      public void setThreadPool(ThreadPool pool) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;propInj&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;property name=&quot;threadPool&quot;&gt;&lt;inject type=&quot;ByName&quot; option=&quot;Callback&quot;/&gt;&lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>The <systemitem>org.jboss.beans.metadata.api.model.InjectOption</systemitem> enum defines the
+      valid values to use. <property>InjectOption.STRICT</property> is the default when using
+      annotations, and <property>Strict</property> the default when using xml. Another possible value
+      for <varname>option</varname> is <property>InjectOption.OPTIONAL</property> when using annotations, and
+      <property>Optional</property> when using xml, if this option is used the dependency is injected
+      if present at injection time, otherwise it is ignored.</para>
+      <para>Sometimes you may want to prevent a bean from being injected automatically using
+      auto-wiring. In these situations you can set its <varname>autowire-candidate</varname> attribute
+      to false so that it&apos;s not included in the search for matching beans. This is not
+      currently possible using annotations as there is no annotation to declare a bean.</para>
+      <programlisting role="XML">&lt;bean name=&quot;ignored&quot; class=&quot;com.acme.Example&quot; autowire-candidate=&quot;false&quot; /&gt;</programlisting>
+    </section>
+  </chapter>
+  <chapter>
+    <title>Defining dependencies</title>
+    <section>
+      <title>POJO dependencies</title>
+      <para>Dependencies between beans (POJO instances) are created when they are wired together
+      through the use of the @Inject annotation or &lt;inject&gt; element. Specifically a bean
+      which has another bean injected into it is said to be dependent on the other bean. For
+      example here we have a Person bean that is dependent on an Address bean.</para>
+      <programlisting role="JAVA">public class Person {
+      @Inject(bean=&quot;AddressBean&quot;)
+      public void setAddress(Address address) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;Person&quot; class=&quot;org.jboss.test.Person&quot;&gt;
+      &lt;property name=&quot;address&quot;&gt;
+      &lt;inject bean=&quot;AddressBean&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>The reason for the dependency is because the address property of the Person bean
+      cannot be configured until the Address bean has been deployed. Internally JBoss
+      Microcontainer enforces this by moving each bean through a series of states during
+      deployment. Consequently the Person bean will be prevented from moving to the CONFIGURED
+      state until the Address bean has reached the INSTALLED state representing a deployed
+      bean.</para>
+      <para>By default there are 8 states that a bean can be in during deployment and
+      undeployment:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>NOT_INSTALLED - Metadata describing the bean has been parsed from annotations or a
+	  deployment descriptor.</para>
+	</listitem>
+	<listitem>
+	  <para>PRE_INSTALL - the scope of the bean within the microcontainer has been discovered
+	  and classloading dependencies have been resolved.</para>
+	</listitem>
+	<listitem>
+	  <para>DESCRIBED - Any AOP dependencies have been added.</para>
+	</listitem>
+	<listitem>
+	  <para>INSTANTIATED -All dependencies have been resolved to construct the bean. These
+	  include; a classloader exists, the class can be found, a constructor or factory method
+	  can be found and any parameter injections can be resolved.</para>
+	</listitem>
+	<listitem>
+	  <para>CONFIGURED - All the property injections can be resolved. This includes any
+	  injections within collections.</para>
+	</listitem>
+	<listitem>
+	  <para>CREATE - All the beans metioned in the @Depends annotation or &lt;depends&gt;
+	  element have reached the CREATE state including any parameter injections in the create
+	  method.</para>
+	</listitem>
+	<listitem>
+	  <para>START - All the beans metioned in the @Depends annotation or &lt;depends&gt;
+	  element have reached the START state including any parameter injections in the start
+	  method.</para>
+	</listitem>
+	<listitem>
+	  <para>INSTALLED - Any deployment actions have been processed and the bean has been added
+	  to the list of items that the controller supplies.</para>
+	</listitem>
+      </itemizedlist>
+      <para>You may notice that we refer to injections being resolved in the above list. This is a
+      shorthand way of saying that an injected bean has reached a certain state. In our simple
+      example we can say that the injected Address bean has been resolved when it reaches the
+      INSTALLED state. If necessary you can change the state that an injected bean must reach
+      before being considered resolved by using the
+      <varname>dependentState/state</varname> attribute.</para>
+      <programlisting role="JAVA">public class Person {
+      @Inject(bean=&quot;OtherBean&quot;,
+      dependentState=&quot;Instantiated&quot;)
+      public void setAddress(Address address) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;Person&quot; class=&quot;org.jboss.test.Person&quot;&gt;
+      &lt;property name=&quot;address&quot;&gt;
+      &lt;inject bean=&quot;Address&quot; state=&quot;Instantiated&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>Here we are saying the Address bean needs to reach the INSTANTIATED state before the
+      Person bean can use it to configure the address property and thus move to the CONFIGURED
+      state. Be aware that setting the state value to <property>Described</property> in this case would
+      not be appropriate since we must first have an instance of the Address bean before we can
+      inject a reference to it into another bean.</para>
+      <note>
+	<para>The following six values can be used for the
+	<varname>dependentState/state</varname> attribute to control injection. If no
+	value is specified then by default the Installed state is used.</para>
+	<itemizedlist>
+	  <listitem>
+	    <para>Described</para>
+	  </listitem>
+	  <listitem>
+	    <para>Instantiated</para>
+	  </listitem>
+	  <listitem>
+	    <para>Configured</para>
+	  </listitem>
+	  <listitem>
+	    <para>Create</para>
+	  </listitem>
+	  <listitem>
+	    <para>Start</para>
+	  </listitem>
+	  <listitem>
+	    <para>Installed</para>
+	  </listitem>
+	</itemizedlist>
+      </note>
+      <para>The ability to control when injection occurs is especially useful when dealing with
+      circular dependencies. A circular dependency happens when one bean depends on another
+      which in turn depends on the first bean:</para>
+      <programlisting role="XML">&lt;bean name=&quot;Circular1&quot; class=&quot;org.jboss.example.InjectionBean&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;Circular1&lt;/parameter&gt;
+      &lt;/constructor&gt;
+
+      &lt;property name=&quot;other&quot;&gt;
+      &lt;inject bean=&quot;Circular2&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;Circular2&quot; class=&quot;org.jboss.example.InjectionBean&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;Circular2&lt;/parameter&gt;
+      &lt;/constructor&gt;
+
+      &lt;property name=&quot;other&quot;&gt;
+      &lt;inject bean=&quot;Circular1&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>In this configuration the microcontainer is unable to deploy either bean since each
+      one is waiting in the INSTANTIATED state waiting for the other to reach the INSTALLED
+      state. To solve this we can use the <varname>state</varname> attribute to specify that Circular1
+      can be injected into Circular2 as soon as it reaches the INSTANTIATED state. </para>
+      <programlisting role="XML">&lt;bean name=&quot;Circular1&quot; class=&quot;org.jboss.example.InjectionBean&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;Circular1&lt;/parameter&gt;
+      &lt;/constructor&gt;
+
+      &lt;property name=&quot;other&quot;&gt;
+      &lt;inject bean=&quot;Circular2&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;Circular2&quot; class=&quot;org.jboss.example.InjectionBean&quot;&gt;
+      &lt;constructor&gt;
+      &lt;parameter&gt;Circular2&lt;/parameter&gt;
+      &lt;/constructor&gt;
+
+      &lt;property name=&quot;other&quot;&gt;
+      &lt;inject bean=&quot;Circular1&quot; state=&quot;Instantiated&quot;/&gt;
+      &lt;/property&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>Circular2 can thus progress to the INSTALLED state whereupon Circular1 will inject it
+      into its <varname>other</varname> property and continue deploying.</para>
+    </section>
+    <section>
+      <title>Supply and Demand</title>
+      <para>Sometimes dependencies may exist between beans that are not wired together using
+      injections. One example would be a bean representing a service that requires a transaction
+      manager to be present in JNDI before it can start. In these situations we can use a
+      @Demand annotation or &lt;demand&gt; element to specify that we need another bean to be
+      deployed before we can reach a certain state.</para>
+      <programlisting role="JAVA">@Demands(@Demand(&quot;TransactionManager&quot;))
+      public class Example {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;TransactionManager&quot; class=&quot;com.acme.TransactionManager&quot;/&gt;
+
+      &lt;bean name=&quot;Name2&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;demand&gt;TransactionManager&lt;/demand&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>By default the bean declaring the demand will wait until the beans it requires have
+      been deployed before it moves to the INSTANTIATED state. However you can change this using
+      the <varname>whenRequired/state</varname> attribute to specify a different state
+      that can only be reached once all the beans listed as demands have been deployed.</para>
+      <programlisting role="JAVA">@Demands(@Demand(&quot;TransactionManager&quot;, whenRequired=&quot;Start&quot;))
+      public class Example {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;TransactionManager&quot; class=&quot;com.acme.TransactionManager&quot;/&gt;
+
+      &lt;bean name=&quot;Name2&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;demand state=&quot;Start&quot;&gt;TransactionManager&lt;/demand&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>Here we are stating that the TransactionManager bean must be deployed before the Name2
+      bean can reach the Start state. To specify multiple dependencies on other beans you simply
+      need to list @Demand annotations or nest &lt;demand&gt; elements:</para>
+      <programlisting role="JAVA">@Demands(@Demand(&quot;TransactionManager&quot;, whenRequired=&quot;Start&quot;),
+      @Demand(&quot;OtherBean&quot;))
+      public class Example {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;TransactionManager&quot; class=&quot;com.acme.SomeSingleton&quot;&gt;
+      &lt;property name=&quot;host&quot;&gt;http://www.jboss.org&lt;/property&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;Name2&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;demand state=&quot;Start&quot;&gt;TransactionManager&lt;/demand&gt;
+      &lt;demand&gt;OtherBean&lt;/demand&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>In addition to specifying dependencies on other beans you can also specify
+      dependencies on arbitrary objects that other beans supply. This can be useful if a bean
+      depends on something that is provided by multiple beans but doesn&apos;t necessarily care
+      which one provides it. To create these arbitrary objects you need to use the @Supply
+      annotation or &lt;supply&gt; element.</para>
+      <programlisting role="JAVA">@Supply(&quot;SomethingUseful&quot;)
+      public class Provider {
+      ...
+      }
+
+      @Demands(@Demand(&quot;SomethingUseful&quot;))
+      public class Consumer {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;Provider&quot; class=&quot;com.acme.Provider&quot;&gt;
+      &lt;supply&gt;SomethingUseful&lt;/supply&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;Consumer&quot; class=&quot;com.acme.Consumer&quot;&gt;
+      &lt;demand&gt;SomethingUseful&lt;/demand&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>A bean can also supply multiple objects if necessary:</para>
+      <programlisting role="JAVA">@Supplys({@Supply(&quot;SomethingUseful&quot;),
+      @Supply(&quot;SomethingElse&quot;)})
+      public class Provider {
+      ...
+      }
+
+      @Demands({@Demand(&quot;SomethingUseful&quot;)})
+      public class Consumer {
+      ...
+      }
+
+      @Demand(&quot;SomethingElse&quot;)
+      public class OtherConsumer {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;Provider&quot; class=&quot;com.acme.Provider&quot;&gt;
+      &lt;supply&gt;SomethingUseful&lt;/supply&gt;
+      &lt;supply&gt;SomethingElse&lt;/supply&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;Consumer&quot; class=&quot;com.acme.Consumer&quot;&gt;
+      &lt;demand&gt;SomethingUseful&lt;/demand&gt;
+      &lt;/bean&gt;
+
+      &lt;bean name=&quot;OtherConsumer&quot; class=&quot;com.acme.Consumer&quot;&gt;
+      &lt;demand&gt;SomethingElse&lt;/demand&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>Behind the scenes JBoss Microcontainer creates a bean of type java.lang.Object for
+      each @Supply annotation or &lt;supply&gt; element named after its value. These beans are
+      then moved automatically through all of the states to reach the INSTALLED state and become
+      deployed. From this point onwards the @Demand annotation and &lt;demand&gt; element work
+      in exactly the same way as before, checking to see if the named bean has been deployed
+      before allowing the bean declaring the demands to move to a certain state.</para>
+      <section>
+	<title>Customizing how Supply and Demand are Matched</title>
+	<para>To control how a demand matches a supply you can specify a transformer that
+	customizes how the demand value is matched to a supply value. The matching is customized
+	by specifying a transformer to a demand. The transformer is an implementation of the
+	following org.jboss.kernel.api.dependency.MatcherTransformer and associated
+	org.jboss.kernel.api.dependency.Matcher interfaces: </para>
+	<programlisting role="Java">
+	  package org.jboss.kernel.api.dependency;
+
+	  public interface MatcherTransformer
+	  {
+	  /**
+	  * Transform value param to Matcher instance.
+	  *
+	  * @param value the value
+	  * @return Matcher instance
+	  */
+	  Matcher transform(Object value);
+	  }
+
+	  package org.jboss.kernel.api.dependency;
+
+	  /**
+	  * Matcher.
+	  * Match this instance against any object.
+	  *
+	  */
+	  public interface Matcher
+	  {
+	  /**
+	  * Do we match this object other param.
+	  *
+	  * @param other the object to match
+	  * @return true if we match the other param, false otherwise
+	  */
+	  boolean match(Object other);
+
+	  /**
+	  * Do we need an exact match.
+	  * No match or single match is acceptable.
+	  *
+	  * @return true if matcher accepts only exact matches 
+	  */
+	  boolean needExactMatch();
+	  }
+
+	</programlisting>
+	<para>There are a number of pre-existing implementations that may be referenced by a one
+	of the following keys:<simplelist>
+	<member>default : org.jboss.kernel.plugins.dependency.DefaultMatcherFactory a
+	transformer that builds a matcher which simply uses object equality between the
+	demand and supply values.</member>
+	<member>interval : org.jboss.kernel.plugins.dependency.IntervalMatcherTransformer  a
+	transformer that builds a matcher by using the demand value as a mathematical range
+	to test supply values as integers against.</member>
+	<member>regex : org.jboss.kernel.plugins.dependency.RegexpMatcherTransformer a
+	transformer that builds a matcher by using the demand value as a regular expression
+	to match against the supply values.</member>
+	</simplelist></para>
+	<para>Any other transformer value is treated as a class name which implements the
+	MatcherTransformer interface. Below is an example of a demand that specifies a custom
+	implementation of org.jboss.kernel.api.dependency.MatcherTransformer.</para>
+	<programlisting role="Java">import org.jboss.beans.metadata.api.annotations.Demands;
+	import org.jboss.beans.metadata.api.annotations.Demand;
+
+	@Demands({@Demand(value = "fragment", transformer = "org.jboss.test.kernel.dependency.support.CapabilityMatcherTransfomer")})
+	public class CustomDemander
+	{
+	}
+	</programlisting>
+	<para>The corresponding CapabilityMatcherTransfomer implementation is given in the
+	following listing. This transformer treats </para>
+	<programlisting role="Java">
+	  package org.jboss.test.kernel.dependency.support;
+
+	  import java.io.ByteArrayInputStream;
+	  import java.io.IOException;
+	  import java.util.Properties;
+
+	  import org.jboss.kernel.api.dependency.Matcher;
+	  import org.jboss.kernel.api.dependency.NonNullMatcherTransformer;
+	  import org.jboss.kernel.api.dependency.ClassMatcher;
+
+	  public class CapabilityMatcherTransfomer extends NonNullMatcherTransformer
+	  {
+	  protected Matcher internalTransform(Object value)
+	  {
+	  return new PropertiesMatcher(value.toString());
+	  }
+
+	  private class PropertiesMatcher extends ClassMatcher&lt;Properties&gt;
+	  {
+	  private Properties props;
+
+	  public PropertiesMatcher(String string)
+	  {
+	  super(Properties.class);
+	  if (string == null)
+	  throw new IllegalArgumentException("Null fragment");
+	  
+	  this.props = new Properties();
+	  ByteArrayInputStream bais = new ByteArrayInputStream(string.getBytes());
+	  try
+	  {
+	  props.load(bais);
+	  }
+	  catch(IOException e)
+	  {
+	  throw new IllegalStateException(e);
+	  }
+	  }
+
+	  protected boolean matchByType(Properties other)
+	  {
+	  boolean matches = false;
+	  for(Object key : props.keySet())
+	  {
+	  String skey = key.toString();
+	  String requires = props.getProperty(skey);
+	  String capability = other.getProperty(skey);
+	  if(requires.equalsIgnoreCase(capability))
+	  matches |= true;
+	  }
+	  return matches;
+	  }
+
+	  public String toString()
+	  {
+	  return props.toString();
+	  }
+	  }
+	  }
+	</programlisting>
+	<para>An example of bean deployments where a demand matches a supply based on this matcher
+	is shown in the following
+	listing:<programlisting role="XML">&lt;?xml version="1.0" encoding="UTF-8"?>
+
+	&lt;deployment xmlns="urn:jboss:bean-deployer:2.0">
+	&lt;bean name="capabilitySupplier" class="org.jboss.test.kernel.dependency.support.SimpleBeanImpl">
+	&lt;supply class="java.util.Properties">
+	key1=value1
+	key2=value2
+	&lt;/supply>
+	&lt;supply class="java.util.Properties">
+	key2.1=value2.1
+	key2.2=value2.2
+	&lt;/supply>
+	&lt;/bean>
+
+	&lt;bean name="requiresDemand" class="org.jboss.test.kernel.dependency.support.SimpleBeanImpl">
+	&lt;demand transformer="org.jboss.test.kernel.dependency.support.CapabilityMatcherTransfomer">
+	key1=value1
+	key2=value2
+	&lt;/demand>
+	&lt;/bean>
+	&lt;/deployment>
+	</programlisting></para>
+      </section>
+    </section>
+    <section>
+      <title>Service dependencies</title>
+      <para>So far we have considered how POJOs depend on each other either explictly through
+      injections or implicitly through the use of arbitrary objects supplied during deployment.
+      These dependencies help us to assemble POJOs in a well defined order to create services
+      but what about when one service depends on another?</para>
+      <para>Services typically consist of many individual POJOs wired together in order to perform
+      a well-defined function. Once a service is deployed it can be stopped and started as many
+      times as necessary in order to make best use of valuable resources such as CPU and memory.
+      This is possible thanks to the service lifecycle:</para>
+      <itemizedlist>
+	<listitem>
+	  <para>create - the service has been deployed</para>
+	</listitem>
+	<listitem>
+	  <para>start - the service is started</para>
+	</listitem>
+	<listitem>
+	  <para>stop - the service is stopped</para>
+	</listitem>
+	<listitem>
+	  <para>destroy - the service is being undeployed</para>
+	</listitem>
+      </itemizedlist>
+      <para>If one service depends on another then we need someway to ensure that they are created
+      and started in the correct order. Similarly we also need to ensure that they are stopped
+      and destroyed correctly. This is done by adding a @Depends annotation or &lt;depends&gt;
+      element to the POJO that defines a service&apos;s public methods and specifying the name
+      of the bean that represents the other service.</para>
+      <programlisting role="JAVA">@Depends(&quot;AnotherBean&quot;)
+      public class MyBean {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;AnotherBean&quot; class=&quot;org.jboss.test.Example&quot;/&gt;
+
+      &lt;bean name=&quot;MyBean&quot; class=&quot;org.jboss.test.Example&quot;&gt;
+      &lt;depends&gt;AnotherBean&lt;/depends&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>The microcontainer will then ensure that the beans, representing the two services, are
+      deployed in the correct order. Specifically the beans named in the @Depends or
+      &lt;depends&gt; values will reach their CREATE states before the bean declaring the
+      dependencies reaches its CREATE state. The same is true for the START, STOP and DESTROY
+      states. It&apos;s possible to define multiple dependencies on other services simply by
+      listing names or nesting &lt;depends&gt; elements:</para>
+      <programlisting role="JAVA">@Depends(&quot;AnotherBean&quot;, &quot;YetAnotherBean&quot;)
+      public class MyBean {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;AnotherBean&quot; class=&quot;org.jboss.test.Example&quot;/&gt;
+
+      &lt;bean name=&quot;MyBean&quot; class=&quot;org.jboss.test.Example&quot;&gt;
+      &lt;depends&gt;AnotherBean&lt;/depends&gt;
+      &lt;depends&gt;YetAnotherBean&lt;/depends&gt;
+      &lt;/bean&gt;</programlisting>
+    </section>
+  </chapter>
+  <chapter>
+    <title>Adding deployment behaviour</title>
+    <section>
+      <title>Deployment actions</title>
+      <para>In Part I - Getting Started we covered how to add behaviour to beans during the
+      deployment and undeployment process using AOP lifecycle callbacks. This gave us a powerful
+      way to apply common logic to a number of beans, identified using pointcut expressions, at
+      various points in their lifecycles. However setting up AOP lifecycle callbacks for
+      occasions when an individual bean needs to call arbitrary methods before deployment or
+      after undeployment can be time consuming. Fortunately JBoss Microcontainer provides an
+      alternative way to do this using deployment/undeployment actions.</para>
+      <para>To specify a method within a bean that should be called after the bean reaches the
+      START state you should use the @InstallMethod annotation or &lt;install&gt; element as
+      follows:</para>
+      <programlisting role="JAVA">@InstallMethod
+      public String doSomething() {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;install method=&quot;doSomething&quot;/&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>Parameters can also be passed in using nested &lt;parameter&gt; elements or by
+      defining values with annotations.</para>
+      <programlisting role="JAVA">@InstallMethod
+      public String doSomething(@StringValue(&quot;10&quot;) Integer integer, @StringValue(&quot;my string&quot;) String string) {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;install method=&quot;doSomething&quot;&gt;
+      &lt;parameter&gt;10&lt;/parameter&gt;
+      &lt;parameter&gt;my string&lt;/parameter&gt;
+      &lt;/install&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>If necessary multiple install methods can be defined. They will be called in the order
+      in which they appear as annotations or in the deployment descriptor.</para>
+      <programlisting role="JAVA">@InstallMethod
+      public String doSomething() {
+      ...
+      }
+
+      @InstallMethod
+      public String doSomethingElse() {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;install method=&quot;doSomething&quot;/&gt;
+      &lt;install method=&quot;doSomethingElse&quot;/&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>During undeployment uninstall methods can also be defined which will be called before
+      the bean reaches the STOP state.</para>
+      <programlisting role="JAVA">@UninstallMethod
+      public String doSomething() {
+      ...
+      }
+
+      @UninstallMethod
+      public String doSomethingElse() {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;uninstall method=&quot;doSomething&quot;/&gt;
+      &lt;uninstall method=&quot;doSomethingElse&quot;/&gt;
+      &lt;/bean&gt;</programlisting>
+      <para>If you want a bean to call a method on another bean during deployment or undeployment
+      then you can use the @ExternalInstalls/@ExternalUninstalls annotations or the
+      <varname>bean</varname> attribute of the &lt;install&gt;/&lt;uninstall&gt; elements. You can
+      also define parameters to pass in if necessary.</para>
+      <programlisting role="JAVA">@ExternalInstalls(@ExternalInstall(bean=&quot;OtherBean&quot;, method=&quot;doWork&quot;)
+      @ExternalUninstalls(@ExternalInstall(bean=&quot;OtherBean&quot;, method=&quot;doBye&quot;, parameters=&quot;{@Value(string=@StringValue(&quot;Goodbye&quot;)), at Value(string=@StringValue(&quot;Saturday&quot;))}&quot;))
+      public class MyBean {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;install bean=&quot;OtherBean&quot; method=&quot;doWork&quot;/&gt;
+      &lt;uninstall bean=&quot;OtherBean&quot; method=&quot;doBye&quot;&gt;
+      &lt;parameter name=&quot;message&quot;&gt;Goodbye&lt;/parameter&gt;
+      &lt;parameter name=&quot;day&quot;&gt;Saturday&lt;/parameter&gt;
+      &lt;/uninstall&gt;
+      &lt;/bean&gt;</programlisting>
+      <note>
+	<para>Currently both the @ExternalInstalls and @ExternalUninstalls annotations take a list
+	of @ExternalInstall annotations. </para>
+      </note>
+      <para>By default the other bean must have reached the INSTALLED state before its method will
+      be called. This can be changed by using the <property>dependentState/state</property>
+      attribute.</para>
+      <programlisting role="JAVA">@ExternalInstalls(@ExternalInstall(bean=&quot;OtherBean&quot;, method=&quot;doWork&quot;, dependentState=&quot;Configured&quot;)
+      public class MyBean {
+      ...
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;SimpleBean&quot; class=&quot;org.jboss.example.SimpleBean&quot;&gt;
+      &lt;install bean=&quot;OtherBean&quot; method=&quot;doWork&quot; state=&quot;Configured&quot;/&gt;
+      &lt;/bean&gt;</programlisting>
+    </section>
+    <section>
+      <title>Deployment callbacks</title>
+      <para>Sometimes it is useful for a bean to know when other beans have been deployed. For
+      example a manager bean might want to keep a list of all of the beans it manages. Rather
+      than placing code into each managed bean to register itself with the manager when
+      deployed, it would be better if the manager was automatically called back each time to
+      notify it. JBoss Microcontainer allows such callbacks to occur during deployment and
+      undeployment using the @Install/@Uninstall annotations and
+      &lt;incallback&gt;/&lt;uncallback&gt; elements.</para>
+      <note>
+	<para>&lt;incallback&gt; is an abbreviation of installCallback and &lt;uncallback&gt; is
+	an abbreviation of uninstallCallback.</para>
+      </note>
+      <programlisting role="JAVA">public class Example {
+      @Install
+      public void addEditor(Editor editor) {
+      ...
+      }
+
+      @Uninstall
+      public void removeEditor(Editor editor) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;editorHolder&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;incallback method=&quot;addEditor&quot;/&gt;
+      &lt;uncallback method=&quot;removeEditor&quot;/&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>In the above example the addEditor method of the editorHolder bean will be called each
+      time a bean of class Editor is deployed. Similarly the removeEditor method will be called
+      each time a bean of class Editor is undeployed. By default the bean class to look for is
+      determined by the class of the parameter in the callback method. If there are multiple
+      methods with the same name but different parameter types then you can add a
+      <varname>signature</varname> attribute to the &lt;incallback&gt;/&lt;uncallback&gt; element to
+      specify the correct one. This is not required when using annotations as we simply annotate
+      the method we want.</para>
+      <programlisting role="JAVA">public class Example {
+      public void addEditor(Editor editor) {
+      ...
+      }
+
+      @Install
+      public void addEditor(DifferentEditor editor) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;editorHolder&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;incallback method=&quot;addEditor&quot; signature=&quot;org.jboss.example.DifferentEditor&quot;/&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>Multiple callback methods can be defined per bean. They will be called in the order
+      that they appear as annotations or in the deployment descriptor.</para>
+      <programlisting role="JAVA">public class Example {
+      @Install
+      public void addEditor(Editor editor) {
+      ...
+      }
+
+      @Install
+      public void addViewer(Viewer viewer) {
+      ...
+      }
+
+      @Uninstall
+      public void removeEditor(Editor editor) {
+      ...
+      }
+
+      @Uninstall
+      public void removeViewer(Viewer viewer) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;editorHolder&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;incallback method=&quot;addEditor&quot;/&gt;
+      &lt;incallback method=&quot;addViewer&quot;/&gt;
+      &lt;uncallback method=&quot;removeEditor&quot;/&gt;
+      &lt;uncallback method=&quot;removeViewer&quot;/&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>By default each callback will be executed when beans matching the parameter types
+      reach the INSTALLED state. This can be changed if necessary using the
+      <varname>dependentState/state</varname> attribute.</para>
+      <programlisting role="JAVA">public class Example {
+      @Install(dependentState=&quot;Configured&quot;)
+      public void addEditor(Editor editor) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;editorHolder&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;incallback method=&quot;addEditor&quot; state=&quot;Configured&quot;/&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>Here we are declaring that the addEditor method of the editorHolder bean should be
+      called when any beans of class Editor reach the CONFIGURED state.</para>
+      <para>It is also possible to configure when the callback methods are executed during the
+      deployment of the bean using the <varname>whenRequired</varname> attribute.</para>
+      <programlisting role="JAVA">public class Example {
+      @Install(whenRequired=&quot;Installed&quot;)
+      public void addEditor(Editor editor) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;editorHolder&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;incallback method=&quot;addEditor&quot; whenRequired=&quot;Installed&quot;/&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>Here we are declaring that the addEditor method will be called before the editorHolder
+      bean reaches the INSTALLED state. By default the callbacks are exceuted before the bean
+      reaches the CONFIGURED state.</para>
+      <para>Finally we can also control when the callback methods are executed depending on how
+      many beans matching the parameter class have been deployed. This is done using the
+      <varname>cardinality</varname> attribute.</para>
+      <programlisting role="JAVA">public class Example {
+      @Install(cardinality=&quot;2..n&quot;)
+      public void addEditor(Editor editor) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;editorHolder&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;incallback method=&quot;addEditor&quot; cardinality=&quot;2..n&quot;/&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>Here we are declaring that the addEditor method of the editorHolder bean will only be
+      called when two or more beans of class Editor have been deployed.</para>
+      <note>
+	<para>When using callbacks with collection classes as parameters only the following basic
+	interfaces are currently supported; List, Set and Queue. This is done using the
+	<methodname>BasicCollectionCallbackItemFactory</methodname> implementation. You can change this if
+	required by setting the <varname>org.jboss.dependency.collectionCallbackItemFactory</varname>
+	system property to the fully-qualified class name of your
+	<methodname>CollectionCallbackItemFactory</methodname> implementation.</para>
+      </note>
+    </section>
+    <section>
+      <title>Service lifecycle</title>
+      <para>So far we have discussed how to define deployment/undeployment actions for beans
+      together with callback methods for notification when other beans have been
+      deployed/undeployed. These features are useful for adding behaviours to POJOs but what
+      about adding behaviour to services?</para>
+      <para>As explained in the previous chapter services have a lifecycle consisting of 4 stages;
+      create, start, stop and destroy. The reason for this is because we want the ability to
+      start and stop a deployed service repeatably at runtime to make best use of valuable
+      resources such as CPU and memory. At each point in this lifecycle the microcontainer will
+      look for a method to call in order to perform appropriate actions. For example starting a
+      service may require that an object is bound into JNDI. By default these methods are named
+      after the lifecycle stage that they represent.</para>
+      <programlisting role="JAVA">public class LifecycleBean {
+      public void create() {
+      ...
+      }
+
+      public void start() {
+      ...
+      }
+
+      public void stop() {
+      ...
+      }
+
+      public void destroy() {
+      ...
+      }
+      } </programlisting>
+      <para>If methods like these are defined in your bean then they will be called as the bean is
+      deployed and undeployed. Specifically the create and start methods are called as the bean
+      reaches the CREATE and START states during deployment. The stop and destroy methods are
+      called when the bean passes through the START and CREATE states during undeployment. Only
+      those methods that are defined will be called. For example if you omit the start method
+      then the bean will move to the START state without anything happening.</para>
+      <para>If you want a different method to be called for any of the stages then you can provide
+      an annotation or XML element to specify which one to use.</para>
+      <programlisting role="JAVA">public class Example {
+      @Create
+      public void initialize() {
+      ...
+      }
+
+      @Start
+      public void go() {
+      ...
+      }
+
+      @Stop
+      public void halt() {
+      ...
+      }
+
+      @Destroy
+      public void remove() {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;Name1&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;create method=&quot;initialize&quot;/&gt;
+      &lt;start method=&quot;go&quot;/&gt;
+      &lt;stop method=&quot;halt&quot;/&gt;
+      &lt;destroy method=&quot;remove&quot;/&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>You can also specify parameters if necessary.</para>
+      <programlisting role="JAVA">public class Example {
+      @Start
+      public void go(@StringValue(&quot;MyService&quot;) String serviceName,
+      @StringValue(&quot;5&quot;) Integer priority) {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;Name1&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;start method=&quot;go&quot;&gt;
+      &lt;parameter&gt;MyService&lt;/parameter&gt;
+      &lt;parameter&gt;5&lt;/parameter&gt;
+      &lt;/start&gt;
+      &lt;/bean&gt; </programlisting>
+      <para>Sometimes you may want lifecycle methods to be ignored. This can be done using the
+      <varname>ignore</varname> attribute which if set to true prevents the microcontainer from
+      calling the method when the corresponding lifecycle stage is reached.</para>
+      <programlisting role="JAVA">public class Example {
+      @Stop(ignored=&quot;true&quot;)
+      public void stop() {
+      ...
+      }
+      }</programlisting>
+      <programlisting role="XML">&lt;bean name=&quot;Name1&quot; class=&quot;com.acme.Example&quot;&gt;
+      &lt;stop method=&quot;stop&quot; ignored=&quot;true&quot;/&gt;
+      &lt;/bean&gt; </programlisting>
+    </section>
+  </chapter>
+</part>

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Preface.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Preface.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/Preface.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % RH-ENTITIES SYSTEM "Common_Config/rh-entities.ent">
+]>
+
+<preface>
+  <title>What this Book Covers</title>
+  <para>This book aims to help you become familiar with JBoss Microcontainer in order that you can
+  use it to develop your own services or applications.</para>
+  <para>Part I &apos;Getting Started&apos; introduces the technology and explains how it relates
+  to Java development in general. It then goes on to cover a complete use-case so that you can
+  quickly see how the microcontainer works in real-life.</para>
+  <para>Part II &apos;POJO Development&apos; takes a look at the various methods you can use to
+  construct POJOs and wire them together using injection together with other features.</para>
+  <para>Part III &apos;AOP Development&apos; goes on to look at how you can add behaviour to your
+  POJOs using aspects and modify the deployment/undeployment process with lifecycle
+  callbacks.</para>
+  <para> Part IV &apos;Extending the Microcontainer&apos; shows how you can write your own
+  extensions by creating new dependencies and gives some examples of how this has already been
+  done.</para>
+
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Common_Content/Conventions.xml">
+    <xi:fallback xmlns:xi="http://www.w3.org/2001/XInclude">
+      <xi:include href="fallback_content/Conventions.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
+    </xi:fallback>
+  </xi:include>
+
+  
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Common_Content/Feedback.xml">
+    <xi:fallback xmlns:xi="http://www.w3.org/2001/XInclude">
+      <xi:include href="fallback_content/Feedback.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
+    </xi:fallback>
+  </xi:include>
+
+</preface>
+
+
+

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/fallback_content/Conventions.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/fallback_content/Conventions.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/fallback_content/Conventions.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,165 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<section>
+	<title>Document Conventions</title>
+	<para>
+		This manual uses several conventions to highlight certain words and phrases and draw attention to specific pieces of information.
+	</para>
+	<para>
+		In PDF and paper editions, this manual uses typefaces drawn from the <ulink url="https://fedorahosted.org/liberation-fonts/">Liberation Fonts</ulink> set. The Liberation Fonts set is also used in HTML editions if the set is installed on your system. If not, alternative but equivalent typefaces are displayed. Note: Red Hat Enterprise Linux 5 and later includes the Liberation Fonts set by default.
+	</para>
+	<section>
+		<title>Typographic Conventions</title>
+		<para>
+			Four typographic conventions are used to call attention to specific words and phrases. These conventions, and the circumstances they apply to, are as follows.
+		</para>
+		<para>
+			<literal>Mono-spaced Bold</literal>
+		</para>
+		<para>
+			Used to highlight system input, including shell commands, file names and paths. Also used to highlight keycaps and key combinations. For example:
+		</para>
+		<blockquote>
+			<para>
+				To see the contents of the file <filename>my_next_bestselling_novel</filename> in your current working directory, enter the <command>cat my_next_bestselling_novel</command> command at the shell prompt and press <keycap>Enter</keycap> to execute the command.
+			</para>
+		</blockquote>
+		<para>
+			The above includes a file name, a shell command and a keycap, all presented in mono-spaced bold and all distinguishable thanks to context.
+		</para>
+		<para>
+			Key combinations can be distinguished from keycaps by the hyphen connecting each part of a key combination. For example:
+		</para>
+		<blockquote>
+			<para>
+				Press <keycap>Enter</keycap> to execute the command.
+			</para>
+			<para>
+				Press <keycombo><keycap>Ctrl</keycap><keycap>Alt</keycap><keycap>F1</keycap></keycombo> to switch to the first virtual terminal. Press <keycombo><keycap>Ctrl</keycap><keycap>Alt</keycap><keycap>F7</keycap></keycombo> to return to your X-Windows session.
+			</para>
+		</blockquote>
+		<para>
+			The first paragraph highlights the particular keycap to press. The second highlights two key combinations (each a set of three keycaps with each set pressed simultaneously).
+		</para>
+		<para>
+			If source code is discussed, class names, methods, functions, variable names and returned values mentioned within a paragraph will be presented as above, in <literal>mono-spaced bold</literal>. For example:
+		</para>
+		<blockquote>
+			<para>
+				File-related classes include <classname>filesystem</classname> for file systems, <classname>file</classname> for files, and <classname>dir</classname> for directories. Each class has its own associated set of permissions.
+			</para>
+		</blockquote>
+		<para>
+			<application>Proportional Bold</application>
+		</para>
+		<para>
+			This denotes words or phrases encountered on a system, including application names; dialog box text; labeled buttons; check-box and radio button labels; menu titles and sub-menu titles. For example:
+		</para>
+		<blockquote>
+			<para>
+				Choose <menuchoice><guimenu>System</guimenu><guisubmenu>Preferences</guisubmenu><guimenuitem>Mouse</guimenuitem></menuchoice> from the main menu bar to launch <application>Mouse Preferences</application>. In the <guilabel>Buttons</guilabel> tab, click the <guilabel>Left-handed mouse</guilabel> check box and click <guibutton>Close</guibutton> to switch the primary mouse button from the left to the right (making the mouse suitable for use in the left hand).
+			</para>
+			<para>
+				To insert a special character into a <application>gedit</application> file, choose <menuchoice><guimenu>Applications</guimenu><guisubmenu>Accessories</guisubmenu><guimenuitem>Character Map</guimenuitem></menuchoice> from the main menu bar. Next, choose <menuchoice><guimenu>Search</guimenu><guimenuitem>Find&hellip;</guimenuitem></menuchoice> from the <application>Character Map</application> menu bar, type the name of the character in the <guilabel>Search</guilabel> field and click <guibutton>Next</guibutton>. The character you sought will be highlighted in the <guilabel>Character Table</guilabel>. Double-click this highlighted character to place it in the <guilabel>Text to copy</guilabel> field and then click the <guibutton>Copy</guibutton> button. Now switch back to your document and choose <menuchoice><guimenu>Edit</guimenu><guimenuitem>Paste</guimenuitem></menuchoice> from the <application>gedit</application> menu bar.
+			</para>
+		</blockquote>
+		<para>
+			The above text includes application names; system-wide menu names and items; application-specific menu names; and buttons and text found within a GUI interface, all presented in proportional bold and all distinguishable by context.
+		</para>
+		<para>
+			<command><replaceable>Mono-spaced Bold Italic</replaceable></command> or <application><replaceable>Proportional Bold Italic</replaceable></application>
+		</para>
+		<para>
+			Whether mono-spaced bold or proportional bold, the addition of italics indicates replaceable or variable text. Italics denotes text you do not input literally or displayed text that changes depending on circumstance. For example:
+		</para>
+		<blockquote>
+			<para>
+				To connect to a remote machine using ssh, type <command>ssh <replaceable>username</replaceable>@<replaceable>domain.name</replaceable></command> at a shell prompt. If the remote machine is <filename>example.com</filename> and your username on that machine is john, type <command>ssh john at example.com</command>.
+			</para>
+			<para>
+				The <command>mount -o remount <replaceable>file-system</replaceable></command> command remounts the named file system. For example, to remount the <filename>/home</filename> file system, the command is <command>mount -o remount /home</command>.
+			</para>
+			<para>
+				To see the version of a currently installed package, use the <command>rpm -q <replaceable>package</replaceable></command> command. It will return a result as follows: <command><replaceable>package-version-release</replaceable></command>.
+			</para>
+		</blockquote>
+		<para>
+			Note the words in bold italics above &mdash; username, domain.name, file-system, package, version and release. Each word is a placeholder, either for text you enter when issuing a command or for text displayed by the system.
+		</para>
+		<para>
+			Aside from standard usage for presenting the title of a work, italics denotes the first use of a new and important term. For example:
+		</para>
+		<blockquote>
+			<para>
+				Publican is a <firstterm>DocBook</firstterm> publishing system.
+			</para>
+		</blockquote>
+	</section>
+	
+	<section>
+		<title>Pull-quote Conventions</title>
+		<para>
+			Terminal output and source code listings are set off visually from the surrounding text.
+		</para>
+		<para>
+			Output sent to a terminal is set in <computeroutput>mono-spaced roman</computeroutput> and presented thus:
+		</para>
+		
+<screen>books        Desktop   documentation  drafts  mss    photos   stuff  svn
+books_tests  Desktop1  downloads      images  notes  scripts  svgs
+</screen>
+		<para>
+			Source-code listings are also set in <computeroutput>mono-spaced roman</computeroutput> but add syntax highlighting as follows:
+		</para>
+		
+<programlisting language="Java">package org.jboss.book.jca.ex1;
+
+import javax.naming.InitialContext;
+
+public class ExClient
+{
+   public static void main(String args[]) 
+       throws Exception
+   {
+      InitialContext iniCtx = new InitialContext();
+      Object         ref    = iniCtx.lookup("EchoBean");
+      EchoHome       home   = (EchoHome) ref;
+      Echo           echo   = home.create();
+
+      System.out.println("Created Echo");
+
+      System.out.println("Echo.echo('Hello') = " + echo.echo("Hello"));
+   }
+}
+</programlisting>
+	</section>
+	
+	<section>
+		<title>Notes and Warnings</title>
+		<para>
+			Finally, we use three visual styles to draw attention to information that might otherwise be overlooked.
+		</para>
+		<note>
+			<title>Note</title>
+			<para>
+				Notes are tips, shortcuts or alternative approaches to the task at hand. Ignoring a note should have no negative consequences, but you might miss out on a trick that makes your life easier.
+			</para>
+		</note>
+		<important>
+			<title>Important</title>
+			<para>
+				Important boxes detail things that are easily missed: configuration changes that only apply to the current session, or services that need restarting before an update will apply. Ignoring a box labeled 'Important' won't cause data loss but may cause irritation and frustration.
+			</para>
+		</important>
+		<warning>
+			<title>Warning</title>
+			<para>
+				Warnings should not be ignored. Ignoring warnings will most likely cause data loss.
+			</para>
+		</warning>
+	</section>
+
+</section>
+
+

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/fallback_content/Feedback.xml
===================================================================
--- projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/fallback_content/Feedback.xml	                        (rev 0)
+++ projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/fallback_content/Feedback.xml	2010-03-26 04:11:33 UTC (rev 103002)
@@ -0,0 +1,21 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<section>
+	<title>We Need Feedback!</title>
+	<indexterm>
+		<primary>feedback</primary>
+		<secondary>contact information for this manual</secondary>
+	</indexterm>
+	<para>
+		If you find a typographical error in this manual, or if you have thought of a way to make this manual better, we would love to hear from you! Please submit a report in the JBoss Issue Tracker: <ulink url="https://jira.jboss.org/">https://jira.jboss.org/</ulink> against the product <application>&PRODUCT;.</application>
+	</para>
+	<para>
+		When submitting a bug report, be sure to mention the manual's identifier: <citetitle>&BOOKID;</citetitle>
+	</para>
+	<para>
+		If you have a suggestion for improving the documentation, try to be as specific as possible when describing it. If you have found an error, please include the section number and some of the surrounding text so we can find it easily.
+	</para>
+</section>
+
+

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/images/deployOutput.png
===================================================================
(Binary files differ)


Property changes on: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/images/deployOutput.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/images/tuiMenu.png
===================================================================
(Binary files differ)


Property changes on: projects/microcontainer/mcdocs/trunk/userguide/src/main/docbook/en-US/images/tuiMenu.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream




More information about the jboss-cvs-commits mailing list