[jboss-cvs] jboss-docs/jbossas/j2ee/en ...

Norman Richards norman.richards at jboss.com
Mon Sep 18 12:48:19 EDT 2006


  User: nrichards
  Date: 06/09/18 12:48:19

  Added:       jbossas/j2ee/en  master.xml
  Log:
  problems checking in?
  
  Revision  Changes    Path
  1.1      date: 2006/09/18 16:48:19;  author: nrichards;  state: Exp;jboss-docs/jbossas/j2ee/en/master.xml
  
  Index: master.xml
  ===================================================================
  <?xml version='1.0' encoding="iso-8859-1"?>
  
  <book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="../../../../docbook-support/support/docbook-xsd/docbook.xsd">
      <bookinfo>
          <title>The JBoss 4 Application Server J2EE Reference</title>
          <subtitle>JBoss AS 4.0.4</subtitle>
          
          <mediaobject>
              <imageobject>
                  <imagedata fileref="images/title.jpg"/>
              </imageobject>
          </mediaobject>
          <copyright>
              <year>2006></year>
              <holder>JBoss, Inc.</holder>
          </copyright>
      </bookinfo>
      <toc/>
  
      <chapter id="ch2.chapter">
          <title>The JBoss JMX Microkernel</title>
          <para>Modularly developed from the ground up, the JBoss server and container are completely implemented using
              component-based plug-ins. The modularization effort is supported by the use of JMX, the Java Management
              Extension API. Using JMX, industry-standard interfaces help manage both JBoss/Server components and the
              applications deployed on it. Ease of use is still the number one priority, and the JBoss Server architecture
              sets a new standard for modular, plug-in design as well as ease of server and application management.</para>
          <para>This high degree of modularity benefits the application developer in several ways. The already tight code
              can be further trimmed down to support applications that must have a small footprint. For example, if EJB
              passivation is unnecessary in your application, simply take the feature out of the server. If you later
              decide to deploy the same application under an Application Service Provider (ASP) model, simply enable the
              server's passivation feature for that web-based deployment. Another example is the freedom you have to drop
              your favorite object to relational database (O-R) mapping tool, such as TOPLink, directly into the
              container.</para>
          <para>This chapter will introduce you to JMX and its role as the JBoss server component bus. You will also be
              introduced to the JBoss MBean service notion that adds life cycle operations to the basic JMX management
              component.</para>
          <section id="ch2.jmx">
              <title>An Introduction to JMX</title>
              <para>The success of the full Open Source J2EE stack lies with the use of JMX (Java Management Extension).
                  JMX is the best tool for integration of software. It prov ides a common spine that allows the user to
                  integrate modules, containers, and plug-ins. <xref linkend="ch2.jmxbus.fig"/> shows the role of JMX as
                  an integration spine or bus into which components plug. Components are declared as MBean services that
                  are then loaded into JBoss. The components may subsequently be administered using JMX.</para>
              <figure id="ch2.jmxbus.fig">
                  <title>The JBoss JMX integration bus and the standard JBoss components</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/Chap2-3.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
  
              <para>Before looking at how JBoss uses JMX as its component bus, it would help to get a basic overview what
                  JMX is by touching on some of its key aspects.</para>
              <para>JMX components are defined by the Java Management Extensions Instrumentation and Agent Specification,
                  v1.2, which is available from the JSR003 Web page at <ulink url="http://jcp.org/en/jsr/detail?id=3"/>.
                  The material in this JMX overview section is derived from the JMX instrumentation specification, with a
                  focus on the aspects most used by JBoss. A more comprehensive discussion of JMX and its application can
                  be found in <emphasis>JMX: Managing J2EE with Java Management Extensions</emphasis> written by Juha
                  Lindfors (Sams, 2002).</para>
              <para>JMX is a standard for managing and monitoring all varieties of software and hardware components from
                  Java. Further, JMX aims to provide integration with the large number of existing management standards.
                      <xref linkend="ch2.jmxrel.fig"/> shows examples of components found in a JMX environment, and
                  illustrates the relationship between them as well as how they relate to the three levels of the JMX
                  model. The three levels are:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">Instrumentation</emphasis>, which are the resources to manage</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Agents</emphasis>, which are the controllers of the instrumentation level
                          objects</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Distributed services</emphasis>, the mechanism by which administration
                          applications interact with agents and their managed objects</para>
                  </listitem>
              </itemizedlist>
              <figure id="ch2.jmxrel.fig">
                  <title>The Relationship between the components of the JMX architecture</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/Chap2-5.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <section>
                  <title>Instrumentation Level</title>
                  <para>The instrumentation level defines the requirements for implementing JMX manageable resources. A
                      JMX manageable resource can be virtually anything, including applications, service components,
                      devices, and so on. The manageable resource exposes a Java object or wrapper that describes its
                      manageable features, which makes the resource instrumented so that it can be managed by
                      JMX-compliant applications.</para>
                  <para>The user provides the instrumentation of a given resource using one or more managed beans, or
                      MBeans. There are four varieties of MBean implementations: standard, dynamic, model, and open. The
                      differences between the various MBean types is discussed in Managed Beans or MBeans.</para>
                  <para>The instrumentation level also specifies a notification mechanism. The purpose of the notification
                      mechanism is to allow MBeans to communicate changes with their environment. This is similar to the
                      JavaBean property change notification mechanism, and can be used for attribute change notifications,
                      state change notifications, and so on.</para>
              </section>
              <section>
                  <title>Agent Level</title>
                  <para>The agent level defines the requirements for implementing agents. Agents are responsible for
                      controlling and exposing the managed resources that are registered with the agent. By default,
                      management agents are located on the same hosts as their resources. This collocation is not a
                      requirement.</para>
                  <para>The agent requirements make use of the instrumentation level to define a standard MBeanServer
                      management agent, supporting services, and a communications connector. JBoss provides both an html
                      adaptor as well as an RMI adaptor.</para>
                  <para>The JMX agent can be located in the hardware that hosts the JMX manageable resources when a Java
                      Virtual Machine (JVM) is available. This is how the JBoss server uses the MBeanServer. A JMX agent
                      does not need to know which resources it will serve. JMX manageable resources may use any JMX agent
                      that offers the services it requires.</para>
                  <para>Managers interact with an agent's MBeans through a protocol adaptor or connector, as described in
                      the <xref linkend="ch2.distlevel.sect"/> in the next section. The agent does not need to know
                      anything about the connectors or management applications that interact with the agent and its
                      MBeans.</para>
              </section>
              <section id="ch2.distlevel.sect">
                  <title>Distributed Services Level</title>
                  <para>The JMX specification notes that a complete definition of the distributed services level is beyond
                      the scope of the initial version of the JMX specification. This was indicated by the component boxes
                      with the horizontal lines in <xref linkend="ch2.jmxrel.fig"/>. The general purpose of this level is
                      to define the interfaces required for implementing JMX management applications or managers. The
                      following points highlight the intended functionality of the distributed services level as discussed
                      in the current JMX specification.</para>
                  <itemizedlist>
                      <listitem>
                          <para>Provide an interface for management applications to interact transparently with an agent
                              and its JMX manageable resources through a connector</para>
                      </listitem>
                      <listitem>
                          <para>Exposes a management view of a JMX agent and its MBeans by mapping their semantic meaning
                              into the constructs of a data-rich protocol (for example HTML or SNMP)</para>
                      </listitem>
                      <listitem>
                          <para>Distributes management information from high-level management platforms to numerous JMX
                              agents</para>
                      </listitem>
                      <listitem>
                          <para>Consolidates management information coming from numerous JMX agents into logical views
                              that are relevant to the end user's business operations</para>
                      </listitem>
                      <listitem>
                          <para>Provides security</para>
                      </listitem>
                  </itemizedlist>
                  <para>It is intended that the distributed services level components will allow for cooperative
                      management of networks of agents and their resources. These components can be expanded to provide a
                      complete management application.</para>
              </section>
              <section>
                  <title>JMX Component Overview</title>
                  <para>This section offers an overview of the instrumentation and agent level components. The
                      instrumentation level components include the following:</para>
                  <itemizedlist spacing="compact">
                      <listitem>
                          <para>MBeans (standard, dynamic, open, and model MBeans)</para>
                      </listitem>
                      <listitem>
                          <para>Notification model elements</para>
                      </listitem>
                      <listitem>
                          <para>MBean metadata classes</para>
                      </listitem>
                  </itemizedlist>
                  <para>The agent level components include:</para>
                  <itemizedlist spacing="compact">
                      <listitem>
                          <para>MBean server</para>
                      </listitem>
                      <listitem>
                          <para>Agent services</para>
                      </listitem>
                  </itemizedlist>
                  <section>
                      <title>Managed Beans or MBeans</title>
                      <para>An MBean is a Java object that implements one of the standard MBean interfaces and follows the
                          associated design patterns. The MBean for a resource exposes all necessary information and
                          operations that a management application needs to control the resource.</para>
                      <para>The scope of the management interface of an MBean includes the following:</para>
                      <itemizedlist spacing="compact">
                          <listitem>
                              <para>Attribute values that may be accessed by name</para>
                          </listitem>
                          <listitem>
                              <para>Operations or functions that may be invoked</para>
                          </listitem>
                          <listitem>
                              <para>Notifications or events that may be emitted</para>
                          </listitem>
                          <listitem>
                              <para>The constructors for the MBean's Java class</para>
                          </listitem>
                      </itemizedlist>
                      <para>JMX defines four types of MBeans to support different instrumentation needs:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">Standard MBeans</emphasis>: These use a simple JavaBean style
                                  naming convention and a statically defined management interface. This is the most common
                                  type of MBean used by JBoss.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">Dynamic MBeans</emphasis>: These must implement the
                                      <literal>javax.management.DynamicMBean</literal> interface, and they expose their
                                  management interface at runtime when the component is instantiated for the greatest
                                  flexibility. JBoss makes use of Dynamic MBeans in circumstances where the components to
                                  be managed are not known until runtime.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">Open MBeans</emphasis>: These are an extension of dynamic MBeans.
                                  Open MBeans rely on basic, self-describing, user-friendly data types for universal
                                  manageability. </para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">Model MBeans</emphasis>: These are also an extension of dynamic
                                  MBeans. Model MBeans must implement the
                                  <literal>javax.management.modelmbean.ModelMBean</literal> interface. Model MBeans
                                  simplify the instrumentation of resources by providing default behavior. JBoss XMBeans
                                  are an implementation of Model MBeans. </para>
                          </listitem>
                      </itemizedlist>
                      <para>We will present an example of a Standard and a Model MBean in the section that discusses
                          extending JBoss with your own custom services.</para>
                  </section>
                  <section>
                      <title>Notification Model</title>
                      <para>JMX Notifications are an extension of the Java event model. Both the MBean server and MBeans
                          can send notifications to provide information. The JMX specification defines the
                              <literal>javax.management</literal> package <literal>Notification</literal> event object,
                              <literal>NotificationBroadcaster</literal> event sender, and
                          <literal>NotificationListener</literal> event receiver interfaces. The specification also
                          defines the operations on the MBean server that allow for the registration of notification
                          listeners.</para>
                  </section>
                  <section>
                      <title>MBean Metadata Classes</title>
                      <para>There is a collection of metadata classes that describe the management interface of an MBean.
                          Users can obtain a common metadata view of any of the four MBean types by querying the MBean
                          server with which the MBeans are registered. The metadata classes cover an MBean's attributes,
                          operations, notifications, and constructors. For each of these, the metadata includes a name, a
                          description, and its particular characteristics. For example, one characteristic of an attribute
                          is whether it is readable, writable, or both. The metadata for an operation contains the
                          signature of its parameter and return types.</para>
                      <para>The different types of MBeans extend the metadata classes to be able to provide additional
                          information as required. This common inheritance makes the standard information available
                          regardless of the type of MBean. A management application that knows how to access the extended
                          information of a particular type of MBean is able to do so.</para>
                  </section>
                  <section>
                      <title>MBean Server</title>
                      <para>A key component of the agent level is the managed bean server. Its functionality is exposed
                          through an instance of the <literal>javax.management.MBeanServer</literal>. An MBean server is a
                          registry for MBeans that makes the MBean management interface available for use by management
                          applications. The MBean never directly exposes the MBean object itself; rather, its management
                          interface is exposed through metadata and operations available in the MBean server interface.
                          This provides a loose coupling between management applications and the MBeans they manage.</para>
                      <para>MBeans can be instantiated and registered with the MBeanServer by the following:</para>
                      <itemizedlist spacing="compact">
                          <listitem>
                              <para>Another MBean</para>
                          </listitem>
                          <listitem>
                              <para>The agent itself</para>
                          </listitem>
                          <listitem>
                              <para>A remote management application (through the distributed services)</para>
                          </listitem>
                      </itemizedlist>
                      <para>When you register an MBean, you must assign it a unique object name. The object name then
                          becomes the unique handle by which management applications identify the object on which to
                          perform management operations. The operations available on MBeans through the MBean server
                          include the following:</para>
                      <itemizedlist spacing="compact">
                          <listitem>
                              <para>Discovering the management interface of MBeans</para>
                          </listitem>
                          <listitem>
                              <para>Reading and writing attribute values</para>
                          </listitem>
                          <listitem>
                              <para>Invoking operations defined by MBeans</para>
                          </listitem>
                          <listitem>
                              <para>Registering for notifications events</para>
                          </listitem>
                          <listitem>
                              <para>Querying MBeans based on their object name or their attribute values</para>
                          </listitem>
                      </itemizedlist>
                      <para>Protocol adaptors and connectors are required to access the MBeanServer from outside the
                          agent's JVM. Each adaptor provides a view via its protocol of all MBeans registered in the MBean
                          server the adaptor connects to. An example adaptor is an HTML adaptor that allows for the
                          inspection and editing of MBeans using a Web browser. As was indicated in <xref
                              linkend="ch2.jmxrel.fig"/>, there are no protocol adaptors defined by the current JMX
                          specification. Later versions of the specification will address the need for remote access
                          protocols in standard ways.</para>
                      <para>A connector is an interface used by management applications to provide a common API for
                          accessing the MBean server in a manner that is independent of the underlying communication
                          protocol. Each connector type provides the same remote interface over a different protocol. This
                          allows a remote management application to connect to an agent transparently through the network,
                          regardless of the protocol. The specification of the remote management interface will be
                          addressed in a future version of the JMX specification.</para>
                      <para>Adaptors and connectors make all MBean server operations available to a remote management
                          application. For an agent to be manageable from outside of its JVM, it must include at least one
                          protocol adaptor or connector. JBoss currently includes a custom HTML adaptor implementation and
                          a custom JBoss RMI adaptor.</para>
                  </section>
                  <section>
                      <title>Agent Services</title>
                      <para>The JMX agent services are objects that support standard operations on the MBeans registered
                          in the MBean server. The inclusion of supporting management services helps you build more
                          powerful management solutions. Agent services are often themselves MBeans, which allow the agent
                          and their functionality to be controlled through the MBean server. The JMX specification defines
                          the following agent services:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">A dynamic class loading MLet (management applet)
                                  service</emphasis>: This allows for the retrieval and instantiation of new classes and
                                  native libraries from an arbitrary network location.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">Monitor services</emphasis>: These observe an MBean attribute's
                                  numerical or string value, and can notify other objects of several types of changes in
                                  the target.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">Timer services</emphasis>: These provide a scheduling mechanism
                                  based on a one-time alarm-clock notification or on a repeated, periodic
                              notification.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">The relation service</emphasis>: This service defines associations
                                  between MBeans and enforces consistency on the relationships.</para>
                          </listitem>
                      </itemizedlist>
                      <para>Any JMX-compliant implementation will provide all of these agent services. However, JBoss does
                          not rely on any of these standard agent services.</para>
                  </section>
              </section>
          </section>
          <section id="ch2.architecture">
              <title>JBoss JMX Implementation Architecture</title>
              <section>
                  <title>The JBoss ClassLoader Architecture</title>
                  <para>JBoss employs a class loading architecture that facilitates sharing of classes across deployment
                      units and hot deployment of services and applications. Before discussing the JBoss specific class
                      loading model, we need to understand the nature of Java's type system and how class loaders fit
                  in.</para>
              </section>
              <section>
                  <title>Class Loading and Types in Java</title>
                  <para>Class loading is a fundamental part of all server architectures. Arbitrary services and their
                      supporting classes must be loaded into the server framework. This can be problematic due to the
                      strongly typed nature of Java. Most developers know that the type of a class in Java is a function
                      of the fully qualified name of the class. However the type is also a function of the
                          <literal>java.lang.ClassLoader</literal> that is used to define that class. This additional
                      qualification of type is necessary to ensure that environments in which classes may be loaded from
                      arbitrary locations would be type-safe. </para>
                  <para> However, in a dynamic environment like an application server, and especially JBoss with its
                      support for hot deployment are that class cast exceptions, linkage errors and illegal access errors
                      can show up in ways not seen in more static class loading contexts. Let's take a look at the meaning
                      of each of these exceptions and how they can happen.</para>
                  <section>
                      <title>ClassCastExceptions - I'm Not Your Type</title>
                      <para>A <literal>java.lang.ClassCastException</literal> results whenever an attempt is made to cast
                          an instance to an incompatible type. A simple example is trying to obtain a
                          <literal>String</literal> from a <literal>List</literal> into which a <literal>URL</literal> was
                          placed:</para>
                      <programlisting>ArrayList array = new ArrayList();
  array.add(new URL("file:/tmp"));
  String url = (String) array.get(0);
  
  java.lang.ClassCastException: java.net.URL
  at org.jboss.chap2.ex0.ExCCEa.main(Ex1CCE.java:16)</programlisting>
                      <para>The <literal>ClassCastException</literal> tells you that the attempt to cast the array element
                          to a <literal>String</literal> failed because the actual type was <literal>URL</literal>. This
                          trivial case is not what we are interested in however. Consider the case of a JAR being loaded
                          by different class loaders. Although the classes loaded through each class loader are identical
                          in terms of the bytecode, they are completely different types as viewed by the Java type system.
                          An example of this is illustrated by the code shown in <xref linkend="ch2.duploader.ex"/>.</para>
                      <example id="ch2.duploader.ex">
                          <title>The ExCCEc class used to demonstrate ClassCastException due to duplicate class loaders</title>
                          <programlisting>package org.jboss.chap2.ex0;
  
  import java.io.File;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.lang.reflect.Method;
  
  import org.apache.log4j.Logger;
  
  import org.jboss.util.ChapterExRepository;
  import org.jboss.util.Debug;
  
  /**
   * An example of a ClassCastException that
   * results from classes loaded through
   * different class loaders.
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class ExCCEc
  {
      public static void main(String[] args) throws Exception
      {
          ChapterExRepository.init(ExCCEc.class);
  
          String chapDir = System.getProperty("chapter.dir");
          Logger ucl0Log = Logger.getLogger("UCL0");
          File jar0 = new File(chapDir+"/j0.jar");
          ucl0Log.info("jar0 path: "+jar0.toString());
          URL[] cp0 = {jar0.toURL()};
          URLClassLoader ucl0 = new URLClassLoader(cp0);
          Thread.currentThread().setContextClassLoader(ucl0);
          Class objClass = ucl0.loadClass("org.jboss.chap2.ex0.ExObj");
          StringBuffer buffer = new
              StringBuffer("ExObj Info");
          Debug.displayClassInfo(objClass, buffer, false);
          ucl0Log.info(buffer.toString());
          Object value = objClass.newInstance();
          
          File jar1 = new File(chapDir+"/j0.jar");
          Logger ucl1Log = Logger.getLogger("UCL1");
          ucl1Log.info("jar1 path: "+jar1.toString());
          URL[] cp1 = {jar1.toURL()};
          URLClassLoader ucl1 = new URLClassLoader(cp1);
          Thread.currentThread().setContextClassLoader(ucl1);
          Class ctxClass2 = ucl1.loadClass("org.jboss.chap2.ex0.ExCtx");
          buffer.setLength(0);
          buffer.append("ExCtx Info");
          Debug.displayClassInfo(ctxClass2, buffer, false);
          ucl1Log.info(buffer.toString());
          Object ctx2 = ctxClass2.newInstance();
          
          try {
              Class[] types = {Object.class};
              Method useValue =
                  ctxClass2.getMethod("useValue", types);
              Object[] margs = {value};
              useValue.invoke(ctx2, margs);
          } catch(Exception e) {
              ucl1Log.error("Failed to invoke ExCtx.useValue", e);
              throw e;
          }
      }
  }</programlisting>
                      </example>
                      <example id="ch2.threeclasses.ex">
                          <title>The ExCtx, ExObj, and ExObj2 classes used by the examples</title>
                          <programlisting>package org.jboss.chap2.ex0;
  
  import java.io.IOException;
  import org.apache.log4j.Logger;
  import org.jboss.util.Debug;
  
  /**
   * A classes used to demonstrate various class
   * loading issues
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class ExCtx
  {
      ExObj value;
      
      public ExCtx() 
          throws IOException
      {
          value = new ExObj();
          Logger log = Logger.getLogger(ExCtx.class);
          StringBuffer buffer = new StringBuffer("ctor.ExObj");
          Debug.displayClassInfo(value.getClass(), buffer, false);
          log.info(buffer.toString());
          ExObj2 obj2 = value.ivar;
          buffer.setLength(0);
          buffer = new StringBuffer("ctor.ExObj.ivar");
          Debug.displayClassInfo(obj2.getClass(), buffer, false);
          log.info(buffer.toString());
      }
  
      public Object getValue()
      {
          return value;
      }
  
      public void useValue(Object obj) 
          throws Exception
      {
          Logger log = Logger.getLogger(ExCtx.class);
          StringBuffer buffer = new
              StringBuffer("useValue2.arg class");
          Debug.displayClassInfo(obj.getClass(), buffer, false);
          log.info(buffer.toString());
          buffer.setLength(0);
          buffer.append("useValue2.ExObj class");
          Debug.displayClassInfo(ExObj.class, buffer, false);
          log.info(buffer.toString());
          ExObj ex = (ExObj) obj;
      }
  
      void pkgUseValue(Object obj) 
          throws Exception
      {
          Logger log = Logger.getLogger(ExCtx.class);
          log.info("In pkgUseValue");
      }
  }</programlisting>
                          <programlisting>package org.jboss.chap2.ex0;
  
  import java.io.Serializable;
  
  /**
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class ExObj
      implements Serializable
  {
      public ExObj2 ivar = new ExObj2();
  }</programlisting>
                          <programlisting>package org.jboss.chap2.ex0;
  
  import java.io.Serializable;
  
  /**
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class ExObj2 
      implements Serializable
  {
  } </programlisting>
                      </example>
                      <para>The <literal>ExCCEc.main</literal> method uses reflection to isolate the classes that are
                          being loaded by the class loaders <literal>ucl0</literal> and <literal>ucl1</literal> from the
                          application class loader. Both are setup to load classes from the
                          <literal>output/chap2/j0.jar</literal>, the contents of which are:</para>
                      <programlisting>[examples]$ jar -tf output/chap2/j0.jar
  ...
  org/jboss/chap2/ex0/ExCtx.class
  org/jboss/chap2/ex0/ExObj.class
  org/jboss/chap2/ex0/ExObj2.class
  </programlisting>
                      <para>We will run an example that demonstrates how a class cast exception can occur and then look at
                          the specific issue with the example. See <xref linkend="appendix-install"/> for instructions on
                          installing the examples accompanying the book, and then run the example from within the examples
                          directory using the following command:</para>
                      <programlisting>[examples]$ ant -Dchap=chap2 -Dex=0c run-example
  ...
       [java] [ERROR,UCL1] Failed to invoke ExCtx.useValue
       [java] java.lang.reflect.InvocationTargetException
       [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl
  .java:25)
       [java] at java.lang.reflect.Method.invoke(Method.java:324)
       [java] at org.jboss.chap2.ex0.ExCCEc.main(ExCCEc.java:58)
       [java] Caused by: java.lang.ClassCastException
       [java] at org.jboss.chap2.ex0.ExCtx.useValue(ExCtx.java:44)
       [java] ... 5 more</programlisting>
                      <para>Only the exception is shown here. The full output can be found in the
                              <literal>logs/chap2-ex0c.log</literal> file. At line 55 of <literal>ExCCEc.java</literal> we
                          are invoking <literal>ExcCCECtx.useValue(Object)</literal> on the instance loaded and created in
                          lines 37-48 using <literal>ucl1</literal>. The <literal>ExObj</literal> passed in is the one
                          loaded and created in lines 25-35 via <literal>ucl0</literal>. The exception results when the
                              <literal>ExCtx.useValue</literal> code attempts to cast the argument passed in to a
                              <literal>ExObj</literal>. To understand why this fails consider the debugging output from
                          the <literal>chap2-ex0c.log</literal> file shown in <xref linkend="ch2.debug.ex"/>.</para>
                      <example id="ch2.debug.ex">
                          <title>The chap2-ex0c.log debugging output for the ExObj classes seen</title>
                          <programlisting>[INFO,UCL0] ExObj Info
  org.jboss.chap2.ex0.ExObj(113fe2).ClassLoader=java.net.URLClassLoader at 6e3914
  ..java.net.URLClassLoader at 6e3914
  ....file:/C:/Scott/JBoss/Books/AdminDevel/education/books/admin-devel/examples/output/
    chap2/j0.jar
  ++++CodeSource:
      (file:/C:/Scott/JBoss/Books/AdminDevel/education/books/admin-devel/examples/output/
    chap2/j0.jar &lt;no certificates&gt;)
  Implemented Interfaces:
  ++interface java.io.Serializable(7934ad)
  ++++ClassLoader: null
  ++++Null CodeSource
   
  [INFO,ExCtx] useValue2.ExObj class
  org.jboss.chap2.ex0.ExObj(415de6).ClassLoader=java.net.URLClassLoader at 30e280
  ..java.net.URLClassLoader at 30e280
  ....file:/C:/Scott/JBoss/Books/AdminDevel/education/books/admin-devel/examples/output/
    chap2/j0.jar
  ++++CodeSource:
      (file:/C:/Scott/JBoss/Books/AdminDevel/education/books/admin-devel/examples/output/
    chap2/j0.jar &lt;no certificates&gt;)
  Implemented Interfaces:
  ++interface java.io.Serializable(7934ad)
  ++++ClassLoader: null
  ++++Null CodeSource</programlisting>
                      </example>
                      <para>The first output prefixed with <literal>[INFO,UCL0]</literal> shows that the
                          <literal>ExObj</literal> class loaded at line <literal>ExCCEc.java:31</literal> has a hash code
                          of <literal>113fe2</literal> and an associated <literal>URLClassLoader</literal> instance with a
                          hash code of <literal>6e3914</literal>, which corresponds to ucl0. This is the class used to
                          create the instance passed to the <literal>ExCtx.useValue</literal> method. The second output
                          prefixed with <literal>[INFO,ExCtx]</literal> shows that the <literal>ExObj</literal> class as
                          seen in the context of the <literal>ExCtx.useValue</literal> method has a hash code of
                              <literal>415de6</literal> and a <literal>URLClassLoader</literal> instance with an
                          associated hash code of <literal>30e280</literal>, which corresponds to <literal>ucl1</literal>.
                          So even though the <literal>ExObj</literal> classes are the same in terms of actual bytecode
                          since it comes from the same <literal>j0.jar</literal>, the classes are different as seen by
                          both the <literal>ExObj</literal> class hash codes, and the associated
                          <literal>URLClassLoader</literal> instances. Hence, attempting to cast an instance of
                              <literal>ExObj</literal> from one scope to the other results in the
                              <literal>ClassCastException</literal>.</para>
                      <para>This type of error is common when redeploying an application to which other applications are
                          holding references to classes from the redeployed application. For example, a standalone WAR
                          accessing an EJB. If you are redeploying an application, all dependent applications must flush
                          their class references. Typically this requires that the dependent applications themselves be
                          redeployed.</para>
                      <para>An alternate means of allowing independent deployments to interact in the presence of
                          redeployment would be to isolate the deployments by configuring the EJB layer to use the
                          standard call-by-value semantics rather than the call-by-reference JBoss will default to for
                          components collocated in the same VM. An example of how to enable call-by-value semantics is
                          presented in <xref linkend="ch5.chapter"/>
                      </para>
                  </section>
                  <section>
                      <title>IllegalAccessException - Doing what you should not</title>
                      <para>A <literal>java.lang.IllegalAccessException</literal> is thrown when one attempts to access a
                          method or member that visibility qualifiers do not allow. Typical examples are attempting to
                          access private or protected methods or instance variables. Another common example is accessing
                          package protected methods or members from a class that appears to be in the correct package, but
                          is really not due to caller and callee classes being loaded by different class loaders. An
                          example of this is illustrated by the code shown in <xref linkend="ch2.ldcon.ex"/>.</para>
                      <example>
                          <title>The ExIAEd class used to demonstrate IllegalAccessException due to duplicate class
                              loaders</title>
                          <programlisting>package org.jboss.chap2.ex0;
  
  import java.io.File;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.lang.reflect.Method;
  
  import org.apache.log4j.Logger;
  
  import org.jboss.util.ChapterExRepository;
  import org.jboss.util.Debug;
  
  /**
   * An example of IllegalAccessExceptions due to
   * classes loaded by two class loaders.
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class ExIAEd
  {
      public static void main(String[] args) throws Exception
      {
  	ChapterExRepository.init(ExIAEd.class);
  
  	String chapDir = System.getProperty("chapter.dir");
  	Logger ucl0Log = Logger.getLogger("UCL0");
  	File jar0 = new File(chapDir+"/j0.jar");
  	ucl0Log.info("jar0 path: "+jar0.toString());
  	URL[] cp0 = {jar0.toURL()};
  	URLClassLoader ucl0 = new URLClassLoader(cp0);
  	Thread.currentThread().setContextClassLoader(ucl0);
  	
  	StringBuffer buffer = new
  	    StringBuffer("ExIAEd Info");
  	Debug.displayClassInfo(ExIAEd.class, buffer, false);
  	ucl0Log.info(buffer.toString());
  	
  	Class ctxClass1 = ucl0.loadClass("org.jboss.chap2.ex0.ExCtx");
  	buffer.setLength(0);
  	buffer.append("ExCtx Info");
  	Debug.displayClassInfo(ctxClass1, buffer, false);
  	ucl0Log.info(buffer.toString());
  	Object ctx0 = ctxClass1.newInstance();
  
  	try {
  	    Class[] types = {Object.class};
  	    Method useValue =
  		ctxClass1.getDeclaredMethod("pkgUseValue", types);
  	    Object[] margs = {null};
  	    useValue.invoke(ctx0, margs);
  	} catch(Exception e) {
  	    ucl0Log.error("Failed to invoke ExCtx.pkgUseValue", e);
  	}
      }
  }</programlisting>
                      </example>
                      <para>The <literal>ExIAEd.main</literal> method uses reflection to load the <literal>ExCtx</literal>
                          class via the <literal>ucl0</literal> class loader while the <literal>ExIEAd</literal> class was
                          loaded by the application class loader. We will run this example to demonstrate how the
                              <literal>IllegalAccessException</literal> can occur and then look at the specific issue with
                          the example. Run the example using the following command:</para>
                      <programlisting>[examples]$ ant -Dchap=chap2 -Dex=0d run-example
  Buildfile: build.xml
  ...
  [java] [ERROR,UCL0] Failed to invoke ExCtx.pkgUseValue
  [java] java.lang.IllegalAccessException: Class org.jboss.chap2.ex0.ExIAEd 
    can not access a member of class org.jboss.chap2.ex0.ExCtx with modifiers ""
  [java] at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:57)
  [java] at java.lang.reflect.Method.invoke(Method.java:317)
  [java] at org.jboss.chap2.ex0.ExIAEd.main(ExIAEd.java:48)</programlisting>
                      <para>The truncated output shown here illustrates the <literal>IllegalAccessException</literal>. The
                          full output can be found in the <literal>logs/chap2-ex0d.log</literal> file. At line 48 of
                              <literal>ExIAEd.java</literal> the <literal>ExCtx.pkgUseValue(Object)</literal> method is
                          invoked via reflection. The <literal>pkgUseValue</literal> method has package protected access
                          and even though both the invoking class <literal>ExIAEd</literal> and the
                          <literal>ExCtx</literal> class whose method is being invoked reside in the
                              <literal>org.jboss.chap2.ex0</literal> package, the invocation is seen to be invalid due to
                          the fact that the two classes are loaded by different class loaders. This can be seen by looking
                          at the debugging output from the <literal>chap2-ex0d.log file</literal>.</para>
                      <programlisting>[INFO,UCL0] ExIAEd Info
  org.jboss.chap2.ex0.ExIAEd(65855a).ClassLoader=sun.misc.Launcher$AppClassLoader at 3f52a5
  ..sun.misc.Launcher$AppClassLoader at 3f52a5
  ...
  [INFO,UCL0] ExCtx Info
  org.jboss.chap2.ex0.ExCtx(70eed6).ClassLoader=java.net.URLClassLoader at 113fe2
  ..java.net.URLClassLoader at 113fe2
  ...</programlisting>
                      <para>The ExIAEd class is seen to have been loaded via the default application class loader instance
                              <literal>sun.misc.Launcher$AppClassLoader at 3f52a5</literal>, while the
                          <literal>ExCtx</literal> class was loaded by the
                          <literal>java.net.URLClassLoader at 113fe2</literal> instance. Because the classes are loaded by
                          different class loaders, access to the package protected method is seen to be a security
                          violation. So, not only is type a function of both the fully qualified class name and class
                          loader, the package scope is as well.</para>
                      <para>An example of how this can happen in practice is to include the same classes in two different
                          SAR deployments. If classes in the deployment have a package protected relationship, users of
                          the SAR service may end up loading one class from SAR class loading at one point, and then load
                          another class from the second SAR at a later time. If the two classes in question have a
                          protected access relationship an <literal>IllegalAccessError</literal> will result. The solution
                          is to either include the classes in a separate jar that is referenced by the SARs, or to combine
                          the SARs into a single deployment. This can either be a single SAR, or an EAR that includes both
                          SARs.</para>
                  </section>
                  <section>
                      <title>LinkageErrors - Making Sure You Are Who You Say You Are</title>
                      <para>Loading constraints validate type expectations in the context of class loader scopes to ensure
                          that a class <literal>X</literal> is consistently the same class when multiple class loaders are
                          involved. This is important because Java allows for user defined class loaders. Linkage errors
                          are essentially an extension of the class cast exception that is enforced by the VM when classes
                          are loaded and used.</para>
                      <para>To understand what loading constraints are and how they ensure type-safety we will first
                          introduce the nomenclature of the Liang and Bracha paper along with an example from this paper.
                          There are two type of class loaders, initiating and defining. An initiating class loader is one
                          that a <literal>ClassLoader.loadClass</literal> method has been invoked on to initiate the
                          loading of the named class. A defining class loader is the loader that calls one of the
                              <literal>ClassLoader.defineClass</literal> methods to convert the class byte code into a
                              <literal>Class</literal> instance. The most complete expression of a class is given by
                                  <literal>&lt;C,Ld&gt;<superscript>Li</superscript>
                          </literal>, where <literal>C</literal> is the fully qualified class name, <literal>Ld</literal>
                          is the defining class loader, and <literal>Li</literal> is the initiating class loader. In a
                          context where the initiating class loader is not important the type may be represented by
                              <literal>&lt;C,Ld&gt;</literal>, while when the defining class loader is not
                          important, the type may be represented by <literal>C<superscript>Li</superscript>
                          </literal>. In the latter case, there is still a defining class loader, it's just not important
                          what the identity of the defining class loader is. Also, a type is completely defined by
                              <literal>&lt;C,Ld&gt;</literal>. The only time the initiating loader is relevant is
                          when a loading constraint is being validated. Now consider the classes shown in <xref
                              linkend="ch2.ldcon.ex"/>.</para>
                      <example id="ch2.ldcon.ex">
                          <title>Classes demonstrating the need for loading constraints</title>
                          <programlisting>class &lt;C,L1&gt; {
      void f() {
          &lt;Spoofed, L1&gt;<superscript>L1</superscript>x = &lt;Delegated, L2&gt;<superscript>L2</superscript>
          x.secret_value = 1; // Should not be allowed
      }
  }</programlisting>
                          <programlisting>class &lt;Delegated,L2&gt; {
      static &lt;Spoofed, L2&gt;<superscript>L3</superscript> g() {...}
      }
  }</programlisting>
                          <programlisting>class &lt;Spoofed, L1&gt; {
      public int secret_value;
  }</programlisting>
                          <programlisting>class &lt;Spoofed, L2&gt; {
      private int secret_value;
  }</programlisting>
                      </example>
                      <para>The class <literal>C</literal> is defined by <literal>L1</literal> and so
                          <literal>L1</literal> is used to initiate loading of the classes <literal>Spoofed</literal> and
                              <literal>Delegated</literal> referenced in the <literal>C.f()</literal> method. The
                              <literal>Spoofed</literal> class is defined by <literal>L1</literal>, but
                          <literal>Delegated</literal> is defined by <literal>L2</literal> because <literal>L1</literal>
                          delegates to <literal>L2</literal>. Since <literal>Delegated</literal> is defined by
                          <literal>L2</literal>, <literal>L2</literal> will be used to initiate loading of
                              <literal>Spoofed</literal> in the context of the <literal>Delegated.g()</literal> method. In
                          this example both <literal>L1</literal> and <literal>L2</literal> define different versions of
                              <literal>Spoofed</literal> as indicated by the two versions shown at the end of <xref
                              linkend="ch2.ldcon.ex"/>. Since <literal>C.f()</literal> believes <literal>x</literal> is an
                          instance of <literal>&lt;Spoofed,L1&gt;</literal> it is able to access the private field
                              <literal>secret_value</literal> of <literal>&lt;Spoofed,L2&gt;</literal> returned by
                              <literal>Delegated.g()</literal> due to the 1.1 and earlier Java VM's failure to take into
                          account that a class type is determined by both the fully qualified name of the class and the
                          defining class loader.</para>
                      <para>Java addresses this problem by generating loader constraints to validate type consistency when
                          the types being used are coming from different defining class loaders. For the <xref
                              linkend="ch2.ldcon.ex"/> example, the VM generates a constraint
                                  <literal>Spoofed<superscript>L1</superscript>=Spoofed<superscript>L2</superscript>
                          </literal> when the first line of method <literal>C.f() </literal>is verified to indicate that
                          the type <literal>Spoofed</literal> must be the same regardless of whether the load of
                              <literal>Spoofed</literal> is initiated by <literal>L1</literal> or <literal>L2</literal>.
                          It does not matter if <literal>L1</literal> or <literal>L2</literal>, or even some other class
                          loader defines <literal>Spoofed</literal>. All that matters is that there is only one
                              <literal>Spoofed</literal> class defined regardless of whether <literal>L1</literal> or
                              <literal>L2</literal> was used to initiate the loading. If <literal>L1</literal> or
                              <literal>L2</literal> have already defined separate versions of <literal>Spoofed</literal>
                          when this check is made a <literal>LinkageError</literal> will be generated immediately.
                          Otherwise, the constraint will be recorded and when <literal>Delegated.g()</literal> is
                          executed, any attempt to load a duplicate version of <literal>Spoofed</literal> will result in a
                              <literal>LinkageError</literal>.</para>
                      <para>Now let's take a look at how a <literal>LinkageError</literal> can occur with a concrete
                          example. <xref linkend="ch2.linkerror.ex"/> gives the example main class along with the custom
                          class loader used.</para>
                      <example id="ch2.linkerror.ex">
                          <title>A concrete example of a LinkageError</title>
                          <!-- linenumbering="numbered" -->
                          <programlisting>package org.jboss.chap2.ex0;
  import java.io.File;
  import java.net.URL;
  
  import org.apache.log4j.Logger;
  import org.jboss.util.ChapterExRepository;
  import org.jboss.util.Debug;
  
  /** 
   * An example of a LinkageError due to classes being defined by more
   * than one class loader in a non-standard class loading environment.
   *
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class ExLE
  {
      public static void main(String[] args) 
  	throws Exception
      {
          ChapterExRepository.init(ExLE.class);
  
          String chapDir = System.getProperty("chapter.dir");
          Logger ucl0Log = Logger.getLogger("UCL0");
          File jar0 = new File(chapDir+"/j0.jar");
          ucl0Log.info("jar0 path: "+jar0.toString());
          URL[] cp0 = {jar0.toURL()};
          Ex0URLClassLoader ucl0 = new Ex0URLClassLoader(cp0);
          Thread.currentThread().setContextClassLoader(ucl0);
          <emphasis role="bold">Class ctxClass1  = ucl0.loadClass("org.jboss.chap2.ex0.ExCtx");</emphasis>
          <emphasis role="bold">Class obj2Class1 = ucl0.loadClass("org.jboss.chap2.ex0.ExObj2");</emphasis>
          StringBuffer buffer = new StringBuffer("ExCtx Info");
          Debug.displayClassInfo(ctxClass1, buffer, false);
          ucl0Log.info(buffer.toString());
          buffer.setLength(0);
          buffer.append("ExObj2 Info, UCL0");
          Debug.displayClassInfo(obj2Class1, buffer, false);
          ucl0Log.info(buffer.toString());
          
          File jar1 = new File(chapDir+"/j1.jar");
          Logger ucl1Log = Logger.getLogger("UCL1");
          ucl1Log.info("jar1 path: "+jar1.toString());
          URL[] cp1 = {jar1.toURL()};
          Ex0URLClassLoader ucl1 = new Ex0URLClassLoader(cp1);
          <emphasis role="bold">Class obj2Class2 = ucl1.loadClass("org.jboss.chap2.ex0.ExObj2");</emphasis>
          buffer.setLength(0);
          buffer.append("ExObj2 Info, UCL1");
          Debug.displayClassInfo(obj2Class2, buffer, false);
          ucl1Log.info(buffer.toString());
          
          <emphasis role="bold">ucl0.setDelegate(ucl1);</emphasis>
          try {
              ucl0Log.info("Try ExCtx.newInstance()");
              <emphasis role="bold">Object ctx0 = ctxClass1.newInstance();</emphasis>
              ucl0Log.info("ExCtx.ctor succeeded, ctx0: "+ctx0);
          } catch(Throwable e) {
              ucl0Log.error("ExCtx.ctor failed", e);
          }
      }
  }</programlisting>
                          <programlisting>package org.jboss.chap2.ex0;
  
  import java.net.URLClassLoader;
  import java.net.URL;
  
  import org.apache.log4j.Logger;
  
  /** 
   * A custom class loader that overrides the standard parent delegation
   * model
   *
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class Ex0URLClassLoader extends URLClassLoader
  {
      private static Logger log = Logger.getLogger(Ex0URLClassLoader.class);
      private Ex0URLClassLoader delegate;
  
      public Ex0URLClassLoader(URL[] urls)
      {
          super(urls);
      }
      
      void setDelegate(Ex0URLClassLoader delegate)
      {
          this.delegate = delegate;
      }
      
      protected synchronized Class loadClass(String name, boolean resolve)
          throws ClassNotFoundException
      {
          Class clazz = null;
          if (delegate != null) {
              log.debug(Integer.toHexString(hashCode()) +
  		      "; Asking delegate to loadClass: " + name);
              clazz = delegate.loadClass(name, resolve);
              log.debug(Integer.toHexString(hashCode()) +
  		      "; Delegate returned: "+clazz);
          } else {
              log.debug(Integer.toHexString(hashCode()) + 
  		      "; Asking super to loadClass: "+name);
              clazz = super.loadClass(name, resolve);
              log.debug(Integer.toHexString(hashCode()) + 
  		      "; Super returned: "+clazz);
          }
          return clazz;
      }
  
      protected Class findClass(String name)
          throws ClassNotFoundException
      {
          Class clazz = null;
          log.debug(Integer.toHexString(hashCode()) + 
  		  "; Asking super to findClass: "+name);
          clazz = super.findClass(name);
          log.debug(Integer.toHexString(hashCode()) + 
  		  "; Super returned: "+clazz);
          return clazz;
      }
  }</programlisting>
                      </example>
                      <para>The key component in this example is the <literal>URLClassLoader</literal> subclass
                              <literal>Ex0URLClassLoader</literal>. This class loader implementation overrides the default
                          parent delegation model to allow the <literal>ucl0</literal> and <literal>ucl1</literal>
                          instances to both load the <literal>ExObj2</literal> class and then setup a delegation
                          relationship from <literal>ucl0</literal> to <literal>ucl1</literal>. At lines 30 and 31. the
                              <literal>ucl0</literal>
                          <literal>Ex0URLClassLoader</literal> is used to load the <literal>ExCtx</literal> and
                              <literal>ExObj2</literal> classes. At line 45 of <literal>ExLE.main</literal> the
                              <literal>ucl1</literal>
                          <literal>Ex0URLClassLoader</literal> is used to load the <literal>ExObj2</literal> class again.
                          At this point both the <literal>ucl0</literal> and <literal>ucl1</literal> class loaders have
                          defined the <literal>ExObj2</literal> class. A delegation relationship from
                          <literal>ucl0</literal> to <literal>ucl1</literal> is then setup at line 51 via the
                              <literal>ucl0.setDelegate(ucl1)</literal> method call. Finally, at line 54 of
                              <literal>ExLE.main</literal> an instance of <literal>ExCtx</literal> is created using the
                          class loaded via <literal>ucl0</literal>. The <literal>ExCtx</literal> class is the same as
                          presented in <xref linkend="ch2.threeclasses.ex"/>, and the constructor was:</para>
                      <programlisting>public ExCtx() 
      throws IOException
  {
      value = new ExObj();
      Logger log = Logger.getLogger(ExCtx.class);
      StringBuffer buffer = new StringBuffer("ctor.ExObj");
      Debug.displayClassInfo(value.getClass(), buffer, false);
      log.info(buffer.toString());
      ExObj2 obj2 = value.ivar;
      buffer.setLength(0);
      buffer = new StringBuffer("ctor.ExObj.ivar");
      Debug.displayClassInfo(obj2.getClass(), buffer, false);
      log.info(buffer.toString());
  }    </programlisting>
                      <para>Now, since the <literal>ExCtx</literal> class was defined by the <literal>ucl0</literal> class
                          loader, and at the time the <literal>ExCtx</literal> constructor is executed,
                          <literal>ucl0</literal> delegates to <literal>ucl1</literal>, line 24 of the
                          <literal>ExCtx</literal> constructor involves the following expression which has been rewritten
                          in terms of the complete type expressions:</para>
                      <para> &lt;ExObj2,ucl0&gt;<superscript>ucl0</superscript> obj2 =
                              &lt;ExObj,ucl1&gt;<superscript>ucl0</superscript> value * ivar </para>
                      <para>This generates a loading constraint of <literal>ExObj2<superscript>ucl0</superscript> =
                                  ExObj2<superscript>ucl1</superscript>
                          </literal> since the <literal>ExObj2</literal> type must be consistent across the
                          <literal>ucl0</literal> and <literal>ucl1</literal> class loader instances. Because we have
                          loaded <literal>ExObj2</literal> using both <literal>ucl0</literal> and <literal>ucl1</literal>
                          prior to setting up the delegation relationship, the constraint will be violated and should
                          generate a <literal>LinkageError</literal> when run. Run the example using the following
                          command:</para>
                      <programlisting>[examples]$ ant -Dchap=chap2 -Dex=0e run-example
  Buildfile: build.xml
  ...
  [java] java.lang.LinkageError: loader constraints violated when linking org/jboss/chap2/ex0/E
  xObj2 class
  [java] at org.jboss.chap2.ex0.ExCtx.&lt;init&gt;(ExCtx.java:24)
  [java] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  [java] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl
  .java:39)
  [java] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAcce
  ssorImpl.java:27)
  [java] at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
  [java] at java.lang.Class.newInstance0(Class.java:308)
  [java] at java.lang.Class.newInstance(Class.java:261)
  [java] at org.jboss.chap2.ex0.ExLE.main(ExLE.java:53)</programlisting>
                      <para>As expected, a LinkageError is thrown while validating the loader constraints required by line
                          24 of the <literal>ExCtx</literal> constructor.</para>
                      <section>
                          <title>Debugging Class Loading Issues</title>
                          <para>Debugging class loading issues comes down to finding out where a class was loaded from. A
                              useful tool for this is the code snippet shown in <xref linkend="ch2.debuginfo.ex"/> taken
                              from the org.jboss.util.Debug class of the book examples.</para>
                          <example id="ch2.debuginfo.ex">
                              <title>Obtaining debugging information for a Class</title>
                              <programlisting>Class clazz =...;
  StringBuffer results = new StringBuffer();
  
  ClassLoader cl = clazz.getClassLoader();
  results.append("\n" + clazz.getName() + "(" + 
                 Integer.toHexString(clazz.hashCode()) + ").ClassLoader=" + cl);
  ClassLoader parent = cl;
  
  while (parent != null) {
      results.append("\n.."+parent);
      URL[] urls = getClassLoaderURLs(parent);
  
      int length = urls != null ? urls.length : 0;
      for(int u = 0; u &lt; length; u ++) {
  	results.append("\n...."+urls[u]);
      }
  
      if (showParentClassLoaders == false) {
  	break;
      }
      if (parent != null) {
  	parent = parent.getParent();
      }
  }
  
  CodeSource clazzCS = clazz.getProtectionDomain().getCodeSource();
  if (clazzCS != null) {
      results.append("\n++++CodeSource: "+clazzCS);
  } else {
      results.append("\n++++Null CodeSource");
  }</programlisting>
                          </example>
                          <para>The key items are shown in bold. The first is that every Class object knows its defining
                                  <literal>ClassLoader</literal> and this is available via the
                              <literal>getClassLoader()</literal> method. The defines the scope in which the
                                  <literal>Class</literal> type is known as we have just seen in the previous sections on
                              class cast exceptions, illegal access exceptions and linkage errors. From the
                                  <literal>ClassLoader</literal> you can view the hierarchy of class loaders that make up
                              the parent delegation chain. If the class loader is a <literal>URLClassLoader</literal> you
                              can also see the URLs used for class and resource loading.</para>
                          <para>The defining <literal>ClassLoader</literal> of a <literal>Class</literal> cannot tell you
                              from what location that <literal>Class</literal> was loaded. To determine this you must
                              obtain the <literal>java.security.ProtectionDomain</literal> and then the
                                  <literal>java.security.CodeSource</literal>. It is the <literal>CodeSource</literal>
                              that has the URL p location from which the class originated. Note that not every
                                  <literal>Class</literal> has a <literal>CoPdeSource</literal>. If a class is loaded by
                              the bootstrap class loader then its <literal>CodeSource</literal> will be null. This will be
                              the case for all classes in the <literal>java.*</literal> and <literal>javax.*</literal>
                              packages, for example.</para>
                          <para>Beyond that it may be useful to view the details of classes being loaded into the JBoss
                              server. You can enable verbose logging of the JBoss class loading layer using a Log4j
                              configuration fragment like that shown in <xref linkend="ch2.log4j.ex"/>.</para>
                          <example id="ch2.log4j.ex">
                              <title>An example log4j.xml configuration fragment for enabling verbose class loading
                                  logging</title>
                              <programlisting>&lt;appender name="UCL" class="org.apache.log4j.FileAppender"&gt;
      &lt;param name="File" value="${jboss.server.home.dir}/log/ucl.log"/&gt;
      &lt;param name="Append" value="false"/&gt;
      &lt;layout class="org.apache.log4j.PatternLayout"&gt;
          &lt;param name="ConversionPattern" value="[%r,%c{1},%t] %m%n"/&gt;
      &lt;/layout&gt;
  &lt;/appender&gt;
                              
  &lt;category name="org.jboss.mx.loading" additivity="false"&gt;
      &lt;priority value="TRACE" class="org.jboss.logging.XLevel"/&gt;
      &lt;appender-ref ref="UCL"/&gt;
  &lt;/category&gt;</programlisting>
                          </example>
                          <para>This places the output from the classes in the <literal>org.jboss.mx.loading</literal>
                              package into the <literal>ucl.log</literal> file of the server configurations log directory.
                              Although it may not be meaningful if you have not looked at the class loading code, it is
                              vital information needed for submitting bug reports or questions regarding class loading
                              problems. </para>
                      </section>
                  </section>
                  <section>
                      <title>Inside the JBoss Class Loading Architecture</title>
                      <para>Now that we have the role of class loaders in the Java type system defined, let's take a look
                          at the JBoss class loading architecture. <xref linkend="ch2.loadarch.fig"/>.</para>
                      <figure id="ch2.loadarch.fig">
                          <title>The core JBoss class loading components</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/Chap2-24.jpg"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para>The central component is the <literal>org.jboss.mx.loading.UnifiedClassLoader3</literal> (UCL)
                          class loader. This is an extension of the standard <literal>java.net.URLClassLoader</literal>
                          that overrides the standard parent delegation model to use a shared repository of classes and
                          resources. This shared repository is the
                          <literal>org.jboss.mx.loading.UnifiedLoaderRepository3</literal>. Every UCL is associated with a
                          single <literal>UnifiedLoaderRepository3</literal>, and a
                          <literal>UnifiedLoaderRepository3</literal> typically has many UCLs. A UCL may have multiple
                          URLs associated with it for class and resource loading. Deployers use the top-level deployment's
                          UCL as a shared class loader and all deployment archives are assigned to this class loader. We
                          will talk about the JBoss deployers and their interaction with the class loading system in more
                          detail latter in <xref linkend="ch2.mbeanservice.sect"/>.</para>
                      <para>When a UCL is asked to load a class, it first looks to the repository cache it is associated
                          with to see if the class has already been loaded. Only if the class does not exist in the
                          repository will it be loaded into the repository by the UCL. By default, there is a single
                              <literal>UnifiedLoaderRepository3</literal> shared across all UCL instances. This means the
                          UCLs form a single flat class loader namespace. The complete sequence of steps that occur when a
                              <literal>UnfiedClassLoader3.loadClass(String, boolean)</literal> method is called is:</para>
                      <orderedlist>
                          <listitem>
                              <para>Check the <literal>UnifiedLoaderRepository3</literal> classes cache associated with
                                  the <literal>UnifiedClassLoader3</literal>. If the class is found in the cache it is
                                  returned.</para>
                          </listitem>
                          <listitem>
                              <para>Else, ask the <literal>UnfiedClassLoader3</literal> if it can load the class. This is
                                  essentially a call to the superclass <literal>URLClassLoader.loadClass(String,
                                  boolean)</literal> method to see if the class is among the URLs associated with the
                                  class loader, or visible to the parent class loader. If the class is found it is placed
                                  into the repository classes cache and returned.</para>
                          </listitem>
                          <listitem>
                              <para>Else, the repository is queried for all UCLs that are capable of providing the class
                                  based on the repository package name to UCL map. When a UCL is added to a repository an
                                  association between the package names available in the URLs associated with the UCL is
                                  made, and a mapping from package names to the UCLs with classes in the package is
                                  updated. This allows for a quick determination of which UCLs are capable of loading the
                                  class. The UCLs are then queried for the requested class in the order in which the UCLs
                                  were added to the repository. If a UCL is found that can load the class it is returned,
                                  else a <literal>java.lang.ClassNotFoundException</literal> is thrown.</para>
                          </listitem>
                      </orderedlist>
                      <section>
                          <title>Viewing Classes in the Loader Repository</title>
                          <para>Another useful source of information on classes is the UnifiedLoaderRepository itself.
                              This is an MBean that contains operations to display class and package information. The
                              default repository is located under a standard JMX name of
                                  <literal>JMImplementation:name=Default,service=LoaderRepository</literal>, and its MBean
                              can be accessed via the JMX console by following its link from the front page. The JMX
                              console view of this MBean is shown in <xref linkend="ch2.loaderjmx.fig"/>. </para>
                          <figure id="ch2.loaderjmx.fig">
                              <title>The default class LoaderRepository MBean view in the JMX console</title>
                              <mediaobject>
                                  <imageobject>
                                      <imagedata align="center" fileref="images/console-loader-repository.jpg"/>
                                  </imageobject>
                              </mediaobject>
                          </figure>
                          <para>Two useful operations you will find here are
                              <literal>getPackageClassLoaders(String)</literal> and
                              <literal>displayClassInfo(String)</literal>. The <literal>getPackageClassLoaders</literal>
                              operation returns a set of class loaders that have been indexed to contain classes or
                              resources for the given package name. The package name must have a trailing period. If you
                              type in the package name <literal>org.jboss.ejb.</literal>, the following information is
                              displayed:</para>
                          <programlisting>[org.jboss.mx.loading.UnifiedClassLoader3 at e26ae7{
    url=file:/private/tmp/jboss-4.0.1/server/default/tmp/deploy/tmp11895jboss-service.xml,
    addedOrder=2}]</programlisting>
                          <para>This is the string representation of the set. It shows one
                              <literal>UnifiedClassLoader3</literal> instance with a primary URL pointing to the
                                  <literal>jboss-service.xml</literal> descriptor. This is the second class loader added
                              to the repository (shown by <literal>addedOrder=2</literal>). It is the class loader that
                              owns all of the JARs in the <literal>lib</literal> directory of the server configuration
                              (e.g., <literal>server/default/lib</literal>).</para>
                          <para>The view the information for a given class, use the <literal>displayClassInfo</literal>
                              operation, passing in the fully qualified name of the class to view. For example, if we use
                                  <literal>org.jboss.jmx.adaptor.html.HtmlAdaptorServlet</literal> which is from the
                              package we just looked at, the following description is displayed:</para>
                          <mediaobject>
                              <imageobject>
                                  <imagedata fileref="images/displayClassInfo.jpg"/>
                              </imageobject>
                          </mediaobject>
                          <para>The information is a dump of the information for the Class instance in the loader
                              repository if one has been loaded, followed by the class loaders that are seen to have the
                              class file available. If a class is seen to have more than one class loader associated with
                              it, then there is the potential for class loading related errors.</para>
                      </section>
                      <section id="ch2.scoping.sect">
                          <title>Scoping Classes</title>
                          <para>If you need to deploy multiple versions of an application you need to use deployment based
                              scoping. With deployment based scoping, each deployment creates its own class loader
                              repository in the form of a <literal>HeirarchicalLoaderRepository3</literal> that looks
                              first to the <literal>UnifiedClassLoader3</literal> instances of the deployment units
                              included in the EAR before delegating to the default
                              <literal>UnifiedLoaderRepository3</literal>. To enable an EAR specific loader repository,
                              you need to create a <literal>META-INF/jboss-app.xml</literal> descriptor as shown in <xref
                                  linkend="ch2.scopedapp.ex"/>.</para>
                          <example id="ch2.scopedapp.ex">
                              <title>An example jboss-app.xml descriptor for enabled scoped class loading at the EAR
                                  level.</title>
                              <programlisting>&lt;jboss-app&gt;
      &lt;loader-repository&gt;some.dot.com:loader=webtest.ear&lt;/loader-repository&gt;
  &lt;/jboss-app&gt;</programlisting>
                          </example>
                          <para>The value of the <literal>loader-repository</literal> element is the JMX object name to
                              assign to the repository created for the EAR. This must be unique and valid JMX ObjectName,
                              but the actual name is not important.</para>
                      </section>
                      <section>
                          <title>The Complete Class Loading Model</title>
                          <para>The previous discussion of the core class loading components introduced the custom
                                  <literal>UnifiedClassLoader3</literal> and <literal>UnifiedLoaderRepository3</literal>
                              classes that form a shared class loading space. The complete class loading picture must also
                              include the parent class loader used by <literal>UnifiedClassLoader3</literal>s as well as
                              class loaders introduced for scoping and other specialty class loading purposes. <xref
                                  linkend="ch2.classloaderview.fig"/> shows an outline of the class hierarchy that would
                              exist for an EAR deployment containing EJBs and WARs.</para>
                          <figure id="ch2.classloaderview.fig">
                              <title>A complete class loader view</title>
                              <mediaobject>
                                  <imageobject>
                                      <imagedata align="center" fileref="images/Chap2-26.gif"/>
                                  </imageobject>
                              </mediaobject>
                          </figure>
                          <para>The following points apply to this figure:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">System ClassLoaders</emphasis>: The System ClassLoaders node
                                      refers to either the thread context class loader (TCL) of the VM main thread or of
                                      the thread of the application that is loading the JBoss server if it is
                                  embedded.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">ServerLoader</emphasis>: The ServerLoader node refers to the a
                                          <literal>URLClassLoader</literal> that delegates to the System ClassLoaders and
                                      contains the following boot URLs:</para>
                                  <itemizedlist>
                                      <listitem>
                                          <para>All URLs referenced via the <literal>jboss.boot.library.list</literal>
                                              system property. These are path specifications relative to the
                                                  <literal>libraryURL</literal> defined by the
                                              <literal>jboss.lib.url</literal> property. If there is no
                                                  <literal>jboss.lib.url</literal> property specified, it defaults to
                                                  <literal>jboss.home.url + /lib/</literal>. If there is no
                                                  <literal>jboss.boot.library</literal> property specified, it defaults to
                                                  <literal>jaxp.jar</literal>, <literal>log4j-boot.jar</literal>,
                                                  <literal>jboss-common.jar</literal>, and
                                              <literal>jboss-system.jar</literal>.</para>
                                      </listitem>
                                      <listitem>
                                          <para>The JAXP JAR which is either <literal>crimson.jar</literal> or
                                                  <literal>xerces.jar</literal> depending on the <literal>-j</literal>
                                              option to the <literal>Main</literal> entry point. The default is
                                                  <literal>crimson.jar</literal>.</para>
                                      </listitem>
                                      <listitem>
                                          <para>The JBoss JMX jar and GNU regex jar, <literal>jboss-jmx.jar</literal> and
                                                  <literal>gnu-regexp.jar</literal>.</para>
                                      </listitem>
                                      <listitem>
                                          <para>Oswego concurrency classes JAR, <literal>concurrent.jar</literal>
                                          </para>
                                      </listitem>
                                      <listitem>
                                          <para>Any JARs specified as libraries via <literal>-L</literal> command line
                                              options</para>
                                      </listitem>
                                      <listitem>
                                          <para>Any other JARs or directories specified via <literal>-C</literal> command
                                              line options</para>
                                      </listitem>
                                  </itemizedlist>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">Server</emphasis>: The Server node represent a collection of
                                      UCLs created by the <literal>org.jboss.system.server.Server</literal> interface
                                      implementation. The default implementation creates UCLs for the
                                      <literal>patchDir</literal> entries as well as the server <literal>conf</literal>
                                      directory. The last UCL created is set as the JBoss main thread context class
                                      loader. This will be combined into a single UCL now that multiple URLs per UCL are
                                      supported.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">All UnifiedClassLoader3s</emphasis>: The <emphasis>All
                                          UnifiedClassLoader3</emphasis> node represents the UCLs created by deployers.
                                      This covers EARs, jars, WARs, SARs and directories seen by the deployment scanner as
                                      well as JARs referenced by their manifests and any nested deployment units they may
                                      contain. This is a flat namespace and there should not be multiple instances of a
                                      class in different deployment JARs. If there are, only the first loaded will be used
                                      and the results may not be as expected. There is a mechanism for scoping visibility
                                      based on EAR deployment units that we discussed in <xref linkend="ch2.scoping.sect"
                                      />. Use this mechanism if you need to deploy multiple versions of a class in a given
                                      JBoss server.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">EJB DynClassLoader</emphasis>: The EJB
                                      <literal>DynClassLoader</literal> node is a subclass of
                                      <literal>URLClassLoader</literal> that is used to provide RMI dynamic class loading
                                      via the simple HTTP WebService. It specifies an empty <literal>URL[]</literal> and
                                      delegates to the TCL as its parent class loader. If the WebService is configured to
                                      allow system level classes to be loaded, all classes in the
                                          <literal>UnifiedLoaderRepository3</literal> as well as the system classpath are
                                      available via HTTP.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">EJB ENCLoader</emphasis>: The <emphasis>EJB
                                      ENCLoader</emphasis> node is a <literal>URLClassLoader</literal> that exists only to
                                      provide a unique context for an EJB deployment's <literal>java:comp</literal> JNDI
                                      context. It specifies an empty <literal>URL[]</literal> and delegates to the EJB
                                          <literal>DynClassLoader</literal> as its parent class loader.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">Web ENCLoader</emphasis>: The Web <literal>ENCLoader</literal>
                                      node is a URLClassLoader that exists only to provide a unique context for a web
                                      deployment's <literal>java:comp</literal> JNDI context. It specifies an empty
                                          <literal>URL[]</literal> and delegates to the TCL as its parent class
                                  loader.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">WAR Loader</emphasis>: The <emphasis>WAR Loader</emphasis> is
                                      a servlet container specific classloader that delegates to the Web ENCLoader as its
                                      parent class loader. The default behavior is to load from its parent class loader
                                      and then the WAR <literal>WEB-INF</literal>
                                      <literal>classes</literal> and <literal>lib</literal> directories. If the servlet
                                      2.3 class loading model is enabled it will first load from the its
                                      <literal>WEB-INF</literal> directories and then the parent class loader.</para>
                              </listitem>
                          </itemizedlist>
                          <para>In its current form there are some advantages and disadvantages to the JBoss class loading
                              architecture. Advantages include:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>Classes do not need to be replicated across deployment units in order to have
                                      access to them.</para>
                              </listitem>
                              <listitem>
                                  <para>Many future possibilities including novel partitioning of the repositories into
                                      domains, dependency and conflict detection, etc.</para>
                              </listitem>
                          </itemizedlist>
                          <para>Disadvantages include:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>Existing deployments may need to be repackaged to avoid duplicate classes.
                                      Duplication of classes in a loader repository can lead to class cast exceptions and
                                      linkage errors depending on how the classes are loaded.</para>
                              </listitem>
                              <listitem>
                                  <para>Deployments that depend on different versions of a given class need to be isolated
                                      in separate EARs and a unique <literal>HeirarchicalLoaderRepository3</literal>
                                      defined using a <literal>jboss-app.xml</literal> descriptor.</para>
                              </listitem>
                          </itemizedlist>
                      </section>
                  </section>
              </section>
              <section>
                  <title>JBoss XMBeans</title>
                  <para>XMBeans are the JBoss JMX implementation version of the JMX model MBean. XMBeans have the richness
                      of the dynamic MBean metadata without the tedious programming required by a direct implementation of
                      the <literal>DynamicMBean</literal> interface. The JBoss model MBean implementation allows one to
                      specify the management interface of a component through a XML descriptor, hence the X in XMBean. In
                      addition to providing a simple mechanism for describing the metadata required for a dynamic MBean,
                      XMBeans also allow for the specification of attribute persistence, caching behavior, and even
                      advanced customizations like the MBean implementation interceptors. The high level elements of the
                          <literal>jboss_xmbean_1_2.dtd</literal> for the XMBean descriptor is given in <xref
                          linkend="ch2.xmbeandtd.fig"/>.</para>
                  <figure id="ch2.xmbeandtd.fig">
                      <title>The JBoss 1.0 XMBean DTD Overview (jboss_xmbean_1_2.dtd)</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/xmbean_1_2.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The <literal>mbean</literal> element is the root element of the document containing the required
                      elements for describing the management interface of one MBean (constructors, attributes, operations
                      and notifications). It also includes an optional description element, which can be used to describe
                      the purpose of the MBean, as well as an optional descriptors element which allows for persistence
                      policy specification, attribute caching, etc.</para>
                  <section>
                      <title>Descriptors</title>
                      <para>The descriptors element contains all the descriptors for a containing element, as subelements.
                          The descriptors suggested in the JMX specification as well as those used by JBoss have
                          predefined elements and attributes, whereas custom descriptors have a generic descriptor element
                          with name and value attributes as show in <xref linkend="ch2.descriptorselem.fig"/>. </para>
                      <figure id="ch2.descriptorselem.fig">
                          <title> The descriptors element content model</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/xmbean_1_2_descriptors.jpg"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para>The key descriptors child elements include:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">interceptors</emphasis>: The <literal>interceptors</literal>
                                  element specifies a customized stack of interceptors that will be used in place of the
                                  default stack. Currently this is only used when specified at the MBean level, but it
                                  could define a custom attribute or operation level interceptor stack in the future. The
                                  content of the interceptors element specifies a custom interceptor stack. If no
                                  interceptors element is specified the standard <literal>ModelMBean</literal>
                                  interceptors will be used. The standard interceptors are: </para>
                              <itemizedlist spacing="compact">
                                  <listitem>
                                      <para>org.jboss.mx.interceptor.PersistenceInterceptor</para>
                                  </listitem>
                                  <listitem>
                                      <para>org.jboss.mx.interceptor.MBeanAttributeInterceptor</para>
                                  </listitem>
                                  <listitem>
                                      <para>org.jboss.mx.interceptor.ObjectReferenceInterceptor</para>
                                  </listitem>
                              </itemizedlist>
                              <para>When specifying a custom interceptor stack you would typically include the standard
                                  interceptors along with your own unless you are replacing the corresponding standard
                                  interceptor.</para>
                              <para>Each interceptor element content value specifies the fully qualified class name of the
                                  interceptor implementation. The class must implement the
                                      <literal>org.jboss.mx.interceptor.Interceptor</literal> interface. The interceptor
                                  class must also have either a no-arg constructor, or a constructor that accepts a
                                      <literal>javax.management.MBeanInfo</literal>.</para>
                              <para>The interceptor elements may have any number of attributes that correspond to JavaBean
                                  style properties on the interceptor class implementation. For each
                                  <literal>interceptor</literal> element attribute specified, the interceptor class is
                                  queried for a matching setter method. The attribute value is converted to the true type
                                  of the interceptor class property using the <literal>java.beans.PropertyEditor</literal>
                                  associated with the type. It is an error to specify an attribute for which there is no
                                  setter or <literal>PropertyEditor</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">persistence</emphasis>: The <literal>persistence</literal> element
                                  allows the specification of the <literal>persistPolicy</literal>,
                                  <literal>persistPeriod</literal>, <literal>persistLocation</literal>, and
                                      <literal>persistName</literal> persistence attributes suggested by the JMX
                                  specification. The persistence element attributes are: </para>
                              <itemizedlist>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">persistPolicy</emphasis>: The
                                          <literal>persistPolicy</literal> attribute defines when attributes should be
                                          persisted and its value must be one of </para>
                                      <itemizedlist>
                                          <listitem>
                                              <para>
                                                  <emphasis role="bold">Never</emphasis>: attribute values are transient
                                                  values that are never persisted</para>
                                          </listitem>
                                          <listitem>
                                              <para>
                                                  <emphasis role="bold">OnUpdate</emphasis>: attribute values are
                                                  persisted whenever they are updated</para>
                                          </listitem>
                                          <listitem>
                                              <para>
                                                  <emphasis role="bold">OnTimer</emphasis>: attribute values are persisted
                                                  based on the time given by the <literal>persistPeriod</literal>.</para>
                                          </listitem>
                                          <listitem>
                                              <para>
                                                  <emphasis role="bold">NoMoreOftenThan</emphasis>: attribute values are
                                                  persisted when updated but no more often than the
                                                  <literal>persistPeriod</literal>.</para>
                                          </listitem>
                                      </itemizedlist>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">persistPeriod</emphasis>: The
                                          <literal>persistPeriod</literal> attribute gives the update frequency in
                                          milliseconds if the <literal>perisitPolicy</literal> attribute is
                                              <literal>NoMoreOftenThan</literal> or <literal>OnTimer</literal>.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">persistLocation</emphasis>: The
                                          <literal>persistLocation</literal> attribute specifies the location of the
                                          persistence store. Its form depends on the JMX persistence implementation.
                                          Currently this should refer to a directory into which the attributes will be
                                          serialized if using the default JBoss persistence manager.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">persistName</emphasis>: The <literal>persistName</literal>
                                          attribute can be used in conjunction with the <literal>persistLocation</literal>
                                          attribute to further qualify the persistent store location. For a directory
                                              <literal>persistLocation</literal> the <literal>persistName</literal>
                                          specifies the file to which the attributes are stored within the
                                      directory.</para>
                                  </listitem>
                              </itemizedlist>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">currencyTimeLimit</emphasis>: The
                                  <literal>currencyTimeLimit</literal> element specifies the time in seconds that a cached
                                  value of an attribute remains valid. Its value attribute gives the time in seconds. A
                                  value of 0 indicates that an attribute value should always be retrieved from the MBean
                                  and never cached. A value of -1 indicates that a cache value is always valid.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">display-name</emphasis>: The <literal>display-name</literal>
                                  element specifies the human friendly name of an item. </para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">default</emphasis>: The <literal>default</literal> element
                                  specifies a default value to use when a field has not been set. Note that this value is
                                  not written to the MBean on startup as is the case with the
                                  <literal>jboss-service.xml</literal> attribute element content value. Rather, the
                                  default value is used only if there is no attribute accessor defined, and there is no
                                  value element defined. </para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">value</emphasis>: The <literal>value</literal> element specifies a
                                  management attribute's current value. Unlike the <literal>default</literal> element, the
                                      <literal>value</literal> element is written through to the MBean on startup provided
                                  there is a setter method available. </para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">persistence-manager</emphasis>: The
                                  <literal>persistence-manager</literal> element gives the name of a class to use as the
                                  persistence manager. The <literal>value</literal> attribute specifies the class name
                                  that supplies the <literal>org.jboss.mx.persistence.PersistenceManager</literal>
                                  interface implementation. The only implementation currently supplied by JBoss is the
                                      <literal>org.jboss.mx.persistence.ObjectStreamPersistenceManager</literal> which
                                  serializes the <literal>ModelMBeanInfo</literal> content to a file using Java
                                  serialization.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">descriptor</emphasis>: The <literal>descriptor</literal> element
                                  specifies an arbitrary descriptor not known to JBoss. Its <literal>name</literal>
                                  attribute specifies the type of the descriptor and its <literal>value</literal>
                                  attribute specifies the descriptor value. The <literal>descriptor</literal> element
                                  allows for the attachment of arbitrary management metadata.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">injection</emphasis>: The <literal>injection</literal> element
                                  describes an injection point for receiving information from the microkernel. Each
                                  injection point specifies the type and the set method to use to inject the information
                                  into the resource. The <literal>injection</literal> element supports type attributes:</para>
                              <itemizedlist>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">id</emphasis>: The <literal>id</literal> attribute
                                          specifies the injection point type. The current injection point types are: </para>
                                      <itemizedlist>
                                          <listitem>
                                              <para>
                                                  <emphasis role="bold">MBeanServerType</emphasis>: An
                                                      <emphasis>MBeanServerType</emphasis> injection point receives a
                                                  reference to the <emphasis>MBeanServer</emphasis> that the XMBean is
                                                  registered with. </para>
                                          </listitem>
                                          <listitem>
                                              <para>
                                                  <emphasis role="bold">MBeanInfoType</emphasis>: An
                                                      <emphasis>MBeanInfoType</emphasis> injection point receives a
                                                  reference to the XMBean <emphasis>ModelMBeanInfo</emphasis> metadata.
                                              </para>
                                          </listitem>
                                          <listitem>
                                              <para>
                                                  <emphasis role="bold">ObjectNameType</emphasis>: The
                                                      <emphasis>ObjectName</emphasis> injection point receives the
                                                      <emphasis>ObjectName</emphasis> that the XMBean is registered
                                              under.</para>
                                          </listitem>
                                      </itemizedlist>
                                  </listitem>
                              </itemizedlist>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">setMethod</emphasis>: The <emphasis>setMethod</emphasis> attribute
                                  gives the name of the method used to set the injection value on the resource. The set
                                  method should accept values of the type corresponding to the injection point type.
                              </para>
                          </listitem>
                      </itemizedlist>
                      <para>Note that any of the constructor, attribute, operation or notification elements may have a
                              <literal>descriptors</literal> element to specify the specification defined descriptors as
                          well as arbitrary extension descriptor settings.</para>
                  </section>
                  <section>
                      <title>The Management Class</title>
                      <para>The <literal>class</literal> element specifies the fully qualified name of the managed object
                          whose management interface is described by the XMBean descriptor.</para>
                  </section>
                  <section>
                      <title>The Constructors</title>
                      <para>The <literal>constructor</literal> element(s) specifies the constructors available for
                          creating an instance of the managed object. The constructor element and its content model are
                          shown in <xref linkend="ch2.xmcons.fig"/>.</para>
                      <figure id="ch2.xmcons.fig">
                          <title>The XMBean constructor element and its content model</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/xmbean_1_2_constructor.jpg"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para>The key child elements are:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">description</emphasis>: A description of the constructor.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">name</emphasis>: The name of the constructor, which must be the
                                  same as the implementation class.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">parameter</emphasis>: The parameter element describes a
                                  constructor parameter. The parameter element has the following attributes:</para>
                              <itemizedlist>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">description</emphasis>: An optional description of the
                                          parameter.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">name</emphasis>: The required variable name of the
                                          parameter.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">type</emphasis>: The required fully qualified class name
                                          of the parameter type.</para>
                                  </listitem>
                              </itemizedlist>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">descriptors</emphasis>: Any descriptors to associate with the
                                  constructor metadata.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>The Attributes</title>
                      <para>The <literal>attribute</literal> element(s) specifies the management attributes exposed by the
                          MBean. The attribute element and its content model are shown in <xref linkend="ch2.xmattr.fig"
                          />.</para>
                      <figure id="ch2.xmattr.fig">
                          <title>The XMBean attribute element and its content model</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/xmbean_1_2_attribute.jpg"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para> The <literal>attribute</literal> element supported attributes include:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">access</emphasis>: The optional <literal>access</literal>
                                  attribute defines the read/write access modes of an attribute. It must be one of:</para>
                              <itemizedlist>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">read-only</emphasis>: The attribute may only be
                                      read.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">write-only</emphasis>: The attribute may only be
                                      written.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">read-write</emphasis>: The attribute is both readable and
                                          writable. This is the implied default.</para>
                                  </listitem>
                              </itemizedlist>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">getMethod</emphasis>: The <literal>getMethod</literal> attribute
                                  defines the name of the method which reads the named attribute. This must be specified
                                  if the managed attribute should be obtained from the MBean instance.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">setMethod</emphasis>: The <literal>setMethod</literal> attribute
                                  defines the name of the method which writes the named attribute. This must be specified
                                  if the managed attribute should be obtained from the MBean instance.</para>
                          </listitem>
                      </itemizedlist>
                      <para>The key child elements of the attribute element include:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">description</emphasis>: A description of the attribute.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">name</emphasis>: The name of the attribute as would be used in the
                                      <literal>MBeanServer.getAttribute()</literal> operation.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">type</emphasis>: The fully qualified class name of the attribute
                                  type.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">descriptors</emphasis>: Any additional descriptors that affect the
                                  attribute persistence, caching, default value, etc.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>The Operations</title>
                      <para>The management operations exposed by the XMBean are specified via one or more operation
                          elements. The operation element and its content model are shown in <xref linkend="ch2.xmops.fig"
                          />.</para>
                      <figure id="ch2.xmops.fig">
                          <title>The XMBean operation element and its content model</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/xmbean_1_2_operation.jpg"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para>The impact attribute defines the impact of executing the operation and must be one of:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ACTION</emphasis>: The operation changes the state of the MBean
                                  component (write operation)</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">INFO</emphasis>: The operation should not alter the state of the
                                  MBean component (read operation).</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ACTION_INFO</emphasis>: The operation behaves like a read/write
                                  operation.</para>
                          </listitem>
                      </itemizedlist>
                      <para>The child elements are:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">description</emphasis>: This element specifies a human readable
                                  description of the operation.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">name</emphasis>: This element contains the operation's name</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">parameter</emphasis>: This element describes the operation's
                                  signature.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">return-type</emphasis>: This element contains a fully qualified
                                  class name of the return type from this operation. If not specified, it defaults to
                                  void.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">descriptors</emphasis>: Any descriptors to associate with the
                                  operation metadata.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>Notifications</title>
                      <para>The <literal>notification</literal> element(s) describes the management notifications that may
                          be emitted by the XMBean. The notification element and its content model is shown in <xref
                              linkend="ch2.xmnot.fig"/>.</para>
                      <figure id="ch2.xmnot.fig">
                          <title>The XMBean notification element and content model</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/xmbean_1_2_notification.jpg"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para>The child elements are:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">description</emphasis>: This element gives a human readable
                                  description of the notification.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">name</emphasis>: This element contains the fully qualified name of
                                  the notification class.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">notification-type</emphasis>: This element contains the
                                  dot-separated notification type string.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">descriptors</emphasis>: Any descriptors to associate with the
                                  notification metadata.</para>
                          </listitem>
                      </itemizedlist>
                      <!--  
                  <para>For a reference of the complete DTD content model see the
                      expanded view of the complete provided in <xref
                      linkend="ch2.xmdtd.fig"/>. We will work through examples of
                      creating an XMBeans when we discuss the JBoss MBean services
                      notion. See <xref linkend="ch2.xmbeanexamples.sect"/> for
                  these examples.</para>
       
                  <figure id="ch2.xmdtd.fig">
                      <title>An expanded view of the jboss_xmbean_1_0 DTD</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/xmbean_1_2_full.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  -->
                  </section>
              </section>
          </section>
          <section id="ch2.jmxinvoke">
              <title>Connecting to the JMX Server</title>
              <para>JBoss includes adaptors that allow access to the JMX MBeanServer from outside of the JBoss server VM.
                  The current adaptors include HTML, an RMI interface, and an EJB.</para>
              <section id="ch2.console.sect">
                  <title>Inspecting the Server - the JMX Console Web Application</title>
                  <para>JBoss comes with its own implementation of a JMX HTML adaptor that allows one to view the server's
                      MBeans using a standard web browser. The default URL for the console web application is <ulink
                          url="http://localhost:8080/jmx-console/"/>. If you browse this location you will see something
                      similar to that presented in <xref linkend="ch2.console1.fig"/>.</para>
                  <figure id="ch2.console1.fig">
                      <title>The JBoss JMX console web application agent view</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/console-index.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The top view is called the agent view and it provides a listing of all MBeans registered with the
                          <literal>MBeanServer</literal> sorted by the domain portion of the MBean's
                      <literal>ObjectName</literal>. Under each domain are the MBeans under that domain. When you select
                      one of the MBeans you will be taken to the MBean view. This allows one to view and edit an MBean's
                      attributes as well as invoke operations. As an example, <xref linkend="ch2.console2.fig"/> shows the
                      MBean view for the <literal>jboss.system:type=Server</literal> MBean.</para>
                  <figure id="ch2.console2.fig">
                      <title>The MBean view for the "jboss.system:type=Server" MBean</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/console-system.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The source code for the JMX console web application is located in the <literal>varia</literal>
                      module under the <literal>src/main/org/jboss/jmx</literal> directory. Its web pages are located
                      under <literal>varia/src/resources/jmx</literal>. The application is a simple MVC servlet with JSP
                      views that utilize the MBeanServer.</para>
                  <section>
                      <title>Securing the JMX Console</title>
                      <para>Since the JMX console web application is just a standard servlet, it may be secured using
                          standard J2EE role based security. The <literal>jmx-console.war</literal> that is deployed as an
                          unpacked WAR that includes template settings for quickly enabling simple username and password
                          based access restrictions. If you look at the <literal>jmx-console.war</literal> in the
                              <literal>server/default/deploy</literal> directory you will find the
                          <literal>web.xml</literal> and <literal>jboss-web.xml</literal> descriptors in the
                              <literal>WEB-INF</literal> directory. The <literal>jmx-console-roles.properties</literal>
                          and <literal>jmx-console-users.properties</literal> files are located in the
                              <literal>server/default/conf/props</literal> directory. </para>
                      <para>By uncommenting the security sections of the <literal>web.xml</literal> and
                              <literal>jboss-web.xml</literal> descriptors as shown in <xref
                              linkend="ch2.secureconsole.ex"/>, you enable HTTP basic authentication that restricts access
                          to the JMX Console application to the user <literal>admin</literal> with password
                          <literal>admin</literal>. The username and password are determined by the <literal>admin=admin
                          </literal>line in the <literal>jmx-console-users.properties</literal> file.</para>
                      <example id="ch2.secureconsole.ex">
                          <title>The jmx-console.war web.xml descriptors with the security elements uncommented.</title>
                          <programlisting>&lt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE web-app PUBLIC
            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
            "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;
  &lt;web-app&gt;
      &lt;!-- ... --&gt;
      
      &lt;!-- A security constraint that restricts access to the HTML JMX console
           to users with the role JBossAdmin. Edit the roles to what you want and
           uncomment the WEB-INF/jboss-web.xml/security-domain element to enable
           secured access to the HTML JMX console.
      --&gt;
      &lt;security-constraint&gt;
          &lt;web-resource-collection&gt;
              &lt;web-resource-name&gt;HtmlAdaptor&lt;/web-resource-name&gt;
              &lt;description&gt; An example security config that only allows users with
                  the role JBossAdmin to access the HTML JMX console web
                  application &lt;/description&gt;
              &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
              &lt;http-method&gt;GET&lt;/http-method&gt;
              &lt;http-method&gt;POST&lt;/http-method&gt;
          &lt;/web-resource-collection&gt;
          &lt;auth-constraint&gt;
              &lt;role-name&gt;JBossAdmin&lt;/role-name&gt;
          &lt;/auth-constraint&gt;
      &lt;/security-constraint&gt;
      &lt;login-config&gt;
          &lt;auth-method&gt;BASIC&lt;/auth-method&gt;
          &lt;realm-name&gt;JBoss JMX Console&lt;/realm-name&gt;
      &lt;/login-config&gt;
      &lt;security-role&gt;
          &lt;role-name&gt;JBossAdmin&lt;/role-name&gt;
      &lt;/security-role&gt;
  &lt;/web-app&gt;
  </programlisting>
                      </example>
                      <example>
                          <title>The jmx-console.war jboss-web.xml descriptors with the security elements uncommented.</title>
                          <programlisting>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE jboss-web
      PUBLIC "-//JBoss//DTD Web Application 2.3//EN"
      "http://www.jboss.org/j2ee/dtd/jboss-web_3_0.dtd"&gt;
  &lt;jboss-web&gt;
      &lt;!-- 
          Uncomment the security-domain to enable security. You will
          need to edit the htmladaptor login configuration to setup the
          login modules used to authentication users.      
      --&gt;
      &lt;security-domain&gt;java:/jaas/jmx-console&lt;/security-domain&gt;
  &lt;/jboss-web&gt;</programlisting>
                      </example>
                      <para>Make these changes and then when you try to access the JMX Console URL. You will see a dialog
                          similar to that shown in <xref linkend="ch2.basicauth.fig"/>.</para>
                      <figure id="ch2.basicauth.fig">
                          <title>The JMX Console basic HTTP login dialog.</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/Chap2-36.jpg"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para>You probably to use the properties files for securing access to the JMX console application.
                          To see how to properly configure the security settings of web applications see <xref
                              linkend="ch8.chapter"/>.</para>
                  </section>
              </section>
              <section>
                  <title>Connecting to JMX Using RMI</title>
                  <para>JBoss supplies an RMI interface for connecting to the JMX MBeanServer. This interface is
                          <literal>org.jboss.jmx.adaptor.rmi.RMIAdaptor</literal>. The <literal>RMIAdaptor</literal>
                      interface is bound into JNDI in the default location of <literal>jmx/invoker/RMIAdaptor</literal> as
                      well as <literal>jmx/rmi/RMIAdaptor</literal> for backwards compatibility with older clients.</para>
                  <para>
                      <xref linkend="ch2.rmiclient.ex"/> shows a client that makes use of the
                      <literal>RMIAdaptor</literal> interface to query the <literal>MBeanInfo</literal> for the
                          <literal>JNDIView</literal> MBean. It also invokes the MBean's <literal>list(boolean)</literal>
                      method and displays the result.</para>
                  <example id="ch2.rmiclient.ex">
                      <title> A JMX client that uses the RMIAdaptor</title>
                      <programlisting>public class JMXBrowser
  {
      /**
       * @param args the command line arguments
       */
      public static void main(String[] args) throws Exception
      {
          InitialContext ic = new InitialContext();
          RMIAdaptor server = (RMIAdaptor) ic.lookup("jmx/invoker/RMIAdaptor");
          
          // Get the MBeanInfo for the JNDIView MBean
          ObjectName name = new ObjectName("jboss:service=JNDIView");
          MBeanInfo  info = server.getMBeanInfo(name);
          System.out.println("JNDIView Class: " + info.getClassName());
  
          MBeanOperationInfo[] opInfo = info.getOperations();
          System.out.println("JNDIView Operations: ");
          for(int o = 0; o &lt; opInfo.length; o ++) {
              MBeanOperationInfo op = opInfo[o];
  
              String returnType = op.getReturnType();
              String opName     = op.getName();
              System.out.print(" + " + returnType + " " + opName + "(");
  
              MBeanParameterInfo[] params = op.getSignature();
              for(int p = 0; p &lt; params.length; p++)  {
                  MBeanParameterInfo paramInfo = params[p];
  
                  String pname = paramInfo.getName();
                  String type  = paramInfo.getType();
  
                  if (pname.equals(type)) {
                      System.out.print(type);
                  } else {
                      System.out.print(type + " " + name);
                  }
  
                  if (p &lt; params.length-1) {
                      System.out.print(','); 
                  }
              }
              System.out.println(")");
          }
          
          // Invoke the list(boolean) op
          String[] sig    = {"boolean"};
          Object[] opArgs = {Boolean.TRUE};
          Object   result = server.invoke(name, "list", opArgs, sig);
  
          System.out.println("JNDIView.list(true) output:\n"+result);
      }
  }</programlisting>
                  </example>
                  <para>To test the client access using the <literal>RMIAdaptor</literal>, run the following:</para>
                  <programlisting>[examples]$ ant -Dchap=chap2 -Dex=4 run-example
  ...
                   
  run-example4:
       [java] JNDIView Class: org.jboss.mx.modelmbean.XMBean
       [java] JNDIView Operations: 
       [java]  + java.lang.String list(boolean jboss:service=JNDIView)
       [java]  + java.lang.String listXML()
       [java]  + void create()
       [java]  + void start()
       [java]  + void stop()
       [java]  + void destroy()
       [java]  + void jbossInternalLifecycle(java.lang.String jboss:service=JNDIView)
       [java]  + java.lang.String getName()
       [java]  + int getState()
       [java]  + java.lang.String getStateString()
       [java] JNDIView.list(true) output:
       [java] &lt;h1&gt;java: Namespace&lt;/h1&gt;
       [java] &lt;pre&gt;
       [java]   +- XAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
       [java]   +- DefaultDS (class: javax.sql.DataSource)
       [java]   +- SecurityProxyFactory (class: org.jboss.security.SubjectSecurityProxyFactory)
       [java]   +- DefaultJMSProvider (class: org.jboss.jms.jndi.JNDIProviderAdapter)
       [java]   +- comp (class: javax.naming.Context)
       [java]   +- JmsXA (class: org.jboss.resource.adapter.jms.JmsConnectionFactoryImpl)
       [java]   +- ConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
       [java]   +- jaas (class: javax.naming.Context)
       [java]   |   +- JmsXARealm (class: org.jboss.security.plugins.SecurityDomainContext)
       [java]   |   +- jbossmq (class: org.jboss.security.plugins.SecurityDomainContext)
       [java]   |   +- HsqlDbRealm (class: org.jboss.security.plugins.SecurityDomainContext)
       [java]   +- timedCacheFactory (class: javax.naming.Context)
       [java] Failed to lookup: timedCacheFactory, errmsg=null
       [java]   +- TransactionPropagationContextExporter (class: org.jboss.tm.TransactionPropag
  ationContextFactory)
       [java]   +- StdJMSPool (class: org.jboss.jms.asf.StdServerSessionPoolFactory)
       [java]   +- Mail (class: javax.mail.Session)
       [java]   +- TransactionPropagationContextImporter (class: org.jboss.tm.TransactionPropag
  ationContextImporter)
       [java]   +- TransactionManager (class: org.jboss.tm.TxManager)
       [java] &lt;/pre&gt;
       [java] &lt;h1&gt;Global JNDI Namespace&lt;/h1&gt;
       [java] &lt;pre&gt;
       [java]   +- XAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
       [java]   +- UIL2ConnectionFactory[link -&gt; ConnectionFactory] (class: javax.naming.Lin
  kRef)
       [java]   +- UserTransactionSessionFactory (proxy: $Proxy11 implements interface org.jbos
  s.tm.usertx.interfaces.UserTransactionSessionFactory)
       [java]   +- HTTPConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
       [java]   +- console (class: org.jnp.interfaces.NamingContext)
       [java]   |   +- PluginManager (proxy: $Proxy36 implements interface org.jboss.console.ma
  nager.PluginManagerMBean)
       [java]   +- UIL2XAConnectionFactory[link -&gt; XAConnectionFactory] (class: javax.naming
  .LinkRef)
       [java]   +- UUIDKeyGeneratorFactory (class: org.jboss.ejb.plugins.keygenerator.uuid.UUID
  KeyGeneratorFactory)
       [java]   +- HTTPXAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
       [java]   +- topic (class: org.jnp.interfaces.NamingContext)
       [java]   |   +- testDurableTopic (class: org.jboss.mq.SpyTopic)
       [java]   |   +- testTopic (class: org.jboss.mq.SpyTopic)
       [java]   |   +- securedTopic (class: org.jboss.mq.SpyTopic)
       [java]   +- queue (class: org.jnp.interfaces.NamingContext)
       [java]   |   +- A (class: org.jboss.mq.SpyQueue)
       [java]   |   +- testQueue (class: org.jboss.mq.SpyQueue)
       [java]   |   +- ex (class: org.jboss.mq.SpyQueue)
       [java]   |   +- DLQ (class: org.jboss.mq.SpyQueue)
       [java]   |   +- D (class: org.jboss.mq.SpyQueue)
       [java]   |   +- C (class: org.jboss.mq.SpyQueue)
       [java]   |   +- B (class: org.jboss.mq.SpyQueue)
       [java]   +- ConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
       [java]   +- UserTransaction (class: org.jboss.tm.usertx.client.ClientUserTransaction)
       [java]   +- jmx (class: org.jnp.interfaces.NamingContext)
       [java]   |   +- invoker (class: org.jnp.interfaces.NamingContext)
       [java]   |   |   +- RMIAdaptor (proxy: $Proxy35 implements interface org.jboss.jmx.adapt
  or.rmi.RMIAdaptor,interface org.jboss.jmx.adaptor.rmi.RMIAdaptorExt)
       [java]   |   +- rmi (class: org.jnp.interfaces.NamingContext)
       [java]   |   |   +- RMIAdaptor[link -&gt; jmx/invoker/RMIAdaptor] (class: javax.naming.L
  inkRef)
       [java]   +- HiLoKeyGeneratorFactory (class: org.jboss.ejb.plugins.keygenerator.hilo.HiLo
  KeyGeneratorFactory)
       [java]   +- UILXAConnectionFactory[link -&gt; XAConnectionFactory] (class: javax.naming.
  LinkRef)
       [java]   +- UILConnectionFactory[link -&gt; ConnectionFactory] (class: javax.naming.Link
  Ref)
       [java] &lt;/pre&gt;</programlisting>
              </section>
              <section>
                  <title>Command Line Access to JMX</title>
                  <para>JBoss provides a simple command line tool that allows for interaction with a remote JMX server
                      instance. This tool is called twiddle (for twiddling bits via JMX) and is located in the
                          <literal>bin</literal> directory of the distribution. Twiddle is a command execution tool, not a
                      general command shell. It is run using either the <literal>twiddle.sh</literal> or
                          <literal>twiddle.bat</literal> scripts, and passing in a
                      <literal>-h</literal>(<literal>--help</literal>) argument provides the basic syntax, and
                          <literal>--help-commands</literal> shows what you can do with the tool:</para>
                  <programlisting>[bin]$ ./twiddle.sh -h
  A JMX client to 'twiddle' with a remote JBoss server.
  
  usage: twiddle.sh [options] &lt;command&gt; [command_arguments]
  
  options:
      -h, --help                Show this help message
          --help-commands       Show a list of commands
      -H=&lt;command&gt;              Show command specific help
      -c=command.properties     Specify the command.properties file to use
      -D&lt;name&gt;[=&lt;value&gt;]        Set a system property
      --                        Stop processing options
      -s, --server=&lt;url&gt;        The JNDI URL of the remote server
      -a, --adapter=&lt;name&gt;      The JNDI name of the RMI adapter to use
      -q, --quiet               Be somewhat more quiet
  </programlisting>
                  <section>
                      <title>Connecting twiddle to a Remote Server</title>
                      <para>By default the twiddle command will connect to the localhost at port 1099 to lookup the
                          default <literal>jmx/rmi/RMIAdaptor</literal> binding of the <literal>RMIAdaptor</literal>
                          service as the connector for communicating with the JMX server. To connect to a different
                          server/port combination you can use the <literal>-s</literal> (<literal>--server</literal>)
                          option:</para>
                      <programlisting>[bin]$ ./twiddle.sh -s toki serverinfo -d jboss
  [bin]$ ./twiddle.sh -s toki:1099 serverinfo -d jboss
  </programlisting>
                      <para>To connect using a different RMIAdaptor binding use the <literal>-a</literal>
                              (--<literal>adapter</literal>) option:</para>
                      <programlisting>[bin]$ ./twiddle.sh -s toki -a jmx/rmi/RMIAdaptor serverinfo -d jboss</programlisting>
                  </section>
                  <section>
                      <title>Sample twiddle Command Usage</title>
                      <para>To access basic information about a server, use the <literal>serverinfo</literal> command.
                          This currently supports:</para>
                      <programlisting>[bin]$ ./twiddle.sh -H serverinfo
  Get information about the MBean server
  
  usage: serverinfo [options]
  
  options:
      -d, --domain    Get the default domain
      -c, --count     Get the MBean count
      -l, --list      List the MBeans
      --              Stop processing options
  [bin]$ ./twiddle.sh --server=toki serverinfo --count
  460
  [bin]$ ./twiddle.sh --server=toki serverinfo --domain
  jboss
  </programlisting>
                      <para>To query the server for the name of MBeans matching a pattern, use the
                          <literal>query</literal> command. This currently supports:</para>
                      <programlisting>[bin]$ ./twiddle.sh -H query
  Query the server for a list of matching MBeans
   
  usage: query [options] &lt;query&gt;
  options:
      -c, --count    Display the matching MBean count
      --             Stop processing options
  Examples:
   query all mbeans: query '*:*'
   query all mbeans in the jboss.j2ee domain: query 'jboss.j2ee:*'
  [bin]$ ./twiddle.sh -s toki query 'jboss:service=invoker,*'
  jboss:readonly=true,service=invoker,target=Naming,type=http
  jboss:service=invoker,type=jrmp
  jboss:service=invoker,type=local
  jboss:service=invoker,type=pooled
  jboss:service=invoker,type=http
  jboss:service=invoker,target=Naming,type=http</programlisting>
                      <para>To get the attributes of an MBean, use the get command:</para>
                      <programlisting>[bin]$ ./twiddle.sh -H get
  Get the values of one or more MBean attributes
   
  usage: get [options] &lt;name&gt; [&lt;attr&gt;+]
    If no attribute names are given all readable attributes are retrieved
  options:
      --noprefix    Do not display attribute name prefixes
      --            Stop processing options
  [bin]$ ./twiddle.sh get jboss:service=invoker,type=jrmp RMIObjectPort StateString
  RMIObjectPort=4444
  StateString=Started
  [bin]$ ./twiddle.sh get jboss:service=invoker,type=jrmp
  ServerAddress=0.0.0.0
  RMIClientSocketFactoryBean=null
  StateString=Started
  State=3
  RMIServerSocketFactoryBean=org.jboss.net.sockets.DefaultSocketFactory at ad093076
  EnableClassCaching=false
  SecurityDomain=null
  RMIServerSocketFactory=null
  Backlog=200
  RMIObjectPort=4444
  Name=JRMPInvoker
  RMIClientSocketFactory=null</programlisting>
                      <para>To query the MBeanInfo for an MBean, use the info command:</para>
                      <programlisting>[bin]$ ./twiddle.sh -H info
  Get the metadata for an MBean
   
  usage: info &lt;mbean-name&gt;
    Use '*' to query for all attributes
  [bin]$ Description: Management Bean.
  +++ Attributes:
   Name: ServerAddress
   Type: java.lang.String
   Access: rw
   Name: RMIClientSocketFactoryBean
   Type: java.rmi.server.RMIClientSocketFactory
   Access: rw
   Name: StateString
   Type: java.lang.String
   Access: r-
   Name: State
   Type: int
   Access: r-
   Name: RMIServerSocketFactoryBean
   Type: java.rmi.server.RMIServerSocketFactory
   Access: rw
   Name: EnableClassCaching
   Type: boolean
   Access: rw
   Name: SecurityDomain
   Type: java.lang.String
   Access: rw
   Name: RMIServerSocketFactory
   Type: java.lang.String
   Access: rw
   Name: Backlog
   Type: int
   Access: rw
   Name: RMIObjectPort
   Type: int
   Access: rw
   Name: Name
   Type: java.lang.String
   Access: r-
   Name: RMIClientSocketFactory
   Type: java.lang.String
   Access: rw
  +++ Operations:
   void start()
   void jbossInternalLifecycle(java.lang.String java.lang.String)
   void create()
   void stop()
   void destroy()</programlisting>
                      <para>To invoke an operation on an MBean, use the invoker command:</para>
                      <programlisting>[bin]$ ./twiddle.sh -H invoke
  Invoke an operation on an MBean
   
  usage: invoke [options] &lt;query&gt; &lt;operation&gt; (&lt;arg&gt;)*
  
  options:
      -q, --query-type[=&lt;type&gt;]    Treat object name as a query
      --                           Stop processing options
  
  query type:
      f[irst]    Only invoke on the first matching name [default]
      a[ll]      Invoke on all matching names
  [bin]$ ./twiddle.sh invoke jboss:service=JNDIView list true
  &lt;h1&gt;java: Namespace&lt;/h1&gt;
  &lt;pre&gt;
    +- XAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
    +- DefaultDS (class: javax.sql.DataSource)
    +- SecurityProxyFactory (class: org.jboss.security.SubjectSecurityProxyFactory)
    +- DefaultJMSProvider (class: org.jboss.jms.jndi.JNDIProviderAdapter)
    +- comp (class: javax.naming.Context)
    +- JmsXA (class: org.jboss.resource.adapter.jms.JmsConnectionFactoryImpl)
    +- ConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
    +- jaas (class: javax.naming.Context)
    |   +- JmsXARealm (class: org.jboss.security.plugins.SecurityDomainContext)
    |   +- jbossmq (class: org.jboss.security.plugins.SecurityDomainContext)
    |   +- HsqlDbRealm (class: org.jboss.security.plugins.SecurityDomainContext)
    +- timedCacheFactory (class: javax.naming.Context)
  Failed to lookup: timedCacheFactory, errmsg=null
    +- TransactionPropagationContextExporter (class: org.jboss.tm.TransactionPropagationContext
  Factory)
    +- StdJMSPool (class: org.jboss.jms.asf.StdServerSessionPoolFactory)
    +- Mail (class: javax.mail.Session)
    +- TransactionPropagationContextImporter (class: org.jboss.tm.TransactionPropagationContext
  Importer)
    +- TransactionManager (class: org.jboss.tm.TxManager)
  &lt;/pre&gt;
  &lt;h1&gt;Global JNDI Namespace&lt;/h1&gt;
  &lt;pre&gt;
    +- XAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
    +- UIL2ConnectionFactory[link -&gt; ConnectionFactory] (class: javax.naming.LinkRef)
    +- UserTransactionSessionFactory (proxy: $Proxy11 implements interface org.jboss.tm.usertx.
  interfaces.UserTransactionSessionFactory)
    +- HTTPConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
    +- console (class: org.jnp.interfaces.NamingContext)
    |   +- PluginManager (proxy: $Proxy36 implements interface org.jboss.console.manager.Plugin
  ManagerMBean)
    +- UIL2XAConnectionFactory[link -&gt; XAConnectionFactory] (class: javax.naming.LinkRef)
    +- UUIDKeyGeneratorFactory (class: org.jboss.ejb.plugins.keygenerator.uuid.UUIDKeyGenerator
  Factory)
    +- HTTPXAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
    +- topic (class: org.jnp.interfaces.NamingContext)
    |   +- testDurableTopic (class: org.jboss.mq.SpyTopic)
    |   +- testTopic (class: org.jboss.mq.SpyTopic)
    |   +- securedTopic (class: org.jboss.mq.SpyTopic)
    +- queue (class: org.jnp.interfaces.NamingContext)
    |   +- A (class: org.jboss.mq.SpyQueue)
    |   +- testQueue (class: org.jboss.mq.SpyQueue)
    |   +- ex (class: org.jboss.mq.SpyQueue)
    |   +- DLQ (class: org.jboss.mq.SpyQueue)
    |   +- D (class: org.jboss.mq.SpyQueue)
    |   +- C (class: org.jboss.mq.SpyQueue)
    |   +- B (class: org.jboss.mq.SpyQueue)
    +- ConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
    +- UserTransaction (class: org.jboss.tm.usertx.client.ClientUserTransaction)
    +- jmx (class: org.jnp.interfaces.NamingContext)
    |   +- invoker (class: org.jnp.interfaces.NamingContext)
    |   |   +- RMIAdaptor (proxy: $Proxy35 implements interface org.jboss.jmx.adaptor.rmi.RMIAd
  aptor,interface org.jboss.jmx.adaptor.rmi.RMIAdaptorExt)
    |   +- rmi (class: org.jnp.interfaces.NamingContext)
    |   |   +- RMIAdaptor[link -&gt; jmx/invoker/RMIAdaptor] (class: javax.naming.LinkRef)
    +- HiLoKeyGeneratorFactory (class: org.jboss.ejb.plugins.keygenerator.hilo.HiLoKeyGenerator
  Factory)
    +- UILXAConnectionFactory[link -&gt; XAConnectionFactory] (class: javax.naming.LinkRef)
    +- UILConnectionFactory[link -&gt; ConnectionFactory] (class: javax.naming.LinkRef)
  &lt;/pre&gt;</programlisting>
                  </section>
              </section>
              <section id="ch2.jmxany.sect">
                  <title>Connecting to JMX Using Any Protocol</title>
                  <para>With the detached invokers and a somewhat generalized proxy factory capability, you can really
                      talk to the JMX server using the <literal>InvokerAdaptorService</literal> and a proxy factory
                      service to expose an <literal>RMIAdaptor</literal> or similar interface over your protocol of
                      choice. We will introduce the detached invoker notion along with proxy factories in <xref
                          linkend="ch2.remoteaccess"/>. See <xref linkend="ch2.detinv.sect"/> for an example of an invoker
                      service that allows one to access the MBean server using to the <literal>RMIAdaptor</literal>
                      interface over any protocol for which a proxy factory service exists.</para>
              </section>
          </section>
          <section id="ch2.microkernel">
              <title>Using JMX as a Microkernel</title>
              <para>When JBoss starts up, one of the first steps performed is to create an MBean server instance
                      (<literal>javax.management.MBeanServer</literal>). The JMX MBean server in the JBoss architecture
                  plays the role of a microkernel. All other manageable MBean components are plugged into JBoss by
                  registering with the MBean server. The kernel in that sense is only an framework, and not a source of
                  actual functionality. The functionality is provided by MBeans, and in fact all major JBoss components
                  are manageable MBeans interconnected through the MBean server.</para>
              <section>
                  <title>The Startup Process</title>
                  <para>In this section we will describe the JBoss server startup process. A summary of the steps that
                      occur during the JBoss server startup sequence is:</para>
                  <orderedlist>
                      <listitem>
                          <para>The run start script initiates the boot sequence using the
                                  <literal>org.jboss.Main.main(String[])</literal> method entry point.</para>
                      </listitem>
                      <listitem>
                          <para>The <literal>Main.main</literal> method creates a thread group named
                              <literal>jboss</literal> and then starts a thread belonging to this thread group. This
                              thread invokes the Main.boot method.</para>
                      </listitem>
                      <listitem>
                          <para>The <literal>Main.boot</literal> method processes the <literal>Main.main</literal>
                              arguments and then creates an <literal>org.jboss.system.server.ServerLoader</literal> using
                              the system properties along with any additional properties specified as arguments.</para>
                      </listitem>
                      <listitem>
                          <para>The XML parser libraries, <literal>jboss-jmx.jar</literal>,
                              <literal>concurrent.jar</literal> and extra libraries and classpaths given as arguments are
                              registered with the <literal>ServerLoader</literal> .</para>
                      </listitem>
                      <listitem>
                          <para>The JBoss server instance is created using the
                              <literal>ServerLoader.load(ClassLoader)</literal> method with the current thread context
                              class loader passed in as the <literal>ClassLoader</literal> argument. The returned server
                              instance is an implementation of the <literal>org.jboss.system.server.Server</literal>
                              interface. The creation of the server instance entails:</para>
                          <itemizedlist>
                              <listitem>
                                  <para> Creating a <literal>java.net.URLClassLoader</literal> with the URLs of the jars
                                      and directories registered with the <literal>ServerLoader</literal> . This
                                          <literal>URLClassLoader</literal> uses the <literal>ClassLoader</literal> passed
                                      in as its parent and it is pushed as the thread context class loader.</para>
                              </listitem>
                              <listitem>
                                  <para>The class name of the implementation of the <literal>Server</literal> interface to
                                      use is determined by the <literal>jboss.server.type</literal> property. This
                                      defaults to <literal>org.jboss.system.server.ServerImpl</literal>.</para>
                              </listitem>
                              <listitem>
                                  <para>The <literal>Server</literal> implementation class is loaded using the
                                          <literal>URLClassLoader</literal> created in step 6 and instantiated using its
                                      no-arg constructor. The thread context class loader present on entry into the
                                          <literal>ServerLoader.load</literal> method is restored and the server instance
                                      is returned.</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                      <listitem>
                          <para>The server instance is initialized with the properties passed to the
                              <literal>ServerLoader</literal> constructor using the
                              <literal>Server.init(Properties)</literal> method.</para>
                      </listitem>
                      <listitem>
                          <para>The server instance is then started using the <literal>Server.start()</literal> method.
                              The default implementation performs the following steps:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>Set the thread context class loader to the class loader used to load the
                                          <literal>ServerImpl</literal> class.</para>
                              </listitem>
                              <listitem>
                                  <para>Create an <literal>MBeanServer</literal> under the <literal>jboss</literal> domain
                                      using the <literal>MBeanServerFactory.createMBeanServer(String)</literal>
                                  method.</para>
                              </listitem>
                              <listitem>
                                  <para>Register the <literal>ServerImpl</literal> and <literal>ServerConfigImpl</literal>
                                      MBeans with the MBean server.</para>
                              </listitem>
                              <listitem>
                                  <para>Initialize the unified class loader repository to contain all JARs in the optional
                                      patch directory as well as the server configuration file conf directory, for
                                      example, <literal>server/default/conf</literal>. For each JAR and directory an
                                          <literal>org.jboss.mx.loading.UnifiedClassLoader</literal> is created and
                                      registered with the unified repository. One of these
                                      <literal>UnifiedClassLoader</literal> is then set as the thread context class
                                      loader. This effectively makes all <literal>UnifiedClassLoader</literal>s available
                                      through the thread context class loader.</para>
                              </listitem>
                              <listitem>
                                  <para>The <literal>org.jboss.system.ServiceController</literal> MBean is created. The
                                          <literal>ServiceController</literal> manages the JBoss MBean services life
                                      cycle. We will discuss the JBoss MBean services notion in detail in <xref
                                          linkend="ch2.mbeanservice.sect"/>.</para>
                              </listitem>
                              <listitem>
                                  <para>The <literal>org.jboss.deployment.MainDeployer</literal> is created and started.
                                      The <literal>MainDeployer</literal> manages deployment dependencies and directing
                                      deployments to the correct deployer.</para>
                              </listitem>
                              <listitem>
                                  <para>The <literal>org.jboss.deployment.JARDeployer</literal> is created and started.
                                      The <literal>JARDeployer</literal> handles the deployment of JARs that are simple
                                      library JARs.</para>
                              </listitem>
                              <listitem>
                                  <para>The <literal>org.jboss.deployment.SARDeployer</literal> is created and started.
                                      The SARDeployer handles the deployment of JBoss MBean services.</para>
                              </listitem>
                              <listitem>
                                  <para>The <literal>MainDeployer</literal> is invoked to deploy the services defined in
                                      the <literal>conf/jboss-service.xml</literal> of the current server file set.</para>
                              </listitem>
                              <listitem>
                                  <para>Restore the thread context class loader.</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                  </orderedlist>
                  <para>The JBoss server starts out as nothing more than a container for the JMX MBean server, and then
                      loads its personality based on the services defined in the <literal>jboss-service.xml</literal>
                      MBean configuration file from the named configuration set passed to the server on the command line.
                      Because MBeans define the functionality of a JBoss server instance, it is important to understand
                      how the core JBoss MBeans are written, and how you should integrate your existing services into
                      JBoss using MBeans. This is the topic of the next section.</para>
              </section>
              <section id="ch2.mbeanservice.sect">
                  <title>JBoss MBean Services</title>
                  <para>As we have seen, JBoss relies on JMX to load in the MBean services that make up a given server
                      instance's personality. All of the bundled functionality provided with the standard JBoss
                      distribution is based on MBeans. The best way to add services to the JBoss server is to write your
                      own JMX MBeans.</para>
                  <para>There are two classes of MBeans: those that are independent of JBoss services, and those that are
                      dependent on JBoss services. MBeans that are independent of JBoss services are the trivial case.
                      They can be written per the JMX specification and added to a JBoss server by adding an mbean tag to
                      the <literal>deploy/user-service.xml</literal> file. Writing an MBean that relies on a JBoss service
                      such as naming requires you to follow the JBoss service pattern. The JBoss MBean service pattern
                      consists of a set of life cycle operations that provide state change notifications. The
                      notifications inform an MBean service when it can create, start, stop, and destroy itself. The
                      management of the MBean service life cycle is the responsibility of three JBoss MBeans:
                          <literal>SARDeployer</literal>, <literal>ServiceConfigurator</literal> and
                          <literal>ServiceController</literal>.</para>
                  <section>
                      <title>The SARDeployer MBean</title>
                      <para>JBoss manages the deployment of its MBean services via a custom MBean that loads an XML
                          variation of the standard JMX MLet configuration file. This custom MBean is implemented in the
                              <literal>org.jboss.deployment.SARDeployer</literal> class. The
                          <literal>SARDeployer</literal> MBean is loaded when JBoss starts up as part of the bootstrap
                          process. The SAR acronym stands for <emphasis>service archive</emphasis>.</para>
                      <para>The <literal>SARDeployer</literal> handles services archives. A service archive can be either
                          a jar that ends with a <literal>.sar</literal> suffix and contains a
                              <literal>META-INF/jboss-service.xml</literal> descriptor, or a standalone XML descriptor
                          with a naming pattern that matches <literal>*-service.xml</literal>. The DTD for the service
                          descriptor is <literal>jboss-service_4.0.dtd</literal> and is shown in <xref
                              linkend="ch2.sardtd.fig"/>.</para>
                      <figure id="ch2.sardtd.fig">
                          <title>The DTD for the MBean service descriptor parsed by the SARDeployer</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/jboss-service_4.0.jpg"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para>The elements of the DTD are:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">loader-repository</emphasis>: This element specifies the name of
                                  the <literal>UnifiedLoaderRepository</literal> MBean to use for the SAR to provide SAR
                                  level scoping of classes deployed in the sar. It is a unique JMX
                                  <literal>ObjectName</literal> string. It may also specify an arbitrary configuration by
                                  including a <literal>loader-repository-config</literal> element. The optional
                                      <literal>loaderRepositoryClass</literal> attribute specifies the fully qualified
                                  name of the loader repository implementation class. It defaults to
                                      <literal>org.jboss.mx.loading.HeirachicalLoaderRepository3</literal>.</para>
                              <itemizedlist>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">loader-repository-config</emphasis>: This optional element
                                          specifies an arbitrary configuration that may be used to configure the
                                              <literal>loadRepositoryClass</literal>. The optional
                                              <literal>configParserClass</literal> attribute gives the fully qualified
                                          name of the
                                              <literal>org.jboss.mx.loading.LoaderRepositoryFactory.LoaderRepositoryConfigParser</literal>
                                          implementation to use to parse the <literal>loader-repository-config</literal>
                                          content.</para>
                                  </listitem>
                              </itemizedlist>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">local-directory</emphasis>: This element specifies a path within
                                  the deployment archive that should be copied to the
                                      <literal>server/&lt;config&gt;/db</literal> directory for use by the MBean.
                                  The path attribute is the name of an entry within the deployment archive.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">classpath</emphasis>: This element specifies one or more external
                                  JARs that should be deployed with the MBean(s). The optional archives attribute
                                  specifies a comma separated list of the JAR names to load, or the <literal>*</literal>
                                  wild card to signify that all jars should be loaded. The wild card only works with file
                                  URLs, and http URLs if the web server supports the WEBDAV protocol. The codebase
                                  attribute specifies the URL from which the JARs specified in the archive attribute
                                  should be loaded. If the codebase is a path rather than a URL string, the full URL is
                                  built by treating the codebase value as a path relative to the JBoss distribution
                                      <literal>server/&lt;config&gt;</literal> directory. The order of JARs
                                  specified in the archives as well as the ordering across multiple classpath element is
                                  used as the classpath ordering of the JARs. Therefore, if you have patches or
                                  inconsistent versions of classes that require a certain ordering, use this feature to
                                  ensure the correct ordering. </para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">mbean</emphasis>: This element specifies an MBean service. The
                                  required code attribute gives the fully qualified name of the MBean implementation
                                  class. The required name attribute gives the JMX <literal>ObjectName</literal> of the
                                  MBean. The optional <literal>xmbean-dd</literal> attribute specifies the path to the
                                  XMBean resource if this MBean service uses the JBoss XMBean descriptor to define a Model
                                  MBean management interface.</para>
                              <itemizedlist>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">constructor</emphasis>: The <literal>constructor</literal>
                                          element defines a non-default constructor to use when instantiating the MBean
                                          The <literal>arg</literal> element specify the constructor arguments in the
                                          order of the constructor signature. Each <literal>arg</literal> has a
                                              <literal>type</literal> and <literal>value</literal> attribute. </para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">attribute</emphasis>: Each attribute element specifies a
                                          name/value pair of the attribute of the MBean. The name of the attribute is
                                          given by the name attribute, and the attribute element body gives the value. The
                                          body may be a text representation of the value, or an arbitrary element and
                                          child elements if the type of the MBean attribute is
                                              <literal>org.w3c.dom.Element</literal>. For text values, the text is
                                          converted to the attribute type using the JavaBean
                                              <literal>java.beans.PropertyEditor</literal> mechanism.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">server/mbean/depends</emphasis> and <emphasis role="bold"
                                              >server/mbean/depends-list</emphasis>: these elements specify a dependency
                                          from the MBean using the element to the MBean(s) named by the
                                          <literal>depends</literal> or <literal>depends-list</literal> elements. <xref
                                              linkend="ch2.servicedep.fig"/>. Note that the dependency value can be
                                          another mbean element which defines a nested mbean.</para>
                                  </listitem>
                              </itemizedlist>
                          </listitem>
                      </itemizedlist>
                      <para> MBean attribute values don't need to be hardcoded literal strings. Service files may contain
                          references to system properties using the <literal>${name}</literal> notation, where
                              <literal>name</literal> is the name of a Java system property. The value of this system
                          property, as would be returned from the call <literal>System.getProperty("name")</literal>.
                          Multiple properties can be specified separated by commas like
                          <literal>${name1,name2,name3}</literal>. If there is no system property named
                          <literal>name1</literal>, <literal>name2</literal> will be tried and then
                          <literal>name3</literal>. This allows multiple levels of substitution to be used. Finally, a
                          default value can be added using a colon separator. The substitution <literal>${name:default
                              value}</literal> would substitute the the text "<literal>default value</literal>" if the
                          system property <literal>name</literal> didn't exist. If none of the listed properties exist and
                          no default value is given, no substitution will occur. </para>
                      <para>When the <literal>SARDeployer</literal> is asked to deploy a service performs several steps.
                              <xref linkend="ch2.sardepstart.fig"/> is a sequence diagram that shows the init through
                          start phases of a service.</para>
                      <figure id="ch2.sardepstart.fig">
                          <title>A sequence diagram highlighting the main activities performed by the SARDeployer to start
                              a JBoss MBean service</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/Chap2-38.gif"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para> In <xref linkend="ch2.sardepstart.fig"/> the following is illustrated: </para>
                      <itemizedlist>
                          <listitem>
                              <para>Methods prefixed with 1.1 correspond to the load and parse of the XML service
                                  descriptor.</para>
                          </listitem>
                          <listitem>
                              <para>Methods prefixed with 1.2 correspond to processing each classpath element in the
                                  service descriptor to create an independent deployment that makes the jar or directory
                                  available through a <literal>UnifiedClassLoader</literal> registered with the unified
                                  loader repository.</para>
                          </listitem>
                          <listitem>
                              <para>Methods prefixed with 1.3 correspond to processing each
                                  <literal>local-directory</literal> element in the service descriptor. This does a copy
                                  of the SAR elements specified in the path attribute to the
                                      <literal>server/&lt;config&gt;/db</literal> directory.</para>
                          </listitem>
                          <listitem>
                              <para>Method 1.4. Process each deployable unit nested in the service a child deployment is
                                  created and added to the service deployment info subdeployment list.</para>
                          </listitem>
                          <listitem>
                              <para>Method 2.1. The <literal>UnifiedClassLoader</literal> of the SAR deployment unit is
                                  registered with the MBean Server so that is can be used for loading of the SAR
                              MBeans.</para>
                          </listitem>
                          <listitem>
                              <para>Method 2.2. For each MBean element in the descriptor, create an instance and
                                  initialize its attributes with the values given in the service descriptor. This is done
                                  by calling the <literal>ServiceController.install</literal> method.</para>
                          </listitem>
                          <listitem>
                              <para>Method 2.4.1. For each MBean instance created, obtain its JMX
                                  <literal>ObjectName</literal> and ask the ServiceController to handle the create step of
                                  the service life cycle. The <literal>ServiceController</literal> handles the
                                  dependencies of the MBean service. Only if the service's dependencies are satisfied is
                                  the service create method invoked.</para>
                          </listitem>
                          <listitem>
                              <para>Methods prefixed with 3.1 correspond to the start of each MBean service defined in the
                                  service descriptor. For each MBean instance created, obtain its JMX ObjectName and ask
                                  the <literal>ServiceController</literal> to handle the start step of the service life
                                  cycle. The <literal>ServiceController</literal> handles the dependencies of the MBean
                                  service. Only if the service's dependencies are satisfied is the service start method
                                  invoked.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>The Service Life Cycle Interface</title>
                      <para>The JMX specification does not define any type of life cycle or dependency management for
                          MBeans. The JBoss ServiceController MBean introduces this notion. A JBoss MBean is an extension
                          of the JMX MBean in that an MBean is expected to decouple creation from the life cycle of its
                          service duties. This is necessary to implement any type of dependency management. For example,
                          if you are writing an MBean that needs a JNDI naming service to be able to function, your MBean
                          needs to be told when its dependencies are satisfied. This ranges from difficult to impossible
                          to do if the only life cycle event is the MBean constructor. Therefore, JBoss introduces a
                          service life cycle interface that describes the events a service can use to manage its behavior.
                          The following listing shows the <literal>org.jboss.system.Service</literal> interface:</para>
                      <programlisting>package org.jboss.system;
  public interface Service
  {
      public void create() throws Exception;
      public void start() throws Exception;
      public void stop();
      public void destroy();
  }</programlisting>
                      <para>The <literal>ServiceController</literal> MBean invokes the methods of the
                          <literal>Service</literal> interface at the appropriate times of the service life cycle. We'll
                          discuss the methods in more detail in the <literal>ServiceController</literal> section.</para>
                  </section>
                  <section>
                      <title>The ServiceController MBean</title>
                      <para>JBoss manages dependencies between MBeans via the
                          <literal>org.jboss.system.ServiceController</literal> custom MBean. The SARDeployer delegates to
                          the ServiceController when initializing, creating, starting, stopping and destroying MBean
                          services. <xref linkend="ch2.servicecontroller.fig"/> shows a sequence diagram that highlights
                          interaction between the <literal>SARDeployer</literal> and <literal>ServiceController</literal>.</para>
                      <figure id="ch2.servicecontroller.fig">
                          <title>The interaction between the SARDeployer and ServiceController to start a service</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/Chap2-39.gif"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para>The <literal>ServiceController</literal> MBean has four key methods for the management of the
                          service life cycle: <literal>create</literal>, <literal>start</literal>, <literal>stop</literal>
                          and <literal>destroy</literal>.</para>
                      <section>
                          <title>The create(ObjectName) method</title>
                          <para>The <literal>create(ObjectName)</literal> method is called whenever an event occurs that
                              affects the named services state. This could be triggered by an explicit invocation by the
                                  <literal>SARDeployer</literal>, a notification of a new class, or another service
                              reaching its created state.</para>
                          <para>When a service's <literal>create</literal> method is called, all services on which the
                              service depends have also had their create method invoked. This gives an MBean an
                              opportunity to check that required MBeans or resources exist. A service cannot utilize other
                              MBean services at this point, as most JBoss MBean services do not become fully functional
                              until they have been started via their <literal>start</literal> method. Because of this,
                              service implementations often do not implement <literal>create</literal> in favor of just
                              the <literal>start</literal> method because that is the first point at which the service can
                              be fully functional.</para>
                      </section>
                      <section>
                          <title>The start(ObjectName) method</title>
                          <para>The <literal>start(ObjectName)</literal> method is called whenever an event occurs that
                              affects the named services state. This could be triggered by an explicit invocation by the
                                  <literal>SARDeployer</literal>, a notification of a new class, or another service
                              reaching its started state.</para>
                          <para>When a service's <literal>start</literal> method is called, all services on which the
                              service depends have also had their <literal>start</literal> method invoked. Receipt of a
                                  <literal>start</literal> method invocation signals a service to become fully operational
                              since all services upon which the service depends have been created and started.</para>
                      </section>
                      <section>
                          <title>The stop(ObjectName) method</title>
                          <para>The <literal>stop(ObjectName)</literal> method is called whenever an event occurs that
                              affects the named services state. This could be triggered by an explicit invocation by the
                                  <literal>SARDeployer</literal>, notification of a class removal, or a service on which
                              other services depend reaching its stopped state.</para>
                      </section>
                      <section>
                          <title>The destroy(ObjectName) method</title>
                          <para>The <literal>destroy(ObjectName)</literal> method is called whenever an event occurs that
                              affects the named services state. This could be triggered by an explicit invocation by the
                                  <literal>SARDeployer</literal>, notification of a class removal, or a service on which
                              other services depend reaching its destroyed state.</para>
                          <para>Service implementations often do not implement <literal>destroy</literal> in favor of
                              simply implementing the <literal>stop</literal> method, or neither <literal>stop</literal>
                              nor <literal>destroy</literal> if the service has no state or resources that need
                          cleanup.</para>
                      </section>
                  </section>
                  <section id="ch2.servicedep.fig">
                      <title>Specifying Service Dependencies</title>
                      <para>To specify that an MBean service depends on other MBean services you need to declare the
                          dependencies in the mbean element of the service descriptor. This is done using the
                              <literal>depends</literal> and <literal>depends-list</literal> elements. One difference
                          between the two elements relates to the <literal>optional-attribute-name</literal> attribute
                          usage. If you track the <literal>ObjectName</literal>s of dependencies using single valued
                          attributes you should use the depends element. If you track the <literal>ObjectName</literal>s
                          of dependencies using <literal>java.util.List</literal> compatible attributes you would use the
                              <literal>depends-list</literal> element. If you only want to specify a dependency and don't
                          care to have the associated service <literal>ObjectName</literal> bound to an attribute of your
                          MBean then use whatever element is easiest. The following listing shows example service
                          descriptor fragments that illustrate the usage of the dependency related elements.</para>
                      <programlisting>&lt;mbean code="org.jboss.mq.server.jmx.Topic"
         name="jms.topic:service=Topic,name=testTopic"&gt;
      &lt;!-- Declare a dependency on the "jboss.mq:service=DestinationManager" and
           bind this name to the DestinationManager attribute --&gt;
      &lt;depends optional-attribute-name="DestinationManager"&gt;
          jboss.mq:service=DestinationManager 
      &lt;/depends&gt;
  
      &lt;!-- Declare a dependency on the "jboss.mq:service=SecurityManager" and
           bind this name to the SecurityManager attribute --&gt;
      &lt;depends optional-attribute-name="SecurityManager"&gt;
          jboss.mq:service=SecurityManager
      &lt;/depends&gt;
  
      &lt;!-- ... --&gt;
  
      &lt;!-- Declare a dependency on the
           "jboss.mq:service=CacheManager" without
           any binding of the name to an attribute--&gt;
      &lt;depends&gt;jboss.mq:service=CacheManager&lt;/depends&gt;
  &lt;/mbean&gt;
  
  &lt;mbean code="org.jboss.mq.server.jmx.TopicMgr" 
         name="jboss.mq.destination:service=TopicMgr"&gt;
      &lt;!-- Declare a dependency on the given topic destination mbeans and
           bind these names to the Topics attribute --&gt;
      &lt;depends-list optional-attribute-name="Topics"&gt;
          &lt;depends-list-element&gt;jms.topic:service=Topic,name=A&lt;/depends-list-element&gt;
          &lt;depends-list-element&gt;jms.topic:service=Topic,name=B&lt;/depends-list-element&gt;
          &lt;depends-list-element&gt;jms.topic:service=Topic,name=C&lt;/depends-list-element&gt;
      &lt;/depends-list&gt;
  &lt;/mbean&gt;
  </programlisting>
                      <para>Another difference between the <literal>depends</literal> and <literal>depends-list</literal>
                          elements is that the value of the depends element may be a complete MBean service configuration
                          rather than just the <literal>ObjectName</literal> of the service. <xref
                              linkend="ch2.dependon.ex"/> shows an example from the <literal>hsqldb-service.xml</literal>
                          descriptor. In this listing the
                          <literal>org.jboss.resource.connectionmanager.RARDeployment</literal> service configuration is
                          defined using a nested <literal>mbean</literal> element as the <literal>depends</literal>
                          element value. This indicates that the
                              <literal>org.jboss.resource.connectionmanager.LocalTxConnectionManager</literal> MBean
                          depends on this service. The <literal>jboss.jca:service=LocalTxDS,name=hsqldbDS</literal>
                          <literal>ObjectName</literal> will be bound to the
                          <literal>ManagedConnectionFactoryName</literal> attribute of the
                              <literal>LocalTxConnectionManager</literal> class.</para>
                      <example id="ch2.dependon.ex">
                          <title>An example of using the depends element to specify the complete configuration of a
                              depended on service.</title>
                          <programlisting>&lt;mbean code="org.jboss.resource.connectionmanager.LocalTxConnectionManager" 
         name="jboss.jca:service=LocalTxCM,name=hsqldbDS"&gt;
      &lt;depends optional-attribute-name="ManagedConnectionFactoryName"&gt;
          &lt;!--embedded mbean--&gt;
          &lt;mbean code="org.jboss.resource.connectionmanager.RARDeployment" 
                 name="jboss.jca:service=LocalTxDS,name=hsqldbDS"&gt;
              &lt;attribute name="JndiName"&gt;DefaultDS&lt;/attribute&gt;
              &lt;attribute name="ManagedConnectionFactoryProperties"&gt;
                  &lt;properties&gt;
                      &lt;config-property name="ConnectionURL"
                                       type="java.lang.String"&gt;    
                          jdbc:hsqldb:hsql://localhost:1476
                      &lt;/config-property&gt;
                      &lt;config-property name="DriverClass" type="java.lang.String"&gt;
                          org.hsqldb.jdbcDriver
                      &lt;/config-property&gt;
                      &lt;config-property name="UserName" type="java.lang.String"&gt;
                          sa
                      &lt;/config-property&gt;
                      &lt;config-property name="Password" type="java.lang.String"/&gt;
                  &lt;/properties&gt;
              &lt;/attribute&gt;
              &lt;!-- ... --&gt;
          &lt;/mbean&gt;
      &lt;/depends&gt;
      &lt;!-- ... --&gt;
  &lt;/mbean&gt;</programlisting>
                      </example>
                  </section>
                  <section>
                      <title>Identifying Unsatisfied Dependencies</title>
                      <para>The <literal>ServiceController</literal> MBean supports two operations that can help determine
                          which MBeans are not running due to unsatisfied dependencies. The first operation is
                              <literal>listIncompletelyDeployed</literal>. This returns a
                          <literal>java.util.List</literal> of <literal>org.jboss.system.ServiceContext</literal> objects
                          for the MBean services that are not in the <literal>RUNNING</literal> state.</para>
                      <para>The second operation is <literal>listWaitingMBeans</literal>. This operation returns a
                              <literal>java.util.List</literal> of the JMX <literal>ObjectName</literal>s of MBean
                          services that cannot be deployed because the class specified by the code attribute is not
                          available.</para>
                  </section>
                  <section>
                      <title>Hot Deployment of Components, the URLDeploymentScanner</title>
                      <para>The <literal>URLDeploymentScanner</literal> MBean service provides the JBoss hot deployment
                          capability. This service watches one or more URLs for deployable archives and deploys the
                          archives as they appear or change. It also undeploys previously deployed applications if the
                          archive from which the application was deployed is removed. The configurable attributes include:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">URLs</emphasis>: A comma separated list of URL strings for the
                                  locations that should be watched for changes. Strings that do not correspond to valid
                                  URLs are treated as file paths. Relative file paths are resolved against the server home
                                  URL, for example, <literal>JBOSS_DIST/server/default</literal> for the default config
                                  file set. If a URL represents a file then the file is deployed and watched for
                                  subsequent updates or removal. If a URL ends in <literal>/</literal> to represent a
                                  directory, then the contents of the directory are treated as a collection of deployables
                                  and scanned for content that are to be watched for updates or removal. The requirement
                                  that a URL end in a <literal>/</literal> to identify a directory follows the RFC2518
                                  convention and allows discrimination between collections and directories that are simply
                                  unpacked archives. </para>
                              <para>The default value for the URLs attribute is <literal>deploy/</literal> which means
                                  that any SARs, EARs, JARs, WARs, RARs, etc. dropped into the
                                      <literal>server/&lt;name&gt;/deploy</literal> directory will be
                                  automatically deployed and watched for updates.</para>
                              <para>Example URLs include:</para>
                              <itemizedlist>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">deploy/</emphasis> scans
                                              <literal>${jboss.server.url}/deploy/</literal>, which is local or remote
                                          depending on the URL used to boot the server</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">${jboss.server.home.dir}/deploy/</emphasis> scans
                                              <emphasis>${jboss.server.home.dir)/deploy</emphasis>, which is always
                                      local</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">file:/var/opt/myapp.ear</emphasis> deploys
                                              <literal>myapp.ear</literal> from a local location</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">file:/var/opt/apps/</emphasis> scans the specified
                                          directory</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">http://www.test.com/netboot/myapp.ear</emphasis> deploys
                                              <literal>myapp.ear</literal> from a remote location</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">http://www.test.com/netboot/apps/</emphasis> scans the
                                          specified remote location using WebDAV. This will only work if the remote http
                                          server supports the WebDAV PROPFIND command.</para>
                                  </listitem>
                              </itemizedlist>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ScanPeriod</emphasis>: The time in milliseconds between runs of
                                  the scanner thread. The default is 5000 (5 seconds).</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">URLComparator</emphasis>: The class name of a
                                      <literal>java.util.Comparator</literal> implementation used to specify a deployment
                                  ordering for deployments found in a scanned directory. The implementation must be able
                                  to compare two <literal>java.net.URL</literal> objects passed to its compare method. The
                                  default setting is the <literal>org.jboss.deployment.DeploymentSorter</literal> class
                                  which orders based on the deployment URL suffix. The ordering of suffixes is:
                                      <literal>deployer</literal>, <literal>deployer.xml</literal>,
                                  <literal>sar</literal>, <literal>rar</literal>, <literal>ds.xml</literal>,
                                      <literal>service.xml</literal>, <literal>har</literal>, <literal>jar</literal>,
                                      <literal>war</literal>, <literal>wsr</literal>, <literal>ear</literal>,
                                  <literal>zip</literal>, <literal>bsh</literal>, <literal>last</literal>.</para>
                              <para>An alternate implementation is the
                                      <literal>org.jboss.deployment.scanner.PrefixDeploymentSorter</literal> class. This
                                  orders the URLs based on numeric prefixes. The prefix digits are converted to an int
                                  (ignoring leading zeroes), smaller prefixes are ordered ahead of larger numbers.
                                  Deployments that do not start with any digits will be deployed after all numbered
                                  deployments. Deployments with the same prefix value are further sorted by the
                                      <literal>DeploymentSorter</literal> logic.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">Filter</emphasis>: The class name of a
                                  <literal>java.io.FileFilter</literal> implementation that is used to filter the contents
                                  of scanned directories. Any file not accepted by this filter will not be deployed. The
                                  default is <literal>org.jboss.deployment.scanner.DeploymentFilter</literal> which is an
                                  implementation that rejects the following patterns:</para>
                              <para>"<literal>#*</literal>", "<literal>%*</literal>", "<literal>,*</literal>",
                                      "<literal>.*</literal>", "<literal>_$*</literal>", "<literal>*#</literal>",
                                      "<literal>*$</literal>", "<literal>*%</literal>", "<literal>*.BAK</literal>",
                                      "<literal>*.old</literal>", "<literal>*.orig</literal>", "<literal>*.rej</literal>",
                                      "<literal>*.bak</literal>", "<literal>*.sh</literal>", "<literal>*,v</literal>",
                                      "<literal>*~</literal>", "<literal>.make.state</literal>",
                                  "<literal>.nse_depinfo</literal>", "<literal>CVS</literal>",
                                  "<literal>CVS.admin</literal>", "<literal>RCS</literal>", "<literal>RCSLOG</literal>",
                                      "<literal>SCCS</literal>", "<literal>TAGS</literal>", "<literal>core</literal>",
                                      "<literal>tags</literal>"</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">RecursiveSearch</emphasis>: This property indicates whether or not
                                  deploy subdirectories are seen to be holding deployable content. If this is false,
                                  deploy subdirectories that do not contain a dot (<literal>.</literal>) in their name are
                                  seen to be unpackaged JARs with nested subdeployments. If true, then deploy
                                  subdirectories are just groupings of deployable content. The difference between the two
                                  views shows is related to the depth first deployment model JBoss supports. The false
                                  setting which treats directories as unpackaged JARs with nested content triggers the
                                  deployment of the nested content as soon as the JAR directory is deployed. The true
                                  setting simply ignores the directory and adds its content to the list of deployable
                                  packages and calculates the order based on the previous filter logic. The default is
                                  true.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">Deployer</emphasis>: The JMX <literal>ObjectName</literal> string
                                  of the MBean that implements the <literal>org.jboss.deployment.Deployer</literal>
                                  interface operations. The default setting is to use the <literal>MainDeployer</literal>
                                  created by the bootstrap startup process.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
              </section>
              <section id="ch2.writembean.sect">
                  <title>Writing JBoss MBean Services</title>
                  <para>Writing a custom MBean service that integrates into the JBoss server requires the use of the
                          <literal>org.jboss.system.Service</literal> interface pattern if the custom service is dependent
                      on other services. When a custom MBean depends on other MBean services you cannot perform any
                      service dependent initialization in any of the <literal>javax.management.MBeanRegistration</literal>
                      interface methods since JMX has no dependency notion. Instead, you must manage dependency state
                      using the <literal>Service</literal> interface <literal>create</literal> and/or
                      <literal>start</literal> methods. You can do this using any one of the following approaches:</para>
                  <itemizedlist>
                      <listitem>
                          <para>Add any of the <literal>Service</literal> methods that you want called on your MBean to
                              your MBean interface. This allows your MBean implementation to avoid dependencies on JBoss
                              specific interfaces.</para>
                      </listitem>
                      <listitem>
                          <para>Have your MBean interface extend the <literal>org.jboss.system.Service</literal>
                              interface.</para>
                      </listitem>
                      <listitem>
                          <para>Have your MBean interface extend the <literal>org.jboss.system.ServiceMBean</literal>
                              interface. This is a subinterface of <literal>org.jboss.system.Service</literal> that adds
                                  <literal>getName()</literal>, <literal>getState()</literal>,
                              <literal>getStateString()</literal> methods.</para>
                      </listitem>
                  </itemizedlist>
                  <para>Which approach you choose depends on whether or not you want your code to be coupled to JBoss
                      specific code. If you don't, then you would use the first approach. If you don't care about
                      dependencies on JBoss classes, the simplest approach is to have your MBean interface extend from
                          <literal>org.jboss.system.ServiceMBean</literal> and your MBean implementation class extend from
                      the abstract <literal>org.jboss.system.ServiceMBeanSupport</literal> class. This class implements
                      the <literal>org.jboss.system.ServiceMBean</literal> interface.
                      <literal>ServiceMBeanSupport</literal> provides implementations of the <literal>create</literal>,
                          <literal>start</literal>, <literal>stop</literal>, and <literal>destroy</literal> methods that
                      integrate logging and JBoss service state management tracking. Each method delegates any subclass
                      specific work to <literal>createService</literal>, <literal>startService</literal>,
                          <literal>stopService</literal>, and <literal>destroyService</literal> methods respectively. When
                      subclassing <literal>ServiceMBeanSupport</literal>, you would override one or more of the
                          <literal>createService</literal>, <literal>startService</literal>,
                      <literal>stopService</literal>, and <literal>destroyService</literal> methods as required</para>
                  <section>
                      <title>A Standard MBean Example</title>
                      <para>This section develops a simple MBean that binds a <literal>HashMap</literal> into the JBoss
                          JNDI namespace at a location determined by its <literal>JndiName</literal> attribute to
                          demonstrate what is required to create a custom MBean. Because the MBean uses JNDI, it depends
                          on the JBoss naming service MBean and must use the JBoss MBean service pattern to be notified
                          when the naming service is available.</para>
                      <para>Version one of the classes, shown in <xref linkend="ch2.jndimap1.ex"/>, is based on the
                          service interface method pattern. This version of the interface declares the
                          <literal>start</literal> and <literal>stop</literal> methods needed to start up correctly
                          without using any JBoss-specific classes. </para>
                      <example id="ch2.jndimap1.ex">
                          <title>JNDIMapMBean interface and implementation based on the service interface method pattern</title>
                          <programlisting>package org.jboss.chap2.ex1;
                  
  // The JNDIMap MBean interface
  import javax.naming.NamingException;
                  
  public interface JNDIMapMBean
  {
      public String getJndiName();
      public void setJndiName(String jndiName) throws NamingException;
      public void start() throws Exception;
      public void stop() throws Exception;
  }
  </programlisting>
                          <programlisting>package org.jboss.chap2.ex1;
  
  // The JNDIMap MBean implementation
  import java.util.HashMap;
  import javax.naming.InitialContext;
  import javax.naming.Name;
  import javax.naming.NamingException;
  import org.jboss.naming.NonSerializableFactory;
  
  public class JNDIMap implements JNDIMapMBean
  {
      private String jndiName;
      private HashMap contextMap = new HashMap();
      private boolean started;
      
      public String getJndiName()
      {
          return jndiName;
      }
      public void setJndiName(String jndiName) throws NamingException
      {
          String oldName = this.jndiName;
          this.jndiName = jndiName;
          if (started) {
              unbind(oldName);
              try {
                  rebind();
              } catch(Exception e) {
                  NamingException ne = new NamingException("Failedto update jndiName");
                  ne.setRootCause(e);
                  throw ne;
              }
          }
      }
  
      public void start() throws Exception
      {
          started = true;
          rebind();
      }
                  
      public void stop()
      {
          started = false;
          unbind(jndiName);
      }
                  
      private void rebind() throws NamingException
      {
          InitialContext rootCtx = new InitialContext();
          Name fullName = rootCtx.getNameParser("").parse(jndiName);
          System.out.println("fullName="+fullName);
          NonSerializableFactory.rebind(fullName, contextMap, true);
      }
  
      private void unbind(String jndiName)
      {
          try {
              InitialContext rootCtx = new InitialContext();
              rootCtx.unbind(jndiName);
              NonSerializableFactory.unbind(jndiName);
          } catch(NamingException e) {
              e.printStackTrace();
          }
      }
  }</programlisting>
                      </example>
                      <para>Version two of the classes, shown in <xref linkend="ch2.jndimap1.ex"/>, use the JBoss
                              <literal>ServiceMBean</literal> interface and <literal>ServiceMBeanSupport</literal> class.
                          In this version, the implementation class extends the <literal>ServiceMBeanSupport</literal>
                          class and overrides the <literal>startService</literal> and <literal>stopService</literal>
                          methods. <literal>JNDIMapMBean</literal> also implements the abstract <literal>getName</literal>
                          method to return a descriptive name for the MBean. The <literal>JNDIMapMBean</literal> interface
                          extends the <literal>org.jboss.system.ServiceMBean</literal> interface and only declares the
                          setter and getter methods for the <literal>JndiName</literal> attribute because it inherits the
                          service life cycle methods from <literal>ServiceMBean</literal>. This is the third approach
                          mentioned at the start of the <xref linkend="ch2.mbeanservice.sect"/>.</para>
                      <example id="ch2.jndimap2.ex">
                          <title>JNDIMap MBean interface and implementation based on the ServiceMBean interface and
                              ServiceMBeanSupport class</title>
                          <programlisting>package org.jboss.chap2.ex2;
  
  // The JNDIMap MBean interface
  import javax.naming.NamingException;
  
  public interface JNDIMapMBean extends org.jboss.system.ServiceMBean
  {
      public String getJndiName();
      public void setJndiName(String jndiName) throws NamingException;
  } </programlisting>
                          <programlisting>package org.jboss.chap2.ex2;
  // The JNDIMap MBean implementation
  import java.util.HashMap;
  import javax.naming.InitialContext;
  import javax.naming.Name;
  import javax.naming.NamingException;
  import org.jboss.naming.NonSerializableFactory;
  
  public class JNDIMap extends org.jboss.system.ServiceMBeanSupport
      implements JNDIMapMBean
  {
      private String jndiName;
      private HashMap contextMap = new HashMap();
      
      public String getJndiName()
      {
          return jndiName;
      }
  
      public void setJndiName(String jndiName) 
          throws NamingException
      {
          String oldName = this.jndiName;
          this.jndiName = jndiName;
          if (super.getState() == STARTED) {
              unbind(oldName);
              try {
                  rebind();
              } catch(Exception e) {
                  NamingException ne = new NamingException("Failed to update jndiName");
                  ne.setRootCause(e);
                  throw ne;
              }
          }
      }
      
      public void startService() throws Exception
      {
          rebind();
      }
  
      public void stopService()
      {
          unbind(jndiName);
      }
      
      private void rebind() throws NamingException
      {
          InitialContext rootCtx = new InitialContext();
          Name fullName = rootCtx.getNameParser("").parse(jndiName);
          log.info("fullName="+fullName);
          NonSerializableFactory.rebind(fullName, contextMap, true);
      }
  
      private void unbind(String jndiName)
      {
          try {
              InitialContext rootCtx = new InitialContext();
              rootCtx.unbind(jndiName);
              NonSerializableFactory.unbind(jndiName);
          } catch(NamingException e) {
              log.error("Failed to unbind map", e);
          }
      }
  }</programlisting>
                      </example>
                      <para>The source code for these MBeans along with the service descriptors is located in the
                              <literal>examples/src/main/org/jboss/chap2/{ex1,ex2}</literal> directories.</para>
                      <para>The jboss-service.xml descriptor for the first version is shown below. </para>
                      <programlisting>&lt;!-- The SAR META-INF/jboss-service.xml descriptor --&gt;
  &lt;server&gt;
      &lt;mbean code="org.jboss.chap2.ex1.JNDIMap" 
             name="chap2.ex1:service=JNDIMap"&gt;
          &lt;attribute name="JndiName"&gt;inmemory/maps/MapTest&lt;/attribute&gt;
          &lt;depends&gt;jboss:service=Naming&lt;/depends&gt;
      &lt;/mbean&gt;
  &lt;/server&gt; </programlisting>
                      <para>The JNDIMap MBean binds a <literal>HashMap</literal> object under the
                              <literal>inmemory/maps/MapTest</literal> JNDI name and the client code fragment demonstrates
                          retrieving the HashMap object from the <literal>inmemory/maps/MapTest</literal> location. The
                          corresponding client code is shown below. </para>
                      <programlisting>// Sample lookup code
  InitialContext ctx = new InitialContext();
  HashMap map = (HashMap) ctx.lookup("inmemory/maps/MapTest");</programlisting>
                  </section>
                  <section id="ch2.xmbeanexamples.sect">
                      <title>XMBean Examples</title>
                      <para>In this section we will develop a variation of the <literal>JNDIMap</literal> MBean introduced
                          in the preceding section that exposes its management metadata using the JBoss XMBean framework.
                          Our core managed component will be exactly the same core code from the
                          <literal>JNDIMap</literal> class, but it will not implement any specific management related
                          interface. We will illustrate the following capabilities not possible with a standard MBean:</para>
                      <itemizedlist>
                          <listitem>
                              <para>The ability to add rich descriptions to attribute and operations</para>
                          </listitem>
                          <listitem>
                              <para>The ability to expose notification information</para>
                          </listitem>
                          <listitem>
                              <para>The ability to add persistence of attributes</para>
                          </listitem>
                          <listitem>
                              <para>The ability to add custom interceptors for security and remote access through a typed
                                  interface</para>
                          </listitem>
                      </itemizedlist>
                      <section>
                          <title>Version 1, The Annotated JNDIMap XMBean</title>
                          <para>Let's start with a simple XMBean variation of the standard MBean version of the JNDIMap
                              that adds the descriptive information about the attributes and operations and their
                              arguments. The following listing shows the <literal>jboss-service.xml</literal> descriptor
                              and the <literal>jndimap-xmbean1.xml</literal> XMBean descriptor. The source can be found in
                              the <literal>src/main/org/jboss/chap2/xmbean</literal> directory of the book examples.</para>
                          <programlisting>&lt;?xml version='1.0' encoding='UTF-8' ?&gt;
  &lt;!DOCTYPE server PUBLIC    
                       "-//JBoss//DTD MBean Service 3.2//EN"
                       "http://www.jboss.org/j2ee/dtd/jboss-service_3_2.dtd"&gt;
  &lt;server&gt;
      &lt;mbean code="org.jboss.chap2.xmbean.JNDIMap"
             name="chap2.xmbean:service=JNDIMap" 
             xmbean-dd="META-INF/jndimap-xmbean.xml"&gt;
          &lt;attribute name="JndiName"&gt;inmemory/maps/MapTest&lt;/attribute&gt;
          &lt;depends&gt;jboss:service=Naming&lt;/depends&gt;
      &lt;/mbean&gt;
  &lt;/server&gt;</programlisting>
                          <programlisting>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE mbean PUBLIC
            "-//JBoss//DTD JBOSS XMBEAN 1.0//EN"
            "http://www.jboss.org/j2ee/dtd/jboss_xmbean_1_0.dtd"&gt;
  &lt;mbean&gt;
      &lt;description&gt;The JNDIMap XMBean Example Version 1&lt;/description&gt;
      &lt;descriptors&gt;
          &lt;persistence persistPolicy="Never" persistPeriod="10"
              persistLocation="data/JNDIMap.data" persistName="JNDIMap"/&gt;
          &lt;currencyTimeLimit value="10"/&gt;
          &lt;state-action-on-update value="keep-running"/&gt;
      &lt;/descriptors&gt;
      &lt;class&gt;org.jboss.test.jmx.xmbean.JNDIMap&lt;/class&gt;
      &lt;constructor&gt;
          &lt;description&gt;The default constructor&lt;/description&gt;
          &lt;name&gt;JNDIMap&lt;/name&gt;
      &lt;/constructor&gt;  
      &lt;!-- Attributes --&gt;
      &lt;attribute access="read-write" getMethod="getJndiName" setMethod="setJndiName"&gt;
          &lt;description&gt;
              The location in JNDI where the Map we manage will be bound
          &lt;/description&gt;
          &lt;name&gt;JndiName&lt;/name&gt;
          &lt;type&gt;java.lang.String&lt;/type&gt;
          &lt;descriptors&gt;
              &lt;default value="inmemory/maps/MapTest"/&gt;
          &lt;/descriptors&gt;
      &lt;/attribute&gt;
      &lt;attribute access="read-write" getMethod="getInitialValues"
                 setMethod="setInitialValues"&gt;
          &lt;description&gt;The array of initial values that will be placed into the
              map associated with the service. The array is a collection of
              key,value pairs with elements[0,2,4,...2n] being the keys and
              elements [1,3,5,...,2n+1] the associated values. The
              "[Ljava.lang.String;" type signature is the VM representation of the
              java.lang.String[] type. &lt;/description&gt;
          &lt;name&gt;InitialValues&lt;/name&gt;
          &lt;type&gt;[Ljava.lang.String;&lt;/type&gt;
          &lt;descriptors&gt;
              &lt;default value="key0,value0"/&gt;
          &lt;/descriptors&gt;
      &lt;/attribute&gt;  
      &lt;!-- Operations --&gt;
      &lt;operation&gt;
          &lt;description&gt;The start lifecycle operation&lt;/description&gt;
          &lt;name&gt;start&lt;/name&gt;
      &lt;/operation&gt;
      &lt;operation&gt;
          &lt;description&gt;The stop lifecycle operation&lt;/description&gt;
          &lt;name&gt;stop&lt;/name&gt;
      &lt;/operation&gt;
      &lt;operation impact="ACTION"&gt;
          &lt;description&gt;Put a value into the map&lt;/description&gt;
          &lt;name&gt;put&lt;/name&gt;
          &lt;parameter&gt;
              &lt;description&gt;The key the value will be store under&lt;/description&gt;
              &lt;name&gt;key&lt;/name&gt;
              &lt;type&gt;java.lang.Object&lt;/type&gt;
          &lt;/parameter&gt;
          &lt;parameter&gt;
              &lt;description&gt;The value to place into the map&lt;/description&gt;
              &lt;name&gt;value&lt;/name&gt;
              &lt;type&gt;java.lang.Object&lt;/type&gt;
          &lt;/parameter&gt;
      &lt;/operation&gt;
      &lt;operation impact="INFO"&gt;
          &lt;description&gt;Get a value from the map&lt;/description&gt;
          &lt;name&gt;get&lt;/name&gt;
          &lt;parameter&gt;
              &lt;description&gt;The key to lookup in the map&lt;/description&gt;
              &lt;name&gt;get&lt;/name&gt;
              &lt;type&gt;java.lang.Object&lt;/type&gt;
          &lt;/parameter&gt;
          &lt;return-type&gt;java.lang.Object&lt;/return-type&gt;
      &lt;/operation&gt;  
      &lt;!-- Notifications --&gt;
      &lt;notification&gt;
          &lt;description&gt;The notification sent whenever a value is get into the map
              managed by the service&lt;/description&gt;
          &lt;name&gt;javax.management.Notification&lt;/name&gt;
          &lt;notification-type&gt;org.jboss.chap2.xmbean.JNDIMap.get&lt;/notification-type&gt;
      &lt;/notification&gt;
      &lt;notification&gt;
          &lt;description&gt;The notification sent whenever a value is put into the map
              managed by the service&lt;/description&gt;
          &lt;name&gt;javax.management.Notification&lt;/name&gt;
          &lt;notification-type&gt;org.jboss.chap2.xmbean.JNDIMap.put&lt;/notification-type&gt;
      &lt;/notification&gt;
  &lt;/mbean&gt;</programlisting>
                          <para>You can build, deploy and test the XMBean as follows:</para>
                          <programlisting>[examples]$ ant -Dchap=chap2 -Dex=xmbean1  run-example
  ...
  run-examplexmbean1:
       [copy] Copying 1 file to /tmp/jboss-4.0.2/server/default/deploy
       [java] JNDIMap Class: org.jboss.mx.modelmbean.XMBean
       [java] JNDIMap Operations: 
       [java]  + void start()
       [java]  + void stop()
       [java]  + void put(java.lang.Object chap2.xmbean:service=JNDIMap,java.lang.Object cha
  p2.xmbean:service=JNDIMap)
       [java]  + java.lang.Object get(java.lang.Object chap2.xmbean:service=JNDIMap)
       [java]  + java.lang.String getJndiName()
       [java]  + void setJndiName(java.lang.String chap2.xmbean:service=JNDIMap)
       [java]  + [Ljava.lang.String; getInitialValues()
       [java]  + void setInitialValues([Ljava.lang.String; chap2.xmbean:service=JNDIMap)
       [java] handleNotification, event: null
       [java] key=key0, value=value0
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.put,sequenceNumber=3,timeStamp=10986315
  27823,message=null,userData=null]
       [java] JNDIMap.put(key1, value1) successful
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.get,sequenceNumber=4,timeStamp=10986315
  27940,message=null,userData=null]
       [java] JNDIMap.get(key0): null
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.get,sequenceNumber=5,timeStamp=10986315
  27985,message=null,userData=null]
       [java] JNDIMap.get(key1): value1
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.put,sequenceNumber=6,timeStamp=10986315
  27999,message=null,userData=null]</programlisting>
                          <para>The functionality is largely the same as the Standard MBean with the notable exception of
                              the JMX notifications. A Standard MBean has no way of declaring that it will emit
                              notifications. An XMBean may declare the notifications it emits using notification elements
                              as is shown in the version 1 descriptor. We see the notifications from the get and put
                              operations on the test client console output. Note that there is also an
                                  <literal>jmx.attribute.change notification</literal> emitted when the
                                  <literal>InitialValues</literal> attribute was changed. This is because the
                                  <literal>ModelMBean</literal> interface extends the
                                  <literal>ModelMBeanNotificationBroadcaster</literal> which supports
                                  <literal>AttributeChangeNotificationListeners</literal>.</para>
                          <para>The other major difference between the Standard and XMBean versions of JNDIMap is the
                              descriptive metadata. Look at the <literal>chap2.xmbean:service=JNDIMap</literal> in the JMX
                              Console, and you will see the attributes section as shown in <xref linkend="ch11.v1.fig"/>.</para>
                          <figure id="ch11.v1.fig">
                              <title>The Version 1 JNDIMapXMBean jmx-console view</title>
                              <mediaobject>
                                  <imageobject>
                                      <imagedata align="center" fileref="images/Chap2-40.jpg"/>
                                  </imageobject>
                              </mediaobject>
                          </figure>
                          <para>Notice that the JMX Console now displays the full attribute description as specified in
                              the XMBean descriptor rather than <literal>MBean Attribute</literal> text seen in standard
                              MBean implementations. Scroll down to the operations and you will also see that these now
                              also have nice descriptions of their function and parameters.</para>
                      </section>
                      <section>
                          <title>Version 2, Adding Persistence to the JNDIMap XMBean</title>
                          <para>In version 2 of the XMBean we add support for persistence of the XMBean attributes. The
                              updated XMBean deployment descriptor is given below. </para>
                          <programlisting>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE mbean PUBLIC
            "-//JBoss//DTD JBOSS XMBEAN 1.0//EN"
            "http://www.jboss.org/j2ee/dtd/jboss_xmbean_1_0.dtd"&gt;
  &lt;mbean&gt;
      &lt;description&gt;The JNDIMap XMBean Example Version 2&lt;/description&gt;
      &lt;descriptors&gt;
          &lt;persistence persistPolicy="OnUpdate" persistPeriod="10"
              persistLocation="${jboss.server.data.dir}" persistName="JNDIMap.ser"/&gt;
          &lt;currencyTimeLimit value="10"/&gt;
          &lt;state-action-on-update value="keep-running"/&gt;
          &lt;persistence-manager value="org.jboss.mx.persistence.ObjectStreamPersistenceManager"/&gt;
      &lt;/descriptors&gt;   &lt;class&gt;org.jboss.test.jmx.xmbean.JNDIMap&lt;/class&gt;
      &lt;constructor&gt;
          &lt;description&gt;The default constructor&lt;/description&gt;
          &lt;name&gt;JNDIMap&lt;/name&gt;
      &lt;/constructor&gt;  
      &lt;!-- Attributes --&gt;
      &lt;attribute access="read-write" getMethod="getJndiName" setMethod="setJndiName"&gt;
          &lt;description&gt;
              The location in JNDI where the Map we manage will be bound
          &lt;/description&gt;
          &lt;name&gt;JndiName&lt;/name&gt;
          &lt;type&gt;java.lang.String&lt;/type&gt;
          &lt;descriptors&gt;
              &lt;default value="inmemory/maps/MapTest"/&gt;
          &lt;/descriptors&gt;
      &lt;/attribute&gt;
      &lt;attribute access="read-write" getMethod="getInitialValues"
                 setMethod="setInitialValues"&gt;
          &lt;description&gt;The array of initial values that will be placed into the
              map associated with the service. The array is a collection of
              key,value pairs with elements[0,2,4,...2n] being the keys and
              elements [1,3,5,...,2n+1] the associated values&lt;/description&gt;
          &lt;name&gt;InitialValues&lt;/name&gt;
          &lt;type&gt;[Ljava.lang.String;&lt;/type&gt;
          &lt;descriptors&gt;
              &lt;default value="key0,value0"/&gt;
          &lt;/descriptors&gt;
      &lt;/attribute&gt;  
      &lt;!-- Operations --&gt;
      &lt;operation&gt;
          &lt;description&gt;The start lifecycle operation&lt;/description&gt;
          &lt;name&gt;start&lt;/name&gt;
      &lt;/operation&gt;
      &lt;operation&gt;
          &lt;description&gt;The stop lifecycle operation&lt;/description&gt;
          &lt;name&gt;stop&lt;/name&gt;
      &lt;/operation&gt;
      &lt;operation impact="ACTION"&gt;
          &lt;description&gt;Put a value into the nap&lt;/description&gt;
          &lt;name&gt;put&lt;/name&gt;
          &lt;parameter&gt;
              &lt;description&gt;The key the value will be store under&lt;/description&gt;
              &lt;name&gt;key&lt;/name&gt;
              &lt;type&gt;java.lang.Object&lt;/type&gt;
          &lt;/parameter&gt;
          &lt;parameter&gt;
              &lt;description&gt;The value to place into the map&lt;/description&gt;
              &lt;name&gt;value&lt;/name&gt;
              &lt;type&gt;java.lang.Object&lt;/type&gt;
          &lt;/parameter&gt;
      &lt;/operation&gt;
      &lt;operation impact="INFO"&gt;
          &lt;description&gt;Get a value from the map&lt;/description&gt;
          &lt;name&gt;get&lt;/name&gt;
          &lt;parameter&gt;
              &lt;description&gt;The key to lookup in the map&lt;/description&gt;
              &lt;name&gt;get&lt;/name&gt;
              &lt;type&gt;java.lang.Object&lt;/type&gt;
          &lt;/parameter&gt;
          &lt;return-type&gt;java.lang.Object&lt;/return-type&gt;
      &lt;/operation&gt;  
      &lt;!-- Notifications --&gt;
      &lt;notification&gt;
          &lt;description&gt;The notification sent whenever a value is get into the map
              managed by the service&lt;/description&gt;
          &lt;name&gt;javax.management.Notification&lt;/name&gt;
          &lt;notification-type&gt;org.jboss.chap2.xmbean.JNDIMap.get&lt;/notification-type&gt;
      &lt;/notification&gt;
      &lt;notification&gt;
          &lt;description&gt;The notification sent whenever a value is put into the map
              managed by the service&lt;/description&gt;
          &lt;name&gt;javax.management.Notification&lt;/name&gt;
          &lt;notification-type&gt;org.jboss.chap2.xmbean.JNDIMap.put&lt;/notification-type&gt;
      &lt;/notification&gt;
  &lt;/mbean&gt;</programlisting>
                          <para>Build, deploy and test the version 2 XMBean as follows:</para>
                          <programlisting>[examples]$ ant -Dchap=chap2 -Dex=xmbean2 -Djboss.deploy.conf=rmi-adaptor run-example
  ...
  run-examplexmbean2:
       [java] JNDIMap Class: org.jboss.mx.modelmbean.XMBean
       [java] JNDIMap Operations: 
       [java]  + void start()
       [java]  + void stop()
       [java]  + void put(java.lang.Object chap2.xmbean:service=JNDIMap,java.lang.Object cha
  p2.xmbean:service=JNDIMap)
       [java]  + java.lang.Object get(java.lang.Object chap2.xmbean:service=JNDIMap)
       [java]  + java.lang.String getJndiName()
       [java]  + void setJndiName(java.lang.String chap2.xmbean:service=JNDIMap)
       [java]  + [Ljava.lang.String; getInitialValues()
       [java]  + void setInitialValues([Ljava.lang.String; chap2.xmbean:service=JNDIMap)
       [java] handleNotification, event: null
       [java] key=key10, value=value10
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.put,sequenceNumber=7,timeStamp=10986326
  93716,message=null,userData=null]
       [java] JNDIMap.put(key1, value1) successful
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.get,sequenceNumber=8,timeStamp=10986326
  93857,message=null,userData=null]
       [java] JNDIMap.get(key0): null
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.get,sequenceNumber=9,timeStamp=10986326
  93896,message=null,userData=null]
       [java] JNDIMap.get(key1): value1
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.put,sequenceNumber=10,timeStamp=1098632
  693925,message=null,userData=null]</programlisting>
                          <para>There is nothing manifestly different about this version of the XMBean at this point
                              because we have done nothing to test that changes to attribute value are actually persisted.
                              Perform this test by running example xmbean2a several times:</para>
                          <para>
                              <programlisting>[examples] ant -Dchap=chap2 -Dex=xmbean2a run-example
  ...
       [java] InitialValues.length=2
       [java] key=key10, value=value10</programlisting>
                              <programlisting>[examples] ant -Dchap=chap2 -Dex=xmbean2a run-example
  ...
       [java] InitialValues.length=4
       [java] key=key10, value=value10
       [java] key=key2, value=value2</programlisting>
                          </para>
                          <para>  
                              <programlisting>[examples] ant -Dchap=chap2 -Dex=xmbean2a run-example
  ...
       [java] InitialValues.length=6
       [java] key=key10, value=value10
       [java] key=key2, value=value2
       [java] key=key3, value=value3</programlisting>
                          </para>
                          <para>The <literal>org.jboss.chap2.xmbean.TestXMBeanRestart</literal> used in this example
                              obtains the current <literal>InitialValues</literal> attribute setting, and then adds
                              another key/value pair to it. The client code is shown below.</para>
                          <programlisting>package org.jboss.chap2.xmbean;
  
  import javax.management.Attribute;
  import javax.management.ObjectName;
  import javax.naming.InitialContext;
  
  import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
  
  /**
   *  A client that demonstrates the persistence of the xmbean
   *  attributes. Every time it run it looks up the InitialValues
   *  attribute, prints it out and then adds a new key/value to the
   *  list.
   *  
   *  @author Scott.Stark at jboss.org
   *  @version $Revision: 1.1 $
   */
  public class TestXMBeanRestart
  {
      /**
       * @param args the command line arguments
       */
      public static void main(String[] args) throws Exception
      {
  	InitialContext ic = new InitialContext();
  	RMIAdaptor server = (RMIAdaptor) ic.lookup("jmx/rmi/RMIAdaptor");
  	
  	// Get the InitialValues attribute
  	ObjectName name = new ObjectName("chap2.xmbean:service=JNDIMap");
  	String[] initialValues = (String[])
  	    server.getAttribute(name, "InitialValues");
  	System.out.println("InitialValues.length="+initialValues.length);
  	int length = initialValues.length;
  	for (int n = 0; n &lt; length; n += 2) {
  	    String key = initialValues[n];
  	    String value = initialValues[n+1];
  	    
  	    System.out.println("key="+key+", value="+value);
  	}
  	// Add a new key/value pair
  	String[] newInitialValues = new String[length+2];
  	System.arraycopy(initialValues, 0, newInitialValues,
  			 0, length);
  	newInitialValues[length] = "key"+(length/2+1);
  	newInitialValues[length+1] = "value"+(length/2+1);
  	
  	Attribute ivalues = new
  	    Attribute("InitialValues", newInitialValues);
  	server.setAttribute(name, ivalues);
      }
  }</programlisting>
                          <para>At this point you may even shutdown the JBoss server, restart it and then rerun the
                              initial example to see if the changes are persisted across server restarts:</para>
                          <programlisting>[examples]$ ant -Dchap=chap2 -Dex=xmbean2 run-example
  ...
   
  run-examplexmbean2:
       [java] JNDIMap Class: org.jboss.mx.modelmbean.XMBean
       [java] JNDIMap Operations: 
       [java]  + void start()
       [java]  + void stop()
       [java]  + void put(java.lang.Object chap2.xmbean:service=JNDIMap,java.lang.Object cha
  p2.xmbean:service=JNDIMap)
       [java]  + java.lang.Object get(java.lang.Object chap2.xmbean:service=JNDIMap)
       [java]  + java.lang.String getJndiName()
       [java]  + void setJndiName(java.lang.String chap2.xmbean:service=JNDIMap)
       [java]  + [Ljava.lang.String; getInitialValues()
       [java]  + void setInitialValues([Ljava.lang.String; chap2.xmbean:service=JNDIMap)
       [java] handleNotification, event: null
       [java] <emphasis role="bold">key=key10, value=value10</emphasis>
       [java] <emphasis role="bold">key=key2, value=value2</emphasis>
       [java] <emphasis role="bold">key=key3, value=value3</emphasis>
       [java] <emphasis role="bold">key=key4, value=value4</emphasis>
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.put,sequenceNumber=3,timeStamp=10986336
  64712,message=null,userData=null]
       [java] JNDIMap.put(key1, value1) successful
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.get,sequenceNumber=4,timeStamp=10986336
  64821,message=null,userData=null]
       [java] JNDIMap.get(key0): null
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.get,sequenceNumber=5,timeStamp=10986336
  64860,message=null,userData=null]
       [java] JNDIMap.get(key1): value1
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.put,sequenceNumber=6,timeStamp=10986336
  64877,message=null,userData=null]
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.put,sequenceNumber=7,timeStamp=10986336
  64895,message=null,userData=null]
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.put,sequenceNumber=8,timeStamp=10986336
  64899,message=null,userData=null]
       [java] handleNotification, event: javax.management.Notification[source=chap2.xmbean:s
  ervice=JNDIMap,type=org.jboss.chap2.xmbean.JNDIMap.put,sequenceNumber=9,timeStamp=10986336
  65614,message=null,userData=null]   </programlisting>
                          <para>You see that the last <literal>InitialValues</literal> attribute setting is in fact
                              visible.</para>
                      </section>
                      <!-- 
                  <section id="ch2.jndimapv3.sect">
                      <title>Version 3, Adding Security and Remote Access to the
                          JNDIMap XMBean</title>
                      <para>The last example version of the JNDIMap XMBean will
                          demonstrate customization of the server interceptor
                          stack as well as exposing a subset of the XMBean
                          management interface via a typed proxy to a remote
                          client using RMI/JRMP. On the server side we will add a
                          simple security interceptor that only allows access to
                          attributes or operations by a user specified in the
                          interceptor configuration. We will also use another
                          custom interceptor to implement the MBean detached
                          invoker pattern described in <xref
                          linkend="ch2.remoteaccess.sect"/>. By implementing this
                          pattern in an invoker rather than the XMBean, we
                          demonstrate how to introduce a remote access aspect
                          without having to modify the existing JNDIMap implementation.</para>
                      <para>We will use the <literal>JRMPProxyFactory</literal>
                          service to expose the <literal>ClientInterface</literal>
                          to remote clients. </para>
                      <programlisting>
  public interface ClientInterface
  {
      public String[] getInitialValues();
      public void setInitialValues(String[] keyValuePairs);
      public Object get(Object key);
      public void put(Object key, Object value);
  } </programlisting>
                      <para>Our test client will obtain the
                          <literal>ClientInterface</literal> proxy from JNDI and
                          interact with the XMBean through RMI style calls instead
                          of the <literal>RMIAdaptor</literal> and MBean Server
                          style used previously.</para>
                      <programlisting>package org.jboss.chap2.xmbean;
  
  import javax.naming.InitialContext;
  import org.jboss.security.SecurityAssociation;
  import org.jboss.security.SimplePrincipal;
  
  /** 
   *  A client that accesses an XMBean through its RMI interface
   *  @author Scott.Stark at jboss.org
   *  @version $Revision: 1.1 $
   */
  public class TestXMBean3
  {
      
      /**
       * @param args the command line arguments
       */
      public static void main(String[] args) throws Exception
      {
          InitialContext ic = new InitialContext();
          ClientInterface xmbean = (ClientInterface) 
              ic.lookup("secure-xmbean/ClientInterface");
          
          // This call should fail because we have not set a security context
          try {
              String[] tmp = xmbean.getInitialValues();
              throw new IllegalStateException("Was able to call getInitialValues");
          } catch(Exception e) {
              System.out.println("Called to getInitialValues failed as expected: "
                                 + e.getMessage());
          }
          
          // Set a security context using the SecurityAssociation
          SecurityAssociation.setPrincipal(new SimplePrincipal("admin"));
          
          // Get the InitialValues attribute
          String[] initialValues = xmbean.getInitialValues();
          for(int n = 0; n &lt; initialValues.length; n += 2) {
              String key = initialValues[n];
              String value = initialValues[n+1];
              
              System.out.println("key="+key+", value="+value);
          }
          
          // Invoke the put(Object, Object) op
          xmbean.put("key1", "value1");
          System.out.println("JNDIMap.put(key1,
                          value1) successful");
          Object result0 = xmbean.get("key0");
          System.out.println("JNDIMap.get(key0): "+result0);
          Object result1 = xmbean.get("key1");
          System.out.println("JNDIMap.get(key1): "+result1);
          
          // Change the InitialValues
          initialValues[0] += ".1";
          initialValues[1] += ".2";
          xmbean.setInitialValues(initialValues);
          
          initialValues = xmbean.getInitialValues();
          for(int n = 0; n &lt; initialValues.length; n += 2) {
              String key = initialValues[n];
              String value = initialValues[n+1];
              
              System.out.println("key="+key+", value="+value);
          }
      }
  }</programlisting>
                      <para>The deployment descriptor is shown below:</para>
                      <programlisting>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE mbean PUBLIC
            "-//JBoss//DTD JBOSS XMBEAN 1.0//EN"
            "http://www.jboss.org/j2ee/dtd/jboss_xmbean_1_0.dtd"
            [&lt;!ATTLIST interceptor adminName CDATA #IMPLIED&gt;]&gt;
  &lt;mbean&gt;
      &lt;description&gt;The JNDIMap XMBean Example Version 3&lt;/description&gt;
      &lt;descriptors&gt;
          &lt;interceptors&gt;
              &lt;interceptor code="org.jboss.chap2.xmbean.ServerSecurityInterceptor" 
                           adminName="admin"/&gt;
              &lt;interceptor code="org.jboss.chap2.xmbean.InvokerInterceptor"/&gt;
              &lt;interceptor code="org.jboss.mx.interceptor.PersistenceInterceptor2"/&gt;
              &lt;interceptor code="org.jboss.mx.interceptor.ModelMBeanInterceptor"/&gt;
              &lt;interceptor code="org.jboss.mx.interceptor.ObjectReferenceInterceptor"/&gt;
          &lt;/interceptors&gt;
          &lt;persistence persistPolicy="Never"/&gt;
          &lt;currencyTimeLimit value="10"/&gt;
          &lt;state-action-on-update value="keep-running"/&gt;
      &lt;/descriptors&gt;
      &lt;class&gt;org.jboss.test.jmx.xmbean.JNDIMap&lt;/class&gt;
      &lt;constructor&gt;
          &lt;description&gt;The default constructor&lt;/description&gt;
          &lt;name&gt;JNDIMap&lt;/name&gt;
      &lt;/constructor&gt;  
      &lt;!- - Attributes - -&gt;
      &lt;attribute access="read-write" getMethod="getJndiName" setMethod="setJndiName"&gt;
          &lt;description&gt;
              The location in JNDI where the Map we manage will be bound
          &lt;/description&gt;
          &lt;name&gt;JndiName&lt;/name&gt;
          &lt;type&gt;java.lang.String&lt;/type&gt;
          &lt;descriptors&gt;
              &lt;default value="inmemory/maps/MapTest"/&gt;
          &lt;/descriptors&gt;
      &lt;/attribute&gt;
      &lt;attribute access="read-write" getMethod="getInitialValues" 
                 setMethod="setInitialValues"&gt;
          &lt;description&gt;The array of initial values that will be placed into the
              map associated with the service. The array is a collection of
              key,value pairs with elements[0,2,4,...2n] being the keys and
              elements [1,3,5,...,2n+1] the associated values&lt;/description&gt;
          &lt;name&gt;InitialValues&lt;/name&gt;
          &lt;type&gt;[Ljava.lang.String;&lt;/type&gt;
          &lt;descriptors&gt;
              &lt;default value="key0,value0"/&gt;
          &lt;/descriptors&gt;
      &lt;/attribute&gt;  
      &lt;!- - Operations - -&gt;
      &lt;operation&gt;
          &lt;description&gt;The start lifecycle operation&lt;/description&gt;
          &lt;name&gt;start&lt;/name&gt;
      &lt;/operation&gt;
      &lt;operation&gt;
          &lt;description&gt;The stop lifecycle operation&lt;/description&gt;
          &lt;name&gt;stop&lt;/name&gt;
      &lt;/operation&gt;
      &lt;operation impact="ACTION"&gt;
          &lt;description&gt;Put a value into the nap&lt;/description&gt;
          &lt;name&gt;put&lt;/name&gt;
          &lt;parameter&gt;
              &lt;description&gt;The key the value will be store under&lt;/description&gt;
              &lt;name&gt;key&lt;/name&gt;
              &lt;type&gt;java.lang.Object&lt;/type&gt;
          &lt;/parameter&gt;
          &lt;parameter&gt;
              &lt;description&gt;The value to place into the map&lt;/description&gt;
              &lt;name&gt;value&lt;/name&gt;
              &lt;type&gt;java.lang.Object&lt;/type&gt;
          &lt;/parameter&gt;
      &lt;/operation&gt;
      &lt;operation impact="INFO"&gt;
          &lt;description&gt;Get a value from the map&lt;/description&gt;
          &lt;name&gt;get&lt;/name&gt;
          &lt;parameter&gt;
              &lt;description&gt;The key to lookup in the map&lt;/description&gt;
              &lt;name&gt;get&lt;/name&gt;
              &lt;type&gt;java.lang.Object&lt;/type&gt;
          &lt;/parameter&gt;
          &lt;return-type&gt;java.lang.Object&lt;/return-type&gt;
      &lt;/operation&gt;
  &lt;/mbean&gt;</programlisting>
                      <para>The addition over the previous versions of the
                          <literal>JNDIMap</literal> XMBean is the interceptors
                          element shown in bold in the listing. This defines the
                          interceptor stack through which all MBean attribute
                          access and operations pass. The first two interceptors,
                          <literal>org.jboss.chap2.xmbean.ServerSecurityInterceptor</literal>
                          and
                          <literal>org.jboss.chap2.xmbean.InvokerInterceptor</literal>
                          are the example custom interceptors. The remaining three
                          interceptors are the standard ModelMBean interceptors.
                          Because we have a persistence policy of
                          <literal>Never</literal>, we could in fact remove the
                          standard
                          <literal>org.jboss.mx.interceptor.PersistenceInterceptor2</literal>.
                          The JMX interceptors are an ordered chain of filters.
                          The standard base class of an interceptor is shown below.</para>
                      <programlisting>package org.jboss.mx.interceptor;
  
  import javax.management.MBeanInfo;
  import org.jboss.mx.server.MBeanInvoker;
  
  /**
   * Base class for all interceptors.
   *
   * @see org.jboss.mx.interceptor.StandardMBeanInterceptor
   * @see org.jboss.mx.interceptor.LogInterceptor
   *
   * @author &lt;a href="mailto:juha at jboss.org"&gt;Juha Lindfors&lt;/a&gt;.
   * @version $Revision: 1.1 $
   *
   */
  public class AbstractInterceptor implements Interceptor
  {
      // Attributes 
      protected Interceptor next = null;
      protected String name = null;
      protected MBeanInfo info;
      protected MBeanInvoker invoker;
      
      // Constructors 
      public AbstractInterceptor()
      {
          this(null);
      }
      public AbstractInterceptor(String name)
      {
          this.name = name;
      }
      public AbstractInterceptor(MBeanInfo info,
                                 MBeanInvoker invoker)
      {
          this.name = getClass().getName();
          this.info = info;
          this.invoker = invoker;
      }
      
      // Public 
      public Object invoke(Invocation invocation) 
          throws InvocationException
      {
          return getNext().invoke(invocation);
      }
      
      public Interceptor getNext()
      {
          return next;
      }
      
      public Interceptor setNext(Interceptor interceptor)
      {
          this.next = interceptor;
          return interceptor;
      }
      
  }</programlisting>
                      <para>The custom interceptors for the version 3 XMBean
                          example are the
                          <literal>ServerSecurityInterceptor</literal> and the
                          <literal>InvokerInterceptor</literal>. The
                          <literal>ServerSecurityInterceptor</literal> intercepts
                          invoke operations and validates that the
                          <literal>Invocation</literal> context include an admin principal.</para>
                      <programlisting>package org.jboss.chap2.xmbean;
  
  import java.security.Principal;
  
  import org.jboss.logging.Logger;
  import org.jboss.mx.interceptor.AbstractInterceptor;
  import org.jboss.mx.interceptor.Invocation;
  import org.jboss.mx.interceptor.InvocationException;
  import org.jboss.security.SimplePrincipal;
  
  
  /** 
   * A simple security interceptor example that restricts access to a
   * single principal
   *
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
   
  public class ServerSecurityInterceptor extends AbstractInterceptor
  {
      private static Logger log = Logger.getLogger(ServerSecurityInterceptor.class);
      private SimplePrincipal admin = new SimplePrincipal("admin");
      
      public String getAdminName()
      {
          return admin.getName();
      }
      public void setAdminName(String name)
      {
          admin = new SimplePrincipal(name);
      }
  
      public Object invoke(Invocation invocation) 
          throws InvocationException
      {
          String opName = invocation.getName();
  
          // If this is not the invoke(Invocation) op just pass it along
          if (opName.equals("invoke") == false) {
              return getNext().invoke(invocation);
          }
  
          Object[] args = invocation.getArgs();
          org.jboss.invocation.Invocation invokeInfo =
              (org.jboss.invocation.Invocation) args[0];
          Principal caller = invokeInfo.getPrincipal();
          log.info("invoke, opName="+opName+", caller="+caller);
  
          // Only the admin caller is allowed access
          if (caller == null || caller.equals(admin) == false) {
              throw new InvocationException(new SecurityException("Caller=" + 
                                                                  caller + 
                                                                  " is not allowed access"));
          }
          return getNext().invoke(invocation);
      }
  }</programlisting>
                      <para>The InvokerInterceptor implements the detached invoker
                          pattern. This is discussed in detail in <xref linkend="ch2.remoteaccess.sect"/>.</para>
                      <programlisting>package org.jboss.chap2.xmbean;
  
  import java.lang.reflect.Method;
  import java.util.HashMap;
  import javax.management.Descriptor;
  import javax.management.MBeanInfo;
  
  import org.jboss.logging.Logger;
  import org.jboss.mx.interceptor.AbstractInterceptor;
  import org.jboss.mx.interceptor.Invocation;
  import org.jboss.mx.interceptor.InvocationException;
  import org.jboss.mx.server.MBeanInvoker;
  import org.jboss.invocation.MarshalledInvocation;
  
  /** An interceptor that handles the
   *
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class InvokerInterceptor 
      extends AbstractInterceptor
  {
      private static Logger log = Logger.getLogger(InvokerInterceptor.class);
      private Class exposedInterface = ClientInterface.class;
      private HashMap methodMap = new HashMap();
      private HashMap invokeMap = new HashMap();
  
      public InvokerInterceptor(MBeanInfo info,
                                MBeanInvoker invoker)
      {
          super(info, invoker);
          try {
              Descriptor[] descriptors = invoker.getDescriptors();
              Object resource = invoker.getResource();
              Class[] getInitialValuesSig = {};
              Method getInitialValues =
  		exposedInterface.getDeclaredMethod("getInitialValues",
  						   getInitialValuesSig);
              Long hash = new Long(MarshalledInvocation.calculateHash(getInitialValues));
              InvocationInfo invokeInfo = 
  		new InvocationInfo("InitialValues",
  				   Invocation.ATTRIBUTE, 
  				   Invocation.READ, getInitialValuesSig,
  				   descriptors, resource);
              methodMap.put(hash, getInitialValues);
              invokeMap.put(getInitialValues, invokeInfo);
              log.debug("getInitialValues hash:"+hash);
  
              Class[] setInitialValuesSig = {String[].class};
              Method setInitialValues = 
  		exposedInterface.getDeclaredMethod("setInitialValues",
  						   setInitialValuesSig);
  
              hash = new Long(MarshalledInvocation.calculateHash(setInitialValues));
              invokeInfo = new InvocationInfo("InitialValues",
                                              Invocation.ATTRIBUTE, 
  					    Invocation.WRITE, 
  					    setInitialValuesSig,
                                              descriptors, resource);
              methodMap.put(hash, setInitialValues);
              invokeMap.put(setInitialValues, invokeInfo);
              log.debug("setInitialValues hash:"+hash);
  
              Class[] getSig = {Object.class};
              Method get = exposedInterface.getDeclaredMethod("get",
                                                              getSig);
              hash = new Long(MarshalledInvocation.calculateHash(get));
              invokeInfo = new InvocationInfo("get",
                                              Invocation.OPERATION, 
  					    Invocation.READ, getSig,
                                              descriptors, resource);
              methodMap.put(hash, get);
              invokeMap.put(get, invokeInfo);
              log.debug("get hash:"+hash);
  
              Class[] putSig = {Object.class, Object.class};
              Method put = exposedInterface.getDeclaredMethod("put",
                                                              putSig);
              hash = new Long(MarshalledInvocation.calculateHash(put));
              invokeInfo = new InvocationInfo("put",
                                              Invocation.OPERATION, 
  					    Invocation.WRITE, putSig,
                                              descriptors, resource);
              methodMap.put(hash, put);
              invokeMap.put(put, invokeInfo);
              log.debug("putt hash:"+hash);
          } catch(Exception e) {
              log.error("Failed to init InvokerInterceptor", e);
          }
      }
  
      public Object invoke(Invocation invocation) 
          throws InvocationException
      {
          String opName = invocation.getName();
          Object[] args = invocation.getArgs();
          Object returnValue = null;
          if (opName.equals("invoke") == true) {
              org.jboss.invocation.Invocation invokeInfo =
                  (org.jboss.invocation.Invocation) args[0];
              // Set the method hash to Method mapping
              if (invokeInfo instanceof MarshalledInvocation) {
                  MarshalledInvocation mi = (MarshalledInvocation) invokeInfo;
                  mi.setMethodMap(methodMap);
              }
  
              // Invoke the exposedInterface method via reflection if
              // this is an invoke
              Method method = invokeInfo.getMethod();
              Object[] methodArgs = invokeInfo.getArguments();
              InvocationInfo info = (InvocationInfo) invokeMap.get(method);
              Invocation methodInvocation = info.getInvocation(methodArgs);
              returnValue = getNext().invoke(methodInvocation);
          } else {
              returnValue = getNext().invoke(invocation);
          }
          return returnValue;
      }
  
      /**
       * A class that holds the ClientInterface method info needed to build
       * the JMX Invocation to pass down the interceptor stack.
       */
      private class InvocationInfo
      {
          private int type;
          private int impact;
          private String name;
          private String[] signature;
          private Descriptor[] descriptors;
          private Object resource;
  
  
          InvocationInfo(String name, int type, int impact,
                         Class[] signature, Descriptor[] descriptors, 
                         Object resource)
          {
              this.name = name;
              this.type = type;
              this.impact = impact;
              this.descriptors = descriptors;
              this.resource = resource;
              this.signature = new String[signature.length];
              for(int s = 0; s &lt; signature.length; s ++) {
                  this.signature[s] = signature[s].getName();
              }
          }
  
          Invocation getInvocation(Object[] args)
          {
              return new Invocation(name, type, impact, args, signature,
                                    descriptors, resource);
          }
      }
  }</programlisting>
                      <para>The deployment descriptor should include the
                          interceptor stack.</para>
                      <programlisting>&lt;?xml version='1.0' encoding='UTF-8' ?&gt;
  &lt;server&gt;
      &lt;mbean code="org.jboss.chap2.xmbean.JNDIMap"
          name="chap2.xmbean:service=JNDIMap,version=3" 
          xmbean-dd="META-INF/jndimap-xmbean3.xml"&gt;
          &lt;attribute name="JndiName"&gt;inmemory/maps/MapTest&lt;/attribute&gt;
          &lt;depends&gt;jboss:service=Naming&lt;/depends&gt;
      &lt;/mbean&gt;  
      &lt;!- - The JRMP invoker proxy configuration for
                          the naming service  - -&gt;
      &lt;mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory" 
             name="jboss.test:service=proxyFactory,type=jrmp,target=JNDIMap"&gt;
          &lt;!- - Use the standard JRMPInvoker from
                          conf/jboss-service.xml - -&gt;
          &lt;attribute name="InvokerName"&gt;jboss:service=invoker,type=jrmp&lt;/attribute&gt;
          &lt;attribute name="TargetName"&gt;chap2.xmbean:service=JNDIMap,version=3&lt;/attribute&gt;
          &lt;attribute name="JndiName"&gt;secure-xmbean/ClientInterface&lt;/attribute&gt;
          &lt;attribute name="ExportedInterface"&gt;
              org.jboss.chap2.xmbean.ClientInterface
          &lt;/attribute&gt;
          &lt;attribute name="ClientInterceptors"&gt;
              &lt;iterceptors&gt;
                  &lt;interceptor&gt;org.jboss.proxy.ClientMethodInterceptor&lt;/interceptor&gt;
                  &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                  &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
              &lt;/iterceptors&gt;
          &lt;/attribute&gt;
          &lt;depends&gt;jboss:service=invoker,type=jrmp&lt;/depends&gt;
          &lt;depends&gt;chap2.xmbean:service=JNDIMap,version=3&lt;/depends&gt;
      &lt;/mbean&gt;
  &lt;/server&gt;</programlisting>
                      
               
                      <programlisting>[examples]$ ant -Dchap=chap2 -Dex=xmbean3 run-example
  ...
  run-examplexmbean3:
       [java] Called to getInitialValues failed as expected: Caller=null is not allowed access
       [java] key=key0, value=value0
       [java] JNDIMap.put(key1, value1) successful
       [java] JNDIMap.get(key0): null
       [java] JNDIMap.get(key1): value1
       [java] key=key0.1, value=value0.2</programlisting>
                      <programlisting>[examples]$ ant -Dchap=chap2 -Dex=xmbean3 run-example
  ...
  run-examplexmbean3:
       [java] Called to getInitialValues failed as expected: Caller=null is not allowed access
       [java] key=key0.1, value=value0.2
       [java] JNDIMap.put(key1, value1) successful
       [java] JNDIMap.get(key0): null
       [java] JNDIMap.get(key1): value1
       [java] key=key0.1.1, value=value0.2.2
  </programlisting>
                  </section>
                  -->
                  </section>
              </section>
              <section>
                  <title>Deployment Ordering and Dependencies</title>
                  <para>We have seen how to manage dependencies using the service descriptor <literal>depends</literal>
                      and <literal>depends-list</literal> tags. The deployment ordering supported by the deployment
                      scanners provides a coarse-grained dependency management in that there is an order to deployments.
                      If dependencies are consistent with the deployment packages then this is a simpler mechanism than
                      having to enumerate the explicit MBean-MBean dependencies. By writing your own filters you can
                      change the coarse grained ordering performed by the deployment scanner.</para>
                  <para>When a component archive is deployed, its nested deployment units are processed in a depth first
                      ordering. Structuring of components into an archive hierarchy is yet another way to manage
                      deployment ordering.You will need to explicitly state your MBean dependencies if your packaging
                      structure does not happen to resolve the dependencies. Let's consider an example component
                      deployment that consists of an MBean that uses an EJB. Here is the structure of the example EAR.</para>
                  <programlisting><emphasis role="bold">output/chap2/chap2-ex3.ear</emphasis>
  +- META-INF/MANIFEST.MF
  +- META-INF/jboss-app.xml
  +- chap2-ex3.jar (archive) [EJB jar]
  | +- META-INF/MANIFEST.MF
  | +- META-INF/ejb-jar.xml
  | +- org/jboss/chap2/ex3/EchoBean.class
  | +- org/jboss/chap2/ex3/EchoLocal.class
  | +- org/jboss/chap2/ex3/EchoLocalHome.class
  +- chap2-ex3.sar (archive) [MBean sar]
  | +- META-INF/MANIFEST.MF
  | +- META-INF/jboss-service.xml
  | +- org/jboss/chap2/ex3/EjbMBeanAdaptor.class
  +- META-INF/application.xml</programlisting>
                  <para>The EAR contains a <literal>chap2-ex3.jar</literal> and <literal>chap2-ex3.sar</literal>. The
                          <literal>chap2-ex3.jar</literal> is the EJB archive and the <literal>chap2-ex3.sar</literal> is
                      the MBean service archive. We have implemented the service as a Dynamic MBean to provide an
                      illustration of their use.</para>
                  <programlisting>package org.jboss.chap2.ex3;
              
  import java.lang.reflect.Method;
  import javax.ejb.CreateException;
  import javax.management.Attribute;
  import javax.management.AttributeList;
  import javax.management.AttributeNotFoundException;
  import javax.management.DynamicMBean;
  import javax.management.InvalidAttributeValueException;
  import javax.management.JMRuntimeException;
  import javax.management.MBeanAttributeInfo;
  import javax.management.MBeanConstructorInfo;
  import javax.management.MBeanInfo;
  import javax.management.MBeanNotificationInfo;
  import javax.management.MBeanOperationInfo;
  import javax.management.MBeanException;
  import javax.management.MBeanServer;
  import javax.management.ObjectName;
  import javax.management.ReflectionException;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  import org.jboss.system.ServiceMBeanSupport;
  
  /** 
   *  An example of a DynamicMBean that exposes select attributes and
   *  operations of an EJB as an MBean.
   *  @author Scott.Stark at jboss.org
   *  @version $Revision: 1.1 $
   */
  public class EjbMBeanAdaptor extends ServiceMBeanSupport
      implements DynamicMBean
  {
      private String helloPrefix;
      private String ejbJndiName;
      private EchoLocalHome home;
      
      /** These are the mbean attributes we expose
       */
      private MBeanAttributeInfo[] attributes = {
          new MBeanAttributeInfo("HelloPrefix", "java.lang.String",
                                 "The prefix message to append to the session echo reply",
                                 true, // isReadable
                                 true, // isWritable
                                 false), // isIs
          new MBeanAttributeInfo("EjbJndiName", "java.lang.String",
                                 "The JNDI name of the session bean local home",
                                 true, // isReadable
                                 true, // isWritable
                                 false) // isIs
      };
  
      /** 
       * These are the mbean operations we expose
       */
      private MBeanOperationInfo[] operations;
      
      /** 
       * We override this method to setup our echo operation info. It
       * could also be done in a ctor.
       */
      public ObjectName preRegister(MBeanServer server,
                                    ObjectName name)
          throws Exception
      {
          log.info("preRegister notification seen");
          
          operations = new MBeanOperationInfo[5];
          
          Class thisClass = getClass();
          Class[] parameterTypes = {String.class};
          Method echoMethod =
              thisClass.getMethod("echo", parameterTypes);
          String desc = "The echo op invokes the session bean echo method and"
              + " returns its value prefixed with the helloPrefix attribute value";
          operations[0] = new MBeanOperationInfo(desc, echoMethod);
              
          // Add the Service interface operations from our super class
          parameterTypes = new Class[0];
          Method createMethod =
              thisClass.getMethod("create", parameterTypes);
          operations[1] = new MBeanOperationInfo("The
                  JBoss Service.create", createMethod);
          Method startMethod =
              thisClass.getMethod("start", parameterTypes);
          operations[2] = new MBeanOperationInfo("The
                  JBoss Service.start", startMethod);
          Method stopMethod =
              thisClass.getMethod("stop", parameterTypes);
          operations[3] = new MBeanOperationInfo("The
                  JBoss Service.stop", startMethod);
          Method destroyMethod =
              thisClass.getMethod("destroy", parameterTypes);
          operations[4] = new MBeanOperationInfo("The
                  JBoss Service.destroy", startMethod);
          return name;
      }
      
      
      // --- Begin ServiceMBeanSupport overides
      protected void createService() throws Exception
      {
          log.info("Notified of create state");
      }
  
      protected void startService() throws Exception
      {
          log.info("Notified of start state");
          InitialContext ctx = new InitialContext();
          home = (EchoLocalHome) ctx.lookup(ejbJndiName);
      }
  
      protected void stopService()
      {
          log.info("Notified of stop state");
      }
  
      // --- End ServiceMBeanSupport overides
              
      public String getHelloPrefix()
      {
          return helloPrefix;
      }
      public void setHelloPrefix(String helloPrefix)
      {
          this.helloPrefix = helloPrefix;
      }
      
      public String getEjbJndiName()
      {
          return ejbJndiName;
      }
      public void setEjbJndiName(String ejbJndiName)
      {
          this.ejbJndiName = ejbJndiName;
      }
      
      public String echo(String arg)
          throws CreateException, NamingException
      {
          log.debug("Lookup EchoLocalHome@"+ejbJndiName);
          EchoLocal bean = home.create();
          String echo = helloPrefix + bean.echo(arg);
          return echo;
      }
      
      // --- Begin DynamicMBean interface methods
      /** 
       *  Returns the management interface that describes this dynamic
       *  resource.  It is the responsibility of the implementation to
       *  make sure the description is accurate.
       *
       * @return the management interface descriptor.
       */
      public MBeanInfo getMBeanInfo()
      {
          String classname = getClass().getName();
          String description = "This is an MBean that uses a session bean in the"
              + " implementation of its echo operation.";
          MBeanInfo[] constructors = null;
          MBeanNotificationInfo[] notifications = null;
          MBeanInfo mbeanInfo = new MBeanInfo(classname,
                                              description, attributes,
                                              constructors, operations,
                                              notifications);
          // Log when this is called so we know when in the
          lifecycle this is used
              Throwable trace = new Throwable("getMBeanInfo trace");
          log.info("Don't panic, just a stack
                  trace", trace);
          return mbeanInfo;
      }
      
      /** 
       *  Returns the value of the attribute with the name matching the
       *  passed string.
       *
       * @param attribute the name of the attribute.
       * @return the value of the attribute.
       * @exception AttributeNotFoundException when there is no such
       * attribute.
       * @exception MBeanException wraps any error thrown by the
       * resource when
       * getting the attribute.
       * @exception ReflectionException wraps any error invoking the
       * resource.
       */
      public Object getAttribute(String attribute)
          throws AttributeNotFoundException, 
                 MBeanException, 
                 ReflectionException
      {
          Object value = null;
          if (attribute.equals("HelloPrefix")) {
              value = getHelloPrefix();
          } else if(attribute.equals("EjbJndiName")) {
              value = getEjbJndiName();
          } else {
              throw new AttributeNotFoundException("Unknown
                  attribute("+attribute+") requested");
          }
          return value;
      }
              
      /** 
       * Returns the values of the attributes with names matching the
       * passed string array.
       *
       * @param attributes the names of the attribute.
       * @return an {@link AttributeList AttributeList} of name
       * and value pairs.
       */
      public AttributeList getAttributes(String[] attributes)
      {
          AttributeList values = new AttributeList();
          for (int a = 0; a &lt; attributes.length; a++) {
              String name = attributes[a];
              try {
                  Object value = getAttribute(name);
                  Attribute attr = new Attribute(name, value);
                  values.add(attr);
              } catch(Exception e) {
                  log.error("Failed to find attribute: "+name, e);
              }
          }
          return values;
      }
              
      /**
       *  Sets the value of an attribute. The attribute and new value
       *  are passed in the name value pair {@link Attribute
       *  Attribute}.
       *
       * @see javax.management.Attribute
       *
       * @param attribute the name and new value of the attribute.
       * @exception AttributeNotFoundException when there is no such
       * attribute.
       * @exception InvalidAttributeValueException when the new value
       * cannot be converted to the type of the attribute.
       * @exception MBeanException wraps any error thrown by the
       * resource when setting the new value.
       * @exception ReflectionException wraps any error invoking the
       * resource.
       */
      public void setAttribute(Attribute attribute)
          throws AttributeNotFoundException, 
                 InvalidAttributeValueException,
                 MBeanException, 
                 ReflectionException
      {
          String name = attribute.getName();
          if (name.equals("HelloPrefix")) { 
              String value = attribute.getValue().toString();
              setHelloPrefix(value);
          } else if(name.equals("EjbJndiName")) {
              String value = attribute.getValue().toString();
              setEjbJndiName(value);
          } else {
              throw new AttributeNotFoundException("Unknown attribute("+name+") requested");
          }
      }
              
      /**
       * Sets the values of the attributes passed as an
       * {@link AttributeList AttributeList} of name and new
       * value pairs.
       *
       * @param attributes the name an new value pairs.
       * @return an {@link AttributeList AttributeList} of name and
       * value pairs that were actually set.
       */
      public AttributeList setAttributes(AttributeList attributes)
      {
          AttributeList setAttributes = new AttributeList();
          for(int a = 0; a &lt; attributes.size(); a++) {
              Attribute attr = (Attribute) attributes.get(a);
              try {
                  setAttribute(attr);
                  setAttributes.add(attr);
              } catch(Exception ignore) {
              }
          }
          return setAttributes;
      }
      
      /**
       *  Invokes a resource operation.
       *
       *  @param actionName the name of the operation to perform.
       *  @param params the parameters to pass to the operation.
       *  @param signature the signartures of the parameters.
       *  @return the result of the operation.
       *  @exception MBeanException wraps any error thrown by the
       *  resource when performing the operation.
       *  @exception ReflectionException wraps any error invoking the
       *  resource.
       */
      public Object invoke(String actionName, Object[] params,
                           String[] signature)
          throws MBeanException,
                 ReflectionException
      {
          Object rtnValue = null;
          log.debug("Begin invoke, actionName="+actionName);
          try {
              if (actionName.equals("echo")) {
                  String arg = (String) params[0];
                  rtnValue = echo(arg);
                  log.debug("Result: "+rtnValue);
              } else if (actionName.equals("create")) {
                  super.create();
              } else if (actionName.equals("start")) {
                  super.start();
              } else if (actionName.equals("stop")) {
                  super.stop();
              } else if (actionName.equals("destroy")) {
                  super.destroy();
              } else {
                  throw new JMRuntimeException("Invalid state,
                  don't know about op="+actionName);
              }
          } catch(Exception e) {
              throw new ReflectionException(e, "echo failed");
          }
  
  
          log.debug("End invoke, actionName="+actionName);
          return rtnValue;
      }
      
      // --- End DynamicMBean interface methods
      
  }</programlisting>
                  <para>Believe it or not, this is a very trivial MBean. The vast majority of the code is there to provide
                      the MBean metadata and handle the callbacks from the MBean Server. This is required because a
                      Dynamic MBean is free to expose whatever management interface it wants. A Dynamic MBean can in fact
                      change its management interface at runtime simply by returning different metadata from the
                          <literal>getMBeanInfo</literal> method. Of course, some clients may not be happy with such a
                      dynamic object, but the MBean Server will do nothing to prevent a Dynamic MBean from changing its
                      interface.</para>
                  <para>There are two points to this example. First, demonstrate how an MBean can depend on an EJB for
                      some of its functionality and second, how to create MBeans with dynamic management interfaces. If we
                      were to write a standard MBean with a static interface for this example it would look like the
                      following.</para>
                  <programlisting>public interface EjbMBeanAdaptorMBean
  {
      public String getHelloPrefix();
      public void setHelloPrefix(String prefix);
      public String getEjbJndiName();
      public void setEjbJndiName(String jndiName);
      public String echo(String arg) throws CreateException, NamingException;
      public void create() throws Exception;
      public void start() throws Exception;
      public void stop();
      public void destroy();
  } </programlisting>
                  <para>Moving to lines 67-83, this is where the MBean operation metadata is constructed. The
                          <literal>echo(String)</literal>, <literal>create()</literal>, <literal>start()</literal>,
                          <literal>stop()</literal> and <literal>destroy()</literal> operations are defined by obtaining
                      the corresponding java.lang.reflect.Method object and adding a description. Let's go through the
                      code and discuss where this interface implementation exists and how the MBean uses the EJB.
                      Beginning with lines 40-51, the two <literal>MBeanAttributeInfo</literal> instances created define
                      the attributes of the MBean. These attributes correspond to the
                          <literal>getHelloPrefix</literal>/<literal>setHelloPrefix</literal> and
                          <literal>getEjbJndiName</literal>/<literal>setEjbJndiName</literal> of the static interface. One
                      thing to note in terms of why one might want to use a Dynamic MBean is that you have the ability to
                      associate descriptive text with the attribute metadata. This is not something you can do with a
                      static interface.</para>
                  <para>Lines 88-103 correspond to the JBoss service life cycle callbacks. Since we are subclassing the
                          <literal>ServiceMBeanSupport</literal> utility class, we override the
                      <literal>createService</literal>, <literal>startService</literal>, and
                      <literal>stopService</literal> template callbacks rather than the <literal>create</literal>,
                          <literal>start</literal>, and <literal>stop</literal> methods of the service interface. Note
                      that we cannot attempt to lookup the <literal>EchoLocalHome</literal> interface of the EJB we make
                      use of until the <literal>startService</literal> method. Any attempt to access the home interface in
                      an earlier life cycle method would result in the name not being found in JNDI because the EJB
                      container had not gotten to the point of binding the home interfaces. Because of this dependency we
                      will need to specify that the MBean service depends on the EchoLocal EJB container to ensure that
                      the service is not started before the EJB container is started. We will see this dependency
                      specification when we look at the service descriptor.</para>
                  <para>Lines 105-121 are the <literal>HelloPrefix</literal> and <literal>EjbJndiName</literal> attribute
                      accessors implementations. These are invoked in response to
                          <literal>getAttribute</literal>/<literal>setAttribute</literal> invocations made through the
                      MBean Server.</para>
                  <para>Lines 123-130 correspond to the <literal>echo(String)</literal> operation implementation. This
                      method invokes the <literal>EchoLocal.echo(String)</literal> EJB method. The local bean interface is
                      created using the <literal>EchoLocalHome</literal> that was obtained in the
                      <literal>startService</literal> method.</para>
                  <para>The remainder of the class makes up the Dynamic MBean interface implementation. Lines 133-152
                      correspond to the MBean metadata accessor callback. This method returns a description of the MBean
                      management interface in the form of the <literal>javax.management.MBeanInfo</literal> object. This
                      is made up of a <literal>description</literal>, the <literal>MBeanAttributeInfo</literal> and
                          <literal>MBeanOperationInfo</literal> metadata created earlier, as well as constructor and
                      notification information. This MBean does not need any special constructors or notifications so this
                      information is null.</para>
                  <para>Lines 154-258 handle the attribute access requests. This is rather tedious and error prone code so
                      a toolkit or infrastructure that helps generate these methods should be used. A Model MBean
                      framework based on XML called XBeans is currently being investigated in JBoss. Other than this, no
                      other Dynamic MBean frameworks currently exist.</para>
                  <para>Lines 260-310 correspond to the operation invocation dispatch entry point. Here the request
                      operation action name is checked against those the MBean handles and the appropriate method is
                      invoked.</para>
                  <para>The <literal>jboss-service.xml</literal> descriptor for the MBean is given below. The dependency
                      on the EJB container MBean is highlighted in bold. The format of the EJB container MBean ObjectName
                      is: <literal>"jboss.j2ee:service=EJB,jndiName=" + &lt;home-jndi-name&gt;</literal> where the
                      &lt;home-jndi-name&gt; is the EJB home interface JNDI name.</para>
                  <programlisting>&lt;server&gt;
      &lt;mbean code="org.jboss.chap2.ex3.EjbMBeanAdaptor"
             name="jboss.book:service=EjbMBeanAdaptor"&gt;
          &lt;attribute name="HelloPrefix"&gt;AdaptorPrefix&lt;/attribute&gt;
          &lt;attribute name="EjbJndiName"&gt;local/chap2.EchoBean&lt;/attribute&gt;
          &lt;depends&gt;jboss.j2ee:service=EJB,jndiName=local/chap2.EchoBean&lt;/depends&gt;
      &lt;/mbean&gt;
  &lt;/server&gt;    </programlisting>
                  <para>Deploy the example ear by running:</para>
                  <programlisting>[examples]$ ant -Dchap=chap2 -Dex=3 run-example</programlisting>
                  <para>On the server console there will be messages similar to the following:</para>
                  <programlisting>14:57:12,906 INFO  [EARDeployer] Init J2EE application: file:/private/tmp/jboss-4.0.1/server/
  default/deploy/chap2-ex3.ear
  14:57:13,044 INFO  [EjbMBeanAdaptor] Don't panic, just a stack trace
  java.lang.Throwable: getMBeanInfo trace
          at org.jboss.chap2.ex3.EjbMBeanAdaptor.getMBeanInfo(EjbMBeanAdaptor.java:153)
          at org.jboss.mx.server.RawDynamicInvoker.getMBeanInfo(RawDynamicInvoker.java:172)
          at org.jboss.mx.server.RawDynamicInvoker.preRegister(RawDynamicInvoker.java:187)
  ...
  14:57:13,088 INFO  [EjbMBeanAdaptor] preRegister notification seen
  14:57:13,093 INFO  [EjbMBeanAdaptor] Don't panic, just a stack trace
  java.lang.Throwable: getMBeanInfo trace
          at org.jboss.chap2.ex3.EjbMBeanAdaptor.getMBeanInfo(EjbMBeanAdaptor.java:153)
          at org.jboss.mx.server.RawDynamicInvoker.getMBeanInfo(RawDynamicInvoker.java:172)
          at org.jboss.mx.server.registry.BasicMBeanRegistry.registerMBean(BasicMBeanRegistry.j
  ava:207)
  ...
  14:57:13,117 INFO  [EjbMBeanAdaptor] Don't panic, just a stack trace
  java.lang.Throwable: getMBeanInfo trace
          at org.jboss.chap2.ex3.EjbMBeanAdaptor.getMBeanInfo(EjbMBeanAdaptor.java:153)
          at org.jboss.mx.server.RawDynamicInvoker.getMBeanInfo(RawDynamicInvoker.java:172)
          at org.jboss.mx.server.registry.BasicMBeanRegistry.registerMBean(BasicMBeanRegistry.j
  ava:235)
  ...        
  14:57:13,140 WARN  [EjbMBeanAdaptor] Unexcepted error accessing MBeanInfo for null
  java.lang.NullPointerException
          at org.jboss.system.ServiceMBeanSupport.postRegister(ServiceMBeanSupport.java:418)
          at org.jboss.mx.server.RawDynamicInvoker.postRegister(RawDynamicInvoker.java:226)
          at org.jboss.mx.server.registry.BasicMBeanRegistry.registerMBean(BasicMBeanRegistry.j
  ava:312)
  ...
  14:57:13,203 INFO  [EjbMBeanAdaptor] Don't panic, just a stack trace
  java.lang.Throwable: getMBeanInfo trace
          at org.jboss.chap2.ex3.EjbMBeanAdaptor.getMBeanInfo(EjbMBeanAdaptor.java:153)
          at org.jboss.mx.server.RawDynamicInvoker.getMBeanInfo(RawDynamicInvoker.java:172)
          at org.jboss.mx.server.MBeanServerImpl.getMBeanInfo(MBeanServerImpl.java:481)
  ... 
  14:57:13,232 INFO  [EjbMBeanAdaptor] Don't panic, just a stack trace
  java.lang.Throwable: getMBeanInfo trace
          at org.jboss.chap2.ex3.EjbMBeanAdaptor.getMBeanInfo(EjbMBeanAdaptor.java:153)
          at org.jboss.mx.server.RawDynamicInvoker.getMBeanInfo(RawDynamicInvoker.java:172)
          at org.jboss.mx.server.MBeanServerImpl.getMBeanInfo(MBeanServerImpl.java:481)
  ...
  14:57:13,420 INFO  [EjbModule] Deploying Chap2EchoInfoBean
  14:57:13,443 INFO  [EjbModule] Deploying chap2.EchoBean
  14:57:13,488 INFO  [EjbMBeanAdaptor] Don't panic, just a stack trace
  java.lang.Throwable: getMBeanInfo trace
          at org.jboss.chap2.ex3.EjbMBeanAdaptor.getMBeanInfo(EjbMBeanAdaptor.java:153)
          at org.jboss.mx.server.RawDynamicInvoker.getMBeanInfo(RawDynamicInvoker.java:172)
          at org.jboss.mx.server.MBeanServerImpl.getMBeanInfo(MBeanServerImpl.java:481)
  ...
  14:57:13,542 INFO  [EjbMBeanAdaptor] Don't panic, just a stack trace
  java.lang.Throwable: getMBeanInfo trace
          at org.jboss.chap2.ex3.EjbMBeanAdaptor.getMBeanInfo(EjbMBeanAdaptor.java:153)
          at org.jboss.mx.server.RawDynamicInvoker.getMBeanInfo(RawDynamicInvoker.java:172)
          at org.jboss.mx.server.MBeanServerImpl.getMBeanInfo(MBeanServerImpl.java:481)
  ...
  14:57:13,558 INFO  [EjbMBeanAdaptor] Begin invoke, actionName=create
  14:57:13,560 INFO  [EjbMBeanAdaptor] Notified of create state
  14:57:13,562 INFO  [EjbMBeanAdaptor] End invoke, actionName=create
  14:57:13,604 INFO  [EjbMBeanAdaptor] Don't panic, just a stack trace
  java.lang.Throwable: getMBeanInfo trace
          at org.jboss.chap2.ex3.EjbMBeanAdaptor.getMBeanInfo(EjbMBeanAdaptor.java:153)
          at org.jboss.mx.server.RawDynamicInvoker.getMBeanInfo(RawDynamicInvoker.java:172)
          at org.jboss.mx.server.MBeanServerImpl.getMBeanInfo(MBeanServerImpl.java:481)
          at org.jboss.mx.server.MBeanServerImpl.isInstanceOf(MBeanServerImpl.java:639)
  ... 
  14:57:13,621 INFO  [EjbMBeanAdaptor] Don't panic, just a stack trace
  java.lang.Throwable: getMBeanInfo trace
          at org.jboss.chap2.ex3.EjbMBeanAdaptor.getMBeanInfo(EjbMBeanAdaptor.java:153)
          at org.jboss.mx.server.RawDynamicInvoker.getMBeanInfo(RawDynamicInvoker.java:172)
          at org.jboss.mx.server.MBeanServerImpl.getMBeanInfo(MBeanServerImpl.java:481)
          at org.jboss.mx.util.JMXInvocationHandler.&lt;init&gt;(JMXInvocationHandler.java:110)
          at org.jboss.mx.util.MBeanProxy.get(MBeanProxy.java:76)
          at org.jboss.mx.util.MBeanProxy.get(MBeanProxy.java:64)
  14:57:13,641 INFO  [EjbMBeanAdaptor] Begin invoke, actionName=getState
  14:57:13,942 INFO  [EjbMBeanAdaptor] Begin invoke, actionName=start
  14:57:13,944 INFO  [EjbMBeanAdaptor] Notified of start state
  14:57:13,951 INFO  [EjbMBeanAdaptor] Testing Echo
  14:57:13,983 INFO  [EchoBean] echo, info=echo info, arg=, arg=startService
  14:57:13,986 INFO  [EjbMBeanAdaptor] echo(startService) = startService
  14:57:13,988 INFO  [EjbMBeanAdaptor] End invoke, actionName=start
  14:57:13,991 INFO  [EJBDeployer] Deployed: file:/private/tmp/jboss-4.0.1/server/default/tmp/d
  eploy/tmp1418chap2-ex3.ear-contents/chap2-ex3.jar
  14:57:14,075 INFO  [EARDeployer] Started J2EE application: file:/private/tmp/jboss-4.0.1/serv
  er/default/deploy/chap2-ex3.ear</programlisting>
                  <para>The stack traces are not exceptions. They are traces coming from line 150 of the
                          <literal>EjbMBeanAdaptor</literal> code to demonstrate that clients ask for the MBean interface
                      when they want to discover the MBean's capabilities. Notice that the EJB container (lines with
                      [EjbModule]) is started before the example MBean (lines with [EjbMBeanAdaptor]).</para>
                  <para>Now, let's invoke the echo method using the JMX console web application. Go to the JMX Console
                          (<ulink url="http://localhost:8080/jmx-console"/>) and find the
                          <emphasis>service=EjbMBeanAdaptor</emphasis> in the <emphasis>jboss.book</emphasis> domain.
                      Click on the link and scroll down to the <emphasis>echo</emphasis> operation section. The view
                      should be like that shown in <xref linkend="ch2.ejbadaptor.fig"/>.</para>
                  <figure id="ch2.ejbadaptor.fig">
                      <title>The EjbMBeanAdaptor MBean operations JMX console view</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/console-echo-operation.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>As shown, we have already entered an argument string of <literal>-echo-arg</literal> into the
                      ParamValue text field. Press the Invoke button and a result string of
                          <literal>AdaptorPrefix-echo-arg</literal> is displayed on the results page. The server console
                      will show several stack traces from the various metadata queries issues by the JMX console and the
                      MBean invoke method debugging lines:</para>
                  <programlisting>10:51:48,671 INFO [EjbMBeanAdaptor] Begin invoke, actionName=echo
  10:51:48,671 INFO [EjbMBeanAdaptor] Lookup EchoLocalHome at local/chap2.EchoBean
  10:51:48,687 INFO [EchoBean] echo, info=echo info, arg=, arg=-echo-arg
  10:51:48,687 INFO [EjbMBeanAdaptor] Result: AdaptorPrefix-echo-arg
  10:51:48,687 INFO [EjbMBeanAdaptor] End invoke, actionName=echo
  </programlisting>
              </section>
          </section>
          <section id="ch2.deployers">
              <title>JBoss Deployer Architecture</title>
              <para>JBoss has an extensible deployment architecture that allows one to incorporate components into the
                  bare JBoss JMX microkernel. The <literal>MainDeployer</literal> is the deployment entry point. Requests
                  to deploy a component are sent to the <literal>MainDeployer</literal> and it determines if there is a
                  subdeployer capable of handling the deployment, and if there is, it delegates the deployment to the
                  subdeployer. We saw an example of this when we looked at how the <literal>MainDeployer</literal> used
                  the <literal>SARDeployer</literal> to deploy MBean services. Among the deployers provided with JBoss
                  are:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">AbstractWebDeployer</emphasis>: This subdeployer handles web application
                          archives (WARs). It accepts deployment archives and directories whose name ends with a
                              <literal>war</literal> suffix. WARs must have a <literal>WEB-INF/web.xml</literal>
                          descriptor and may have a <literal>WEB-INF/jboss-web.xml</literal> descriptor.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">EARDeployer</emphasis>: This subdeployer handles enterprise application
                          archives (EARs). It accepts deployment archives and directories whose name ends with an
                              <literal>ear</literal> suffix. EARs must have a <literal>META-INF/application.xml</literal>
                          descriptor and may have a <literal>META-INF/jboss-app.xml</literal> descriptor.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">EJBDeployer</emphasis>: This subdeployer handles enterprise bean jars. It
                          accepts deployment archives and directories whose name ends with a <literal>jar</literal>
                          suffix. EJB jars must have a <literal>META-INF/ejb-jar.xml</literal> descriptor and may have a
                              <literal>META-INF/jboss.xml</literal> descriptor.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">JARDeployer</emphasis>: This subdeployer handles library JAR archives. The
                          only restriction it places on an archive is that it cannot contain a <literal>WEB-INF</literal>
                          directory.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">RARDeployer</emphasis>: This subdeployer handles JCA resource archives
                          (RARs). It accepts deployment archives and directories whose name ends with a
                          <literal>rar</literal> suffix. RARs must have a <literal>META-INF/ra.xml</literal>
                      descriptor.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">SARDeployer</emphasis>: This subdeployer handles JBoss MBean service
                          archives (SARs). It accepts deployment archives and directories whose name ends with a
                              <literal>sar</literal> suffix, as well as standalone XML files that end with
                              <literal>service.xml</literal>. SARs that are jars must have a
                              <literal>META-INF/jboss-service.xml</literal> descriptor.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">XSLSubDeployer</emphasis>: This subdeployer deploys arbitrary XML files.
                          JBoss uses the XSLSubDeployer to deploy <literal>ds.xml</literal> files and transform them into
                              <literal>service.xml</literal> files for the <literal>SARDeployer</literal>. However, it is
                          not limited to just this task.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">HARDeployer</emphasis>: This subdeployer deploys hibernate archives
                          (HARs). It accepts deployment archives and directories whose name ends with a
                          <literal>har</literal> suffix. HARs must have a
                          <literal>META-INF/hibernate-service.xml</literal> descriptor. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">AspectDeployer</emphasis>: This subdeployer deploys AOP archives. It
                          accepts deployment archives and directories whose name ends with an <literal>aop</literal>
                          suffix as well as <literal>aop.xml</literal> files. AOP archives must have a
                              <literal>META-INF/jboss-aop.xml</literal> descriptor. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">ClientDeployer</emphasis>: This subdeployer deploys J2EE application
                          clients. It accepts deployment archives and directories whose name ends with a
                          <literal>jar</literal> suffix. J2EE clients must have a
                          <literal>META-INF/application-client.xml</literal> descriptor and may have a
                              <literal>META-INF/jboss-client.xml</literal> descriptor. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">BeanShellSubDeployer</emphasis>: This subdeployer deploys bean shell
                          scripts as MBeans. It accepts files whose name ends with a <literal>bsh</literal> suffix.
                      </para>
                  </listitem>
              </itemizedlist>
              <para>The MainDeployer, JARDeployer and SARDeployer are hard coded deployers in the JBoss server core. All
                  other deployers are MBean services that register themselves as deployers with the MainDeployer using the
                      <literal>addDeployer(SubDeployer)</literal> operation. </para>
              <para> The <literal>MainDeployer</literal> communicates information about the component to be deployed the
                      <literal>SubDeployer</literal> using a <literal>DeploymentInfo</literal> object. The
                      <literal>DeploymentInfo</literal> object is a data structure that encapsulates the complete state of
                  a deployable component. </para>
              <para>When the <literal>MainDeployer</literal> receives a deployment request, it iterates through its
                  registered subdeployers and invokes the <literal>accepts(DeploymentInfo)</literal> method on the
                  subdeployer. The first subdeployer to return true is chosen. The MainDeployer will delegate the init,
                  create, start, stop and destroy deployment life cycle operations to the subdeployer.</para>
              <section>
                  <title>Deployers and ClassLoaders</title>
                  <para>Deployers are the mechanism by which components are brought into a JBoss server. Deployers are
                      also the creators of the majority of UCL instances, and the primary creator is the MainDeployer. The
                      MainDeployer creates the UCL for a deployment early on during its init method. The UCL is created by
                      calling the DeploymentInfo.createClassLoaders() method. Only the topmost
                      <literal>DeploymentInfo</literal> will actually create a UCL. All subdeployments will add their
                      class paths to their parent <literal>DeploymentInfo</literal> UCL. Every deployment does have a
                      standalone URLClassLoader that uses the deployment URL as its path. This is used to localize the
                      loading of resources such as deployment descriptors. <xref linkend="ch2.earclassloader.fig"/>
                      provides an illustration of the interaction between Deployers, DeploymentInfos and class loaders.</para>
                  <figure id="ch2.earclassloader.fig">
                      <title>An illustration of the class loaders involved with an EAR deployment</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/Chap2-43.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The figure illustrates an EAR deployment with EJB and WAR subdeployments. The EJB deployment
                      references the <literal>lib/util.jar</literal> utility jar via its manifest. The WAR includes
                      classes in its <literal>WEB-INF/classes</literal> directory as well as the
                          <literal>WEB-INF/lib/jbosstest-web-util.jar</literal>. Each deployment has a
                          <literal>DeploymentInfo</literal> instance that has a <literal>URLClassLoader</literal> pointing
                      to the deployment archive. The <literal>DeploymentInfo</literal> associated with
                      <literal>some.ear</literal> is the only one to have a UCL created. The <literal>ejbs.jar</literal>
                      and <literal>web.war</literal>
                      <literal>DeploymentInfo</literal>s add their deployment archive to the <literal>some.ear</literal>
                      UCL classpath, and share this UCL as their deployment UCL. The <literal>EJBDeployer</literal> also
                      adds any manifest jars to the EAR UCL.</para>
                  <para>The <literal>WARDeployer</literal> behaves differently than other deployers in that it only adds
                      its WAR archive to the <literal>DeploymentInfo</literal> UCL classpath. The loading of classes from
                      the WAR <literal>WEB-INF/classes</literal> and <literal>WEB-INF/lib</literal> locations is handled
                      by the servlet container class loader. The servlet container class loaders delegate to the WAR
                          <literal>DeploymentInfo</literal> UCL as their parent class loader, but the server container
                      class loader is not part of the JBoss class loader repository. Therefore, classes inside of a WAR
                      are not visible to other components. Classes that need to be shared between web application
                      components and other components such as EJBs, and MBeans need to be loaded into the shared class
                      loader repository either by including the classes into a SAR or EJB deployment, or by referencing a
                      jar containing the shared classes through a manifest <literal>Class-Path</literal> entry. In the
                      case of a SAR, the SAR classpath element in the service deployment serves the same purpose as a JAR
                      manifest <literal>Class-Path</literal>.</para>
              </section>
          </section>
  
          <section id="ch2.remoteaccess">
              <title>Remote Access to Services, Detached Invokers</title>
              <para>In addition to the MBean services notion that allows for the ability to integrate arbitrary
                  functionality, JBoss also has a detached invoker concept that allows MBean services to expose functional
                  interfaces via arbitrary protocols for remote access by clients. The notion of a detached invoker is
                  that remoting and the protocol by which a service is accessed is a functional aspect or service
                  independent of the component. Thus, one can make a naming service available for use via RMI/JRMP,
                  RMI/HTTP, RMI/SOAP, or any arbitrary custom transport.</para>
              <para>Let's begin our discussion of the detached invoker architecture with an overview of the components
                  involved. The main components in the detached invoker architecture are shown in <xref
                      linkend="ch2.dinv.fig"/>.</para>
              <figure id="ch2.dinv.fig">
                  <title>The main components in the detached invoker architecture</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/Chap2-47.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>On the client side, there exists a client proxy which exposes the interface(s) of the MBean service.
                  This is the same smart, compile-less dynamic proxy that we use for EJB home and remote interfaces. The
                  only difference between the proxy for an arbitrary service and the EJB is the set of interfaces exposed
                  as well as the client side interceptors found inside the proxy. The client interceptors are represented
                  by the rectangles found inside of the client proxy. An interceptor is an assembly line type of pattern
                  that allows for transformation of a method invocation and/or return values. A client obtains a proxy
                  through some lookup mechanism, typically JNDI. Although RMI is indicated in <xref linkend="ch2.dinv.fig"
                  />, the only real requirement on the exposed interface and its types is that they are serializable
                  between the client server over JNDI as well as the transport layer.</para>
              <para>The choice of the transport layer is determined by the last interceptor in the client proxy, which is
                  referred to as the <emphasis>Invoker Interceptor</emphasis> in <xref linkend="ch2.dinv.fig"/>. The
                  invoker interceptor contains a reference to the transport specific stub of the server side
                      <emphasis>Detached Invoker</emphasis> MBean service. The invoker interceptor also handles the
                  optimization of calls that occur within the same VM as the target MBean. When the invoker interceptor
                  detects that this is the case the call is passed to a call-by-reference invoker that simply passes the
                  invocation along to the target MBean.</para>
              <para>The detached invoker service is responsible for making a generic invoke operation available via the
                  transport the detached invoker handles. The <literal>Invoker</literal> interface illustrates the generic
                  invoke operation.</para>
              <programlisting>
  package org.jboss.invocation;
               
  import java.rmi.Remote;
  import org.jboss.proxy.Interceptor;
  import org.jboss.util.id.GUID;
               
               
  public interface Invoker
      extends Remote
  {
      GUID ID = new GUID();
  
      String getServerHostName() throws Exception;
   
      Object invoke(Invocation invocation) throws Exception;
  }</programlisting>
              <para>The Invoker interface extends <literal>Remote</literal> to be compatible with RMI, but this does not
                  mean that an invoker must expose an RMI service stub. The detached invoker service simply acts as a
                  transport gateway that accepts invocations represented as the
                  <literal>org.jboss.invocation.Invocation</literal> object over its specific transport, unmarshalls the
                  invocation, forwards the invocation onto the destination MBean service, represented by the
                      <emphasis>Target MBean</emphasis> in <xref linkend="ch2.dinv.fig"/>, and marshalls the return value
                  or exception resulting from the forwarded call back to the client.</para>
              <para>The <literal>Invocation</literal> object is just a representation of a method invocation context. This
                  includes the target MBean name, the method, the method arguments, a context of information associated
                  with the proxy by the proxy factory, and an arbitrary map of data associated with the invocation by the
                  client proxy interceptors. </para>
              <para>The configuration of the client proxy is done by the server side proxy factory MBean service,
                  indicated by the <emphasis>Proxy Factory</emphasis> component in <xref linkend="ch2.dinv.fig"/>. The
                  proxy factory performs the following tasks:</para>
              <itemizedlist>
                  <listitem>
                      <para>Create a dynamic proxy that implements the interface the target MBean wishes to expose.</para>
                  </listitem>
                  <listitem>
                      <para>Associate the client proxy interceptors with the dynamic proxy handler.</para>
                  </listitem>
                  <listitem>
                      <para>Associate the invocation context with the dynamic proxy. This includes the target MBean,
                          detached invoker stub and the proxy JNDI name.</para>
                  </listitem>
                  <listitem>
                      <para>Make the proxy available to clients by binding the proxy into JNDI.</para>
                  </listitem>
              </itemizedlist>
              <para>The last component in <xref linkend="ch2.dinv.fig"/> is the <emphasis>Target MBean</emphasis> service
                  that wishes to expose an interface for invocations to remote clients. The steps required for an MBean
                  service to be accessible through a given interface are:</para>
              <itemizedlist>
                  <listitem>
                      <para>Define a JMX operation matching the signature: <literal>public Object
                              invoke(org.jboss.invocation.Invocation) throws Exception</literal>
                      </para>
                  </listitem>
                  <listitem>
                      <para>Create a <literal>HashMap&lt;Long, Method&gt;</literal> mapping from the exposed
                          interface <literal>java.lang.reflect.Method</literal>s to the long hash representation using the
                              <literal>org.jboss.invocation.MarshalledInvocation.calculateHash</literal> method.</para>
                  </listitem>
                  <listitem>
                      <para>Implement the <literal>invoke(Invocation)</literal> JMX operation and use the interface method
                          hash mapping to transform from the long hash representation of the invoked method to the
                              <literal>java.lang.reflect.Method</literal> of the exposed interface. Reflection is used to
                          perform the actual invocation on the object associated with the MBean service that actually
                          implements the exposed interface.</para>
                  </listitem>
              </itemizedlist>
              <section id="ch2.detinv.sect">
                  <title>A Detached Invoker Example, the MBeanServer Invoker Adaptor Service</title>
                  <para>In the section on connecting to the JMX server we mentioned that there was a service that allows
                      one to access the <literal>javax.management.MBeanServer</literal> via any protocol using an invoker
                      service. In this section we present the
                          <literal>org.jboss.jmx.connector.invoker.InvokerAdaptorService</literal> and its configuration
                      for access via RMI/JRMP as an example of the steps required to provide remote access to an MBean
                      service.</para>
                  <para>The <literal>InvokerAdaptorService</literal> is a simple MBean service that only exists to fulfill
                      the target MBean role in the detached invoker pattern.</para>
                  <example>
                      <title>The InvokerAdaptorService MBean</title>
                      <programlisting>package org.jboss.jmx.connector.invoker;
  public interface InvokerAdaptorServiceMBean
      extends org.jboss.system.ServiceMBean
  {
      Class getExportedInterface();
      void setExportedInterface(Class exportedInterface);
  
      Object invoke(org.jboss.invocation.Invocation invocation)
          throws Exception;
  }
  
  package org.jboss.jmx.connector.invoker;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.lang.reflect.UndeclaredThrowableException;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.Map;
  
  import javax.management.MBeanServer;
  import javax.management.ObjectName;
  
  import org.jboss.invocation.Invocation;
  import org.jboss.invocation.MarshalledInvocation;
  import org.jboss.mx.server.ServerConstants;
  import org.jboss.system.ServiceMBeanSupport;
  import org.jboss.system.Registry;
  
  public class InvokerAdaptorService
      extends ServiceMBeanSupport
      implements InvokerAdaptorServiceMBean, ServerConstants
  {
      private static ObjectName mbeanRegistry;
      
      static {
          try {
              mbeanRegistry = new ObjectName(MBEAN_REGISTRY);
          } catch (Exception e) {
              throw new RuntimeException(e.toString());
          }
      }
  
      private Map marshalledInvocationMapping = new HashMap();
      private Class exportedInterface;
  
      public Class getExportedInterface()
      {
          return exportedInterface;
      }
  
      public void setExportedInterface(Class exportedInterface)
      {
          this.exportedInterface = exportedInterface;
      }
  
      protected void startService()
          throws Exception
      {
          // Build the interface method map
          Method[] methods = exportedInterface.getMethods();
          HashMap tmpMap = new HashMap(methods.length);
          for (int m = 0; m &lt; methods.length; m ++) {
              Method method = methods[m];
              Long hash = new Long(MarshalledInvocation.calculateHash(method));
              tmpMap.put(hash, method);
          }
  
          marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap);
          // Place our ObjectName hash into the Registry so invokers can
          // resolve it
          Registry.bind(new Integer(serviceName.hashCode()), serviceName);
      }
  
      protected void stopService()
          throws Exception
      {
          Registry.unbind(new Integer(serviceName.hashCode()));
      }
  
  
      public Object invoke(Invocation invocation)
          throws Exception
      {
          // Make sure we have the correct classloader before unmarshalling
          Thread thread = Thread.currentThread();
          ClassLoader oldCL = thread.getContextClassLoader();
  
          // Get the MBean this operation applies to
          ClassLoader newCL = null;
          ObjectName objectName = (ObjectName) 
              invocation.getValue("JMX_OBJECT_NAME");
          if (objectName != null) {
              // Obtain the ClassLoader associated with the MBean deployment
              newCL = (ClassLoader) 
                  server.invoke(mbeanRegistry, "getValue",
                                new Object[] { objectName, CLASSLOADER },
                                new String[] { ObjectName.class.getName(),
                                               "java.lang.String" });
          }
          
          if (newCL != null &amp;&amp; newCL != oldCL) {
              thread.setContextClassLoader(newCL);
          }
  
          try {
              // Set the method hash to Method mapping
              if (invocation instanceof MarshalledInvocation) {
                  MarshalledInvocation mi = (MarshalledInvocation) invocation;
                  mi.setMethodMap(marshalledInvocationMapping);
              }
  
              // Invoke the MBeanServer method via reflection
              Method method = invocation.getMethod();
              Object[] args = invocation.getArguments();
              Object value = null;
              try {
                  String name = method.getName();
                  Class[] sig = method.getParameterTypes();
                  Method mbeanServerMethod =
                      MBeanServer.class.getMethod(name, sig);
                  value = mbeanServerMethod.invoke(server, args);
              } catch(InvocationTargetException e) {
                  Throwable t = e.getTargetException();
                  if (t instanceof Exception) {
                      throw (Exception) t;
                  } else {
                      throw new UndeclaredThrowableException(t, method.toString());
                  }
              }
  
              return value;
          } finally {
              if (newCL != null &amp;&amp; newCL != oldCL) {
                  thread.setContextClassLoader(oldCL);
              }
          }
      }
  }    </programlisting>
                  </example>
                  <para>Let's go through the key details of this service. The
                      <literal>InvokerAdaptorServiceMBean</literal> Standard MBean interface of the
                          <literal>InvokerAdaptorService</literal> has a single <literal>ExportedInterface</literal>
                      attribute and a single <literal>invoke(Invocation)</literal> operation. The
                          <literal>ExportedInterface</literal> attribute allows customization of the type of interface the
                      service exposes to clients. This has to be compatible with the <literal>MBeanServer</literal> class
                      in terms of method name and signature. The <literal>invoke(Invocation)</literal> operation is the
                      required entry point that target MBean services must expose to participate in the detached invoker
                      pattern. This operation is invoked by the detached invoker services that have been configured to
                      provide access to the <literal>InvokerAdaptorService</literal>.</para>
                  <para>Lines 54-64 of the InvokerAdaptorService build the HashMap&lt;Long, Method&gt; of the
                      ExportedInterface Class using the <literal>
                          org.jboss.invocation.MarshalledInvocation.calculateHash(Method)</literal> utility method.
                      Because <literal>java.lang.reflect.Method</literal> instances are not serializable, a
                          <literal>MarshalledInvocation</literal> version of the non-serializable
                      <literal>Invocation</literal> class is used to marshall the invocation between the client and
                      server. The <literal>MarshalledInvocation</literal> replaces the Method instances with their
                      corresponding hash representation. On the server side, the <literal>MarshalledInvocation</literal>
                      must be told what the hash to Method mapping is.</para>
                  <para>Line 64 creates a mapping between the <literal>InvokerAdaptorService</literal> service name and
                      its hash code representation. This is used by detached invokers to determine what the target MBean
                          <literal>ObjectName</literal> of an <literal>Invocation</literal> is. When the target MBean name
                      is store in the <literal>Invocation</literal>, its store as its hashCode because
                      <literal>ObjectName</literal>s are relatively expensive objects to create. The
                          <literal>org.jboss.system.Registry</literal> is a global map like construct that invokers use to
                      store the hash code to <literal>ObjectName</literal> mappings in.</para>
                  <para>Lines 77-93 obtain the name of the MBean on which the MBeanServer operation is being performed and
                      lookup the class loader associated with the MBean's SAR deployment. This information is available
                      via the <literal>org.jboss.mx.server.registry.BasicMBeanRegistry</literal>, a JBoss JMX
                      implementation specific class. It is generally necessary for an MBean to establish the correct class
                      loading context because the detached invoker protocol layer may not have access to the class loaders
                      needed to unmarshall the types associated with an invocation.</para>
                  <para>Lines 101-105 install the <literal>ExposedInterface</literal> class method hash to method mapping
                      if the invocation argument is of type <literal>MarshalledInvocation</literal>. The method mapping
                      calculated previously at lines 54-62 is used here.</para>
                  <para>Lines 107-114 perform a second mapping from the <literal>ExposedInterface</literal> Method to the
                      matching method of the MBeanServer class. The <literal>InvokerServiceAdaptor</literal> decouples the
                          <literal>ExposedInterface</literal> from the MBeanServer class in that it allows an arbitrary
                      interface. This is needed on one hand because the standard
                      <literal>java.lang.reflect.Proxy</literal> class can only proxy interfaces. It also allows one to
                      only expose a subset of the MBeanServer methods and add transport specific exceptions like
                          <literal>java.rmi.RemoteException</literal> to the <literal>ExposedInterface</literal> method
                      signatures.</para>
                  <para>Line 115 dispatches the MBeanServer method invocation to the MBeanServer instance to which the
                          <literal>InvokerAdaptorService</literal> was deployed. The server instance variable is inherited
                      from the <literal>ServiceMBeanSupport</literal> superclass.</para>
                  <para>Lines 117-124 handle any exceptions coming from the reflective invocation including the unwrapping
                      of any declared exception thrown by the invocation.</para>
                  <para>Line 126 is the return of the successful MBeanServer method invocation result.</para>
                  <para>Note that the <literal>InvokerAdaptorService</literal> MBean does not deal directly with any
                      transport specific details. There is the calculation of the method hash to Method mapping, but this
                      is a transport independent detail.</para>
                  <para>Now let's take a look at how the <literal>InvokerAdaptorService</literal> may be used to expose
                      the same <literal>org.jboss.jmx.adaptor.rmi.RMIAdaptor</literal> interface via RMI/JRMP as seen in
                      Connecting to JMX Using RMI. We will start by presenting the proxy factory and
                          <literal>InvokerAdaptorService</literal> configurations found in the default setup in the
                          <literal>jmx-invoker-adaptor-service.sar</literal> deployment. <xref
                          linkend="ch2.jmxinvokersar.ex"/> shows the <literal>jboss-service.xml</literal> descriptor for
                      this deployment.</para>
                  <example id="ch2.jmxinvokersar.ex">
                      <title>The default jmx-invoker-adaptor-server.sar jboss-service.xml deployment descriptor</title>
                      <programlisting>&lt;server&gt;
      &lt;!-- The JRMP invoker proxy configuration for the InvokerAdaptorService --&gt;
      &lt;mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
             name="jboss.jmx:type=adaptor,name=Invoker,protocol=jrmp,service=proxyFactory"&gt;
          &lt;!-- Use the standard JRMPInvoker from conf/jboss-service.xml --&gt;
          &lt;attribute name="InvokerName"&gt;jboss:service=invoker,type=jrmp&lt;/attribute&gt;
          &lt;!-- The target MBean is the InvokerAdaptorService configured below --&gt;
          &lt;attribute name="TargetName"&gt;jboss.jmx:type=adaptor,name=Invoker&lt;/attribute&gt;
          &lt;!-- Where to bind the RMIAdaptor proxy --&gt;
          &lt;attribute name="JndiName"&gt;jmx/invoker/RMIAdaptor&lt;/attribute&gt;
          &lt;!-- The RMI compabitle MBeanServer interface --&gt;
          &lt;attribute name="ExportedInterface"&gt;org.jboss.jmx.adaptor.rmi.RMIAdaptor&lt;/attribute&gt;
          &lt;attribute name="ClientInterceptors"&gt;
              &lt;iterceptors&gt;
                  &lt;interceptor&gt;org.jboss.proxy.ClientMethodInterceptor&lt;/interceptor&gt;
                  &lt;interceptor&gt;
                      org.jboss.jmx.connector.invoker.client.InvokerAdaptorClientInterceptor 
                  &lt;/interceptor&gt;
                  &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
              &lt;/iterceptors&gt;
          &lt;/attribute&gt;
          &lt;depends&gt;jboss:service=invoker,type=jrmp&lt;/depends&gt;
      &lt;/mbean&gt;  
      &lt;!-- This is the service that handles the RMIAdaptor invocations by routing
           them to the MBeanServer the service is deployed under. --&gt;
      &lt;mbean code="org.jboss.jmx.connector.invoker.InvokerAdaptorService" 
             name="jboss.jmx:type=adaptor,name=Invoker"&gt;
          &lt;attribute name="ExportedInterface"&gt;org.jboss.jmx.adaptor.rmi.RMIAdaptor&lt;/attribute&gt;
      &lt;/mbean&gt;
  &lt;/server&gt;
  </programlisting>
                  </example>
                  <para>The first MBean, <literal>org.jboss.invocation.jrmp.server.JRMPProxyFactory</literal>, is the
                      proxy factory MBean service that creates proxies for the RMI/JRMP protocol. The configuration of
                      this service as shown in <xref linkend="ch2.jmxinvokersar.ex"/> states that the JRMPInvoker will be
                      used as the detached invoker, the <literal>InvokerAdaptorService</literal> is the target mbean to
                      which requests will be forwarded, that the proxy will expose the <literal>RMIAdaptor</literal>
                      interface, the proxy will be bound into JNDI under the name
                      <literal>jmx/invoker/RMIAdaptor</literal>, and the proxy will contain 3 interceptors:
                          <literal>ClientMethodInterceptor</literal>, <literal>InvokerAdaptorClientInterceptor</literal>,
                          <literal>InvokerInterceptor</literal>. The configuration of the
                      <literal>InvokerAdaptorService</literal> simply sets the RMIAdaptor interface that the service is
                      exposing.</para>
                  <para>The last piece of the configuration for exposing the <literal>InvokerAdaptorService</literal> via
                      RMI/JRMP is the detached invoker. The detached invoker we will use is the standard RMI/JRMP invoker
                      used by the EJB containers for home and remote invocations, and this is the
                          <literal>org.jboss.invocation.jrmp.server.JRMPInvoker</literal> MBean service configured in the
                          <literal>conf/jboss-service.xml</literal> descriptor. That we can use the same service instance
                      emphasizes the detached nature of the invokers. The JRMPInvoker simply acts as the RMI/JRMP endpoint
                      for all RMI/JRMP proxies regardless of the interface(s) the proxies expose or the service the
                      proxies utilize.</para>
              </section>
              <section>
                  <title>Detached Invoker Reference</title>
                  <section>
                      <title>The JRMPInvoker - RMI/JRMP Transport</title>
                      <para>The <literal>org.jboss.invocation.jrmp.server.JRMPInvoker</literal> class is an MBean service
                          that provides the RMI/JRMP implementation of the Invoker interface. The JRMPInvoker exports
                          itself as an RMI server so that when it is used as the Invoker in a remote client, the
                          JRMPInvoker stub is sent to the client instead and invocations use the RMI/JRMP protocol.</para>
                      <para>The JRMPInvoker MBean supports a number of attribute to configure the RMI/JRMP transport
                          layer. Its configurable attributes are:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">RMIObjectPort</emphasis>: sets the RMI server socket listening
                                  port number. This is the port RMI clients will connect to when communicating through the
                                  proxy interface. The default setting in the <literal>jboss-service.xml</literal>
                                  descriptor is 4444, and if not specified, the attribute defaults to 0 to indicate an
                                  anonymous port should be used.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">RMIClientSocketFactory</emphasis>: specifies a fully qualified
                                  class name for the <literal>java.rmi.server.RMIClientSocketFactory</literal> interface
                                  to use during export of the proxy interface.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">RMIServerSocketFactory</emphasis>: specifies a fully qualified
                                  class name for the <literal>java.rmi.server.RMIServerSocketFactory</literal> interface
                                  to use during export of the proxy interface.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ServerAddress</emphasis>: specifies the interface address that
                                  will be used for the RMI server socket listening port. This can be either a DNS hostname
                                  or a dot-decimal Internet address. Since the <literal>RMIServerSocketFactory</literal>
                                  does not support a method that accepts an InetAddress object, this value is passed to
                                  the <literal>RMIServerSocketFactory</literal> implementation class using reflection. A
                                  check for the existence of a <literal>public void setBindAddress(java.net.InetAddress
                                      addr)</literal> method is made, and if one exists the
                                  <literal>RMIServerSocketAddr</literal> value is passed to the
                                      <literal>RMIServerSocketFactory</literal> implementation. If the
                                      <literal>RMIServerSocketFactory</literal> implementation does not support such a
                                  method, the <literal>ServerAddress</literal> value will be ignored.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">SecurityDomain</emphasis>: specifies the JNDI name of an
                                      <literal>org.jboss.security.SecurityDomain</literal> interface implementation to
                                  associate with the <literal>RMIServerSocketFactory</literal> implementation. The value
                                  will be passed to the <literal>RMIServerSocketFactory</literal> using reflection to
                                  locate a method with a signature of <literal>public void
                                      setSecurityDomain(org.jboss.security.SecurityDomain d)</literal>. If no such method
                                  exists the <literal>SecurityDomain</literal> value will be ignored.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>The PooledInvoker - RMI/Socket Transport</title>
                      <para>The <literal>org.jboss.invocation.pooled.server.PooledInvoker</literal> is an MBean service
                          that provides RMI over a custom socket transport implementation of the Invoker interface. The
                              <literal>PooledInvoker</literal> exports itself as an RMI server so that when it is used as
                          the <literal>Invoker</literal> in a remote client, the <literal>PooledInvoker</literal> stub is
                          sent to the client instead and invocations use the custom socket protocol.</para>
                      <para>The <literal>PooledInvoker</literal> MBean supports a number of attribute to configure the
                          socket transport layer. Its configurable attributes are:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">NumAcceptThreads</emphasis>: The number of threads that exist for
                                  accepting client connections. The default is 1.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">MaxPoolSize</emphasis>: The number of server threads for
                                  processing client. The default is 300.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">SocketTimeout</emphasis>: The socket timeout value passed to the
                                      <literal>Socket.setSoTimeout()</literal> method. The default is 60000.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ServerBindPort</emphasis>: The port used for the server socket. A
                                  value of 0 indicates that an anonymous port should be chosen.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ClientConnectAddress</emphasis>: The address that the client
                                  passes to the <literal>Socket(addr, port)</literal> constructor. This defaults to the
                                  server <literal> InetAddress.getLocalHost()</literal> value.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ClientConnectPort</emphasis>: The port that the client passes to
                                  the <literal>Socket(addr, port)</literal> constructor. The default is the port of the
                                  server listening socket.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ClientMaxPoolSize</emphasis>: The client side maximum number of
                                  threads. The default is 300.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">Backlog</emphasis>: The backlog associated with the server accept
                                  socket. The default is 200.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">EnableTcpNoDelay</emphasis>: A boolean flag indicating if client
                                  sockets will enable the <literal>TcpNoDelay</literal> flag on the socket. The default is
                                  false.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ServerBindAddress</emphasis>: The address on which the server
                                  binds its listening socket. The default is an empty value which indicates the server
                                  should be bound on all interfaces.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">TransactionManagerService</emphasis>: The JMX ObjectName of the
                                  JTA transaction manager service.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>The IIOPInvoker - RMI/IIOP Transport</title>
                      <para>The <literal>org.jboss.invocation.iiop.IIOPInvoker</literal> class is an MBean service that
                          provides the RMI/IIOP implementation of the <literal>Invoker</literal> interface. The
                              <literal>IIOPInvoker</literal> routes IIOP requests to CORBA servants. This is used by the
                              <literal>org.jboss.proxy.ejb.IORFactory</literal> proxy factory to create RMI/IIOP proxies.
                          However, rather than creating Java proxies (as the JRMP proxy factory does), this factory
                          creates CORBA IORs. An <literal>IORFactory</literal> is associated to a given enterprise bean.
                          It registers with the IIOP invoker two CORBA servants: <literal>anEjbHomeCorbaServant</literal>
                          for the bean's <literal>EJBHome</literal> and an <literal>EjbObjectCorbaServant</literal> for
                          the bean's <literal>EJBObject</literal>s.</para>
                      <para>The IIOPInvoker MBean has no configurable properties, since all properties are configured from
                          the <literal>conf/jacorb.properties</literal> property file used by the JacORB CORBA
                      service.</para>
                  </section>
                  <section>
                      <title>The JRMPProxyFactory Service - Building Dynamic JRMP Proxies</title>
                      <para>The <literal>org.jboss.invocation.jrmp.server.JRMPProxyFactory</literal> MBean service is a
                          proxy factory that can expose any interface with RMI compatible semantics for access to remote
                          clients using JRMP as the transport.</para>
                      <para>The JRMPProxyFactory supports the following attributes:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">InvokerName</emphasis>: The server side JRMPInvoker MBean service
                                  JMX ObjectName string that will handle the RMI/JRMP transport.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">TargetName</emphasis>: The server side MBean that exposes the
                                      <literal>invoke(Invocation)</literal> JMX operation for the exported interface. This
                                  is used as the destination service for any invocations done through the proxy.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">JndiName</emphasis>: The JNDI name under which the proxy will be
                                  bound.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ExportedInterface</emphasis>: The fully qualified class name of
                                  the interface that the proxy implements. This is the typed view of the proxy that the
                                  client uses for invocations.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ClientInterceptors</emphasis>: An XML fragment of
                                  interceptors/interceptor elements with each interceptor element body specifying the
                                  fully qualified class name of an <literal>org.jboss.proxy.Interceptor</literal>
                                  implementation to include in the proxy interceptor stack. The ordering of the
                                  interceptors/interceptor elements defines the order of the interceptors.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section id="ch2.httpinvoke.sect">
                      <title>The HttpInvoker - RMI/HTTP Transport</title>
                      <para>The <literal>org.jboss.invocation.http.server.HttpInvoker</literal> MBean service provides
                          support for making invocations into the JMX bus over HTTP. Unlike the
                          <literal>JRMPInvoker</literal>, the <literal>HttpInvoker</literal> is not an implementation of
                              <literal>Invoker</literal>, but it does implement the Invoker.invoke method. The HttpInvoker
                          is accessed indirectly by issuing an HTTP POST against the
                              <literal>org.jboss.invocation.http.servlet.InvokerServlet</literal>. The
                              <literal>HttpInvoker</literal> exports a client side proxy in the form of the
                              <literal>org.jboss.invocation.http.interfaces.HttpInvokerProxy</literal> class, which is an
                          implementation of <literal>Invoker</literal>, and is serializable. The
                          <literal>HttpInvoker</literal> is a drop in replacement for the <literal>JRMPInvoker</literal>
                          as the target of the <literal>bean-invoker</literal> and <literal>home-invoker</literal> EJB
                          configuration elements. The <literal>HttpInvoker</literal> and <literal>InvokerServlet</literal>
                          are deployed in the <literal>http-invoker.sar</literal> discussed in the JNDI chapter in the
                          section entitled Accessing JNDI over HTTP</para>
                      <para>The HttpInvoker supports the following attributes:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">InvokerURL</emphasis>: This is either the http URL to the
                                      <literal>InvokerServlet</literal> mapping, or the name of a system property that
                                  will be resolved inside the client VM to obtain the http URL to the
                                      <literal>InvokerServlet</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">InvokerURLPrefix</emphasis>: If there is no
                                  <literal>invokerURL</literal> set, then one will be constructed via the concatenation of
                                      <literal>invokerURLPrefix</literal> + the local host +
                                  <literal>invokerURLSuffix</literal>. The default prefix is
                              <literal>http://</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">InvokerURLSuffix</emphasis>: If there is no
                                  <literal>invokerURL</literal> set, then one will be constructed via the concatenation of
                                      <literal>invokerURLPrefix</literal> + the local host +
                                  <literal>invokerURLSuffix</literal>. The default suffix is
                                      <literal>:8080/invoker/JMXInvokerServlet</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">UseHostName</emphasis>: A boolean flag if the
                                      <literal>InetAddress.getHostName()</literal> or <literal>getHostAddress()</literal>
                                  method should be used as the host component of <literal>invokerURLPrefix</literal> +
                                  host + <literal>invokerURLSuffix</literal>. If true <literal>getHostName()</literal> is
                                  used, otherwise <literal>getHostAddress()</literal> is used.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>The HA JRMPInvoker - Clustered RMI/JRMP Transport</title>
                      <para>The <literal>org.jboss.proxy.generic.ProxyFactoryHA</literal> service is an extension of the
                              <literal>ProxyFactoryHA</literal> that is a cluster aware factory. The
                              <literal>ProxyFactoryHA</literal> fully supports all of the attributes of the
                              <literal>JRMPProxyFactory</literal>. This means that customized bindings of the port,
                          interface and socket transport are available to clustered RMI/JRMP as well. In addition, the
                          following cluster specific attributes are supported:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">PartitionObjectName</emphasis>: The JMX
                                  <literal>ObjectName</literal> of the cluster service to which the proxy is to be
                                  associated with.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">LoadBalancePolicy</emphasis>: The class name of the
                                      <literal>org.jboss.ha.framework.interfaces.LoadBalancePolicy</literal> interface
                                  implementation to associate with the proxy.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>The HA HttpInvoker - Clustered RMI/HTTP Transport</title>
                      <para>The RMI/HTTP layer allows for software load balancing of the invocations in a clustered
                          environment. The HA capable extension of the HTTP invoker borrows much of its functionality from
                          the HA-RMI/JRMP clustering. To enable HA-RMI/HTTP you need to configure the invokers for the EJB
                          container. This is done through either a <literal>jboss.xml</literal> descriptor, or the
                              <literal>standardjboss.xml</literal> descriptor. </para>
                  </section>
                  <section>
                      <title>HttpProxyFactory - Building Dynamic HTTP Proxies</title>
                      <para>The <literal>org.jboss.invocation.http.server.HttpProxyFactory</literal> MBean service is a
                          proxy factory that can expose any interface with RMI compatible semantics for access to remote
                          clients using HTTP as the transport.</para>
                      <para>The HttpProxyFactory supports the following attributes:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">InvokerName</emphasis>: The server side MBean that exposes the
                                  invoke operation for the exported interface. The name is embedded into the
                                      <literal>HttpInvokerProxy</literal> context as the target to which the invocation
                                  should be forwarded by the <literal>HttpInvoker</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">JndiName</emphasis>: The JNDI name under which the
                                      <literal>HttpInvokerProxy</literal> will be bound. This is the name clients lookup
                                  to obtain the dynamic proxy that exposes the service interfaces and marshalls
                                  invocations over HTTP. This may be specified as an empty value to indicate that the
                                  proxy should not be bound into JNDI.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">InvokerURL</emphasis>: This is either the http URL to the
                                      <literal>InvokerServlet</literal> mapping, or the name of a system property that
                                  will be resolved inside the client VM to obtain the http URL to the
                                      <literal>InvokerServlet</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">InvokerURLPrefix</emphasis>: If there is no
                                  <literal>invokerURL</literal> set, then one will be constructed via the concatenation of
                                      <literal>invokerURLPrefix</literal> + the local host +
                                  <literal>invokerURLSuffix</literal>. The default prefix is
                              <literal>http://</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">InvokerURLSuffix</emphasis>: If there is no
                                  <literal>invokerURL</literal> set, then one will be constructed via the concatenation of
                                      <literal>invokerURLPrefix</literal> + the local host +
                                  <literal>invokerURLSuffix</literal>. The default suffix is
                                      <literal>:8080/invoker/JMXInvokerServlet</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">UseHostName</emphasis>: A boolean flag indicating if the
                                      <literal>InetAddress.getHostName()</literal> or <literal>getHostAddress()</literal>
                                  method should be used as the host component of <literal>invokerURLPrefix</literal> +
                                  host + <literal>invokerURLSuffix</literal>. If true <literal>getHostName()</literal> is
                                  used, otherwise <literal>getHostAddress()</literal> is used.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ExportedInterface</emphasis>: The name of the RMI compatible
                                  interface that the <literal>HttpInvokerProxy</literal> implements.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>Steps to Expose Any RMI Interface via HTTP</title>
                      <para>Using the <literal>HttpProxyFactory</literal> MBean and JMX, you can expose any interface for
                          access using HTTP as the transport. The interface to expose does not have to be an RMI
                          interface, but it does have to be compatible with RMI in that all method parameters and return
                          values are serializable. There is also no support for converting RMI interfaces used as method
                          parameters or return values into their stubs.</para>
                      <para>The three steps to making your object invocable via HTTP are:</para>
                      <itemizedlist>
                          <listitem>
                              <para>Create a mapping of longs to the RMI interface methods using the
                                      <literal>MarshalledInvocation.calculateHash</literal> method. Here for example, is
                                  the procedure for an RMI <literal>SRPRemoteServerInterface</literal> interface:</para>
                              <programlisting>import java.lang.reflect.Method;
  import java.util.HashMap;
  import org.jboss.invocation.MarshalledInvocation;
   
  HashMap marshalledInvocationMapping = new HashMap();
   
  // Build the Naming interface method map
  Method[] methods = SRPRemoteServerInterface.class.getMethods();
  for(int m = 0; m &lt; methods.length; m ++) {
      Method method = methods[m];
      Long hash = new Long(MarshalledInvocation.calculateHash(method));
      marshalledInvocationMapping.put(hash, method);
  }</programlisting>
                          </listitem>
                          <listitem>
                              <para>Either create or extend an existing MBean to support an invoke operation. Its
                                  signature is <literal>Object invoke(Invocation invocation) throws Exception</literal>,
                                  and the steps it performs are as shown here for the
                                  <literal>SRPRemoteServerInterface</literal> interface. Note that this uses the
                                      <literal>marshalledInvocationMapping</literal> from step 1 to map from the
                                      <literal>Long</literal> method hashes in the <literal>MarshalledInvocation</literal>
                                  to the <literal>Method</literal> for the interface.</para>
                              <para>
                                  <programlisting>import org.jboss.invocation.Invocation;
  import org.jboss.invocation.MarshalledInvocation;
   
  public Object invoke(Invocation invocation)
      throws Exception
  {
      SRPRemoteServerInterface theServer = &lt;the_actual_rmi_server_object&gt;;
      // Set the method hash to Method mapping
      if (invocation instanceof MarshalledInvocation) {
          MarshalledInvocation mi = (MarshalledInvocation) invocation;
          mi.setMethodMap(marshalledInvocationMapping);
      }
  
      // Invoke the Naming method via reflection
      Method method = invocation.getMethod();
      Object[] args = invocation.getArguments();
      Object value = null;
      try {
          value = method.invoke(theServer, args);
      } catch(InvocationTargetException e) {
          Throwable t = e.getTargetException();    
          if (t instanceof Exception) {
              throw (Exception) e;
          } else {
              throw new UndeclaredThrowableException(t, method.toString());
          }
      }
   
      return value;
  }</programlisting>
                              </para>
                          </listitem>
                          <listitem>
                              <para>Create a configuration of the <literal>HttpProxyFactory</literal> MBean to make the
                                  RMI/HTTP proxy available through JNDI. For example:</para>
                              <programlisting>&lt;!-- Expose the SRP service interface via HTTP --&gt;
  &lt;mbean code="org.jboss.invocation.http.server.HttpProxyFactory"
         name="jboss.security.tests:service=SRP/HTTP"&gt;
      &lt;attribute name="InvokerURL"&gt;http://localhost:8080/invoker/JMXInvokerServlet&lt;/attribute&gt;
      &lt;attribute name="InvokerName"&gt;jboss.security.tests:service=SRPService&lt;/attribute&gt;
      &lt;attribute name="ExportedInterface"&gt;
          org.jboss.security.srp.SRPRemoteServerInterface
      &lt;/attribute&gt;
      &lt;attribute name="JndiName"&gt;srp-test-http/SRPServerInterface&lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
                          </listitem>
                      </itemizedlist>
                      <para>Any client may now lookup the RMI interface from JNDI using the name specified in the
                              <literal>HttpProxyFactory</literal> (e.g.,
                          <literal>srp-test-http/SRPServerInterface</literal>) and use the obtain proxy in exactly the
                          same manner as the RMI/JRMP version.</para>
                  </section>
              </section>
          </section>
      </chapter>
  
  
      <chapter id="ch3.chapter">
          <title>Naming on JBoss</title>
          <subtitle>The JNDI Naming Service</subtitle>
          <para>The naming service plays a key role in enterprise Java applications, providing the core infrastructure
              that is used to locate objects or services in an application server. It is also the mechanism that clients
              external to the application server use to locate services inside the application server. Application code,
              whether it is internal or external to the JBoss instance, need only know that it needs to talk to the a
              message queue named <literal>queue/IncomingOrders</literal> and would not need to worry about any of the
              details of how the queue is configured. In a clustered environment, naming services are even more valuable.
              A client of a service would desire to look up the <literal>ProductCatalog</literal> session bean from the
              cluster without worrying which machine the service is residing. Whether it is a big clustered service, a
              local resource or just a simple application component that is needed, the JNDI naming service provides the
              glue that lets code find the objects in the system by name. </para>
          <section id="ch3.overview">
              <title>An Overview of JNDI</title>
              <para>JNDI is a standard Java API that is bundled with JDK1.3 and higher. JNDI provides a common interface
                  to a variety of existing naming services: DNS, LDAP, Active Directory, RMI registry, COS registry, NIS,
                  and file systems. The JNDI API is divided logically into a client API that is used to access naming
                  services, and a service provider interface (SPI) that allows the user to create JNDI implementations for
                  naming services.</para>
              <para>The SPI layer is an abstraction that naming service providers must implement to enable the core JNDI
                  classes to expose the naming service using the common JNDI client interface. An implementation of JNDI
                  for a naming service is referred to as a JNDI provider. JBoss naming is an example JNDI implementation,
                  based on the SPI classes. Note that the JNDI SPI is not needed by J2EE component developers.</para>
              <para>For a thorough introduction and tutorial on JNDI, which covers both the client and service provider
                  APIs, see the Sun tutorial at <ulink url="http://java.sun.com/products/jndi/tutorial/"/>.</para>
              <para>The main JNDI API package is the <literal>javax.naming</literal> package. It contains five interfaces,
                  10 classes, and several exceptions. There is one key class, <literal>InitialContext</literal>, and two
                  key interfaces, <literal>Context</literal> and <literal>Name</literal>
              </para>
              <section>
                  <title>Names</title>
                  <para>The notion of a name is of fundamental importance in JNDI. The naming system determines the syntax
                      that the name must follow. The syntax of the naming system allows the user to parse string
                      representations of names into its components. A name is used with a naming system to locate objects.
                      In the simplest sense, a naming system is just a collection of objects with unique names. To locate
                      an object in a naming system you provide a name to the naming system, and the naming system returns
                      the object store under the name.</para>
                  <para>As an example, consider the Unix file system's naming convention. Each file is named from its path
                      relative to the root of the file system, with each component in the path separated by the forward
                      slash character ("<literal>/</literal>"). The file's path is ordered from left to right. The
                          pathname<literal>/usr/jboss/readme.txt</literal>, for example, names a file
                      <literal>readme.txt</literal> in the directory <literal>jboss</literal>, under the directory
                          <literal>usr</literal>, located in the root of the file system. JBoss naming uses a UNIX-style
                      namespace as its naming convention.</para>
                  <para>The <literal>javax.naming.Name</literal> interface represents a generic name as an ordered
                      sequence of components. It can be a composite name (one that spans multiple namespaces), or a
                      compound name (one that is used within a single hierarchical naming system). The components of a
                      name are numbered. The indexes of a name with N components range from 0 up to, but not including, N.
                      The most significant component is at index 0. An empty name has no components.</para>
                  <para>A composite name is a sequence of component names that span multiple namespaces. An example of a
                      composite name would be the hostname and file combination commonly used with UNIX commands like
                          <literal>scp</literal>. For example, the following command copies
                      <literal>localfile.txt</literal> to the file <literal>remotefile.txt</literal> in the
                      <literal>tmp</literal> directory on host <literal>ahost.someorg.org</literal>:</para>
                  <programlisting>scp localfile.txt ahost.someorg.org:/tmp/remotefile.txt</programlisting>
                  <para>A compound name is derived from a hierarchical namespace. Each component in a compound name is an
                      atomic name, meaning a string that cannot be parsed into smaller components. A file pathname in the
                      UNIX file system is an example of a compound name.
                      <literal>ahost.someorg.org:/tmp/remotefile.txt</literal> is a composite name that spans the DNS and
                      UNIX file system namespaces. The components of the composite name are
                      <literal>ahost.someorg.org</literal> and <literal>/tmp/remotefile.txt</literal>. A component is a
                      string name from the namespace of a naming system. If the component comes from a hierarchical
                      namespace, that component can be further parsed into its atomic parts by using the
                          <literal>javax.naming.CompoundName</literal> class. The JNDI API provides the
                          <literal>javax.naming.CompositeName</literal> class as the implementation of the
                      <literal>Name</literal> interface for composite names.</para>
              </section>
              <section>
                  <title>Contexts</title>
                  <para>The <literal>javax.naming.Context</literal> interface is the primary interface for interacting
                      with a naming service. The <literal>Context</literal> interface represents a set of name-to-object
                      bindings. Every context has an associated naming convention that determines how the context parses
                      string names into <literal>javax.naming.Name</literal> instances. To create a name to object binding
                      you invoke the bind method of a <literal>Context</literal> and specify a name and an object as
                      arguments. The object can later be retrieved using its name using the <literal>Context</literal>
                      lookup method. A <literal>Context</literal> will typically provide operations for binding a name to
                      an object, unbinding a name, and obtaining a listing of all name-to-object bindings. The object you
                      bind into a <literal>Context</literal> can itself be of type <literal>Context</literal> . The
                          <literal>Context</literal> object that is bound is referred to as a subcontext of the
                          <literal>Context</literal> on which the bind method was invoked.</para>
                  <para>As an example, consider a file directory with a pathname <literal>/usr</literal>, which is a
                      context in the UNIX file system. A file directory named relative to another file directory is a
                      subcontext (commonly referred to as a subdirectory). A file directory with a pathname
                          <literal>/usr/jboss</literal> names a <literal>jboss</literal> context that is a subcontext of
                          <literal>usr</literal>. In another example, a DNS domain, such as <literal>org</literal>, is a
                      context. A DNS domain named relative to another DNS domain is another example of a subcontext. In
                      the DNS domain <literal>jboss.org</literal>, the DNS domain <literal>jboss</literal> is a subcontext
                      of <literal>org</literal> because DNS names are parsed right to left.</para>
                  <section>
                      <title>Obtaining a Context using InitialContext</title>
                      <para>All naming service operations are performed on some implementation of the
                          <literal>Context</literal> interface. Therefore, you need a way to obtain a
                          <literal>Context</literal> for the naming service you are interested in using. The
                              <literal>javax.naming.IntialContext</literal> class implements the
                          <literal>Context</literal> interface, and provides the starting point for interacting with a
                          naming service.</para>
                      <para>When you create an <literal>InitialContext</literal>, it is initialized with properties from
                          the environment. JNDI determines each property's value by merging the values from the following
                          two sources, in order.</para>
                      <itemizedlist>
                          <listitem>
                              <para>The first occurrence of the property from the constructor's environment parameter and
                                  (for appropriate properties) the applet parameters and system properties.</para>
                          </listitem>
                          <listitem>
                              <para>All <literal>jndi.properties</literal> resource files found on the classpath.</para>
                          </listitem>
                      </itemizedlist>
                      <para>For each property found in both of these two sources, the property's value is determined as
                          follows. If the property is one of the standard JNDI properties that specify a list of JNDI
                          factories, all of the values are concatenated into a single colon-separated list. For other
                          properties, only the first value found is used. The preferred method of specifying the JNDI
                          environment properties is through a <literal>jndi.properties</literal> file, which allows your
                          code to externalize the JNDI provider specific information so that changing JNDI providers will
                          not require changes to your code or recompilation.</para>
                      <para>The <literal>Context</literal> implementation used internally by the
                          <literal>InitialContext</literal> class is determined at runtime. The default policy uses the
                          environment property <literal>java.naming.factory.initial</literal>, which contains the class
                          name of the <literal>javax.naming.spi.InitialContextFactory</literal> implementation. You obtain
                          the name of the <literal>InitialContextFactory</literal> class from the naming service provider
                          you are using.</para>
                      <para>
                          <xref linkend="ch3.props.ex"/> gives a sample <literal>jndi.properties</literal> file a client
                          application would use to connect to a JBossNS service running on the local host at port 1099.
                          The client application would need to have the <literal>jndi.properties</literal> file available
                          on the application classpath. These are the properties that the JBossNS JNDI implementation
                          requires. Other JNDI providers will have different properties and values.</para>
                      <example id="ch3.props.ex">
                          <title>A sample jndi.properties file</title>
                          <programlisting>### JBossNS properties
  java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
  java.naming.provider.url=jnp://localhost:1099
  java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces</programlisting>
                      </example>
                  </section>
              </section>
          </section>
          <section id="ch3.nsarch">
              <title>The JBossNS Architecture</title>
              <para>The JBossNS architecture is a Java socket/RMI based implementation of the
                      <literal>javax.naming.Context</literal> interface. It is a client/server implementation that can be
                  accessed remotely. The implementation is optimized so that access from within the same VM in which the
                  JBossNS server is running does not involve sockets. Same VM access occurs through an object reference
                  available as a global singleton. <xref linkend="ch3.jbossns.fig"/> illustrates some of the key classes
                  in the JBossNS implementation and their relationships.</para>
              <figure id="ch3.jbossns.fig">
                  <title>Key components in the JBossNS architecture.</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/Chap3-8.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>We will start with the <literal>NamingService</literal> MBean. The <literal>NamingService</literal>
                  MBean provides the JNDI naming service. This is a key service used pervasively by the J2EE technology
                  components. The configurable attributes for the <literal>NamingService</literal> are as follows.</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">Port</emphasis>: The jnp protocol listening port for the
                              <literal>NamingService</literal>. If not specified default is 1099, the same as the RMI
                          registry default port.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">RmiPort</emphasis>: The RMI port on which the RMI Naming implementation
                          will be exported. If not specified the default is 0 which means use any available port.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">BindAddress</emphasis>: The specific address the
                          <literal>NamingService</literal> listens on. This can be used on a multi-homed host for a
                              <literal>java.net.ServerSocket</literal> that will only accept connect requests on one of
                          its addresses.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">RmiBindAddress</emphasis>: The specific address the RMI server portion of
                          the <literal>NamingService</literal> listens on. This can be used on a multi-homed host for a
                              <literal>java.net.ServerSocket</literal> that will only accept connect requests on one of
                          its addresses. If this is not specified and the <literal>BindAddress</literal> is, the
                              <literal>RmiBindAddress</literal> defaults to the <literal>BindAddress</literal>
                      value.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Backlog</emphasis>: The maximum queue length for incoming connection
                          indications (a request to connect) is set to the <literal>backlog</literal> parameter. If a
                          connection indication arrives when the queue is full, the connection is refused.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">ClientSocketFactory</emphasis>: An optional custom
                              <literal>java.rmi.server.RMIClientSocketFactory</literal> implementation class name. If not
                          specified the default <literal>RMIClientSocketFactory</literal> is used.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">ServerSocketFactory</emphasis>: An optional custom
                              <literal>java.rmi.server.RMIServerSocketFactory</literal> implementation class name. If not
                          specified the default <literal>RMIServerSocketFactory</literal> is used.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">JNPServerSocketFactory</emphasis>: An optional custom
                              <literal>javax.net.ServerSocketFactory</literal> implementation class name. This is the
                          factory for the <literal>ServerSocket</literal> used to bootstrap the download of the JBossNS
                              <literal>Naming</literal> interface. If not specified the
                              <literal>javax.net.ServerSocketFactory.getDefault()</literal> method value is used.</para>
                  </listitem>
              </itemizedlist>
              <para>The <literal>NamingService</literal> also creates the <literal>java:comp</literal> context such that
                  access to this context is isolated based on the context class loader of the thread that accesses the
                      <literal>java:comp</literal> context. This provides the application component private ENC that is
                  required by the J2EE specs. This segregation is accomplished by binding a
                      <literal>javax.naming.Reference</literal> to a context that uses the
                      <literal>org.jboss.naming.ENCFactory</literal> as its <literal>javax.naming.ObjectFactory</literal>.
                  When a client performs a lookup of <literal>java:comp</literal>, or any subcontext, the
                      <literal>ENCFactory</literal> checks the thread context <literal>ClassLoader</literal>, and performs
                  a lookup into a map using the <literal>ClassLoader</literal> as the key. </para>
              <para>If a context instance does not exist for the class loader instance, one is created and associated with
                  that class loader in the <literal>ENCFactory</literal> map. Thus, correct isolation of an application
                  component's ENC relies on each component receiving a unique <literal>ClassLoader</literal> that is
                  associated with the component threads of execution. </para>
              <para>The <literal>NamingService</literal> delegates its functionality to an
                  <literal>org.jnp.server.Main</literal> MBean. The reason for the duplicate MBeans is because JBossNS
                  started out as a stand-alone JNDI implementation, and can still be run as such. The
                      <literal>NamingService</literal> MBean embeds the <literal>Main</literal> instance into the JBoss
                  server so that usage of JNDI with the same VM as the JBoss server does not incur any socket overhead.
                  The configurable attributes of the NamingService are really the configurable attributes of the JBossNS
                      <literal>Main</literal> MBean. The setting of any attributes on the <literal>NamingService</literal>
                  MBean simply set the corresponding attributes on the <literal>Main</literal> MBean the
                      <literal>NamingService</literal> contains. When the <literal>NamingService</literal> is started, it
                  starts the contained <literal>Main</literal> MBean to activate the JNDI naming service. </para>
              <para>In addition, the <literal>NamingService</literal> exposes the <literal>Naming</literal> interface
                  operations through a JMX detyped invoke operation. This allows the naming service to be accessed via JMX
                  adaptors for arbitrary protocols. We will look at an example of how HTTP can be used to access the
                  naming service using the invoke operation later in this chapter.</para>
              <para>The details of threads and the thread context class loader won't be explored here, but the JNDI
                  tutorial provides a concise discussion that is applicable. See <ulink
                      url="http://java.sun.com/products/jndi/tutorial/beyond/misc/classloader.html"/> for the details.</para>
              <para>When the <literal>Main</literal> MBean is started, it performs the following tasks:</para>
              <itemizedlist>
                  <listitem>
                      <para>Instantiates an <literal>org.jnp.naming.NamingService</literal> instance and sets this as the
                          local VM server instance. This is used by any
                          <literal>org.jnp.interfaces.NamingContext</literal> instances that are created within the JBoss
                          server VM to avoid RMI calls over TCP/IP.</para>
                  </listitem>
                  <listitem>
                      <para>Exports the <literal>NamingServer</literal> instance's
                              <literal>org.jnp.naming.interfaces.Naming</literal> RMI interface using the configured
                              <literal>RmiPort</literal>, <literal>ClientSocketFactory</literal>,
                              <literal>ServerSocketFactory</literal>attributes.</para>
                  </listitem>
                  <listitem>
                      <para>Creates a socket that listens on the interface given by the <literal>BindAddress</literal> and
                              <literal>Port</literal> attributes.</para>
                  </listitem>
                  <listitem>
                      <para>Spawns a thread to accept connections on the socket.</para>
                  </listitem>
              </itemizedlist>
          </section>
          <section id="ch3.factories">
              <title>The Naming InitialContext Factories</title>
              <para>The JBoss JNDI provider currently supports several different <literal>InitialContext</literal> factory
                  implementations. </para>
              <section>
                  <title>The standard naming context factory</title>
                  <para>The most commonly used factory is the <literal>org.jnp.interfaces.NamingContextFactory</literal>
                      implementation. Its properties include:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.factory.initial</emphasis>: The name of the environment
                              property for specifying the initial context factory to use. The value of the property should
                              be the fully qualified class name of the factory class that will create an initial context.
                              If it is not specified, a <literal>javax.naming.NoInitialContextException</literal> will be
                              thrown when an <literal>InitialContext</literal> object is created.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.provider.url</emphasis>: The name of the environment
                              property for specifying the location of the JBoss JNDI service provider the client will use.
                              The <literal>NamingContextFactory</literal> class uses this information to know which
                              JBossNS server to connect to. The value of the property should be a URL string. For JBossNS
                              the URL format is <literal>jnp://host:port/[jndi_path]</literal>. The
                              <literal>jnp:</literal> portion of the URL is the protocol and refers to the socket/RMI
                              based protocol used by JBoss. The <literal>jndi_path</literal> portion of the URL is an
                              optional JNDI name relative to the root context, for example, <literal>apps</literal> or
                                  <literal>apps/tmp</literal>. Everything but the host component is optional. The
                              following examples are equivalent because the default port value is 1099. </para>
                          <itemizedlist spacing="compact">
                              <listitem>
                                  <para>
                                      <literal>jnp://www.jboss.org:1099/</literal>
                                  </para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <literal>www.jboss.org:1099</literal>
                                  </para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <literal>www.jboss.org</literal>
                                  </para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.factory.url.pkgs</emphasis>: The name of the environment
                              property for specifying the list of package prefixes to use when loading in URL context
                              factories. The value of the property should be a colon-separated list of package prefixes
                              for the class name of the factory class that will create a URL context factory. For the
                              JBoss JNDI provider this must be <literal>org.jboss.naming:org.jnp.interfaces</literal>.
                              This property is essential for locating the <literal>jnp:</literal> and
                              <literal>java:</literal> URL context factories of the JBoss JNDI provider.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">jnp.socketFactory</emphasis>: The fully qualified class name of the
                                  <literal>javax.net.SocketFactory</literal> implementation to use to create the bootstrap
                              socket. The default value is <literal>org.jnp.interfaces.TimedSocketFactory</literal>. The
                                  <literal>TimedSocketFactory</literal> is a simple <literal>SocketFactory</literal>
                              implementation that supports the specification of a connection and read timeout. These two
                              properties are specified by:</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">jnp.timeout</emphasis>: The connection timeout in milliseconds. The
                              default value is 0 which means the connection will block until the VM TCP/IP layer times
                              out.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">jnp.sotimeout</emphasis>: The connected socket read timeout in
                              milliseconds. The default value is 0 which means reads will block. This is the value passed
                              to the <literal>Socket.setSoTimeout</literal> on the newly connected socket.</para>
                      </listitem>
                  </itemizedlist>
                  <para>When a client creates an <literal>InitialContext</literal> with these JBossNS properties
                      available, the <literal>org.jnp.interfaces.NamingContextFactory</literal> object is used to create
                      the <literal>Context</literal> instance that will be used in subsequent operations. The
                          <literal>NamingContextFactory</literal> is the JBossNS implementation of the
                          <literal>javax.naming.spi.InitialContextFactory</literal> interface. When the
                          <literal>NamingContextFactory</literal> class is asked to create a <literal>Context</literal>,
                      it creates an <literal>org.jnp.interfaces.NamingContext</literal> instance with the
                          <literal>InitialContext</literal> environment and name of the context in the global JNDI
                      namespace. It is the <literal>NamingContext</literal> instance that actually performs the task of
                      connecting to the JBossNS server, and implements the <literal>Context</literal> interface. The
                          <literal>Context.PROVIDER_URL</literal> information from the environment indicates from which
                      server to obtain a <literal>NamingServer</literal> RMI reference.</para>
                  <para>The association of the <literal>NamingContext</literal> instance to a
                      <literal>NamingServer</literal> instance is done in a lazy fashion on the first
                      <literal>Context</literal> operation that is performed. When a <literal>Context</literal> operation
                      is performed and the <literal>NamingContext</literal> has no <literal>NamingServer</literal>
                      associated with it, it looks to see if its environment properties define a
                          <literal>Context.PROVIDER_URL</literal>. A <literal>Context.PROVIDER_URL</literal> defines the
                      host and port of the JBossNS server the <literal>Context</literal> is to use. If there is a provider
                      URL, the <literal>NamingContext</literal> first checks to see if a <literal>Naming</literal>
                      instance keyed by the host and port pair has already been created by checking a
                          <literal>NamingContext</literal> class static map. It simply uses the existing
                      <literal>Naming</literal> instance if one for the host port pair has already been obtained. If no
                          <literal>Naming</literal> instance has been created for the given host and port, the
                          <literal>NamingContext</literal> connects to the host and port using a
                      <literal>java.net.Socket</literal>, and retrieves a <literal>Naming</literal> RMI stub from the
                      server by reading a <literal>java.rmi.MarshalledObject</literal> from the socket and invoking its
                      get method. The newly obtained Naming instance is cached in the <literal>NamingContext</literal>
                      server map under the host and port pair. If no provider URL was specified in the JNDI environment
                      associated with the context, the <literal>NamingContext</literal> simply uses the in VM Naming
                      instance set by the <literal>Main</literal> MBean.</para>
                  <para>The <literal>NamingContext</literal> implementation of the <literal>Context</literal> interface
                      delegates all operations to the <literal>Naming</literal> instance associated with the
                          <literal>NamingContext</literal>. The <literal>NamingServer</literal> class that implements the
                          <literal>Naming</literal> interface uses a <literal>java.util.Hashtable</literal> as the
                          <literal>Context</literal> store. There is one unique <literal>NamingServer</literal> instance
                      for each distinct JNDI Name for a given JBossNS server. There are zero or more transient
                          <literal>NamingContext</literal> instances active at any given moment that refers to a
                          <literal>NamingServer</literal> instance. The purpose of the <literal>NamingContext</literal> is
                      to act as a <literal>Context</literal> to the <literal>Naming</literal> interface adaptor that
                      manages translation of the JNDI names passed to the <literal>NamingContext</literal> . Because a
                      JNDI name can be relative or a URL, it needs to be converted into an absolute name in the context of
                      the JBossNS server to which it refers. This translation is a key function of the
                          <literal>NamingContext</literal>.</para>
              </section>
              <section>
                  <title>The org.jboss.naming.NamingContextFactory</title>
                  <para> This version of the <literal>InitialContextFactory</literal> implementation is a simple extension
                      of the jnp version which differs from the jnp version in that it stores the last configuration
                      passed to its <literal>InitialContextFactory.getInitialContext(Hashtable env)</literal> method in a
                      public thread local variable. This is used by EJB handles and other JNDI sensitive objects like the
                          <literal>UserTransaction</literal> factory to keep track of the JNDI context that was in effect
                      when they were created. If you want this environment to be bound to the object even after its
                      serialized across vm boundaries, then you should the
                      <literal>org.jboss.naming.NamingContextFactory</literal>. If you want the environment that is
                      defined in the current VM <literal>jndi.properties</literal> or system properties, then you should
                      use the <literal>org.jnp.interfaces.NamingContextFactory</literal> version.</para>
              </section>
              <section>
                  <title>Naming Discovery in Clustered Environments</title>
                  <para>When running in a clustered JBoss environment, you can choose not to specify a
                          <literal>Context.PROVIDER_URL</literal> value and let the client query the network for available
                      naming services. This only works with JBoss servers running with the <literal>all</literal>
                      configuration, or an equivalent configuration that has
                          <literal>org.jboss.ha.framework.server.ClusterPartition</literal> and
                          <literal>org.jboss.ha.jndi.HANamingService</literal> services deployed. The discovery process
                      consists of sending a multicast request packet to the discovery address/port and waiting for any
                      node to respond. The response is a HA-RMI version of the <literal>Naming</literal> interface. The
                      following <literal>InitialContext</literal> proerties affect the discovery configuration:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">jnp.partitionName</emphasis>: The cluster partition name discovery
                              should be restricted to. If you are running in an environment with multiple clusters, you
                              may want to restrict the naming discovery to a particular cluster. There is no default
                              value, meaning that any cluster response will be accepted.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">jnp.discoveryGroup</emphasis>: The multicast IP/address to which the
                              discovery query is sent. The default is 230.0.0.4.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">jnp.discoveryPort</emphasis>: The port to which the discovery query is
                              sent. The default is 1102.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">jnp.discoveryTimeout</emphasis>: The time in milliseconds to wait for
                              a discovery query response. The default value is 5000 (5 seconds).</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">jnp.disableDiscovery</emphasis>: A flag indicating if the discovery
                              process should be avoided. Discovery occurs when either no
                              <literal>Context.PROVIDER_URL</literal> is specified, or no valid naming service could be
                              located among the URLs specified. If the <literal>jnp.disableDiscovery</literal> flag is
                              true, then discovery will not be attempted.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>The HTTP InitialContext Factory Implementation</title>
                  <para>The JNDI naming service can be accessed over HTTP. From a JNDI client's perspective this is a
                      transparent change as they continue to use the JNDI <literal>Context</literal> interface. Operations
                      through the <literal>Context</literal> interface are translated into HTTP posts to a servlet that
                      passes the request to the NamingService using its JMX invoke operation. Advantages of using HTTP as
                      the access protocol include better access through firewalls and proxies setup to allow HTTP, as well
                      as the ability to secure access to the JNDI service using standard servlet role based security.</para>
                  <para>To access JNDI over HTTP you use the <literal>org.jboss.naming.HttpNamingContextFactory</literal>
                      as the factory implementation. The complete set of support <literal>InitialContext</literal>
                      environment properties for this factory are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.factory.initial</emphasis>: The name of the environment
                              property for specifying the initial context factory, which must be
                                  <literal>org.jboss.naming.HttpNamingContextFactory</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.provider.url</emphasis> (or
                              <literal>Context.PROVIDER_URL</literal>): This must be set to the HTTP URL of the JNDI
                              factory. The full HTTP URL would be the public URL of the JBoss servlet container plus
                                  <literal>/invoker/JNDIFactory</literal>. Examples include: </para>
                          <itemizedlist spacing="compact">
                              <listitem>
                                  <para>
                                      <literal>http://www.jboss.org:8080/invoker/JNDIFactory</literal>
                                  </para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <literal>http://www.jboss.org/invoker/JNDIFactory</literal>
                                  </para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <literal>https://www.jboss.org/invoker/JNDIFactory</literal>
                                  </para>
                              </listitem>
                          </itemizedlist>
                          <para>The first example accesses the servlet using the port 8080. The second uses the standard
                              HTTP port 80, and the third uses an SSL encrypted connection to the standard HTTPS port
                          443.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.factory.url.pkgs</emphasis>: For all JBoss JNDI provider
                              this must be <literal>org.jboss.naming:org.jnp.interfaces</literal>. This property is
                              essential for locating the <literal>jnp:</literal> and <literal>java:</literal> URL context
                              factories of the JBoss JNDI provider.</para>
                      </listitem>
                  </itemizedlist>
                  <para>The JNDI <literal>Context</literal> implementation returned by the
                          <literal>HttpNamingContextFactory</literal> is a proxy that delegates invocations made on it to
                      a bridge servlet which forwards the invocation to the <literal>NamingService</literal> through the
                      JMX bus and marshalls the reply back over HTTP. The proxy needs to know what the URL of the bridge
                      servlet is in order to operate. This value may have been bound on the server side if the JBoss web
                      server has a well known public interface. If the JBoss web server is sitting behind one or more
                      firewalls or proxies, the proxy cannot know what URL is required. In this case, the proxy will be
                      associated with a system property value that must be set in the client VM. For more information on
                      the operation of JNDI over HTTP see <xref linkend="ch3.accessingjndi"/>.</para>
              </section>
              <section>
                  <title>The Login InitialContext Factory Implementation</title>
                  <para>JAAS is the preferred method for authenticating a remote client to JBoss. However, for simplicity
                      and to ease the migration from other application server environment that do not use JAAS, JBoss
                      alows you the security credentials to be passed through the <literal>InitialContext</literal>. JAAS
                      is still used under the covers, but there is no manifest use of the JAAS interfaces in the client
                      application.</para>
                  <para>The factory class that provides this capability is the
                          <literal>org.jboss.security.jndi.LoginInitialContextFactory</literal>. The complete set of
                      support <literal>InitialContext</literal> environment properties for this factory are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.factory.initial</emphasis>: The name of the environment
                              property for specifying the initial context factory, which must be
                                  <literal>org.jboss.security.jndi.LoginInitialContextFactory</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.provider.url</emphasis>: This must be set to a
                                  <literal>NamingContextFactory</literal> provider URL. The
                              <literal>LoginIntialContext</literal> is really just a wrapper around the
                                  <literal>NamingContextFactory</literal> that adds a JAAS login to the existing
                                  <literal>NamingContextFactory</literal> behavior.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.factory.url.pkgs</emphasis>: For all JBoss JNDI provider
                              this must be <literal>org.jboss.naming:org.jnp.interfaces</literal>. This property is
                              essential for locating the <literal>jnp:</literal> and <literal>java:</literal> URL context
                              factories of the JBoss JNDI provider.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.security.principal</emphasis> (or
                                  <literal>Context.SECURITY_PRINCIPAL</literal>): The principal to authenticate. This may
                              be either a <literal>java.security.Principal</literal> implementation or a string
                              representing the name of a principal.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.security.credentials</emphasis> (or
                                  <literal>Context.SECURITY_CREDENTIALS</literal>), The credentials that should be used to
                              authenticate the principal, e.g., password, session key, etc.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">java.naming.security.protocol</emphasis>:
                                  (<literal>Context.SECURITY_PROTOCOL</literal>) This gives the name of the JAAS login
                              module to use for the authentication of the principal and credentials.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>The ORBInitialContextFactory</title>
                  <para> When using Sun's CosNaming it is necessary to use a different naming context factory from the
                      default. CosNaming looks for the ORB in JNDI instead of using the the ORB configured in
                          <literal>deploy/iiop-service.xml?</literal>. It is neccessary to set the global context factory
                      to <literal>org.jboss.iiop.naming.ORBInitialContextFactory</literal>, which sets the ORB to JBoss's
                      ORB. This is done in the <literal>conf/jndi.propeties</literal> file:</para>
                  <programlisting>
  # DO NOT EDIT THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING
  #
  java.naming.factory.initial=org.jboss.iiop.naming.ORBInitialContextFactory
  java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
                  </programlisting>
                  <para> It is also necessary to use <literal>ORBInitialContextFactory</literal> when using CosNaming in
                      an application client.</para>
              </section>
          </section>
          <section id="ch3.HTTP">
              <title>JNDI over HTTP</title>
              <para> In addition to the legacy RMI/JRMP with a socket bootstrap protocol, JBoss provides support for
                  accessing its JNDI naming service over HTTP. </para>
              <section id="ch3.accessingjndi">
                  <title>Accessing JNDI over HTTP</title>
                  <para>This capability is provided by <literal>http-invoker.sar</literal>. The structure of the
                          <literal>http-invoker.sar</literal> is:</para>
                  <programlisting><emphasis role="bold">http-invoker.sar</emphasis>
  +- META-INF/jboss-service.xml
  +- invoker.war
  | +- WEB-INF/jboss-web.xml
  | +- WEB-INF/classes/org/jboss/invocation/http/servlet/InvokerServlet.class
  | +- WEB-INF/classes/org/jboss/invocation/http/servlet/NamingFactoryServlet.class
  | +- WEB-INF/classes/org/jboss/invocation/http/servlet/ReadOnlyAccessFilter.class
  | +- WEB-INF/classes/roles.properties
  | +- WEB-INF/classes/users.properties
  | +- WEB-INF/web.xml
  | +- META-INF/MANIFEST.MF
  +- META-INF/MANIFEST.MF
  </programlisting>
                  <para>The <literal>jboss-service.xml</literal> descriptor defines the <literal>HttpInvoker</literal> and
                          <literal>HttpInvokerHA</literal> MBeans. These services handle the routing of methods
                      invocations that are sent via HTTP to the appropriate target MBean on the JMX bus.</para>
                  <para>The <literal>http-invoker.war</literal> web application contains servlets that handle the details
                      of the HTTP transport. The <literal>NamingFactoryServlet</literal> handles creation requests for the
                      JBoss JNDI naming service <literal>javax.naming.Context</literal> implementation. The
                          <literal>InvokerServlet</literal> handles invocations made by RMI/HTTP clients. The
                          <literal>ReadOnlyAccessFilter</literal> allows one to secure the JNDI naming service while
                      making a single JNDI context available for read-only access by unauthenticated clients.</para>
                  <figure id="ch3.httpinvoker.fig">
                      <title>The HTTP invoker proxy/server structure for a JNDI Context</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/Chap3-9.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>Before looking at the configurations let's look at the operation of the
                      <literal>http-invoker</literal> services. <xref linkend="ch3.httpinvoker.fig"/> shows a logical view
                      of the structure of a JBoss JNDI proxy and its relationship to the JBoss server side components of
                      the <literal>http-invoker</literal>. The proxy is obtained from the
                      <literal>NamingFactoryServlet</literal> using an <literal>InitialContext</literal> with the
                          <literal>Context.INITIAL_CONTEXT_FACTORY</literal> property set to
                          <literal>org.jboss.naming.HttpNamingContextFactory</literal>, and the
                          <literal>Context.PROVIDER_URL</literal> property set to the HTTP URL of the
                          <literal>NamingFactoryServlet</literal>. The resulting proxy is embedded in an
                          <literal>org.jnp.interfaces.NamingContext</literal> instance that provides the
                      <literal>Context</literal> interface implementation.</para>
                  <para>The proxy is an instance of
                      <literal>org.jboss.invocation.http.interfaces.HttpInvokerProxy</literal>, and implements the
                          <literal>org.jnp.interfaces.Naming</literal> interface. Internally the
                      <literal>HttpInvokerProxy</literal> contains an invoker that marshalls the <literal>Naming</literal>
                      interface method invocations to the <literal>InvokerServlet</literal> via HTTP posts. The
                          <literal>InvokerServlet</literal> translates these posts into JMX invocations to the
                          <literal>NamingService</literal>, and returns the invocation response back to the proxy in the
                      HTTP post reponse.</para>
                  <para>There are several configuration values that need to be set to tie all of these components together
                      and <xref linkend="ch3.httpjndiconf.fig"/> illustrates the relationship between configuration files
                      and the corresponding components.</para>
                  <figure id="ch3.httpjndiconf.fig">
                      <title>The relationship between configuration files and JNDI/HTTP component</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/Chap3-10.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The <literal>http-invoker.sar/META-INF/jboss-service.xml</literal> descriptor defines the
                          <literal>HttpProxyFactory</literal> that creates the <literal>HttpInvokerProxy</literal> for the
                          <literal>NamingService</literal>. The attributes that need to be configured for the
                          <literal>HttpProxyFactory</literal> include:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">InvokerName</emphasis>: The JMX <literal>ObjectName</literal> of the
                                  <literal>NamingService</literal> defined in the
                              <literal>conf/jboss-service.xml</literal> descriptor. The standard setting used in the JBoss
                              distributions is <literal>jboss:service=Naming</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">InvokerURL</emphasis> or <emphasis role="bold"
                              >InvokerURLPrefix</emphasis> + InvokerURLSuffix + <emphasis role="bold"
                              >UseHostName</emphasis>. You can specify the full HTTP URL to the
                              <literal>InvokerServlet</literal> using the <literal>InvokerURL</literal> attribute, or you
                              can specify the hostname independent parts of the URL and have the
                              <literal>HttpProxyFactory</literal> fill them in. An example <literal>InvokerURL</literal>
                              value would be <literal>http://jbosshost1.dot.com:8080/invoker/JMXInvokerServlet</literal>.
                              This can be broken down into: <itemizedlist>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">InvokerURLPrefix</emphasis>: the URL prefix prior to the
                                          hostname. Typically this will be <literal>http://</literal> or
                                          <literal>https://</literal> if SSL is to be used.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">InvokerURLSuffix</emphasis>: the URL suffix after the
                                          hostname. This will include the port number of the web server as well as the
                                          deployed path to the <literal>InvokerServlet</literal> . For the example
                                              <literal>InvokerURL</literal> value the <literal>InvokerURLSuffix</literal>
                                          would be <literal>:8080/invoker/JMXInvokerServlet</literal> without the quotes.
                                          The port number is determined by the web container service settings. The path to
                                          the <literal>InvokerServlet</literal> is specified in the
                                              <literal>http-invoker.sar/invoker.war/WEB-INF/web.xml</literal>
                                      descriptor.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">UseHostName</emphasis>: a flag indicating if the hostname
                                          should be used in place of the host IP address when building the hostname
                                          portion of the full <literal>InvokerURL</literal>. If true,
                                              <literal>InetAddress.getLocalHost().getHostName</literal> method will be
                                          used. Otherwise, the
                                          <literal>InetAddress.getLocalHost().getHostAddress()</literal> method is
                                      used.</para>
                                  </listitem>
                              </itemizedlist>
                          </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ExportedInterface</emphasis>: The
                              <literal>org.jnp.interfaces.Naming</literal> interface the proxy will expose to clients. The
                              actual client of this proxy is the JBoss JNDI implementation
                              <literal>NamingContext</literal> class, which JNDI client obtain from
                                  <literal>InitialContext</literal> lookups when using the JBoss JNDI provider.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">JndiName</emphasis>: The name in JNDI under which the proxy is bound.
                              This needs to be set to a blank/empty string to indicate the interface should not be bound
                              into JNDI. We can't use the JNDI to bootstrap itself. This is the role of the
                                  <literal>NamingFactoryServlet</literal>.</para>
                      </listitem>
                  </itemizedlist>
                  <para>The <literal>http-invoker.sar/invoker.war/WEB-INF/web.xml</literal> descriptor defines the
                      mappings of the <literal>NamingFactoryServlet</literal> and <literal>InvokerServlet</literal> along
                      with their initialzation parameters. The configuration of the
                      <literal>NamingFactoryServlet</literal> relevant to JNDI/HTTP is the <literal>JNDIFactory</literal>
                      entry which defines:</para>
                  <itemizedlist>
                      <listitem>
                          <para>A <literal>namingProxyMBean</literal> initialization parameter that maps to the
                                  <literal>HttpProxyFactory</literal> MBean name. This is used by the
                                  <literal>NamingFactoryServlet</literal> to obtain the <literal>Naming</literal> proxy
                              which it will return in response to HTTP posts. For the default
                                  <literal>http-invoker.sar/META-INF/jboss-service.xml</literal> settings the name
                                  <literal>jboss:service=invoker,type=http,target=Naming</literal>. </para>
                      </listitem>
                      <listitem>
                          <para>A proxy initialzation parameter that defines the name of the
                              <literal>namingProxyMBean</literal> attribute to query for the Naming proxy value. This
                              defaults to an attribute name of <literal>Proxy</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>The servlet mapping for the <literal>JNDIFactory</literal> configuration. The default
                              setting for the unsecured mapping is <literal>/JNDIFactory/*</literal>. This is relative to
                              the context root of the <literal>http-invoker.sar/invoker.war</literal>, which by default is
                              the WAR name minus the <literal>.war</literal> suffix.</para>
                      </listitem>
                  </itemizedlist>
                  <para>The configuration of the <literal>InvokerServlet</literal> relevant to JNDI/HTTP is the
                          <literal>JMXInvokerServlet</literal> which defines:</para>
                  <itemizedlist>
                      <listitem>
                          <para>The servlet mapping of the <literal>InvokerServlet</literal>. The default setting for the
                              unsecured mapping is <literal>/JMXInvokerServlet/*</literal>. This is relative to the
                              context root of the <literal>http-invoker.sar/invoker.war</literal>, which by default is the
                              WAR name minus the <literal>.war</literal> suffix.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>Accessing JNDI over HTTPS</title>
                  <para>To be able to access JNDI over HTTP/SSL you need to enable an SSL connector on the web container.
                      The details of this are covered in the Integrating Servlet Containers for Tomcat. We will
                      demonstrate the use of HTTPS with a simple example client that uses an HTTPS URL as the JNDI
                      provider URL. We will provide an SSL connector configuration for the example, so unless you are
                      interested in the details of the SSL connector setup, the example is self contained.</para>
                  <para>We also provide a configuration of the <literal>HttpProxyFactory</literal> setup to use an HTTPS
                      URL. The following example shows the section of the <literal>http-invoker.sar</literal>
                      <literal>jboss-service.xml</literal> descriptor that the example installs to provide this
                      configuration. All that has changed relative to the standard HTTP configuration are the
                          <literal>InvokerURLPrefix</literal> and <literal>InvokerURLSuffix</literal> attributes, which
                      setup an HTTPS URL using the 8443 port.</para>
                  <programlisting>&lt;!-- Expose the Naming service interface via HTTPS --&gt;
  &lt;mbean code="org.jboss.invocation.http.server.HttpProxyFactory" 
         name="jboss:service=invoker,type=https,target=Naming"&gt;
      &lt;!-- The Naming service we are proxying --&gt;
      &lt;attribute name="InvokerName"&gt;jboss:service=Naming&lt;/attribute&gt;
      &lt;!-- Compose the invoker URL from the cluster node address --&gt;
      &lt;attribute name="InvokerURLPrefix"&gt;https://&lt;/attribute&gt;
      &lt;attribute name="InvokerURLSuffix"&gt;:8443/invoker/JMXInvokerServlet &lt;/attribute&gt;
      &lt;attribute name="UseHostName"&gt;true&lt;/attribute&gt;
      &lt;attribute name="ExportedInterface"&gt;org.jnp.interfaces.Naming &lt;/attribute&gt;
      &lt;attribute name="JndiName"/&gt;
      &lt;attribute name="ClientInterceptors"&gt;
          &lt;interceptors&gt;
              &lt;interceptor&gt;org.jboss.proxy.ClientMethodInterceptor &lt;/interceptor&gt;
              &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
              &lt;interceptor&gt;org.jboss.naming.interceptors.ExceptionInterceptor &lt;/interceptor&gt;
              &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor &lt;/interceptor&gt;
          &lt;/interceptors&gt;
      &lt;/attribute&gt;
  &lt;/mbean&gt;
  </programlisting>
                  <para>At a minimum, a JNDI client using HTTPS requires setting up a HTTPS URL protocol handler. We will
                      be using the Java Secure Socket Extension (JSSE) for HTTPS. The JSSE documentation does a good job
                      of describing what is necessary to use HTTPS, and the following steps were needed to configure the
                      example client shown in <xref linkend="ch3.jndiclienthttps.ex"/>:</para>
                  <itemizedlist>
                      <listitem>
                          <para>A protocol handler for HTTPS URLs must be made available to Java. The JSSE release
                              includes an HTTPS handler in the <literal>com.sun.net.ssl.internal.www.protocol</literal>
                              package. To enable the use of HTTPS URLs you include this package in the standard URL
                              protocol handler search property, <literal>java.protocol.handler.pkgs</literal>. We set the
                                  <literal>java.protocol.handler.pkgs</literal> property in the Ant script.</para>
                      </listitem>
                      <listitem>
                          <para>The JSSE security provider must be installed in order for SSL to work. This can be done
                              either by installing the JSSE jars as an extension package, or programatically. We use the
                              programatic approach in the example since this is less intrusive. Line 18 of the
                                  <literal>ExClient</literal> code demonstrates how this is done.</para>
                      </listitem>
                      <listitem>
                          <para>The JNDI provider URL must use HTTPS as the protocol. Lines 24-25 of the
                              <literal>ExClient</literal> code specify an HTTP/SSL connection to the localhost on port
                              8443. The hostname and port are defined by the web container SSL connector.</para>
                      </listitem>
                      <listitem>
                          <para>The validation of the HTTPS URL hostname against the server certificate must be disabled.
                              By default, the JSSE HTTPS protocol handler employs a strict validation of the hostname
                              portion of the HTTPS URL against the common name of the server certificate. This is the same
                              check done by web browsers when you connect to secured web site. We are using a self-signed
                              server certificate that uses a common name of "<literal>Chapter 8 SSL Example</literal>"
                              rather than a particular hostname, and this is likely to be common in development
                              environments or intranets. The JBoss <literal>HttpInvokerProxy</literal> will override the
                              default hostname checking if a <literal>org.jboss.security.ignoreHttpsHost</literal> system
                              property exists and has a value of true. We set the
                                  <literal>org.jboss.security.ignoreHttpsHost</literal> property to true in the Ant
                              script.</para>
                      </listitem>
                  </itemizedlist>
                  <example id="ch3.jndiclienthttps.ex">
                      <title>A JNDI client that uses HTTPS as the transport</title>
                      <programlisting>package org.jboss.chap3.ex1;
  
  import java.security.Security;
  import java.util.Properties;
  import javax.naming.Context;
  import javax.naming.InitialContext;
                      
  public class ExClient
  {
      public static void main(String args[]) throws Exception
      {
          Properties env = new Properties();
          env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
                          "org.jboss.naming.HttpNamingContextFactory");
          env.setProperty(Context.PROVIDER_URL,
                          "https://localhost:8443/invoker/JNDIFactorySSL");
  
          Context ctx = new InitialContext(env);
          System.out.println("Created InitialContext, env=" + env);
  
          Object data = ctx.lookup("jmx/invoker/RMIAdaptor");
          System.out.println("lookup(jmx/invoker/RMIAdaptor): " + data);
      }
  }</programlisting>
                  </example>
                  <para>To test the client, first build the chapter 3 example to create the <literal>chap3</literal>
                      configuration fileset. </para>
                  <programlisting>[examples]$ ant -Dchap=naming config</programlisting>
                  <para>Next, start the JBoss server using the <literal>naming</literal> configuration fileset:</para>
                  <programlisting>[bin]$ sh run.sh -c naming</programlisting>
                  <para>And finally, run the <literal>ExClient</literal> using:</para>
                  <programlisting>[examples]$ ant -Dchap=naming -Dex=1 run-example
  ...
  run-example1:
       [java] Created InitialContext, env={java.naming.provider.url=https://localhost:8443/invo
  ker/JNDIFactorySSL, java.naming.factory.initial=org.jboss.naming.HttpNamingContextFactory}
       [java] lookup(jmx/invoker/RMIAdaptor): org.jboss.invocation.jrmp.interfaces.JRMPInvokerP
  roxy at cac3fa</programlisting>
              </section>
              <section>
                  <title>Securing Access to JNDI over HTTP</title>
                  <para>One benefit to accessing JNDI over HTTP is that it is easy to secure access to the JNDI
                          <literal>InitialContext</literal> factory as well as the naming operations using standard web
                      declarative security. This is possible because the server side handling of the JNDI/HTTP transport
                      is implemented with two servlets. These servlets are included in the
                          <literal>http-invoker.sar/invoker.war</literal> directory found in the
                      <literal>default</literal> and <literal>all</literal> configuration deploy directories as shown
                      previously. To enable secured access to JNDI you need to edit the
                          <literal>invoker.war/WEB-INF/web.xml</literal> descriptor and remove all unsecured servlet
                      mappings. For example, the <literal>web.xml</literal> descriptor shown in <xref
                          linkend="ch3.webxmlsec.ex"/> only allows access to the <literal>invoker.war</literal> servlets
                      if the user has been authenticated and has a role of <literal>HttpInvoker</literal>.</para>
                  <example id="ch3.webxmlsec.ex">
                      <title> An example web.xml descriptor for secured access to the JNDI servlets</title>
                      <programlisting>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE web-app PUBLIC
            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
            "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;
  &lt;web-app&gt;
      &lt;!-- ### Servlets --&gt;
      &lt;servlet&gt;
          &lt;servlet-name&gt;JMXInvokerServlet&lt;/servlet-name&gt;
          &lt;servlet-class&gt;
              org.jboss.invocation.http.servlet.InvokerServlet
          &lt;/servlet-class&gt;
          &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
      &lt;/servlet&gt;   &lt;servlet&gt;
          &lt;servlet-name&gt;JNDIFactory&lt;/servlet-name&gt;
          &lt;servlet-class&gt;
              org.jboss.invocation.http.servlet.NamingFactoryServlet
          &lt;/servlet-class&gt;
          &lt;init-param&gt;
              &lt;param-name&gt;namingProxyMBean&lt;/param-name&gt;
              &lt;param-value&gt;jboss:service=invoker,type=http,target=Naming&lt;/param-value&gt;
          &lt;/init-param&gt;
          &lt;init-param&gt;
              &lt;param-name&gt;proxyAttribute&lt;/param-name&gt;
              &lt;param-value&gt;Proxy&lt;/param-value&gt;
          &lt;/init-param&gt;
          &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
      &lt;/servlet&gt;  
      &lt;!-- ### Servlet Mappings --&gt;
      &lt;servlet-mapping&gt;
          &lt;servlet-name&gt;JNDIFactory&lt;/servlet-name&gt;
          &lt;url-pattern&gt;/restricted/JNDIFactory/*&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;
      &lt;servlet-mapping&gt;
          &lt;servlet-name&gt;JMXInvokerServlet&lt;/servlet-name&gt;
          &lt;url-pattern&gt;/restricted/JMXInvokerServlet/*&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;   &lt;security-constraint&gt;
          &lt;web-resource-collection&gt;
              &lt;web-resource-name&gt;HttpInvokers&lt;/web-resource-name&gt;
              &lt;description&gt;An example security config that only allows users with
                  the role HttpInvoker to access the HTTP invoker servlets &lt;/description&gt;
              &lt;url-pattern&gt;/restricted/*&lt;/url-pattern&gt;
              &lt;http-method&gt;GET&lt;/http-method&gt;
              &lt;http-method&gt;POST&lt;/http-method&gt;
          &lt;/web-resource-collection&gt;
          &lt;auth-constraint&gt;
              &lt;role-name&gt;HttpInvoker&lt;/role-name&gt;
          &lt;/auth-constraint&gt;
      &lt;/security-constraint&gt;
      &lt;login-config&gt;
          &lt;auth-method&gt;BASIC&lt;/auth-method&gt;
          &lt;realm-name&gt;JBoss HTTP Invoker&lt;/realm-name&gt;
      &lt;/login-config&gt;   &lt;security-role&gt;
          &lt;role-name&gt;HttpInvoker&lt;/role-name&gt;
      &lt;/security-role&gt;
  &lt;/web-app&gt;</programlisting>
                  </example>
                  <para>The <literal>web.xml</literal> descriptor only defines which sevlets are secured, and which roles
                      are allowed to access the secured servlets. You must additionally define the security domain that
                      will handle the authentication and authorization for the war. This is done through the
                          <literal>jboss-web.xml</literal> descriptor, and an example that uses the
                      <literal>http-invoker</literal> security domain is given below.</para>
                  <programlisting>&lt;jboss-web&gt;
      &lt;security-domain&gt;java:/jaas/http-invoker&lt;/security-domain&gt;
  &lt;/jboss-web&gt;</programlisting>
                  <para>The <literal>security-domain</literal> element defines the name of the security domain that will
                      be used for the JAAS login module configuration used for authentication and authorization. See <xref
                          linkend="ch8.declarativesecurity.sect"/> for additional details on the meaning and configuration
                      of the security domain name.</para>
              </section>
              <section>
                  <title>Securing Access to JNDI with a Read-Only Unsecured Context</title>
                  <para>Another feature available for the JNDI/HTTP naming service is the ability to define a context that
                      can be accessed by unauthenticated users in read-only mode. This can be important for services used
                      by the authentication layer. For example, the <literal>SRPLoginModule</literal> needs to lookup the
                      SRP server interface used to perform authentication. We'll now walk through how read-only JNDI works
                      in JBoss. </para>
                  <para>First, the <literal>ReadOnlyJNDIFactory</literal> is declared in
                          <literal>invoker.sar/WEB-INF/web.xml</literal>. It will be mapped to
                          <literal>/invoker/ReadOnlyJNDIFactory</literal>. </para>
                  <programlisting>&lt;servlet&gt;
      &lt;servlet-name&gt;ReadOnlyJNDIFactory&lt;/servlet-name&gt;
      &lt;description&gt;A servlet that exposes the JBoss JNDI Naming service stub
            through http, but only for a single read-only context. The return content 
            is serialized MarshalledValue containg the org.jnp.interfaces.Naming 
            stub.
      &lt;/description&gt;
      &lt;servlet-class&gt;org.jboss.invocation.http.servlet.NamingFactoryServlet&lt;/servlet-class&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;namingProxyMBean&lt;/param-name&gt;
          &lt;param-value&gt;<emphasis role="bold">jboss:service=invoker,type=http,target=Naming,readonly=true</emphasis>&lt;/param-value&gt;
      &lt;/init-param&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;proxyAttribute&lt;/param-name&gt;
          &lt;param-value&gt;Proxy&lt;/param-value&gt;
      &lt;/init-param&gt;
      &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
  &lt;/servlet&gt;
  
  &lt;!-- ... --&gt;
                          
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;ReadOnlyJNDIFactory&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/ReadOnlyJNDIFactory/*&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;</programlisting>
                  <para> The factory only provides a JNDI stub which needs to be connected to an invoker. Here the invoker
                      is <literal>jboss:service=invoker,type=http,target=Naming,readonly=true</literal>. This invoker is
                      declared in the <literal>http-invoker.sar/META-INF/jboss-service.xml</literal> file. </para>
                  <programlisting>   &lt;mbean code="org.jboss.invocation.http.server.HttpProxyFactory"
        name="jboss:service=invoker,type=http,target=Naming,readonly=true"&gt;
        &lt;attribute name="InvokerName"&gt;jboss:service=Naming&lt;/attribute&gt;
        &lt;attribute name="InvokerURLPrefix"&gt;http://&lt;/attribute&gt;
        &lt;attribute name="InvokerURLSuffix"&gt;:8080<emphasis role="bold">/invoker/readonly/JMXInvokerServlet</emphasis>&lt;/attribute&gt;
        &lt;attribute name="UseHostName"&gt;true&lt;/attribute&gt;
        &lt;attribute name="ExportedInterface"&gt;org.jnp.interfaces.Naming&lt;/attribute&gt;
        &lt;attribute name="JndiName"&gt;&lt;/attribute&gt;
        &lt;attribute name="ClientInterceptors"&gt;
            &lt;interceptors&gt;
               &lt;interceptor&gt;org.jboss.proxy.ClientMethodInterceptor&lt;/interceptor&gt;
               &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
               &lt;interceptor&gt;org.jboss.naming.interceptors.ExceptionInterceptor&lt;/interceptor&gt;
               &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
            &lt;/interceptors&gt;
        &lt;/attribute&gt;
     &lt;/mbean&gt;</programlisting>
                  <para> The proxy on the client side needs to talk back to a specific invoker servlet on the server side.
                      The configuration here has the actual invocations going to
                          <literal>/invoker/readonly/JMXInvokerServlet</literal>. This is actually the standard
                          <literal>JMXInvokerServlet</literal> with a read-only filter attached. </para>
                  <programlisting>    &lt;filter&gt;
          &lt;filter-name&gt;ReadOnlyAccessFilter&lt;/filter-name&gt;
          &lt;filter-class&gt;org.jboss.invocation.http.servlet.ReadOnlyAccessFilter&lt;/filter-class&gt;
          &lt;init-param&gt;
              &lt;param-name&gt;readOnlyContext&lt;/param-name&gt;
              &lt;param-value&gt;<emphasis role="bold">readonly</emphasis>&lt;/param-value&gt;
              &lt;description&gt;The top level JNDI context the filter will enforce
                  read-only access on. If specified only Context.lookup operations
                  will be allowed on this context. Another other operations or
                  lookups on any other context will fail. Do not associate this
                  filter with the JMXInvokerServlets if you want unrestricted
                  access. &lt;/description&gt;
          &lt;/init-param&gt;
          &lt;init-param&gt;
              &lt;param-name&gt;invokerName&lt;/param-name&gt;
              &lt;param-value&gt;jboss:service=Naming&lt;/param-value&gt;
              &lt;description&gt;The JMX ObjectName of the naming service mbean &lt;/description&gt;
          &lt;/init-param&gt;
      &lt;/filter&gt;
      
      &lt;filter-mapping&gt;
          &lt;filter-name&gt;ReadOnlyAccessFilter&lt;/filter-name&gt;
          &lt;url-pattern&gt;/readonly/*&lt;/url-pattern&gt;
      &lt;/filter-mapping&gt;
  
      &lt;!-- ... --&gt;
      &lt;!-- A mapping for the JMXInvokerServlet that only allows invocations 
              of lookups under a read-only context. This is enforced by the
              ReadOnlyAccessFilter 
              --&gt;
      &lt;servlet-mapping&gt;
          &lt;servlet-name&gt;JMXInvokerServlet&lt;/servlet-name&gt;
          &lt;url-pattern&gt;/readonly/JMXInvokerServlet/*&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;</programlisting>
                  <para>The <literal>readOnlyContext</literal> parameter is set to <literal>readonly</literal> which means
                      that when you access JBoss through the <literal>ReadOnlyJNDIFactory</literal>, you will only be able
                      to access data in the <literal>readonly</literal> context. Here is a code fragment that illustrates
                      the usage:</para>
                  <programlisting>Properties env = new Properties();
  env.setProperty(Context.INITIAL_CONTEXT_FACTORY, 
                  "org.jboss.naming.HttpNamingContextFactory");
  env.setProperty(Context.PROVIDER_URL, 
                  "http://localhost:8080/invoker/ReadOnlyJNDIFactory");
  
  Context ctx2 = new InitialContext(env);
  Object data = ctx2.lookup("readonly/data");</programlisting>
                  <para> Attempts to look up any objects outside of the readonly context will fail. Note that JBoss
                      doesn't ship with any data in the <literal>readonly</literal> context, so the readonly context won't
                      be bound usable unless you create it. </para>
              </section>
          </section>
          <section id="ch3.mbeans">
              <title>Additional Naming MBeans</title>
              <para>In addition to the <literal>NamingService</literal> MBean that configures an embedded JBossNS server
                  within JBoss, there are several additional MBean services related to naming that ship with JBoss. They
                  are <literal>JndiBindingServiceMgr</literal>, <literal>NamingAlias</literal>,
                  <literal>ExternalContext</literal>, and <literal>JNDIView</literal>.</para>
              <section id="ch3.jndibinding">
                  <title>JNDI Binding Manager</title>
                  <para> The JNDI binding manager service allows you to quickly bind objects into JNDI for use by
                      application code. The MBean class for the binding service is
                          <literal>org.jboss.naming.JNDIBindingServiceMgr</literal>. It has a single attribute,
                          <literal>BindingsConfig</literal>, which accepts an XML document that conforms to the
                          <literal>jndi-binding-service_1_0.xsd</literal> schema. The content of the
                          <literal>BindingsConfig</literal> attribute is unmarshalled using the JBossXB framework. The
                      following is an MBean definition that shows the most basic form usage of the JNDI binding manager
                      service.</para>
                  <programlisting>&lt;mbean code=&quot;org.jboss.naming.JNDIBindingServiceMgr&quot; 
         name=&quot;jboss.tests:name=example1&quot;&gt;
      &lt;attribute name=&quot;BindingsConfig&quot; serialDataType=&quot;jbxb&quot;&gt;
          &lt;jndi:bindings xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; 
                         xmlns:jndi=&quot;urn:jboss:jndi-binding-service&quot;
                         xs:schemaLocation=&quot;urn:jboss:jndi-binding-service resource:jndi-binding-service_1_0.xsd&quot;&gt; 
              &lt;jndi:binding name=&quot;bindexample/message&quot;&gt;
                  &lt;jndi:value trim="true"&gt;
                      Hello, JNDI!
                  &lt;/jndi:value&gt;
              &lt;/jndi:binding&gt;
          &lt;/jndi:bindings&gt;
      &lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
                  <para> This binds the text string "<literal>Hello, JNDI!</literal>" under the JNDI name
                          <literal>bindexample/message</literal>. An application would look up the value just as it would
                      for any other JNDI value. The <literal>trim</literal> attribute specifies that leading and trailing
                      whitespace should be ignored. The use of the attribute here is purely for illustrative purposes as
                      the default value is true. </para>
                  <programlisting>InitialContext ctx  = new InitialContext();
  String         text = (String) ctx.lookup("bindexample/message");</programlisting>
                  <para>String values themselves are not that interesting. If a JavaBeans property editor is available,
                      the desired class name can be specified using the <literal>type</literal> attribute </para>
                  <programlisting>&lt;jndi:binding name=&quot;urls/jboss-home&quot;&gt;
      &lt;jndi:value type=&quot;java.net.URL&quot;&gt;http://www.jboss.org&lt;/jndi:value&gt;
  &lt;/jndi:binding&gt;</programlisting>
                  <para>The <literal>editor</literal> attribute can be used to specify a particular property editor to
                      use.</para>
                  <programlisting>&lt;jndi:binding name=&quot;hosts/localhost&quot;&gt;
      &lt;jndi:value editor=&quot;org.jboss.util.propertyeditor.InetAddressEditor&quot;&gt; 
          127.0.0.1 
      &lt;/jndi:value&gt;
  &lt;/jndi:binding&gt;</programlisting>
                  <para>For more complicated structures, any JBossXB-ready schema may be used. The following example shows
                      how a <literal>java.util.Properties</literal> object would be mapped. </para>
                  <programlisting>&lt;jndi:binding name=&quot;maps/testProps&quot;&gt;
      &lt;java:properties xmlns:java=&quot;urn:jboss:java-properties&quot; 
                       xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
                       xs:schemaLocation=&quot;urn:jboss:java-properties resource:java-properties_1_0.xsd&quot;&gt;
          &lt;java:property&gt;
              &lt;java:key&gt;key1&lt;/java:key&gt;
              &lt;java:value&gt;value1&lt;/java:value&gt;
          &lt;/java:property&gt;
          &lt;java:property&gt;
              &lt;java:key&gt;key2&lt;/java:key&gt;
              &lt;java:value&gt;value2&lt;/java:value&gt;
          &lt;/java:property&gt;
      &lt;/java:properties&gt;
  &lt;/jndi:binding&gt;</programlisting>
                  <para>For more information on JBossXB, see the <ulink
                          url="http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossXB">JBossXB wiki page</ulink>. </para>
              </section>
              <section>
                  <title>The org.jboss.naming.NamingAlias MBean</title>
                  <para>The <literal>NamingAlias</literal> MBean is a simple utility service that allows you to create an
                      alias in the form of a JNDI <literal>javax.naming.LinkRef</literal> from one JNDI name to another.
                      This is similar to a symbolic link in the UNIX file system. To an alias you add a configuration of
                      the <literal>NamingAlias</literal> MBean to the <literal>jboss-service.xml</literal> configuration
                      file. The configurable attributes of the <literal>NamingAlias</literal> service are as follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">FromName</emphasis>: The location where the <literal>LinkRef</literal>
                              is bound under JNDI.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ToName</emphasis>: The to name of the alias. This is the target name
                              to which the <literal>LinkRef</literal> refers. The name is a URL, or a name to be resolved
                              relative to the <literal>InitialContext</literal>, or if the first character of the name is
                              a dot (<literal>.</literal>), the name is relative to the context in which the link is
                              bound.</para>
                      </listitem>
                  </itemizedlist>
                  <para>The following example provides a mapping of the JNDI name
                      <literal>QueueConnectionFactory</literal> to the name <literal>ConnectionFactory</literal>.</para>
                  <programlisting>&lt;mbean code="org.jboss.naming.NamingAlias" 
         name="jboss.mq:service=NamingAlias,fromName=QueueConnectionFactory"&gt;
      &lt;attribute name="ToName"&gt;ConnectionFactory&lt;/attribute&gt;
      &lt;attribute name="FromName"&gt;QueueConnectionFactory&lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
              </section>
              <section>
                  <title>org.jboss.naming.ExternalContext MBean</title>
                  <para>The <literal>ExternalContext</literal> MBean allows you to federate external JNDI contexts into
                      the JBoss server JNDI namespace. The term external refers to any naming service external to the
                      JBossNS naming service running inside of the JBoss server VM. You can incorporate LDAP servers, file
                      systems, DNS servers, and so on, even if the JNDI provider root context is not serializable. The
                      federation can be made available to remote clients if the naming service supports remote access.</para>
                  <para>To incorporate an external JNDI naming service, you have to add a configuration of the
                          <literal>ExternalContext</literal> MBean service to the <literal>jboss-service.xml</literal>
                      configuration file. The configurable attributes of the <literal>ExternalContext</literal> service
                      are as follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">JndiName</emphasis>: The JNDI name under which the external context is
                              to be bound.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">RemoteAccess</emphasis>: A boolean flag indicating if the external
                                  <literal>InitialContext</literal> should be bound using a
                              <literal>Serializable</literal> form that allows a remote client to create the external
                                  <literal>InitialContext</literal> . When a remote client looks up the external context
                              via the JBoss JNDI <literal>InitialContext</literal>, they effectively create an instance of
                              the external <literal>InitialContext</literal> using the same env properties passed to the
                                  <literal>ExternalContext</literal> MBean. This will only work if the client can do a
                                  <literal>new InitialContext(env)</literal> remotely. This requires that the
                                  <literal>Context.PROVIDER_URL</literal> value of env is resolvable in the remote VM that
                              is accessing the context. This should work for the LDAP example. For the file system example
                              this most likely won't work unless the file system path refers to a common network path. If
                              this property is not given it defaults to false.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">CacheContext</emphasis>: The <literal>cacheContext</literal> flag.
                              When set to true, the external <literal>Context</literal> is only created when the MBean is
                              started and then stored as an in memory object until the MBean is stopped. If cacheContext
                              is set to false, the external <literal>Context</literal> is created on each lookup using the
                              MBean properties and InitialContext class. When the uncached <literal>Context</literal> is
                              looked up by a client, the client should invoke <literal>close()</literal> on the Context to
                              prevent resource leaks.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">InitialContext</emphasis>: The fully qualified class name of the
                                  <literal>InitialContext</literal> implementation to use. Must be one of:
                                  <literal>javax.naming.InitialContext</literal>,
                                  <literal>javax.naming.directory.InitialDirContext</literal> or
                                  <literal>javax.naming.ldap.InitialLdapContext</literal>. In the case of the
                                  <literal>InitialLdapContext</literal> a null <literal>Controls</literal> array is used.
                              The default is <literal>javax.naming.InitialContex</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Properties</emphasis>: The <literal>Properties</literal> attribute
                              contains the JNDI properties for the external <literal>InitialContext</literal>. The input
                              should be the text equivalent to what would go into a <literal>jndi.properties</literal>
                              file. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">PropertiesURL</emphasis>: This set the
                              <literal>jndi.properties</literal> information for the external
                              <literal>InitialContext</literal> from an extern properties file. This is either a URL,
                              string or a classpath resource name. Examples are as follows:</para>
                          <itemizedlist spacing="compact">
                              <listitem>
                                  <para>file:///config/myldap.properties</para>
                              </listitem>
                              <listitem>
                                  <para>http://config.mycompany.com/myldap.properties</para>
                              </listitem>
                              <listitem>
                                  <para>/conf/myldap.properties</para>
                              </listitem>
                              <listitem>
                                  <para>myldap.properties</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                  </itemizedlist>
                  <para>The MBean definition below shows a binding to an external LDAP context into the JBoss JNDI
                      namespace under the name <literal>external/ldap/jboss</literal>. </para>
                  <programlisting>&lt;!-- Bind a remote LDAP server --&gt;
  &lt;mbean code="org.jboss.naming.ExternalContext" 
         name="jboss.jndi:service=ExternalContext,jndiName=external/ldap/jboss"&gt;
      &lt;attribute name="JndiName"&gt;external/ldap/jboss&lt;/attribute&gt;
      &lt;attribute name="Properties"&gt;
          java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
          java.naming.provider.url=ldap://ldaphost.jboss.org:389/o=jboss.org
          java.naming.security.principal=cn=Directory Manager
          java.naming.security.authentication=simple
          java.naming.security.credentials=secret
      &lt;/attribute&gt;
      &lt;attribute name="InitialContext"&gt; javax.naming.ldap.InitialLdapContext &lt;/attribute&gt;
      &lt;attribute name="RemoteAccess"&gt;true&lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
                  <para>With this configuration, you can access the external LDAP context located at
                          <literal>ldap://ldaphost.jboss.org:389/o=jboss.org</literal> from within the JBoss VM using the
                      following code fragment:</para>
                  <programlisting>InitialContext iniCtx = new InitialContext();
  LdapContext ldapCtx = iniCtx.lookup("external/ldap/jboss");</programlisting>
                  <para>Using the same code fragment outside of the JBoss server VM will work in this case because the
                          <literal>RemoteAccess</literal> property was set to true. If it were set to false, it would not
                      work because the remote client would receive a <literal>Reference</literal> object with an
                          <literal>ObjectFactory</literal> that would not be able to recreate the external
                          <literal>IntialContext</literal>
                  </para>
                  <programlisting>&lt;!-- Bind the /usr/local file system directory  --&gt;
  &lt;mbean code="org.jboss.naming.ExternalContext" 
         name="jboss.jndi:service=ExternalContext,jndiName=external/fs/usr/local"&gt;
      &lt;attribute name="JndiName"&gt;external/fs/usr/local&lt;/attribute&gt;
      &lt;attribute name="Properties"&gt;
          java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory
          java.naming.provider.url=file:///usr/local
      &lt;/attribute&gt;
      &lt;attribute name="InitialContext"&gt;javax.naming.IntialContext&lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
                  <para>This configuration describes binding a local file system directory <literal>/usr/local</literal>
                      into the JBoss JNDI namespace under the name <literal>external/fs/usr/local</literal>.</para>
                  <para>With this configuration, you can access the external file system context located at
                          <literal>file:///usr/local</literal> from within the JBoss VM using the following code fragment:</para>
                  <programlisting>InitialContext iniCtx = new InitialContext();
                  Context ldapCtx = iniCtx.lookup("external/fs/usr/local");</programlisting>
                  <para>Note that the use the Sun JNDI service providers, which must be downloaded from <ulink
                          url="http://java.sun.com/products/jndi/serviceproviders.html"/>. The provider JARs should be
                      placed in the server configuration <literal>lib</literal> directory. </para>
              </section>
              <section>
                  <title>The org.jboss.naming.JNDIView MBean</title>
                  <para>The JNDIView MBean allows the user to view the JNDI namespace tree as it exists in the JBoss
                      server using the JMX agent view interface. To view the JBoss JNDI namespace using the JNDIView
                      MBean, you connect to the JMX Agent View using the http interface. The default settings put this at
                          <literal>http://localhost:8080/jmx-console/</literal>. On this page you will see a section that
                      lists the registered MBeans sortyed by domain. It should look something like that shown in <xref
                          linkend="ch3.jmxconsole.fig"/>.</para>
                  <figure id="ch3.jmxconsole.fig">
                      <title>The JMX Console view of the configured JBoss MBeans</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/jndiview-1.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>Selecting the JNDIView link takes you to the JNDIView MBean view, which will have a list of the
                      JNDIView MBean operations. This view should look similar to that shown in <xref
                          linkend="ch3.jndiview.fig"/>.</para>
                  <figure id="ch3.jndiview.fig">
                      <title>The JMX Console view of the JNDIView MBean</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/jndiview-2.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The list operation dumps out the JBoss server JNDI namespace as an HTML page using a simple text
                      view. As an example, invoking the list operation produces the view shown in <xref
                          linkend="ch3.jndiviewlist.fig"/>.</para>
                  <figure id="ch3.jndiviewlist.fig">
                      <title>The JMX Console view of the JNDIView list operation output</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/jndiview-3.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
              </section>
          </section>
          <section id="ch3.j2ee">
              <title>J2EE and JNDI - The Application Component Environment</title>
              <para>JNDI is a fundamental aspect of the J2EE specifications. One key usage is the isolation of J2EE
                  component code from the environment in which the code is deployed. Use of the application component's
                  environment allows the application component to be customized without the need to access or change the
                  application component's source code. The application component environment is referred to as the ENC,
                  the enterprise naming context. It is the responsibility of the application component container to make
                  an ENC available to the container components in the form of JNDI Context. The ENC is utilized by the
                  participants involved in the life cycle of a J2EE component in the following ways.</para>
              <itemizedlist>
                  <listitem>
                      <para>Application component business logic should be coded to access information from its ENC. The
                          component provider uses the standard deployment descriptor for the component to specify the
                          required ENC entries. The entries are declarations of the information and resources the
                          component requires at runtime.</para>
                  </listitem>
                  <listitem>
                      <para>The container provides tools that allow a deployer of a component to map the ENC references
                          made by the component developer to the deployment environment entity that satisfies the
                          reference.</para>
                  </listitem>
                  <listitem>
                      <para>The component deployer utilizes the container tools to ready a component for final
                      deployment.</para>
                  </listitem>
                  <listitem>
                      <para>The component container uses the deployment package information to build the complete
                          component ENC at runtime</para>
                  </listitem>
              </itemizedlist>
              <para>The complete specification regarding the use of JNDI in the J2EE platform can be found in section 5 of
                  the J2EE 1.4 specification. The J2EE specification is available at <ulink
                      url="http://java.sun.com/j2ee/download.html"/>.</para>
              <para>An application component instance locates the ENC using the JNDI API. An application component
                  instance creates a <literal>javax.naming.InitialContext</literal> object by using the no argument
                  constructor and then looks up the naming environment under the name <literal>java:comp/env</literal>.
                  The application component's environment entries are stored directly in the ENC, or in its subcontexts.
                      <xref linkend="ch3.enc.ex"/> illustrates the prototypical lines of code a component uses to access
                  its ENC.</para>
              <example id="ch3.enc.ex">
                  <title>ENC access sample code</title>
                  <programlisting>// Obtain the application component's ENC
  Context iniCtx = new InitialContext();
  Context compEnv = (Context) iniCtx.lookup("java:comp/env");</programlisting>
              </example>
              <para>An application component environment is a local environment that is accessible only by the component
                  when the application server container thread of control is interacting with the application component.
                  This means that an EJB <literal>Bean1</literal> cannot access the ENC elements of EJB
                  <literal>Bean2</literal>, and vice versa. Similarly, Web application <literal>Web1</literal> cannot
                  access the ENC elements of Web application <literal>Web2</literal> or <literal>Bean1</literal> or
                      <literal>Bean2</literal> for that matter. Also, arbitrary client code, whether it is executing
                  inside of the application server VM or externally cannot access a component's
                  <literal>java:comp</literal> JNDI context. The purpose of the ENC is to provide an isolated, read-only
                  namespace that the application component can rely on regardless of the type of environment in which the
                  component is deployed. The ENC must be isolated from other components because each component defines its
                  own ENC content. Components <literal>A</literal> and <literal>B</literal>, for example, may define the
                  same name to refer to different objects. For example, EJB <literal>Bean1</literal> may define an
                  environment entry <literal>java:comp/env/red</literal> to refer to the hexadecimal value for the RGB
                  color for red, while Web application <literal>Web1</literal> may bind the same name to the deployment
                  environment language locale representation of red.</para>
              <para>There are three commonly used levels of naming scope in JBoss: names under
                  <literal>java:comp</literal>, names under <literal>java:</literal>, and any other name. As discussed,
                  the <literal>java:comp</literal> context and its subcontexts are only available to the application
                  component associated with that particular context. Subcontexts and object bindings directly under
                      <literal>java:</literal> are only visible within the JBoss server virtual machine and not to remote
                  clients. Any other context or object binding is available to remote clients, provided the context or
                  object supports serialization. You'll see how the isolation of these naming scopes is achieved in the
                      <xref linkend="ch3.nsarch"/>.</para>
              <para>An example of where the restricting a binding to the <literal>java:</literal> context is useful would
                  be a <literal>javax.sql.DataSource</literal> connection factory that can only be used inside of the
                  JBoss server where the associated database pool resides. On the other hand, an EJB home interface would
                  be bound to a globally visible name that should accessible by remote client.</para>
              <section>
                  <title>ENC Usage Conventions</title>
                  <para>JNDI is used as the API for externalizing a great deal of information from an application
                      component. The JNDI name that the application component uses to access the information is declared
                      in the standard <literal>ejb-jar.xml</literal> deployment descriptor for EJB components, and the
                      standard <literal>web.xml</literal> deployment descriptor for Web components. Several different
                      types of information may be stored in and retrieved from JNDI including:</para>
                  <itemizedlist>
                      <listitem>
                          <para>Environment entries as declared by the <literal>env-entry</literal> elements</para>
                      </listitem>
                      <listitem>
                          <para>EJB references as declared by <literal>ejb-ref</literal> and
                              <literal>ejb-local-ref</literal> elements.</para>
                      </listitem>
                      <listitem>
                          <para>Resource manager connection factory references as declared by the
                              <literal>resource-ref</literal> elements</para>
                      </listitem>
                      <listitem>
                          <para>Resource environment references as declared by the <literal>resource-env-ref</literal>
                              elements</para>
                      </listitem>
                  </itemizedlist>
                  <para>Each type of deployment descriptor element has a JNDI usage convention with regard to the name of
                      the JNDI context under which the information is bound. Also, in addition to the standard
                      deploymentdescriptor element, there is a JBoss server specific deployment descriptor element that
                      maps the JNDI name as used by the application component to the deployment environment JNDI name.</para>
                  <section>
                      <title>Environment Entries</title>
                      <para>Environment entries are the simplest form of information stored in a component ENC, and are
                          similar to operating system environment variables like those found on UNIX or Windows.
                          Environment entries are a name-to-value binding that allows a component to externalize a value
                          and refer to the value using a name.</para>
                      <para>An environment entry is declared using an <literal>env-entry</literal> element in the standard
                          deployment descriptors. The <literal>env-entry</literal> element contains the following child
                          elements:</para>
                      <itemizedlist>
                          <listitem>
                              <para>An optional <emphasis role="bold">description</emphasis> element that provides a
                                  description of the entry</para>
                          </listitem>
                          <listitem>
                              <para>An <emphasis role="bold">env-entry-name</emphasis> element giving the name of the
                                  entry relative to <literal>java:comp/env</literal>
                              </para>
                          </listitem>
                          <listitem>
                              <para>An <emphasis role="bold">env-entry-type</emphasis> element giving the Java type of the
                                  entry value that must be one of: <itemizedlist spacing="compact">
                                      <listitem>
                                          <para>
                                              <literal>java.lang.Byte</literal>
                                          </para>
                                      </listitem>
                                      <listitem>
                                          <para>
                                              <literal>java.lang.Boolean</literal>
                                          </para>
                                      </listitem>
                                      <listitem>
                                          <para>
                                              <literal>java.lang.Character</literal>
                                          </para>
                                      </listitem>
                                      <listitem>
                                          <para>
                                              <literal>java.lang.Double</literal>
                                          </para>
                                      </listitem>
                                      <listitem>
                                          <para>
                                              <literal>java.lang.Float</literal>
                                          </para>
                                      </listitem>
                                      <listitem>
                                          <para>
                                              <literal>java.lang.Integer</literal>
                                          </para>
                                      </listitem>
                                      <listitem>
                                          <para>
                                              <literal>java.lang.Long</literal>
                                          </para>
                                      </listitem>
                                      <listitem>
                                          <para>
                                              <literal>java.lang.Short</literal>
                                          </para>
                                      </listitem>
                                      <listitem>
                                          <para>
                                              <literal>java.lang.String</literal>
                                          </para>
                                      </listitem>
                                  </itemizedlist>
                              </para>
                          </listitem>
                          <listitem>
                              <para>An <emphasis role="bold">env-entry-value</emphasis> element giving the value of entry
                                  as a string</para>
                          </listitem>
                      </itemizedlist>
                      <para>An example of an <literal>env-entry</literal> fragment from an <literal>ejb-jar.xml</literal>
                          deployment descriptor is given in <xref linkend="ch3.enventry.ex"/>. There is no JBoss specific
                          deployment descriptor element because an <literal>env-entry</literal> is a complete name and
                          value specification. <xref linkend="ch3.enventry2.ex"/> shows a sample code fragment for
                          accessing the <literal>maxExemptions</literal> and <literal>taxRate</literal>
                          <literal>env-entry</literal> values declared in the deployment descriptor.</para>
                      <example id="ch3.enventry.ex">
                          <title>An example ejb-jar.xml env-entry fragment</title>
                          <programlisting>&lt;!-- ... --&gt;
  &lt;session&gt;
      &lt;ejb-name&gt;ASessionBean&lt;/ejb-name&gt;
      &lt;!-- ... --&gt;
      &lt;env-entry&gt;
          &lt;description&gt;The maximum number of tax exemptions allowed &lt;/description&gt;
          &lt;env-entry-name&gt;maxExemptions&lt;/env-entry-name&gt;
          &lt;env-entry-type&gt;java.lang.Integer&lt;/env-entry-type&gt;
          &lt;env-entry-value&gt;15&lt;/env-entry-value&gt;
      &lt;/env-entry&gt;
      &lt;env-entry&gt;
          &lt;description&gt;The tax rate &lt;/description&gt;
          &lt;env-entry-name&gt;taxRate&lt;/env-entry-name&gt;
          &lt;env-entry-type&gt;java.lang.Float&lt;/env-entry-type&gt;
          &lt;env-entry-value&gt;0.23&lt;/env-entry-value&gt;
      &lt;/env-entry&gt;
  &lt;/session&gt;
  &lt;!-- ... --&gt; </programlisting>
                      </example>
                      <example id="ch3.enventry2.ex">
                          <title> ENC env-entry access code fragment</title>
                          <programlisting>InitialContext iniCtx = new InitialContext();
  Context envCtx = (Context) iniCtx.lookup("java:comp/env");
  Integer maxExemptions = (Integer) envCtx.lookup("maxExemptions");
  Float taxRate = (Float) envCtx.lookup("taxRate");</programlisting>
                      </example>
                  </section>
                  <section>
                      <title>EJB References</title>
                      <para>It is common for EJBs and Web components to interact with other EJBs. Because the JNDI name
                          under which an EJB home interface is bound is a deployment time decision, there needs to be a
                          way for a component developer to declare a reference to an EJB that will be linked by the
                          deployer. EJB references satisfy this requirement.</para>
                      <para>An EJB reference is a link in an application component naming environment that points to a
                          deployed EJB home interface. The name used by the application component is a logical link that
                          isolates the component from the actual name of the EJB home in the deployment environment. The
                          J2EE specification recommends that all references to enterprise beans be organized in the
                              <literal>java:comp/env/ejb</literal> context of the application component's environment.</para>
                      <para>An EJB reference is declared using an <literal>ejb-ref</literal> element in the deployment
                          descriptor. Each <literal>ejb-ref</literal> element describes the interface requirements that
                          the referencing application component has for the referenced enterprise bean. The
                              <literal>ejb-ref</literal> element contains the following child elements:</para>
                      <itemizedlist>
                          <listitem>
                              <para>An optional <emphasis role="bold">description</emphasis> element that provides the
                                  purpose of the reference.</para>
                          </listitem>
                          <listitem>
                              <para>An <emphasis role="bold">ejb-ref-name</emphasis> element that specifies the name of
                                  the reference relative to the <literal>java:comp/env</literal> context. To place the
                                  reference under the recommended <literal>java:comp/env/ejb</literal> context, use an
                                      <literal>ejb/link-name</literal> form for the <literal>ejb-ref-name</literal>
                              value.</para>
                          </listitem>
                          <listitem>
                              <para>An <emphasis role="bold">ejb-ref-type</emphasis> element that specifies the type of
                                  the EJB. This must be either <literal>Entity</literal> or
                              <literal>Session</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">home</emphasis> element that gives the fully qualified class
                                  name of the EJB home interface.</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">remote</emphasis> element that gives the fully qualified class
                                  name of the EJB remote interface.</para>
                          </listitem>
                          <listitem>
                              <para>An optional <emphasis role="bold">ejb-link</emphasis> element that links the reference
                                  to another enterprise bean in the same EJB JAR or in the same J2EE application unit. The
                                      <literal>ejb-link</literal> value is the <literal>ejb-name</literal> of the
                                  referenced bean. If there are multiple enterprise beans with the same
                                  <literal>ejb-name</literal>, the value uses the path name specifying the location of the
                                      <literal>ejb-jar</literal> file that contains the referenced component. The path
                                  name is relative to the referencing <literal>ejb-jar</literal> file. The Application
                                  Assembler appends the <literal>ejb-name</literal> of the referenced bean to the path
                                  name separated by <literal>#</literal>. This allows multiple beans with the same name to
                                  be uniquely identified.</para>
                          </listitem>
                      </itemizedlist>
                      <para>An EJB reference is scoped to the application component whose declaration contains the
                              <literal>ejb-ref</literal> element. This means that the EJB reference is not accessible from
                          other application components at runtime, and that other application components may define
                              <literal>ejb-ref</literal> elements with the same <literal>ejb-ref-name</literal> without
                          causing a name conflict. <xref linkend="ch3.ejbref.ex"/> provides an
                          <literal>ejb-jar.xml</literal> fragment that illustrates the use of the
                          <literal>ejb-ref</literal> element. A code sample that illustrates accessing the
                              <literal>ShoppingCartHome</literal> reference declared in <xref linkend="ch3.ejbref.ex"/> is
                          given in <xref linkend="ch3.ejbref2.ex"/>.</para>
                      <example id="ch3.ejbref.ex">
                          <title>An example ejb-jar.xml ejb-ref descriptor fragment</title>
                          <programlisting>&lt;!-- ... --&gt;
  &lt;session&gt;
      &lt;ejb-name&gt;ShoppingCartBean&lt;/ejb-name&gt;
      &lt;!-- ...--&gt;
  &lt;/session&gt;
  
  &lt;session&gt;
      &lt;ejb-name&gt;ProductBeanUser&lt;/ejb-name&gt;
      &lt;!--...--&gt;
      &lt;ejb-ref&gt;
          &lt;description&gt;This is a reference to the store products entity &lt;/description&gt;
          &lt;ejb-ref-name&gt;ejb/ProductHome&lt;/ejb-ref-name&gt;
          &lt;ejb-ref-type&gt;Entity&lt;/ejb-ref-type&gt;
          &lt;home&gt;org.jboss.store.ejb.ProductHome&lt;/home&gt;
          &lt;remote&gt; org.jboss.store.ejb.Product&lt;/remote&gt;
      &lt;/ejb-ref&gt;
  
  &lt;/session&gt;
  
  &lt;session&gt;
      &lt;ejb-ref&gt;
          &lt;ejb-name&gt;ShoppingCartUser&lt;/ejb-name&gt;
          &lt;!--...--&gt;
          &lt;ejb-ref-name&gt;ejb/ShoppingCartHome&lt;/ejb-ref-name&gt;
          &lt;ejb-ref-type&gt;Session&lt;/ejb-ref-type&gt;
          &lt;home&gt;org.jboss.store.ejb.ShoppingCartHome&lt;/home&gt;
          &lt;remote&gt; org.jboss.store.ejb.ShoppingCart&lt;/remote&gt;
          &lt;ejb-link&gt;ShoppingCartBean&lt;/ejb-link&gt;
      &lt;/ejb-ref&gt;
  &lt;/session&gt;
  
  &lt;entity&gt;
      &lt;description&gt;The Product entity bean &lt;/description&gt;
      &lt;ejb-name&gt;ProductBean&lt;/ejb-name&gt;
      &lt;!--...--&gt;
  &lt;/entity&gt;
  
  &lt;!--...--&gt; </programlisting>
                      </example>
                      <example id="ch3.ejbref2.ex">
                          <title> ENC ejb-ref access code fragment</title>
                          <programlisting>InitialContext iniCtx = new InitialContext();
  Context ejbCtx = (Context) iniCtx.lookup("java:comp/env/ejb");
  ShoppingCartHome home = (ShoppingCartHome) ejbCtx.lookup("ShoppingCartHome"); </programlisting>
                      </example>
                  </section>
                  <section>
                      <title>EJB References with <literal>jboss.xml</literal> and <literal>jboss-web.xml</literal>
                      </title>
                      <para>The JBoss specific <literal>jboss.xml</literal> EJB deployment descriptor affects EJB
                          references in two ways. First, the <literal>jndi-name</literal> child element of the
                              <literal>session</literal> and <literal>entity</literal> elements allows the user to specify
                          the deployment JNDI name for the EJB home interface. In the absence of a
                          <literal>jboss.xml</literal> specification of the <literal>jndi-name</literal> for an EJB, the
                          home interface is bound under the <literal>ejb-jar.xml</literal>
                          <literal>ejb-name</literal> value. For example, the session EJB with the
                          <literal>ejb-name</literal> of <literal>ShoppingCartBean</literal> in <xref
                              linkend="ch3.ejbref.ex"/> would have its home interface bound under the JNDI name
                              <literal>ShoppingCartBean</literal> in the absence of a <literal>jboss.xml</literal>
                          <literal>jndi-name</literal> specification.</para>
                      <para>The second use of the <literal>jboss.xml</literal> descriptor with respect to
                          <literal>ejb-ref</literal>s is the setting of the destination to which a component's ENC
                              <literal>ejb-ref</literal> refers. The <literal>ejb-link</literal> element cannot be used to
                          refer to EJBs in another enterprise application. If your <literal>ejb-ref</literal> needs to
                          access an external EJB, you can specify the JNDI name of the deployed EJB home using the
                              <literal>jboss.xml</literal>
                          <literal>ejb-ref/jndi-name</literal> element.</para>
                      <para>The <literal>jboss-web.xml</literal> descriptor is used only to set the destination to which a
                          Web application ENC <literal>ejb-ref</literal> refers. The content model for the JBoss
                              <literal>ejb-ref</literal> is as follows:</para>
                      <itemizedlist>
                          <listitem>
                              <para>An <emphasis role="bold">ejb-ref-name</emphasis> element that corresponds to the
                                      <emphasis role="bold">ejb-ref-name</emphasis> element in the <emphasis role="bold"
                                      >ejb-jar.xml</emphasis> or <emphasis role="bold">web.xml</emphasis> standard
                                  descriptor</para>
                          </listitem>
                          <listitem>
                              <para>A <literal>jndi-name</literal> element that specifies the JNDI name of the EJB home
                                  interface in the deployment environment</para>
                          </listitem>
                      </itemizedlist>
                      <para>
                          <xref linkend="ch3.productbean.ex"/> provides an example <literal>jboss.xml</literal> descriptor
                          fragment that illustrates the following usage points:</para>
                      <itemizedlist>
                          <listitem>
                              <para>The <literal>ProductBeanUser</literal>
                                  <literal>ejb-ref</literal> link destination is set to the deployment name of
                                      <literal>jboss/store/ProductHome</literal>
                              </para>
                          </listitem>
                          <listitem>
                              <para>The deployment JNDI name of the <literal>ProductBean</literal> is set to
                                      <literal>jboss/store/ProductHome</literal>
                              </para>
                          </listitem>
                      </itemizedlist>
                      <example id="ch3.productbean.ex">
                          <title> An example jboss.xml ejb-ref fragment</title>
                          <programlisting>&lt;!-- ... --&gt;
  &lt;session&gt;
      &lt;ejb-name&gt;ProductBeanUser&lt;/ejb-name&gt;
      &lt;ejb-ref&gt;
          &lt;ejb-ref-name&gt;ejb/ProductHome&lt;/ejb-ref-name&gt;
          &lt;jndi-name&gt;<emphasis role="bold">jboss/store/ProductHome</emphasis>&lt;/jndi-name&gt;
      &lt;/ejb-ref&gt;
  &lt;/session&gt;
                          
  &lt;entity&gt;
      &lt;ejb-name&gt;ProductBean&lt;/ejb-name&gt;
      &lt;jndi-name&gt;<emphasis role="bold">jboss/store/ProductHome</emphasis>&lt;/jndi-name&gt;
       &lt;!-- ... --&gt;
  &lt;/entity&gt;
  &lt;!-- ... --&gt;</programlisting>
                      </example>
                  </section>
                  <section>
                      <title>EJB Local References</title>
                      <para>EJB 2.0 added local interfaces that do not use RMI call by value semantics. These interfaces
                          use a call by reference semantic and therefore do not incur any RMI serialization overhead. An
                          EJB local reference is a link in an application component naming environment that points to a
                          deployed EJB local home interface. The name used by the application component is a logical link
                          that isolates the component from the actual name of the EJB local home in the deployment
                          environment. The J2EE specification recommends that all references to enterprise beans be
                          organized in the <literal>java:comp/env/ejb</literal> context of the application component's
                          environment.</para>
                      <para>An EJB local reference is declared using an <literal>ejb-local-ref</literal> element in the
                          deployment descriptor. Each <literal>ejb-local-ref</literal> element describes the interface
                          requirements that the referencing application component has for the referenced enterprise bean.
                          The <literal>ejb-local-ref</literal> element contains the following child elements:</para>
                      <itemizedlist>
                          <listitem>
                              <para>An optional <emphasis role="bold">description</emphasis> element that provides the
                                  purpose of the reference.</para>
                          </listitem>
                          <listitem>
                              <para>An <emphasis role="bold">ejb-ref-name</emphasis> element that specifies the name of
                                  the reference relative to the <literal>java:comp/env</literal> context. To place the
                                  reference under the recommended <literal>java:comp/env/ejb</literal> context, use an
                                      <literal>ejb/link-name</literal> form for the <literal>ejb-ref-name</literal>
                              value.</para>
                          </listitem>
                          <listitem>
                              <para>An <emphasis role="bold">ejb-ref-type</emphasis> element that specifies the type of
                                  the EJB. This must be either <literal>Entity</literal> or
                              <literal>Session</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">local-home</emphasis> element that gives the fully qualified
                                  class name of the EJB local home interface.</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">local</emphasis> element that gives the fully qualified class
                                  name of the EJB local interface.</para>
                          </listitem>
                          <listitem>
                              <para>An <emphasis role="bold">ejb-link</emphasis> element that links the reference to
                                  another enterprise bean in the <literal>ejb-jar</literal> file or in the same J2EE
                                  application unit. The <literal>ejb-link</literal> value is the
                                  <literal>ejb-name</literal> of the referenced bean. If there are multiple enterprise
                                  beans with the same <literal>ejb-name</literal>, the value uses the path name specifying
                                  the location of the <literal>ejb-jar</literal> file that contains the referenced
                                  component. The path name is relative to the referencing <literal>ejb-jar</literal> file.
                                  The Application Assembler appends the <literal>ejb-name</literal> of the referenced bean
                                  to the path name separated by <literal>#</literal>. This allows multiple beans with the
                                  same name to be uniquely identified. An <literal>ejb-link</literal> element must be
                                  specified in JBoss to match the local reference to the corresponding EJB.</para>
                          </listitem>
                      </itemizedlist>
                      <para>An EJB local reference is scoped to the application component whose declaration contains the
                              <literal>ejb-local-ref</literal> element. This means that the EJB local reference is not
                          accessible from other application components at runtime, and that other application components
                          may define <literal>ejb-local-ref</literal> elements with the same
                          <literal>ejb-ref-name</literal> without causing a name conflict. <xref linkend="ch3.localref.ex"
                          /> provides an <literal>ejb-jar.xml</literal> fragment that illustrates the use of the
                              <literal>ejb-local-ref</literal> element. A code sample that illustrates accessing the
                              <literal>ProbeLocalHome</literal> reference declared in <xref linkend="ch3.localref.ex"/> is
                          given in <xref linkend="ch3.localref2.ex"/>.</para>
                      <example id="ch3.localref.ex">
                          <title> An example ejb-jar.xml ejb-local-ref descriptor fragment</title>
                          <programlisting>    &lt;!-- ... --&gt;
      &lt;session&gt;
          &lt;ejb-name&gt;Probe&lt;/ejb-name&gt;
          &lt;home&gt;org.jboss.test.perf.interfaces.ProbeHome&lt;/home&gt;
          &lt;remote&gt;org.jboss.test.perf.interfaces.Probe&lt;/remote&gt;
          &lt;local-home&gt;org.jboss.test.perf.interfaces.ProbeLocalHome&lt;/local-home&gt;
          &lt;local&gt;org.jboss.test.perf.interfaces.ProbeLocal&lt;/local&gt;
          &lt;ejb-class&gt;org.jboss.test.perf.ejb.ProbeBean&lt;/ejb-class&gt;
          &lt;session-type&gt;Stateless&lt;/session-type&gt;
          &lt;transaction-type&gt;Bean&lt;/transaction-type&gt;
      &lt;/session&gt;
      &lt;session&gt;
          &lt;ejb-name&gt;PerfTestSession&lt;/ejb-name&gt;
          &lt;home&gt;org.jboss.test.perf.interfaces.PerfTestSessionHome&lt;/home&gt;
          &lt;remote&gt;org.jboss.test.perf.interfaces.PerfTestSession&lt;/remote&gt;
          &lt;ejb-class&gt;org.jboss.test.perf.ejb.PerfTestSessionBean&lt;/ejb-class&gt;
          &lt;session-type&gt;Stateless&lt;/session-type&gt;
          &lt;transaction-type&gt;Container&lt;/transaction-type&gt;
          &lt;ejb-ref&gt;
              &lt;ejb-ref-name&gt;ejb/ProbeHome&lt;/ejb-ref-name&gt;
              &lt;ejb-ref-type&gt;Session&lt;/ejb-ref-type&gt;
              &lt;home&gt;org.jboss.test.perf.interfaces.SessionHome&lt;/home&gt;
              &lt;remote&gt;org.jboss.test.perf.interfaces.Session&lt;/remote&gt;
              &lt;ejb-link&gt;Probe&lt;/ejb-link&gt;
          &lt;/ejb-ref&gt;
          &lt;ejb-local-ref&gt;
              &lt;ejb-ref-name&gt;ejb/ProbeLocalHome&lt;/ejb-ref-name&gt;
              &lt;ejb-ref-type&gt;Session&lt;/ejb-ref-type&gt;
              &lt;local-home&gt;org.jboss.test.perf.interfaces.ProbeLocalHome&lt;/local-home&gt;
              &lt;local&gt;org.jboss.test.perf.interfaces.ProbeLocal&lt;/local&gt;
              &lt;ejb-link&gt;Probe&lt;/ejb-link&gt;
          &lt;/ejb-local-ref&gt;
      &lt;/session&gt;
      &lt;!-- ... --&gt;</programlisting>
                      </example>
                      <example id="ch3.localref2.ex">
                          <title>ENC ejb-local-ref access code fragment</title>
                          <programlisting>InitialContext iniCtx = new InitialContext();
  Context ejbCtx = (Context) iniCtx.lookup("java:comp/env/ejb");
  ProbeLocalHome home = (ProbeLocalHome) ejbCtx.lookup("ProbeLocalHome");</programlisting>
                      </example>
                  </section>
                  <section>
                      <title>Resource Manager Connection Factory References</title>
                      <para>Resource manager connection factory references allow application component code to refer to
                          resource factories using logical names called resource manager connection factory references.
                          Resource manager connection factory references are defined by the
                          <literal>resource-ref</literal> elements in the standard deployment descriptors. The
                              <literal>Deployer</literal> binds the resource manager connection factory references to the
                          actual resource manager connection factories that exist in the target operational environment
                          using the <literal>jboss.xml</literal> and <literal>jboss-web.xml</literal> descriptors.</para>
                      <para>Each <literal>resource-ref</literal> element describes a single resource manager connection
                          factory reference. The <literal>resource-ref</literal> element consists of the following child
                          elements:</para>
                      <itemizedlist>
                          <listitem>
                              <para>An optional <emphasis role="bold">description</emphasis> element that provides the
                                  purpose of the reference.</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">res-ref-name</emphasis> element that specifies the name of the
                                  reference relative to the <literal>java:comp/env</literal> context. The resource type
                                  based naming convention for which subcontext to place the
                                  <literal>res-ref-name</literal> into is discussed in the next paragraph.</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">res-type</emphasis> element that specifies the fully qualified
                                  class name of the resource manager connection factory.</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">res-auth</emphasis> element that indicates whether the
                                  application component code performs resource signon programmatically, or whether the
                                  container signs on to the resource based on the principal mapping information supplied
                                  by the Deployer. It must be one of <literal>Application</literal> or
                                  <literal>Container</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>An optional <emphasis role="bold">res-sharing-scope</emphasis> element. This currently
                                  is not supported by JBoss.</para>
                          </listitem>
                      </itemizedlist>
                      <para>The J2EE specification recommends that all resource manager connection factory references be
                          organized in the subcontexts of the application component's environment, using a different
                          subcontext for each resource manager type. The recommended resource manager type to subcontext
                          name is as follows:</para>
                      <itemizedlist>
                          <listitem>
                              <para>JDBC <literal>DataSource</literal> references should be declared in the
                                      <literal>java:comp/env/jdbc</literal> subcontext.</para>
                          </listitem>
                          <listitem>
                              <para>JMS connection factories should be declared in the
                                  <literal>java:comp/env/jms</literal> subcontext.</para>
                          </listitem>
                          <listitem>
                              <para>JavaMail connection factories should be declared in the
                                  <literal>java:comp/env/mail</literal> subcontext.</para>
                          </listitem>
                          <listitem>
                              <para>URL connection factories should be declared in the
                                  <literal>java:comp/env/url</literal> subcontext.</para>
                          </listitem>
                      </itemizedlist>
                      <para>
                          <xref linkend="ch3.resref.ex"/> shows an example <literal>web.xml</literal> descriptor fragment
                          that illustrates the <literal>resource-ref</literal> element usage. <xref
                              linkend="ch3.resref2.ex"/> provides a code fragment that an application component would use
                          to access the <literal>DefaultMail</literal> resource declared by the
                          <literal>resource-ref</literal>.</para>
                      <example id="ch3.resref.ex">
                          <title> A web.xml resource-ref descriptor fragment</title>
                          <programlisting>&lt;web&gt;
      &lt;!-- ... --&gt;
      &lt;servlet&gt;
          &lt;servlet-name&gt;AServlet&lt;/servlet-name&gt;
          &lt;!-- ... --&gt;
      &lt;/servlet&gt;
      &lt;!-- ... --&gt;
      &lt;!-- JDBC DataSources (java:comp/env/jdbc) --&gt;
      &lt;resource-ref&gt;
          &lt;description&gt;The default DS&lt;/description&gt;
          &lt;res-ref-name&gt;jdbc/DefaultDS&lt;/res-ref-name&gt;
          &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
          &lt;res-auth&gt;Container&lt;/res-auth&gt;
      &lt;/resource-ref&gt;
      &lt;!-- JavaMail Connection Factories (java:comp/env/mail) --&gt;
      &lt;resource-ref&gt;
          &lt;description&gt;Default Mail&lt;/description&gt;
          &lt;res-ref-name&gt;mail/DefaultMail&lt;/res-ref-name&gt;
          &lt;res-type&gt;javax.mail.Session&lt;/res-type&gt;
          &lt;res-auth&gt;Container&lt;/res-auth&gt;
      &lt;/resource-ref&gt;
      &lt;!-- JMS Connection Factories (java:comp/env/jms) --&gt;
      &lt;resource-ref&gt;
          &lt;description&gt;Default QueueFactory&lt;/description&gt;
          &lt;res-ref-name&gt;jms/QueueFactory&lt;/res-ref-name&gt;
          &lt;res-type&gt;javax.jms.QueueConnectionFactory&lt;/res-type&gt;
          &lt;res-auth&gt;Container&lt;/res-auth&gt;
      &lt;/resource-ref&gt; 
  &lt;web&gt;                        </programlisting>
                      </example>
                      <example id="ch3.resref2.ex">
                          <title>ENC resource-ref access sample code fragment</title>
                          <programlisting>Context initCtx = new InitialContext();
  javax.mail.Session s = (javax.mail.Session)
  initCtx.lookup("java:comp/env/mail/DefaultMail");</programlisting>
                      </example>
                  </section>
                  <section>
                      <title>Resource Manager Connection Factory References with jboss.xml and jboss-web.xml</title>
                      <para>The purpose of the JBoss <literal>jboss.xml</literal> EJB deployment descriptor and
                              <literal>jboss-web.xml</literal> Web application deployment descriptor is to provide the
                          link from the logical name defined by the <literal>res-ref-name</literal> element to the JNDI
                          name of the resource factory as deployed in JBoss. This is accomplished by providing a
                              <literal>resource-ref</literal> element in the <literal>jboss.xml</literal> or
                              <literal>jboss-web.xml</literal> descriptor. The JBoss <literal>resource-ref</literal>
                          element consists of the following child elements:</para>
                      <itemizedlist>
                          <listitem>
                              <para>A <emphasis role="bold">res-ref-name</emphasis> element that must match the
                                      <literal>res-ref-name</literal> of a corresponding <literal>resource-ref</literal>
                                  element from the <literal>ejb-jar.xml</literal> or <literal>web.xml</literal> standard
                                  descriptors</para>
                          </listitem>
                          <listitem>
                              <para>An optional <emphasis role="bold">res-type</emphasis> element that specifies the fully
                                  qualified class name of the resource manager connection factory</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">jndi-name</emphasis> element that specifies the JNDI name of
                                  the resource factory as deployed in JBoss</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">res-url</emphasis> element that specifies the URL string in
                                  the case of a <literal>resource-ref</literal> of type <literal>java.net.URL</literal>
                              </para>
                          </listitem>
                      </itemizedlist>
                      <para>
                          <xref linkend="ch3.webresref.ex"/> provides a sample <literal>jboss-web.xml</literal> descriptor
                          fragment that shows sample mappings of the <literal>resource-ref</literal> elements given in
                              <xref linkend="ch3.resref.ex"/>.</para>
                      <example id="ch3.webresref.ex">
                          <title>A sample jboss-web.xml resource-ref descriptor fragment</title>
                          <programlisting>&lt;jboss-web&gt;
      &lt;!-- ... --&gt;
      &lt;resource-ref&gt;
          &lt;res-ref-name&gt;jdbc/DefaultDS&lt;/res-ref-name&gt;
          &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
          &lt;jndi-name&gt;java:/DefaultDS&lt;/jndi-name&gt;
      &lt;/resource-ref&gt;
      &lt;resource-ref&gt;
          &lt;res-ref-name&gt;mail/DefaultMail&lt;/res-ref-name&gt;
          &lt;res-type&gt;javax.mail.Session&lt;/res-type&gt;
          &lt;jndi-name&gt;java:/Mail&lt;/jndi-name&gt;
      &lt;/resource-ref&gt;
      &lt;resource-ref&gt;
          &lt;res-ref-name&gt;jms/QueueFactory&lt;/res-ref-name&gt;
          &lt;res-type&gt;javax.jms.QueueConnectionFactory&lt;/res-type&gt;
          &lt;jndi-name&gt;QueueConnectionFactory&lt;/jndi-name&gt;
      &lt;/resource-ref&gt;
      &lt;!-- ... --&gt;
  &lt;/jboss-web&gt;</programlisting>
                      </example>
                  </section>
                  <section>
                      <title>Resource Environment References</title>
                      <para>Resource environment references are elements that refer to administered objects that are
                          associated with a resource (for example, JMS destinations) using logical names. Resource
                          environment references are defined by the <literal>resource-env-ref</literal> elements in the
                          standard deployment descriptors. The <literal>Deployer</literal> binds the resource environment
                          references to the actual administered objects location in the target operational environment
                          using the <literal>jboss.xml</literal> and <literal>jboss-web.xml</literal> descriptors.</para>
                      <para>Each <literal>resource-env-ref</literal> element describes the requirements that the
                          referencing application component has for the referenced administered object. The
                              <literal>resource-env-ref</literal> element consists of the following child elements:</para>
                      <itemizedlist>
                          <listitem>
                              <para>An optional <emphasis role="bold">description</emphasis> element that provides the
                                  purpose of the reference.</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">resource-env-ref-name</emphasis> element that specifies the
                                  name of the reference relative to the <literal>java:comp/env</literal> context.
                                  Convention places the name in a subcontext that corresponds to the associated resource
                                  factory type. For example, a JMS queue reference named <literal>MyQueue</literal> should
                                  have a <literal>resource-env-ref-name</literal> of
                              <literal>jms/MyQueue</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>A <emphasis role="bold">resource-env-ref-type</emphasis> element that specifies the
                                  fully qualified class name of the referenced object. For example, in the case of a JMS
                                  queue, the value would be <literal>javax.jms.Queue</literal>.</para>
                          </listitem>
                      </itemizedlist>
                      <para>
                          <xref linkend="ch3.resenvref.ex"/> provides an example <literal>resource-ref-env</literal>
                          element declaration by a session bean. <xref linkend="ch3.resenvref2.ex"/> gives a code fragment
                          that illustrates how to look up the <literal>StockInfo</literal> queue declared by the
                              <literal>resource-env-ref</literal>. </para>
                      <example id="ch3.resenvref.ex">
                          <title>An example ejb-jar.xml resource-env-ref fragment</title>
                          <programlisting>&lt;session&gt;
      &lt;ejb-name&gt;MyBean&lt;/ejb-name&gt;
      &lt;!-- ... --&gt;
      &lt;resource-env-ref&gt;
          &lt;description&gt;This is a reference to a JMS queue used in the
              processing of Stock info
          &lt;/description&gt;
          &lt;resource-env-ref-name&gt;jms/StockInfo&lt;/resource-env-ref-name&gt;
          &lt;resource-env-ref-type&gt;javax.jms.Queue&lt;/resource-env-ref-type&gt;
      &lt;/resource-env-ref&gt;
      &lt;!-- ... --&gt;
  &lt;/session&gt;</programlisting>
                      </example>
                      <example id="ch3.resenvref2.ex">
                          <title> ENC resource-env-ref access code fragment</title>
                          <programlisting>InitialContext iniCtx = new InitialContext();
  javax.jms.Queue q = (javax.jms.Queue)
  envCtx.lookup("java:comp/env/jms/StockInfo");</programlisting>
                      </example>
                  </section>
                  <section>
                      <title>Resource Environment References and jboss.xml, jboss-web.xml</title>
                      <para>The purpose of the JBoss <literal>jboss.xml</literal> EJB deployment descriptor and
                              <literal>jboss-web.xml</literal> Web application deployment descriptor is to provide the
                          link from the logical name defined by the <literal>resource-env-ref-name</literal> element to
                          the JNDI name of the administered object deployed in JBoss. This is accomplished by providing a
                              <literal>resource-env-ref</literal> element in the <literal>jboss.xml</literal> or
                              <literal>jboss-web.xml</literal> descriptor. The JBoss <literal>resource-env-ref</literal>
                          element consists of the following child elements:</para>
                      <itemizedlist>
                          <listitem>
                              <para>A <literal>resource-env-ref-name</literal> element that must match the
                                      <literal>resource-env-ref-name</literal> of a corresponding
                                      <literal>resource-env-ref</literal> element from the <literal>ejb-jar.xml</literal>
                                  or <literal>web.xml</literal> standard descriptors</para>
                          </listitem>
                          <listitem>
                              <para>A <literal>jndi-name</literal> element that specifies the JNDI name of the resource as
                                  deployed in JBoss</para>
                          </listitem>
                      </itemizedlist>
                      <para>
                          <xref linkend="ch3.jbossxmlres.ex"/> provides a sample <literal>jboss.xml</literal> descriptor
                          fragment that shows a sample mapping for the <literal>StockInfo</literal>
                          <literal>resource-env-ref</literal>.</para>
                      <example id="ch3.jbossxmlres.ex">
                          <title>A sample jboss.xml resource-env-ref descriptor fragment</title>
                          <programlisting>&lt;session&gt;
      &lt;ejb-name&gt;MyBean&lt;/ejb-name&gt;
      &lt;!-- ... --&gt;
      &lt;resource-env-ref&gt;
          &lt;resource-env-ref-name&gt;jms/StockInfo&lt;/resource-env-ref-name&gt;
          &lt;jndi-name&gt;queue/StockInfoQueue&lt;/jndi-name&gt;
      &lt;/resource-env-ref&gt;
      &lt;!-- ... --&gt;
  &lt;/session&gt;  </programlisting>
                      </example>
                  </section>
              </section>
          </section>
      </chapter>
  
  
  
      <chapter id="ch4.chapt">
          <title>Transactions on JBoss</title>
          <subtitle>The JTA Transaction Service</subtitle>
          <para>This chapter discusses transaction management in JBoss and the JBossTX architecture. The JBossTX
              architecture allows for any Java Transaction API (JTA) transaction manager implementation to be used.
              JBossTX includes a fast in-VM implementation of a JTA compatible transaction manager that is used as the
              default transaction manager. We will first provide an overview of the key transaction concepts and notions
              in the JTA to provide sufficient background for the JBossTX architecture discussion. We will then discuss
              the interfaces that make up the JBossTX architecture and conclude with a discussion of the MBeans available
              for integration of alternate transaction managers.</para>
          <section>
              <title>Transaction/JTA Overview</title>
              <para>For the purpose of this discussion, we can define a transaction as a unit of work containing one or
                  more operations involving one or more shared resources having ACID properties. ACID is an acronym for
                  atomicity, consistency, isolation and durability, the four important properties of transactions. The
                  meanings of these terms is:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">Atomicity</emphasis>: A transaction must be atomic. This means that either
                          all the work done in the transaction must be performed, or none of it must be performed. Doing
                          part of a transaction is not allowed. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Consistency</emphasis>: When a transaction is completed, the system must
                          be in a stable and consistent condition.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Isolation</emphasis>: Different transactions must be isolated from each
                          other. This means that the partial work done in one transaction is not visible to other
                          transactions until the transaction is committed, and that each process in a multi-user system
                          can be programmed as if it was the only process accessing the system. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Durability</emphasis>: The changes made during a transaction are made
                          persistent when it is committed. When a transaction is committed, its changes will not be lost,
                          even if the server crashes afterwards. </para>
                  </listitem>
              </itemizedlist>
              <para>To illustrate these concepts, consider a simple banking account application. The banking application
                  has a database with a number of accounts. The sum of the amounts of all accounts must always be 0. An
                  amount of money M is moved from account A to account B by subtracting M from account A and adding M to
                  account B. This operation must be done in a transaction, and all four ACID properties are important.</para>
              <para>The atomicity property means that both the withdrawal and deposit is performed as an indivisible unit.
                  If, for some reason, both cannot be done nothing will be done.</para>
              <para>The consistency property means that after the transaction, the sum of the amounts of all accounts must
                  still be 0.</para>
              <para>The isolation property is important when more than one bank clerk uses the system at the same time. A
                  withdrawal or deposit could be implemented as a three-step process: First the amount of the account is
                  read from the database; then something is subtracted from or added to the amount read from the database;
                  and at last the new amount is written to the database. Without transaction isolation several bad things
                  could happen. For example, if two processes read the amount of account A at the same time, and each
                  independently added or subtracted something before writing the new amount to the database, the first
                  change would be incorrectly overwritten by the last.</para>
              <para>The durability property is also important. If a money transfer transaction is committed, the bank must
                  trust that some subsequent failure cannot undo the money transfer.</para>
              <section>
                  <title>Pessimistic and optimistic locking</title>
                  <para>Transactional isolation is usually implemented by locking whatever is accessed in a transaction.
                      There are two different approaches to transactional locking: Pessimistic locking and optimistic
                      locking.</para>
                  <para>The disadvantage of pessimistic locking is that a resource is locked from the time it is first
                      accessed in a transaction until the transaction is finished, making it inaccessible to other
                      transactions during that time. If most transactions simply look at the resource and never change it,
                      an exclusive lock may be overkill as it may cause lock contention, and optimistic locking may be a
                      better approach. With pessimistic locking, locks are applied in a fail-safe way. In the banking
                      application example, an account is locked as soon as it is accessed in a transaction. Attempts to
                      use the account in other transactions while it is locked will either result in the other process
                      being delayed until the account lock is released, or that the process transaction will be rolled
                      back. The lock exists until the transaction has either been committed or rolled back.</para>
                  <para>With optimistic locking, a resource is not actually locked when it is first is accessed by a
                      transaction. Instead, the state of the resource at the time when it would have been locked with the
                      pessimistic locking approach is saved. Other transactions are able to concurrently access to the
                      resource and the possibility of conflicting changes is possible. At commit time, when the resource
                      is about to be updated in persistent storage, the state of the resource is read from storage again
                      and compared to the state that was saved when the resource was first accessed in the transaction. If
                      the two states differ, a conflicting update was made, and the transaction will be rolled back.</para>
                  <para>In the banking application example, the amount of an account is saved when the account is first
                      accessed in a transaction. If the transaction changes the account amount, the amount is read from
                      the store again just before the amount is about to be updated. If the amount has changed since the
                      transaction began, the transaction will fail itself, otherwise the new amount is written to
                      persistent storage.</para>
              </section>
              <section>
                  <title>The components of a distributed transaction</title>
                  <para>There are a number of participants in a distributed transaction. These include:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">Transaction Manager</emphasis>: This component is distributed across
                              the transactional system. It manages and coordinates the work involved in the transaction.
                              The transaction manager is exposed by the
                              <literal>javax.transaction.TransactionManager</literal> interface in JTA.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Transaction Context</emphasis>: A transaction context identifies a
                              particular transaction. In JTA the corresponding interface is
                                  <literal>javax.transaction.Transaction</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Transactional Client</emphasis>: A transactional client can invoke
                              operations on one or more transactional objects in a single transaction. The transactional
                              client that started the transaction is called the transaction originator. A transaction
                              client is either an explicit or implicit user of JTA interfaces and has no interface
                              representation in the JTA.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Transactional Object</emphasis>: A transactional object is an object
                              whose behavior is affected by operations performed on it within a transactional context. A
                              transactional object can also be a transactional client. Most Enterprise Java Beans are
                              transactional objects.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Recoverable Resource</emphasis>: A recoverable resource is a
                              transactional object whose state is saved to stable storage if the transaction is committed,
                              and whose state can be reset to what it was at the beginning of the transaction if the
                              transaction is rolled back. At commit time, the transaction manager uses the two-phase XA
                              protocol when communicating with the recoverable resource to ensure transactional integrity
                              when more than one recoverable resource is involved in the transaction being committed.
                              Transactional databases and message brokers like JBossMQ are examples of recoverable
                              resources. A recoverable resource is represented using the
                                  <literal>javax.transaction.xa.XAResource</literal> interface in JTA.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>The two-phase XA protocol</title>
                  <para>When a transaction is about to be committed, it is the responsibility of the transaction manager
                      to ensure that either all of it is committed, or that all of is rolled back. If only a single
                      recoverable resource is involved in the transaction, the task of the transaction manager is simple:
                      It just has to tell the resource to commit the changes to stable storage.</para>
                  <para>When more than one recoverable resource is involved in the transaction, management of the commit
                      gets more complicated. Simply asking each of the recoverable resources to commit changes to stable
                      storage is not enough to maintain the atomic property of the transaction. The reason for this is
                      that if one recoverable resource has committed and another fails to commit, part of the transaction
                      would be committed and the other part rolled back.</para>
                  <para>To get around this problem, the two-phase XA protocol is used. The XA protocol involves an extra
                      prepare phase before the actual commit phase. Before asking any of the recoverable resources to
                      commit the changes, the transaction manager asks all the recoverable resources to prepare to commit.
                      When a recoverable resource indicates it is prepared to commit the transaction, it has ensured that
                      it can commit the transaction. The resource is still able to rollback the transaction if necessary
                      as well.</para>
                  <para>So the first phase consists of the transaction manager asking all the recoverable resources to
                      prepare to commit. If any of the recoverable resources fails to prepare, the transaction will be
                      rolled back. But if all recoverable resources indicate they were able to prepare to commit, the
                      second phase of the XA protocol begins. This consists of the transaction manager asking all the
                      recoverable resources to commit the transaction. Because all the recoverable resources have
                      indicated they are prepared, this step cannot fail.</para>
              </section>
              <section>
                  <title>Heuristic exceptions</title>
                  <para>In a distributed environment communications failures can happen. If communication between the
                      transaction manager and a recoverable resource is not possible for an extended period of time, the
                      recoverable resource may decide to unilaterally commit or rollback changes done in the context of a
                      transaction. Such a decision is called a heuristic decision. It is one of the worst errors that may
                      happen in a transaction system, as it can lead to parts of the transaction being committed while
                      other parts are rolled back, thus violating the atomicity property of transaction and possibly
                      leading to data integrity corruption.</para>
                  <para>Because of the dangers of heuristic exceptions, a recoverable resource that makes a heuristic
                      decision is required to maintain all information about the decision in stable storage until the
                      transaction manager tells it to forget about the heuristic decision. The actual data about the
                      heuristic decision that is saved in stable storage depends on the type of recoverable resource and
                      is not standardized. The idea is that a system manager can look at the data, and possibly edit the
                      resource to correct any data integrity problems.</para>
                  <para>There are several different kinds of heuristic exceptions defined by the JTA. The
                          <literal>javax.transaction.HeuristicCommitException</literal> is thrown when a recoverable
                      resource is asked to rollback to report that a heuristic decision was made and that all relevant
                      updates have been committed. On the opposite end is the
                          <literal>javax.transaction.HeuristicRollbackException</literal>, which is thrown by a
                      recoverable resource when it is asked to commit to indicate that a heuristic decision was made and
                      that all relevant updates have been rolled back.</para>
                  <para>The <literal>javax.transaction.HeuristicMixedException</literal> is the worst heuristic exception.
                      It is thrown to indicate that parts of the transaction were committed, while other parts were rolled
                      back. The transaction manager throws this exception when some recoverable resources did a heuristic
                      commit, while other recoverable resources did a heuristic rollback.</para>
              </section>
              <section>
                  <title>Transaction IDs and branches</title>
                  <para>In JTA, the identity of transactions is encapsulated in objects implementing the
                          <literal>javax.transaction.xa.Xid</literal> interface. The transaction ID is an aggregate of
                      three parts:</para>
                  <itemizedlist>
                      <listitem>
                          <para>The format identifier indicates the transaction family and tells how the other two parts
                              should be interpreted.</para>
                      </listitem>
                      <listitem>
                          <para>The global transaction id identified the global transaction within the transaction
                          family.</para>
                      </listitem>
                      <listitem>
                          <para>The branch qualifier denotes a particular branch of the global transaction.</para>
                      </listitem>
                  </itemizedlist>
                  <para>Transaction branches are used to identify different parts of the same global transaction. Whenever
                      the transaction manager involves a new recoverable resource in a transaction it creates a new
                      transaction branch.</para>
              </section>
          </section>
          <section>
              <title>JBoss Transaction Internals</title>
              <para>The JBoss application server is written to be independent of the actual transaction manager used.
                  JBoss uses the JTA <literal>javax.transaction.TransactionManager</literal> interface as its view of the
                  server transaction manager. Thus, JBoss may use any transaction manager which implements the JTA
                      <literal>TransactionManager</literal> interface. Whenever a transaction manager is used it is
                  obtained from the well-known JNDI location, <literal>java:/TransactionManager</literal>. This is the
                  globally available access point for the server transaction manager.</para>
              <para>If transaction contexts are to be propagated with RMI/JRMP calls, the transaction manager must also
                  implement two simple interfaces for the import and export of transaction propagation contexts (TPCs).
                  The interfaces are <literal>TransactionPropagationContextImporter</literal>, and
                      <literal>TransactionPropagationContextFactory</literal>, both in the <literal>org.jboss.tm</literal>
                  package.</para>
              <para>Being independent of the actual transaction manager used also means that JBoss does not specify the
                  format of type of the transaction propagation contexts used. In JBoss, a TPC is of type
                  <literal>Object</literal>, and the only requirement is that the TPC must implementation the
                      <literal>java.io.Serializable</literal> interface.</para>
              <para>When using the RMI/JRMP protocol for remote calls, the TPC is carried as a field in the
                      <literal>org.jboss.ejb.plugins.jrmp.client.RemoteMethodInvocation</literal> class that is used to
                  forward remote method invocation requests.</para>
              <section>
                  <title>Adapting a Transaction Manager to JBoss</title>
                  <para>A transaction manager has to implement the Java Transaction API to be easily integrated with
                      JBoss. As almost everything in JBoss, the transaction manager is managed as an MBean. Like all JBoss
                      services, it should implement <literal>org.jboss.system.ServiceMBean</literal> to ensure proper
                      life-cycle management.</para>
                  <para>The primary requirement of the transaction manager service on startup is that it binds its
                      implementation of the three required interfaces into JNDI. These interfaces and their JNDI locations
                      are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>The <literal>javax.transaction.TransactionManager</literal> interface is used by the
                              application server to manage transactions on behalf of the transactional objects that use
                              container managed transactions. It must be bound under the JNDI name
                                  <literal>java:/TransactionManager</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>The <literal>TransactionPropagationContextFactory</literal> interface is called by JBoss
                              whenever a transaction propagation context is needed for transporting a transaction with a
                              remote method call. It must be bound under the JNDI name
                                  <literal>java:/TransactionPropagationContextImporter</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>The <literal>TransactionPropagationContextImporter</literal> interface is called by JBoss
                              whenever a transaction propagation context from an incoming remote method invocation has to
                              be converted to a transaction that can be used within the receiving JBoss server VM.</para>
                      </listitem>
                  </itemizedlist>
                  <para>Establishing these JNDI bindings is all the transaction manager service needs to do to install its
                      implementation as the JBoss server transaction manager.</para>
              </section>
              <section>
                  <title>The Default Transaction Manager</title>
                  <para>JBoss is by default configured to use the fast in-VM transaction manager. This transaction manager
                      is very fast, but does have two limitations.</para>
                  <itemizedlist>
                      <listitem>
                          <para>It does not do transactional logging, and is thus incapable of automated recovery after a
                              server crash.</para>
                      </listitem>
                      <listitem>
                          <para>While it does support propagating transaction contexts with remote calls, it does not
                              support propagating transaction contexts to other virtual machines, so all transactional
                              work must be done in the same virtual machine as the JBoss server.</para>
                      </listitem>
                  </itemizedlist>
                  <para>The corresponding default transaction manager MBean service is the
                          <literal>org.jboss.tm.TransactionManagerService</literal> MBean. It has two configurable
                      attributes:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">TransactionTimeout</emphasis>: The default transaction timeout in
                              seconds. The default value is 300 seconds (5 minutes).</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">InterruptThreads</emphasis>: Indicates whether or not the transaction
                              manager should interrupt threads when the transaction times out. The default value is
                          false.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">GlobalIdsEnabled</emphasis>: Indicates whether or not the transaction
                              manager should use global transaction ids. This should be set to true for transaction
                              demarcation over IIOP The default value is true.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">XidFactory</emphasis>: The JMX <literal>ObjectName</literal> of the
                              MBean service that provides the <literal>org.jboss.tm.XidFactoryMBean</literal>
                              implementation. The <literal>XidFactoryMBean</literal> interface is used to create
                                  <literal>javax.transaction.xa.Xid</literal> instances. This is a workaround for XA JDBC
                              drivers that only work with their own Xid implementation. Examples of such drivers are the
                              older Oracle XA drivers. The default factory is
                          <literal>jboss:service=XidFactory</literal>.</para>
                      </listitem>
                  </itemizedlist>
                  <section>
                      <title>org.jboss.tm.XidFactory</title>
                      <para>The <literal>XidFactory</literal> MBean is a factory for
                          <literal>javax.transaction.xa.Xid</literal> instances in the form of
                              <literal>org.jboss.tm.XidImpl</literal>. The <literal>XidFactory</literal> allows for
                          customization of the <literal>XidImpl</literal> that it constructs through the following
                          attributes:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">BaseGlobalId</emphasis>: This is used for building globally unique
                                  transaction identifiers. This must be set individually if multiple JBoss instances are
                                  running on the same machine. The default value is the host name of the JBoss server,
                                  followed by a slash.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">GlobalIdNumber</emphasis>: A long value used as initial
                                  transaction id. The default is 0.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">Pad</emphasis>: The pad value determines whether the byte[]
                                  returned by the Xid <literal>getGlobalTransactionId</literal> and
                                      <literal>getBranchQualifier</literal> methods should be equal to maximum 64 byte
                                  length or a variable value &lt;= 64. Some resource managers (Oracle, for example)
                                  require ids that are max length in size.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
              </section>
              <section>
                  <title>UserTransaction Support</title>
                  <para>The JTA <literal>javax.transaction.UserTransaction</literal> interface allows applications to
                      explicitly control transactions. For enterprise session beans that manage transaction themselves
                      (BMT), a <literal>UserTransaction</literal> can be obtained by calling the
                          <literal>getUserTransaction</literal> method on the bean context object,
                          <literal>javax.ejb.SessionContext</literal>.</para>
                  <para>The <literal>ClientUserTransactionService</literal> MBean publishes a
                      <literal>UserTransaction</literal> implementation under the JNDI name
                      <literal>UserTransaction</literal>. When the <literal>UserTransaction</literal> is obtained with a
                      JNDI lookup from a external client, a very simple <literal>UserTransaction</literal> suitable for
                      thin clients is returned. This <literal>UserTransaction</literal> implementation only controls the
                      transactions on the server the <literal>UserTransaction</literal> object was obtained from. Local
                      transactional work done in the client is not done within the transactions started by this
                          <literal>UserTransaction</literal> object.</para>
                  <para>When a <literal>UserTransaction</literal> object is obtained by looking up JNDI name
                          <literal>UserTransaction</literal> in the same virtual machine as JBoss, a simple interface to
                      the JTA <literal>TransactionManager</literal> is returned. This is suitable for web components
                      running in web containers embedded in JBoss. When components are deployed in an embedded web server,
                      the deployer will make a JNDI link from the standard <literal>java:comp/UserTransaction</literal>
                      ENC name to the global <literal>UserTransaction</literal> binding so that the web components can
                      lookup the <literal>UserTranaction</literal> instance under JNDI name as specified by the J2EE.</para>
                  <para>Note: For BMT beans, do not obtain the <literal>UserTransaction</literal> interface using a JNDI
                      lookup. Doing this violates the EJB specification, and the returned
                      <literal>UserTransaction</literal> object does not have the hooks the EJB container needs to make
                      important checks.</para>
              </section>
          </section>
      </chapter>
  
  
      <chapter id="ch5.chapter">
          <title>EJBs on JBoss</title>
          <subtitle>The EJB Container Configuration and Architecture</subtitle>
          <para>The JBoss EJB container architecture employs a modular plug-in approach. All key aspects of the EJB
              container may be replaced by custom versions of a plug-in and/or an interceptor by a developer. This
              approach allows for fine tuned customization of the EJB container behavior to optimally suite your needs.
              Most of the EJB container behavior is configurable through the EJB JAR <literal>META-INF/jboss.xml</literal>
              descriptor and the default server-wide equivalent <literal>standardjboss.xml</literal> descriptor. We will
              look at various configuration capabilities throughout this chapter as we explore the container architecture.</para>
          <section id="ch5.client">
              <title>The EJB Client Side View</title>
              <para>We will begin our tour of the EJB container by looking at the client view of an EJB through the home
                  and remote proxies. It is the responsibility of the container provider to generate the
                      <literal>javax.ejb.EJBHome</literal> and <literal>javax.ejb.EJBObject</literal> for an EJB
                  implementation. A client never references an EJB bean instance directly, but rather references the
                      <literal>EJBHome</literal> which implements the bean home interface, and the
                  <literal>EJBObject</literal> which implements the bean remote interface. <xref linkend="ch5.ejbhome.fig"
                  /> shows the composition of an EJB home proxy and its relation to the EJB deployment.</para>
              <figure id="ch5.ejbhome.fig">
                  <title>The composition of an EJBHome proxy in JBoss.</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/ejbhomeproxy.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>The numbered items in the figure are:</para>
              <orderedlist>
                  <listitem>
                      <para>The EJBDeployer (<literal>org.jboss.ejb.EJBDeployer</literal>) is invoked to deploy an EJB
                          JAR. An <literal>EJBModule</literal> (<literal>org.jboss.ejb.EJBModule</literal>) is created to
                          encapsulate the deployment metadata.</para>
                  </listitem>
                  <listitem>
                      <para>The create phase of the <literal>EJBModule</literal> life cycle creates an
                              <literal>EJBProxyFactory</literal> (<literal>org.jboss.ejb.EJBProxyFactory</literal>) that
                          manages the creation of EJB home and remote interface proxies based on the <literal>EJBModule</literal>
                          <literal>invoker-proxy-bindings</literal> metadata. There can be multiple proxy factories
                          associated with an EJB and we will look at how this is defined shortly.</para>
                  </listitem>
                  <listitem>
                      <para>The <literal>ProxyFactory</literal> constructs the logical proxies and binds the homes into
                          JNDI. A logical proxy is composed of a dynamic <literal>Proxy</literal>
                              (<literal>java.lang.reflect.Proxy</literal>), the home interfaces of the EJB that the proxy
                          exposes, the <literal>ProxyHandler</literal>
                          (<literal>java.lang.reflect.InvocationHandler</literal>) implementation in the form of the
                              <literal>ClientContainer</literal> (<literal>org.jboss.proxy.ClientContainer</literal>), and
                          the client side interceptors.</para>
                  </listitem>
                  <listitem>
                      <para>The proxy created by the <literal>EJBProxyFactory</literal> is a standard dynamic proxy. It is
                          a serializable object that proxies the EJB home and remote interfaces as defined in the
                              <literal>EJBModule</literal> metadata. The proxy translates requests made through the
                          strongly typed EJB interfaces into a detyped invocation using the
                          <literal>ClientContainer</literal> handler associated with the proxy. It is the dynamic proxy
                          instance that is bound into JNDI as the EJB home interface that clients lookup. When a client
                          does a lookup of an EJB home, the home proxy is transported into the client VM along with the
                              <literal>ClientContainer</literal> and its interceptors. The use of dynamic proxies avoids
                          the EJB specific compilation step required by many other EJB containers.</para>
                  </listitem>
                  <listitem>
                      <para>The EJB home interface is declared in the ejb-jar.xml descriptor and available from the
                          EJBModule metadata. A key property of dynamic proxies is that they are seen to implement the
                          interfaces they expose. This is true in the sense of Java's strong type system. A proxy can be
                          cast to any of the home interfaces and reflection on the proxy provides the full details of the
                          interfaces it proxies.</para>
                  </listitem>
                  <listitem>
                      <para>The proxy delegates calls made through any of its interfaces to the
                          <literal>ClientContainer</literal> handler. The single method required of the handler is:
                              <literal>public Object invoke(Object proxy, Method m, Object[] args) throws
                          Throwable</literal>. The <literal>EJBProxyFactory</literal> creates a
                          <literal>ClientContainer</literal> and assigns this as the <literal>ProxyHandler</literal>. The
                              <literal>ClientContainer</literal>'s state consists of an
                          <literal>InvocationContext</literal> (<literal>org.jboss.invocation.InvocationContext</literal>)
                          and a chain of interceptors (<literal>org.jboss.proxy.Interceptor</literal>). The
                              <literal>InvocationContext</literal> contains: </para>
                      <itemizedlist spacing="compact">
                          <listitem>
                              <para>the JMX <literal>ObjectName</literal> of the EJB container MBean the
                                  <literal>Proxy</literal> is associated with</para>
                          </listitem>
                          <listitem>
                              <para>the <literal>javax.ejb.EJBMetaData</literal> for the EJB</para>
                          </listitem>
                          <listitem>
                              <para>the JNDI name of the EJB home interface</para>
                          </listitem>
                          <listitem>
                              <para>the transport specific invoker
                              (<literal>org.jboss.invocation.Invoker</literal>)</para>
                          </listitem>
                      </itemizedlist>
                      <para>The interceptor chain consists of the functional units that make up the EJB home or remote
                          interface behavior. This is a configurable aspect of an EJB as we will see when we discuss the
                              <literal>jboss.xml</literal> descriptor, and the interceptor makeup is contained in the
                              <literal>EJBModule</literal> metadata. Interceptors
                          (<literal>org.jboss.proxy.Interceptor</literal>) handle the different EJB types, security,
                          transactions and transport. You can add your own interceptors as well.</para>
                  </listitem>
                  <listitem>
                      <para>The transport specific invoker associated with the proxy has an association to the server side
                          detached invoker that handles the transport details of the EJB method invocation. The detached
                          invoker is a JBoss server side component.</para>
                  </listitem>
              </orderedlist>
              <para>The configuration of the client side interceptors is done using the <literal>jboss.xml</literal>
                  <literal>client-interceptors</literal> element. When the <literal>ClientContainer</literal> invoke
                  method is called it creates an untyped <literal>Invocation</literal>
                      (<literal>org.jboss.invocation.Invocation</literal>) to encapsulate request. This is then passed
                  through the interceptor chain. The last interceptor in the chain will be the transport handler that
                  knows how to send the request to the server and obtain the reply, taking care of the transport specific
                  details.</para>
              <para>As an example of the client interceptor configuration usage, consider the default stateless session
                  bean configuration found in the <literal>server/default/standardjboss.xml</literal> descriptor. <xref
                      linkend="ch5.sssb.ex"/> shows the <literal>stateless-rmi-invoker</literal> client interceptors
                  configuration referenced by the Standard Stateless SessionBean.</para>
              <example id="ch5.sssb.ex">
                  <title>The client-interceptors from the Standard Stateless SessionBean configuration.</title>
                  <programlisting>&lt;invoker-proxy-binding&gt;
      &lt;name&gt;stateless-rmi-invoker&lt;/name&gt;
      &lt;invoker-mbean&gt;jboss:service=invoker,type=jrmp&lt;/invoker-mbean&gt;
      &lt;proxy-factory&gt;org.jboss.proxy.ejb.ProxyFactory&lt;/proxy-factory&gt;
          &lt;proxy-factory-config&gt;
          &lt;client-interceptors&gt;
              &lt;home&gt;
                  &lt;interceptor&gt;org.jboss.proxy.ejb.HomeInterceptor&lt;/interceptor&gt;
                  &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                  &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
                  &lt;interceptor call-by-value=&quot;false&quot;&gt;
                      org.jboss.invocation.InvokerInterceptor
                  &lt;/interceptor&gt;
                  &lt;interceptor call-by-value=&quot;true&quot;&gt;
                      org.jboss.invocation.MarshallingInvokerInterceptor
                  &lt;/interceptor&gt;
              &lt;/home&gt;
              &lt;bean&gt;
                  &lt;interceptor&gt;org.jboss.proxy.ejb.StatelessSessionInterceptor&lt;/interceptor&gt;
                  &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                  &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
                  &lt;interceptor call-by-value=&quot;false&quot;&gt;
                      org.jboss.invocation.InvokerInterceptor
                  &lt;/interceptor&gt;
                  &lt;interceptor call-by-value=&quot;true&quot;&gt;
                      org.jboss.invocation.MarshallingInvokerInterceptor
                  &lt;/interceptor&gt;
              &lt;/bean&gt;
          &lt;/client-interceptors&gt;
      &lt;/proxy-factory-config&gt;
  &lt;/invoker-proxy-binding&gt;           </programlisting>
                  <programlisting>&lt;container-configuration&gt;
      &lt;container-name&gt;Standard Stateless SessionBean&lt;/container-name&gt;
      &lt;call-logging&gt;false&lt;/call-logging&gt;
      &lt;invoker-proxy-binding-name&gt;stateless-rmi-invoker&lt;/invoker-proxy-binding-name&gt;
      &lt;!-- ... --&gt;
  &lt;/container-configuration&gt;</programlisting>
              </example>
              <para>This is the client interceptor configuration for stateless session beans that is used in the absence
                  of an EJB JAR <literal>META-INF/jboss.xml</literal> configuration that overrides these settings. The
                  functionality provided by each client interceptor is:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">org.jboss.proxy.ejb.HomeInterceptor</emphasis>: handles the
                              <literal>getHomeHandle</literal>, <literal>getEJBMetaData</literal>, and remove methods of
                          the <literal>EJBHome</literal> interface locally in the client VM. Any other methods are
                          propagated to the next interceptor.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">org.jboss.proxy.ejb.StatelessSessionInterceptor</emphasis>: handles the
                              <literal>toString</literal>, <literal>equals</literal>, <literal>hashCode</literal>,
                              <literal>getHandle</literal>, <literal>getEJBHome</literal> and
                          <literal>isIdentical</literal> methods of the <literal>EJBObject</literal> interface locally in
                          the client VM. Any other methods are propagated to the next interceptor.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">org.jboss.proxy.SecurityInterceptor</emphasis>: associates the current
                          security context with the method invocation for use by other interceptors or the server.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">org.jboss.proxy.TransactionInterceptor</emphasis>: associates any active
                          transaction with the invocation method invocation for use by other interceptors.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">org.jboss.invocation.InvokerInterceptor</emphasis>: encapsulates the
                          dispatch of the method invocation to the transport specific invoker. It knows if the client is
                          executing in the same VM as the server and will optimally route the invocation to a by reference
                          invoker in this situation. When the client is external to the server VM, this interceptor
                          delegates the invocation to the transport invoker associated with the invocation context. In the
                          case of the <xref linkend="ch5.sssb.ex"/> configuration, this would be the invoker stub
                          associated with the <literal>jboss:service=invoker,type=jrmp</literal>, the
                          <literal>JRMPInvoker</literal> service.</para>
                      <para>
                          <emphasis role="bold">org.jboss.invocation.MarshallingInvokerInterceptor</emphasis>: extends the
                              <literal>InvokerInterceptor</literal> to not optimize in-VM invocations. This is used to
                          force <literal>call-by-value</literal> semantics for method calls. </para>
                  </listitem>
              </itemizedlist>
              <section>
                  <title>Specifying the EJB Proxy Configuration</title>
                  <para>To specify the EJB invocation transport and the client proxy interceptor stack, you need to define
                      an <literal>invoker-proxy-binding</literal> in either the EJB JAR <literal>META-INF/jboss.xml
                          descriptor</literal>, or the server <literal>standardjboss.xml</literal> descriptor. There are
                      several default <literal>invoker-proxy-bindings</literal> defined in the
                      <literal>standardjboss.xml</literal> descriptor for the various default EJB container configurations
                      and the standard RMI/JRMP and RMI/IIOP transport protocols. The current default proxy configurations
                      are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">entity-rmi-invoker</emphasis>: a RMI/JRMP configuration for entity
                              beans</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">clustered-entity-rmi-invoker</emphasis>: a RMI/JRMP configuration for
                              clustered entity beans</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">stateless-rmi-invoker</emphasis>: a RMI/JRMP configuration for
                              stateless session beans</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">clustered-stateless-rmi-invoker</emphasis>: a RMI/JRMP configuration
                              for clustered stateless session beans</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">stateful-rmi-invoker</emphasis>: a RMI/JRMP configuration for
                              clustered stateful session beans</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">clustered-stateful-rmi-invoker</emphasis>: a RMI/JRMP configuration
                              for clustered stateful session beans</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">message-driven-bean</emphasis>: a JMS invoker for message driven
                          beans</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">singleton-message-driven-bean</emphasis>: a JMS invoker for singleton
                              message driven beans</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">message-inflow-driven-bean</emphasis>: a JMS invoker for message
                              inflow driven beans</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">jms-message-inflow-driven-bean</emphasis>: a JMS inflow invoker for
                              standard message driven beans</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">iiop</emphasis>: a RMI/IIOP for use with session and entity
                          beans.</para>
                      </listitem>
                  </itemizedlist>
                  <para>To introduce a new protocol binding, or customize the proxy factory, or the client side
                      interceptor stack, requires defining a new <literal>invoker-proxy-binding</literal>. The full
                          <literal>invoker-proxy-binding</literal> DTD fragment for the specification of the proxy
                      configuration is given in <xref linkend="ch5.invokerproxy.fig"/>.</para>
                  <figure id="ch5.invokerproxy.fig">
                      <title>The invoker-proxy-binding schema</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/jboss_4_0_invoker_proxy_binding.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The <literal>invoker-proxy-binding</literal> child elements are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">name</emphasis>: The <literal>name</literal> element gives a unique
                              name for the <literal>invoker-proxy-binding</literal>. The name is used to reference the
                              binding from the EJB container configuration when setting the default proxy binding as well
                              as the EJB deployment level to specify addition proxy bindings. You will see how this is
                              done when we look at the <literal>jboss.xml</literal> elements that control the server side
                              EJB container configuration.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">invoker-mbean</emphasis>: The <literal>invoker-mbean</literal> element
                              gives the JMX <literal>ObjectName</literal> string of the detached invoker MBean service the
                              proxy invoker will be associated with.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">proxy-factory</emphasis>: The <literal>proxy-factory</literal> element
                              specifies the fully qualified class name of the proxy factory, which must implement the
                                  <literal>org.jboss.ejb.EJBProxyFactory</literal> interface. The
                              <literal>EJBProxyFactory</literal> handles the configuration of the proxy and the
                              association of the protocol specific invoker and context. The current JBoss implementations
                              of the <literal>EJBProxyFactory</literal> interface include:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">org.jboss.proxy.ejb.ProxyFactory</emphasis>: The RMI/JRMP
                                      specific factory.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">org.jboss.proxy.ejb.ProxyFactoryHA</emphasis>: The cluster
                                      RMI/JRMP specific factory.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">org.jboss.ejb.plugins.jms.JMSContainerInvoker</emphasis>: The
                                      JMS specific factory.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">org.jboss.proxy.ejb.IORFactory</emphasis>: The RMI/IIOP
                                      specific factory.</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">proxy-factory-config</emphasis>: The
                              <literal>proxy-factory-config</literal> element specifies additional information for the
                                  <literal>proxy-factory</literal> implementation. Unfortunately, its currently an
                              unstructured collection of elements. Only a few of the elements apply to each type of proxy
                              factory. The child elements break down into the three invocation protocols: RMI/RJMP,
                              RMI/IIOP and JMS. </para>
                      </listitem>
                  </itemizedlist>
                  <para>For the RMI/JRMP specific proxy factories, <literal>org.jboss.proxy.ejb.ProxyFactory</literal> and
                          <literal>org.jboss.proxy.ejb.ProxyFactoryHA</literal> the following elements apply:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">client-interceptors</emphasis>: The
                              <literal>client-interceptors</literal> define the home, remote and optionally the
                              multi-valued proxy interceptor stacks.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">web-class-loader</emphasis>: The web class loader defines the instance
                              of the <literal>org.jboss.web.WebClassLoader</literal> that should be associated with the
                              proxy for dynamic class loading.</para>
                      </listitem>
                  </itemizedlist>
                  <para> The following <literal>proxy-factory-config</literal> is for an entity bean accessed over RMI.</para>
                  <programlisting>&lt;proxy-factory-config&gt;
      &lt;client-interceptors&gt;
          &lt;home&gt;
              &lt;interceptor&gt;org.jboss.proxy.ejb.HomeInterceptor&lt;/interceptor&gt;
              &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
              &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
              &lt;interceptor call-by-value=&quot;false&quot;&gt;
                  org.jboss.invocation.InvokerInterceptor
              &lt;/interceptor&gt;
              &lt;interceptor call-by-value=&quot;true&quot;&gt;
                  org.jboss.invocation.MarshallingInvokerInterceptor
              &lt;/interceptor&gt;
          &lt;/home&gt;
          &lt;bean&gt;
              &lt;interceptor&gt;org.jboss.proxy.ejb.EntityInterceptor&lt;/interceptor&gt;
              &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
              &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
              &lt;interceptor call-by-value=&quot;false&quot;&gt;
                  org.jboss.invocation.InvokerInterceptor
              &lt;/interceptor&gt;
              &lt;interceptor call-by-value=&quot;true&quot;&gt;
                  org.jboss.invocation.MarshallingInvokerInterceptor
              &lt;/interceptor&gt;
          &lt;/bean&gt;
          &lt;list-entity&gt;
              &lt;interceptor&gt;org.jboss.proxy.ejb.ListEntityInterceptor&lt;/interceptor&gt;
              &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
              &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
              &lt;interceptor call-by-value=&quot;false&quot;&gt;
                  org.jboss.invocation.InvokerInterceptor
              &lt;/interceptor&gt;
              &lt;interceptor call-by-value=&quot;true&quot;&gt;
                  org.jboss.invocation.MarshallingInvokerInterceptor
              &lt;/interceptor&gt;
          &lt;/list-entity&gt;
      &lt;/client-interceptors&gt;
  &lt;/proxy-factory-config&gt;</programlisting>
                  <para>For the RMI/IIOP specific proxy factory, <literal>org.jboss.proxy.ejb.IORFactory</literal>, the
                      following elements apply:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">web-class-loader</emphasis>: The web class loader defines the instance
                              of the <literal>org.jboss.web.WebClassLoader</literal> that should be associated with the
                              proxy for dynamic class loading.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">poa</emphasis>: The portable object adapter usage. Valid values are
                                  <literal>per-servant</literal> and <literal>shared</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">register-ejbs-in-jnp-context</emphasis>: A flag indicating if the EJBs
                              should be register in JNDI.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">jnp-context</emphasis>: The JNDI context in which to register
                          EJBs.</para>
                      </listitem>
  
  
                      <listitem>
                          <para>
                              <emphasis role="bold">interface-repository-supported</emphasis>: This indicates whether or
                              not a deployed EJB has its own CORBA interface repository. </para>
                      </listitem>
                  </itemizedlist>
                  <para> The following shows a <literal>proxy-factory-config</literal> for EJBs accessed over IIOP.</para>
                  <programlisting>&lt;proxy-factory-config&gt;
      &lt;web-class-loader&gt;org.jboss.iiop.WebCL&lt;/web-class-loader&gt;
      &lt;poa&gt;per-servant&lt;/poa&gt;
      &lt;register-ejbs-in-jnp-context&gt;true&lt;/register-ejbs-in-jnp-context&gt;
      &lt;jnp-context&gt;iiop&lt;/jnp-context&gt;
  &lt;/proxy-factory-config&gt; </programlisting>
                  <para>For the JMS specific proxy factory,
                      <literal>org.jboss.ejb.plugins.jms.JMSContainerInvoker</literal>, the following elements apply:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">MinimumSize</emphasis>: This specifies the minimum pool size for MDBs
                              processing . This defaults to 1.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MaximumSize</emphasis>: This specifies the upper limit to the number
                              of concurrent MDBs that will be allowed for the JMS destination. This defaults to 15.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MaxMessages</emphasis>: This specifies the
                              <literal>maxMessages</literal> parameter value for the
                              <literal>createConnectionConsumer</literal> method of
                              <literal>javax.jms.QueueConnection</literal> and
                              <literal>javax.jms.TopicConnection</literal> interfaces, as well as the
                              <literal>maxMessages</literal> parameter value for the
                                  <literal>createDurableConnectionConsumer</literal> method of
                                  <literal>javax.jms.TopicConnection</literal>. It is the maximum number of messages that
                              can be assigned to a server session at one time. This defaults to 1. This value should not
                              be modified from the default unless your JMS provider indicates this is supported.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">KeepAliveMillis</emphasis>: This specifies the keep alive time
                              interval in milliseconds for sessions in the session pool. The default is 30000 (30
                              seconds). </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MDBConfig</emphasis>: Configuration for the MDB JMS connection
                              behavior. Among the elements supported are:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">ReconnectIntervalSec</emphasis>: The time to wait (in seconds)
                                      before trying to recover the connection to the JMS server.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">DeliveryActive</emphasis>: Whether or not the MDB is active at
                                      startup. The default is true.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">DLQConfig</emphasis>: Configuration for an MDB's dead letter
                                      queue, used when messages are redelivered too many times.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">JMSProviderAdapterJNDI</emphasis>: The JNDI name of the JMS
                                      provider adapter in the <literal>java:/</literal> namespace. This is mandatory for
                                      an MDB and must implement
                                  <literal>org.jboss.jms.jndi.JMSProviderAdapter</literal>.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">ServerSessionPoolFactoryJNDI</emphasis>: The JNDI name of the
                                      session pool in the <literal>java:/</literal> namespace of the JMS provider's
                                      session pool factory. This is mandatory for an MDB and must implement
                                          <literal>org.jboss.jms.asf.ServerSessionPoolFactory</literal>.</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                  </itemizedlist>
                  <para>
                      <xref linkend="ch5.jmsinvoker.ex"/> gives a sample <literal>proxy-factory-config</literal> fragment
                      taken from the <literal>standardjboss.xml</literal> descriptor.</para>
                  <example id="ch5.jmsinvoker.ex">
                      <title>A sample JMSContainerInvoker proxy-factory-config</title>
                      <programlisting>&lt;proxy-factory-config&gt;
      &lt;JMSProviderAdapterJNDI&gt;DefaultJMSProvider&lt;/JMSProviderAdapterJNDI&gt;
      &lt;ServerSessionPoolFactoryJNDI&gt;StdJMSPool&lt;/ServerSessionPoolFactoryJNDI&gt;
      &lt;MinimumSize&gt;1&lt;/MinimumSize&gt;
      &lt;MaximumSize&gt;15&lt;/MaximumSize&gt;
      &lt;KeepAliveMillis&gt;30000&lt;/KeepAliveMillis&gt;
      &lt;MaxMessages&gt;1&lt;/MaxMessages&gt;
      &lt;MDBConfig&gt;
          &lt;ReconnectIntervalSec&gt;10&lt;/ReconnectIntervalSec&gt;
          &lt;DLQConfig&gt;
              &lt;DestinationQueue&gt;queue/DLQ&lt;/DestinationQueue&gt;
              &lt;MaxTimesRedelivered&gt;10&lt;/MaxTimesRedelivered&gt;
              &lt;TimeToLive&gt;0&lt;/TimeToLive&gt;
          &lt;/DLQConfig&gt;
      &lt;/MDBConfig&gt;
  &lt;/proxy-factory-config&gt;</programlisting>
                  </example>
              </section>
          </section>
          <section id="ch5.server">
              <title>The EJB Server Side View</title>
              <para>Every EJB invocation must end up at a JBoss server hosted EJB container. In this section we will look
                  at how invocations are transported to the JBoss server VM and find their way to the EJB container via
                  the JMX bus.</para>
              <section>
                  <title>Detached Invokers - The Transport Middlemen</title>
                  <para>We looked at the detached invoker architecture in the context of exposing RMI compatible
                      interfaces of MBean services earlier. Here we will look at how detached invokers are used to expose
                      the EJB container home and bean interfaces to clients. The generic view of the invoker architecture
                      is presented in <xref linkend="ch5.tissa.fig"/>.</para>
                  <figure id="ch5.tissa.fig">
                      <title>The transport invoker server side architecture</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/invoker-architecture.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>For each type of home proxy there is a binding to an invoker and its associated transport
                      protocol. A container may have multiple invocation protocols active simultaneously. In the
                          <literal>jboss.xml</literal> file, an <literal>invoker-proxy-binding-name</literal> maps to an
                          <literal>invoker-proxy-binding/name</literal> element. At the
                      <literal>container-configuration</literal> level this specifies the default invoker that will be
                      used for EJBs deployed to the container. At the bean level, the <literal>invoker-bindings</literal>
                      specify one or more invokers to use with the EJB container MBean.</para>
                  <para>When one specifies multiple invokers for a given EJB deployment, the home proxy must be given a
                      unique JNDI binding location. This is specified by the <literal>invoker/jndi-name</literal> element
                      value. Another issue when multiple invokers exist for an EJB is how to handle remote homes or
                      interfaces obtained when the EJB calls other beans. Any such interfaces need to use the same invoker
                      used to call the outer EJB in order for the resulting remote homes and interfaces to be compatible
                      with the proxy the client has initiated the call through. The <literal>invoker/ejb-ref</literal>
                      elements allow one to map from a protocol independent ENC <literal>ejb-ref</literal> to the home
                      proxy binding for <literal>ejb-ref</literal> target EJB home that matches the referencing invoker
                      type.</para>
                  <para>An example of using a custom <literal>JRMPInvoker</literal> MBean that enables compressed sockets
                      for session beans can be found in the <literal>org.jboss.test.jrmp</literal> package of the
                      testsuite. The following example illustrates the custom <literal>JRMPInvoker</literal> configuration
                      and its mapping to a stateless session bean.</para>
                  <programlisting>&lt;server&gt;
      &lt;mbean code="org.jboss.invocation.jrmp.server.JRMPInvoker"
            name="jboss:service=invoker,type=jrmp,socketType=CompressionSocketFactory"&gt;
          &lt;attribute name="RMIObjectPort"&gt;4445&lt;/attribute&gt;
          &lt;attribute name="RMIClientSocketFactory"&gt;
              org.jboss.test.jrmp.ejb.CompressionClientSocketFactory
          &lt;/attribute&gt;
          &lt;attribute name="RMIServerSocketFactory"&gt;
              org.jboss.test.jrmp.ejb.CompressionServerSocketFactory
          &lt;/attribute&gt;
  &lt;/mbean&gt;
                  &lt;/server&gt;</programlisting>
                  <para> Here the default <literal>JRMPInvoker</literal> has been customized to bind to port 4445 and to
                      use custom socket factories that enable compression at the transport level. </para>
                  <programlisting>&lt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE jboss PUBLIC
            "-//JBoss//DTD JBOSS 3.2//EN"
            "http://www.jboss.org/j2ee/dtd/jboss_3_2.dtd"&gt;
  &lt;!-- The jboss.xml descriptor for the jrmp-comp.jar ejb unit --&gt;
  &lt;jboss&gt;
      &lt;enterprise-beans&gt;
          &lt;session&gt;
              &lt;ejb-name&gt;StatelessSession&lt;/ejb-name&gt;
              &lt;configuration-name&gt;Standard Stateless SessionBean&lt;/configuration-name&gt;
              &lt;invoker-bindings&gt;
                  &lt;invoker&gt;
                      &lt;invoker-proxy-binding-name&gt;
                          stateless-compression-invoker
                      &lt;/invoker-proxy-binding-name&gt;
                      &lt;jndi-name&gt;jrmp-compressed/StatelessSession&lt;/jndi-name&gt;
                  &lt;/invoker&gt;
              &lt;/invoker-bindings&gt;
          &lt;/session&gt;
      &lt;/enterprise-beans&gt;
                      
      &lt;invoker-proxy-bindings&gt;
          &lt;invoker-proxy-binding&gt;
              &lt;name&gt;stateless-compression-invoker&lt;/name&gt;
              &lt;invoker-mbean&gt;
                  jboss:service=invoker,type=jrmp,socketType=CompressionSocketFactory
              &lt;/invoker-mbean&gt;
              &lt;proxy-factory&gt;org.jboss.proxy.ejb.ProxyFactory&lt;/proxy-factory&gt;
              &lt;proxy-factory-config&gt;
                  &lt;client-interceptors&gt;
                      &lt;home&gt;
                          &lt;interceptor&gt;org.jboss.proxy.ejb.HomeInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
                      &lt;/home&gt;
                      &lt;bean&gt;
                          &lt;interceptor&gt;
                              org.jboss.proxy.ejb.StatelessSessionInterceptor
                          &lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
                      &lt;/bean&gt;
                  &lt;/client-interceptors&gt;
              &lt;/proxy-factory-config&gt;
          &lt;/invoker-proxy-binding&gt;
      &lt;/invoker-proxy-bindings&gt;
  &lt;/jboss&gt;     </programlisting>
                  <para> The <literal>StatelessSession</literal> EJB <literal>invoker-bindings</literal> settings specify
                      that the <literal>stateless-compression-invoker</literal> will be used with the home interface bound
                      under the JNDI name <literal>jrmp-compressed/StatelessSession</literal>. The
                          <literal>stateless-compression-invoker</literal> is linked to the custom JRMP invoker we just
                      declared. </para>
                  <para>The following example, <literal>org.jboss.test.hello</literal> testsuite package, is an example of
                      using the <literal>HttpInvoker</literal> to configure a stateless session bean to use the RMI/HTTP
                      protocol. </para>
                  <programlisting>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE jboss PUBLIC
            "-//JBoss//DTD JBOSS 3.2//EN"
            "http://www.jboss.org/j2ee/dtd/jboss_3_2.dtd"&gt;
  &lt;jboss&gt;
      &lt;enterprise-beans&gt;
          &lt;session&gt;
              &lt;ejb-name&gt;HelloWorldViaHTTP&lt;/ejb-name&gt;
              &lt;jndi-name&gt;helloworld/HelloHTTP&lt;/jndi-name&gt;
              &lt;invoker-bindings&gt;
                  &lt;invoker&gt;
                      &lt;invoker-proxy-binding-name&gt;
                          stateless-http-invoker
                      &lt;/invoker-proxy-binding-name&gt;
                  &lt;/invoker&gt;
              &lt;/invoker-bindings&gt;
          &lt;/session&gt;
      &lt;/enterprise-beans&gt;
      &lt;invoker-proxy-bindings&gt;
          &lt;!-- A custom invoker for RMI/HTTP --&gt;
          &lt;invoker-proxy-binding&gt;
              &lt;name&gt;stateless-http-invoker&lt;/name&gt;
              &lt;invoker-mbean&gt;jboss:service=invoker,type=http&lt;/invoker-mbean&gt;
              &lt;proxy-factory&gt;org.jboss.proxy.ejb.ProxyFactory&lt;/proxy-factory&gt;
              &lt;proxy-factory-config&gt;
                  &lt;client-interceptors&gt;
                      &lt;home&gt;
                          &lt;interceptor&gt;org.jboss.proxy.ejb.HomeInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
                      &lt;/home&gt;
                      &lt;bean&gt;
                          &lt;interceptor&gt;
                              org.jboss.proxy.ejb.StatelessSessionInterceptor
                          &lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
                      &lt;/bean&gt;
                  &lt;/client-interceptors&gt;
              &lt;/proxy-factory-config&gt;
          &lt;/invoker-proxy-binding&gt;
      &lt;/invoker-proxy-bindings&gt;
  &lt;/jboss&gt;
  </programlisting>
                  <para>Here a custom invoker-proxy-binding named <literal>stateless-http-invoker</literal> is defined. It
                      uses the <literal>HttpInvoker</literal> MBean as the detached invoker. The
                          <literal>jboss:service=invoker,type=http</literal> name is the default name of the
                          <literal>HttpInvoker</literal> MBean as found in the
                          <literal>http-invoker.sar/META-INF/jboss-service.xml</literal> descriptor, and its service
                      descriptor fragment is show here:</para>
                  <programlisting>&lt;!-- The HTTP invoker service configuration --&gt;
  &lt;mbean code="org.jboss.invocation.http.server.HttpInvoker"
         name="jboss:service=invoker,type=http"&gt;
      &lt;!-- Use a URL of the form http://&lt;hostname&gt;:8080/invoker/EJBInvokerServlet
           where &lt;hostname&gt; is InetAddress.getHostname value on which the server
           is running. --&gt;
      &lt;attribute name="InvokerURLPrefix"&gt;http://&lt;/attribute&gt;
      &lt;attribute name="InvokerURLSuffix"&gt;:8080/invoker/EJBInvokerServlet&lt;/attribute&gt;
      &lt;attribute name="UseHostName"&gt;true&lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
                  <para> The client proxy posts the EJB invocation content to the <literal>EJBInvokerServlet</literal> URL
                      specified in the <literal>HttpInvoker</literal> service configuration. </para>
              </section>
              <section>
                  <title>The HA JRMPInvoker - Clustered RMI/JRMP Transport</title>
                  <para>The <literal>org.jboss.invocation.jrmp.server.JRMPInvokerHA</literal> service is an extension of
                      the <literal>JRMPInvoker</literal> that is a cluster aware invoker. The
                      <literal>JRMPInvokerHA</literal> fully supports all of the attributes of the
                      <literal>JRMPInvoker</literal>. This means that customized bindings of the port, interface and
                      socket transport are available to clustered RMI/JRMP as well. For additional information on the
                      clustering architecture and the implementation of the HA RMI proxies see the JBoss Clustering
                  docs.</para>
              </section>
              <section>
                  <title>The HA HttpInvoker - Clustered RMI/HTTP Transport</title>
                  <para>The RMI/HTTP layer allows for software load balancing of the invocations in a clustered
                      environment. An HA capable extension of the HTTP invoker has been added that borrows much of its
                      functionality from the HA-RMI/JRMP clustering.</para>
                  <para>To enable HA-RMI/HTTP you need to configure the invokers for the EJB container. This is done
                      through either a <literal>jboss.xml</literal> descriptor, or the
                      <literal>standardjboss.xml</literal> descriptor. <xref linkend="ch5.harmihttp.ex"/> shows is an
                      example of a stateless session configuration taken from the <literal>org.jboss.test.hello</literal>
                      testsuite package.</para>
                  <example id="ch5.harmihttp.ex">
                      <title>A jboss.xml stateless session configuration for HA-RMI/HTTP</title>
                      <programlisting>&lt;jboss&gt;
      &lt;enterprise-beans&gt;
          &lt;session&gt;
              &lt;ejb-name&gt;HelloWorldViaClusteredHTTP&lt;/ejb-name&gt;
              &lt;jndi-name&gt;helloworld/HelloHA-HTTP&lt;/jndi-name&gt;
              &lt;invoker-bindings&gt;
                  &lt;invoker&gt;
                      &lt;invoker-proxy-binding-name&gt;
                          stateless-httpHA-invoker
                      &lt;/invoker-proxy-binding-name&gt;
                  &lt;/invoker&gt;
              &lt;/invoker-bindings&gt;
              &lt;clustered&gt;true&lt;/clustered&gt;
          &lt;/session&gt;
      &lt;/enterprise-beans&gt;
      &lt;invoker-proxy-bindings&gt;
          &lt;invoker-proxy-binding&gt;
              &lt;name&gt;stateless-httpHA-invoker&lt;/name&gt;
              &lt;invoker-mbean&gt;jboss:service=invoker,type=httpHA&lt;/invoker-mbean&gt;
              &lt;proxy-factory&gt;org.jboss.proxy.ejb.ProxyFactoryHA&lt;/proxy-factory&gt;
              &lt;proxy-factory-config&gt;
                  &lt;client-interceptors&gt;
                      &lt;home&gt;
                          &lt;interceptor&gt;org.jboss.proxy.ejb.HomeInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
                      &lt;/home&gt;
                      &lt;bean&gt;
                          &lt;interceptor&gt;
                              org.jboss.proxy.ejb.StatelessSessionInterceptor
                          &lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
                          &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
                      &lt;/bean&gt;
                  &lt;/client-interceptors&gt;
              &lt;/proxy-factory-config&gt;
          &lt;/invoker-proxy-binding&gt;
      &lt;/invoker-proxy-bindings&gt;
  &lt;/jboss&gt;</programlisting>
                  </example>
                  <para>The <literal>stateless-httpHA-invoker</literal> invoker-proxy-binding references the
                          <literal>jboss:service=invoker,type=httpHA</literal> invoker service. This service would be
                      configured as shown below.</para>
                  <programlisting>&lt;mbean code="org.jboss.invocation.http.server.HttpInvokerHA"
         name="jboss:service=invoker,type=httpHA"&gt;
      &lt;!-- Use a URL of the form
           http://&lt;hostname&gt;:8080/invoker/EJBInvokerHAServlet
           where &lt;hostname&gt; is InetAddress.getHostname value on which the server
           is running.
      --&gt;
      &lt;attribute name="InvokerURLPrefix"&gt;http://&lt;/attribute&gt;
      &lt;attribute name="InvokerURLSuffix"&gt;:8080/invoker/EJBInvokerHAServlet&lt;/attribute&gt;
      &lt;attribute name="UseHostName"&gt;true&lt;/attribute&gt;
  &lt;/mbean&gt;    </programlisting>
                  <para>The URL used by the invoker proxy is the <literal>EJBInvokerHAServlet</literal> mapping as
                      deployed on the cluster node. The <literal>HttpInvokerHA</literal> instances across the cluster form
                      a collection of candidate http URLs that are made available to the client side proxy for failover
                      and/or load balancing.</para>
              </section>
          </section>
          <section id="ch5.container">
              <title>The EJB Container</title>
              <para>An EJB container is the component that manages a particular class of EJB. In JBoss there is one
                  instance of the <literal>org.jboss.ejb.Container</literal> created for each unique configuration of an
                  EJB that is deployed. The actual object that is instantiated is a subclass of
                  <literal>Container</literal> and the creation of the container instance is managed by the
                      <literal>EJBDeployer</literal> MBean.</para>
              <section>
                  <title>EJBDeployer MBean</title>
                  <para>The <literal>org.jboss.ejb.EJBDeployer</literal> MBean is responsible for the creation of EJB
                      containers. Given an EJB JAR that is ready for deployment, the <literal>EJBDeployer</literal> will
                      create and initialize the necessary EJB containers, one for each type of EJB. The configurable
                      attributes of the <literal>EJBDeployer</literal> are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">VerifyDeployments</emphasis>: a boolean flag indicating if the EJB
                              verifier should be run. This validates that the EJBs in a deployment unit conform to the EJB
                              2.1 specification. Setting this to true is useful for ensuring your deployments are
                          valid.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">VerifierVerbose</emphasis>: A boolean that controls the verboseness of
                              any verification failures/warnings that result from the verification process.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">StrictVerifier</emphasis>: A boolean that enables/disables strict
                              verification. When strict verification is enable an EJB will deploy only if verifier reports
                              no errors.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">CallByValue</emphasis>: a boolean flag that indicates call by value
                              semantics should be used by default.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ValidateDTDs</emphasis>: a boolean flag that indicates if the
                                  <literal>ejb-jar.xml</literal> and <literal>jboss.xml</literal> descriptors should be
                              validated against their declared DTDs. Setting this to true is useful for ensuring your
                              deployment descriptors are valid.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MetricsEnabled</emphasis>: a boolean flag that controls whether
                              container interceptors marked with an <literal>metricsEnabled=true</literal> attribute
                              should be included in the configuration. This allows one to define a container interceptor
                              configuration that includes metrics type interceptors that can be toggled on and off.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">WebServiceName</emphasis>: The JMX ObjectName string of the web
                              service MBean that provides support for the dynamic class loading of EJB classes.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">TransactionManagerServiceName</emphasis>: The JMX ObjectName string of
                              the JTA transaction manager service. This must have an attribute named
                                  <literal>TransactionManager</literal> that returns that
                                  <literal>javax.transaction.TransactionManager</literal> instance.</para>
                      </listitem>
                  </itemizedlist>
                  <para>The deployer contains two central methods: deploy and undeploy. The deploy method takes a URL,
                      which either points to an EJB JAR, or to a directory whose structure is the same as a valid EJB JAR
                      (which is convenient for development purposes). Once a deployment has been made, it can be
                      undeployed by calling undeploy on the same URL. A call to deploy with an already deployed URL will
                      cause an undeploy, followed by deployment of the URL. JBoss has support for full re-deployment of
                      both implementation and interface classes, and will reload any changed classes. This will allow you
                      to develop and update EJBs without ever stopping a running server.</para>
                  <para>During the deployment of the EJB JAR the <literal>EJBDeployer</literal> and its associated classes
                      perform three main functions, verify the EJBs, create a container for each unique EJB, initialize
                      the container with the deployment configuration information. We will talk about each function in the
                      following sections.</para>
                  <section>
                      <title>Verifying EJB deployments</title>
                      <para>When the <literal>VerifyDeployments</literal> attribute of the <literal>EJBDeployer</literal>
                          is true, the deployer performs a verification of EJBs in the deployment. The verification checks
                          that an EJB meets EJB specification compliance. This entails validating that the EJB deployment
                          unit contains the required home and remote, local home and local interfaces. It will also check
                          that the objects appearing in these interfaces are of the proper types and that the required
                          methods are present in the implementation class. This is a useful behavior that is enabled by
                          default since there are a number of steps that an EJB developer and deployer must perform
                          correctly to construct a proper EJB JAR, and it is easy to make a mistake. The verification
                          stage attempts to catch any errors and fail the deployment with an error that indicates what
                          needs to be corrected.</para>
                      <para>Probably the most problematic aspect of writing EJBs is the fact that there is a disconnection
                          between the bean implementation and its remote and home interfaces, as well as its deployment
                          descriptor configuration. It is easy to have these separate elements get out of synch. One tool
                          that helps eliminate this problem is XDoclet. It allows you to use custom JavaDoc-like tags in
                          the EJB bean implementation class to generate the related bean interfaces, deployment
                          descriptors and related objects. See the XDoclet home page, <ulink
                              url="http://sourceforge.net/projects/xdoclet"/> for additional details.</para>
                  </section>
                  <section>
                      <title>Deploying EJBs Into Containers</title>
                      <para>The most important role performed by the <literal>EJBDeployer</literal> is the creation of an
                          EJB container and the deployment of the EJB into the container. The deployment phase consists of
                          iterating over EJBs in an EJB JAR, and extracting the bean classes and their metadata as
                          described by the <literal>ejb-jar.xml</literal> and <literal>jboss.xml</literal> deployment
                          descriptors. For each EJB in the EJB JAR, the following steps are performed:</para>
                      <itemizedlist>
                          <listitem>
                              <para>Create subclass of <literal>org.jboss.ejb.Container</literal> depending on the type of
                                  the EJB: stateless, stateful, BMP entity, CMP entity, or message driven. The container
                                  is assigned a unique <literal>ClassLoader</literal> from which it can load local
                                  resources. The uniqueness of the <literal>ClassLoader</literal> is also used to isolate
                                  the standard <literal>java:comp</literal> JNDI namespace from other J2EE
                              components.</para>
                          </listitem>
                          <listitem>
                              <para>Set all container configurable attributes from a merge of the
                                  <literal>jboss.xml</literal> and <literal>standardjboss.xml</literal>
                              descriptors.</para>
                          </listitem>
                          <listitem>
                              <para>Create and add the container interceptors as configured for the container.</para>
                          </listitem>
                          <listitem>
                              <para>Associate the container with an application object. This application object represents
                                  a J2EE enterprise application and may contain multiple EJBs and web contexts.</para>
                          </listitem>
                      </itemizedlist>
                      <para>If all EJBs are successfully deployed, the application is started which in turn starts all
                          containers and makes the EJBs available to clients. If any EJB fails to deploy, a deployment
                          exception is thrown and the deployment module is failed.</para>
                  </section>
                  <section>
                      <title>Container configuration information</title>
                      <para>JBoss externalizes most if not all of the setup of the EJB containers using an XML file that
                          conforms to the <literal>jboss_4_0.dtd</literal>. The section DTD that relates to container
                          configuration information is shown in <xref linkend="ch5.container-config.fig"/>.</para>
                      <figure id="ch5.container-config.fig">
                          <title>The jboss_4_0 DTD elements related to container configuration.</title>
                          <mediaobject>
                              <imageobject>
                                  <imagedata align="center" fileref="images/jboss_4_0_container_configuration.jpg"/>
                              </imageobject>
                          </mediaobject>
                      </figure>
                      <para>The <literal>container-configuration</literal> element and its subelements specify container
                          configuration settings for a type of container as given by the <literal>container-name</literal>
                          element. Each configuration specifies information such as the default invoker type, the
                          container interceptor makeup, instance caches/pools and their sizes, persistence manager,
                          security, and so on. Because this is a large amount of information that requires a detailed
                          understanding of the JBoss container architecture, JBoss ships with a standard configuration for
                          the four types of EJBs. This configuration file is called <literal>standardjboss.xml</literal>
                          and it is located in the conf directory of any configuration file set that uses EJBs. The
                          following is a sample of <literal>container-configuration</literal> from
                              <literal>standardjboss.xml</literal>.</para>
                      <programlisting>&lt;container-configuration&gt;
      &lt;container-name&gt;Standard CMP 2.x EntityBean&lt;/container-name&gt;
      &lt;call-logging&gt;false&lt;/call-logging&gt;
      &lt;invoker-proxy-binding-name&gt;entity-rmi-invoker&lt;/invoker-proxy-binding-name&gt;
      &lt;sync-on-commit-only&gt;false&lt;/sync-on-commit-only&gt;
      &lt;insert-after-ejb-post-create&gt;false&lt;/insert-after-ejb-post-create&gt;
      &lt;call-ejb-store-on-clean&gt;true&lt;/call-ejb-store-on-clean&gt;
      &lt;container-interceptors&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor&lt;/interceptor&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.LogInterceptor&lt;/interceptor&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.SecurityInterceptor&lt;/interceptor&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.TxInterceptorCMT&lt;/interceptor&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.CallValidationInterceptor&lt;/interceptor&gt;
          &lt;interceptor metricsEnabled=&quot;true&quot;&gt;
              org.jboss.ejb.plugins.MetricsInterceptor
          &lt;/interceptor&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.EntityCreationInterceptor&lt;/interceptor&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.EntityLockInterceptor&lt;/interceptor&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.EntityInstanceInterceptor&lt;/interceptor&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.EntityReentranceInterceptor&lt;/interceptor&gt;
          &lt;interceptor&gt;
               org.jboss.resource.connectionmanager.CachedConnectionInterceptor
          &lt;/interceptor&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.EntitySynchronizationInterceptor&lt;/interceptor&gt;
          &lt;interceptor&gt;org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor&lt;/interceptor&gt;
      &lt;/container-interceptors&gt;
      &lt;instance-pool&gt;org.jboss.ejb.plugins.EntityInstancePool&lt;/instance-pool&gt;
      &lt;instance-cache&gt;org.jboss.ejb.plugins.InvalidableEntityInstanceCache&lt;/instance-cache&gt;
      &lt;persistence-manager&gt;org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager&lt;/persistence-manager&gt;
      &lt;locking-policy&gt;org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock&lt;/locking-policy&gt;
      &lt;container-cache-conf&gt;
          &lt;cache-policy&gt;org.jboss.ejb.plugins.LRUEnterpriseContextCachePolicy&lt;/cache-policy&gt;
          &lt;cache-policy-conf&gt;
              &lt;min-capacity&gt;50&lt;/min-capacity&gt;
              &lt;max-capacity&gt;1000000&lt;/max-capacity&gt;
              &lt;overager-period&gt;300&lt;/overager-period&gt;
              &lt;max-bean-age&gt;600&lt;/max-bean-age&gt;
              &lt;resizer-period&gt;400&lt;/resizer-period&gt;
              &lt;max-cache-miss-period&gt;60&lt;/max-cache-miss-period&gt;
              &lt;min-cache-miss-period&gt;1&lt;/min-cache-miss-period&gt;
              &lt;cache-load-factor&gt;0.75&lt;/cache-load-factor&gt;
          &lt;/cache-policy-conf&gt;
      &lt;/container-cache-conf&gt;
      &lt;container-pool-conf&gt;
          &lt;MaximumSize&gt;100&lt;/MaximumSize&gt;
      &lt;/container-pool-conf&gt;
      &lt;commit-option&gt;B&lt;/commit-option&gt;
  &lt;/container-configuration&gt;</programlisting>
                      <para>These two examples demonstrate how extensive the container configuration options are. The
                          container configuration information can be specified at two levels. The first is in the
                              <literal>standardjboss.xml</literal> file contained in the configuration file set directory.
                          The second is at the EJB JAR level. By placing a <literal>jboss.xml</literal> file in the EJB
                          JAR <literal>META-INF</literal> directory, you can specify either overrides for container
                          configurations in the <literal>standardjboss.xml</literal> file, or entirely new named container
                          configurations. This provides great flexibility in the configuration of containers. As you have
                          seen, all container configuration attributes have been externalized and as such are easily
                          modifiable. Knowledgeable developers can even implement specialized container components, such
                          as instance pools or caches, and easily integrate them with the standard container
                          configurations to optimize behavior for a particular application or environment.</para>
                      <para>How an EJB deployment chooses its container configuration is based on the explicit or implict
                              <literal>jboss/enterprise-beans/&lt;type&gt;/configuration-name</literal> element.
                          The <literal>configuration-name</literal> element is a link to a
                              <literal>container-configurations/container-configuration</literal> element in <xref
                              linkend="ch5.container-config.fig"/>. It specifies which container configuration to use for
                          the referring EJB. The link is from a <literal>configuration-name</literal> element to a
                              <literal>container-name</literal> element. </para>
                      <para>You are able to specify container configurations per class of EJB by including a
                              <literal>container-configuration</literal> element in the EJB definition. Typically one does
                          not define completely new container configurations, although this is supported. The typical
                          usage of a <literal>jboss.xml</literal> level <literal>container-configuration</literal> is to
                          override one or more aspects of a <literal>container-configuration</literal> coming from the
                              <literal>standardjboss.xml</literal> descriptor. This is done by specifying
                              <literal>container-configuration</literal> that references the name of an existing
                              <literal>standardjboss.xml</literal>
                          <literal>container-configuration/container-name</literal> as the value for the
                              <literal>container-configuration/extends</literal> attribute. The following example shows an
                          example of defining a new <literal>Secured Stateless SessionBean</literal> configuration that is
                          an extension of the <literal>Standard Stateless SessionBean</literal> configuration.</para>
                      <programlisting>&lt;?xml version="1.0"?&gt;
  &lt;jboss&gt;
      &lt;enterprise-beans&gt;
          &lt;session&gt;
              &lt;ejb-name&gt;EchoBean&lt;/ejb-name&gt;
              &lt;configuration-name&gt;Secured Stateless SessionBean&lt;/configuration-name&gt;
              &lt;!-- ... --&gt;
          &lt;/session&gt;
      &lt;/enterprise-beans&gt;
      &lt;container-configurations&gt;
          &lt;container-configuration extends="Standard Stateless SessionBean"&gt;
              &lt;container-name&gt;Secured Stateless SessionBean&lt;/container-name&gt;
              &lt;!-- Override the container security domain --&gt;
              &lt;security-domain&gt;java:/jaas/my-security-domain&lt;/security-domain&gt;
          &lt;/container-configuration&gt;
      &lt;/container-configurations&gt;
  &lt;/jboss&gt;</programlisting>
                      <para>If an EJB does not provide a container configuration specification in the deployment unit EJB
                          JAR, the container factory chooses a container configuration from the
                          <literal>standardjboss.xml</literal> descriptor based on the type of the EJB. So, in reality
                          there is an implicit <literal>configuration-name</literal> element for every type of EJB, and
                          the mappings from the EJB type to default container configuration name are as follows:</para>
                      <itemizedlist>
                          <listitem>
                              <para>container-managed persistence entity version 2.0 = Standard CMP 2.x EntityBean</para>
                          </listitem>
                          <listitem>
                              <para>container-managed persistence entity version 1.1 = Standard CMP EntityBean</para>
                          </listitem>
                          <listitem>
                              <para>bean-managed persistence entity = Standard BMP EntityBean</para>
                          </listitem>
                          <listitem>
                              <para>stateless session = Standard Stateless SessionBean</para>
                          </listitem>
                          <listitem>
                              <para>stateful session = Standard Stateful SessionBean</para>
                          </listitem>
                          <listitem>
                              <para>message driven = Standard Message Driven Bean</para>
                          </listitem>
                      </itemizedlist>
                      <para>It is not necessary to indicate which container configuration an EJB is using if you want to
                          use the default based on the bean type. It probably provides for a more self-contained
                          descriptor to include the <literal>configuration-name</literal> element, but this is purely a
                          matter of style.</para>
                      <para>Now that you know how to specify which container configuration an EJB is using and can define
                          a deployment unit level override, we now will look at the
                          <literal>container-configuration</literal> child elements in the following sections. A number of
                          the elements specify interface class implementations whose configuration is affected by other
                          elements, so before starting in on the configuration elements you need to understand the
                              <literal>org.jboss.metadata.XmlLoadable</literal> interface.</para>
                      <para>The <literal>XmlLoadable</literal> interface is a simple interface that consists of a single
                          method. The interface definition is:</para>
                      <programlisting>import org.w3c.dom.Element;
  public interface XmlLoadable
  {
      public void importXml(Element element) throws Exception;
  }</programlisting>
                      <para>Classes implement this interface to allow their configuration to be specified via an XML
                          document fragment. The root element of the document fragment is what would be passed to the
                              <literal>importXml</literal> method. You will see a few examples of this as the container
                          configuration elements are described in the following sections.</para>
                      <section>
                          <title>The container-name element</title>
                          <para>The <literal>container-name</literal> element specifies a unique name for a given
                              configuration. EJBs link to a particular container configuration by setting their
                                  <literal>configuration-name</literal> element to the value of the
                                  <literal>container-name</literal> for the container configuration.</para>
                      </section>
                      <section>
                          <title>The call-logging element</title>
                          <para>The <literal>call-logging</literal> element expects a boolean (true or false) as its value
                              to indicate whether or not the <literal>LogInterceptor</literal> should log method calls to
                              a container. This is somewhat obsolete with the change to log4j, which provides a
                              fine-grained logging API.</para>
                      </section>
                      <section>
                          <title>The invoker-proxy-binding-name element</title>
                          <para>The <literal>invoker-proxy-binding-name</literal> element specifies the name of the
                              default invoker to use. In the absence of a bean level <literal>invoker-bindings</literal>
                              specification, the <literal>invoker-proxy-binding</literal> whose name matches the
                                  <literal>invoker-proxy-binding-name</literal> element value will be used to create home
                              and remote proxies.</para>
                      </section>
                      <section>
                          <title>The sync-on-commit-only element</title>
                          <para>This configures a performance optimization that will cause entity bean state to be
                              synchronized with the database only at commit time. Normally the state of all the beans in a
                              transaction would need to be synchronized when an finder method is called or when an remove
                              method is called, for example.</para>
                      </section>
                      <section>
                          <title>insert-after-ejb-post-create</title>
                          <para> This is another entity bean optimization which cause the database insert command for a
                              new entity bean to be delayed until the <literal>ejbPostCreate</literal> method is called.
                              This allows normal CMP fields as well as CMR fields to be set in a single insert, instead of
                              the default insert followed by an update, which allows removes the requirement for relation
                              ship fields to allow null values. </para>
                      </section>
                      <section>
                          <title>call-ejb-store-on-clean</title>
                          <para>By the specification the container is required to call <literal>ejbStore</literal> method
                              on an entity bean instance when transaction commits even if the instance was not modified in
                              the transaction. Setting this to false will cause JBoss to only call
                              <literal>ejbStore</literal> for dirty objects. </para>
                      </section>
                      <section>
                          <title>The container-interceptors Element</title>
                          <para>The <literal>container-interceptors</literal> element specifies one or more interceptor
                              elements that are to be configured as the method interceptor chain for the container. The
                              value of the interceptor element is a fully qualified class name of an
                                  <literal>org.jboss.ejb.Interceptor</literal> interface implementation. The container
                              interceptors form a <literal>linked-list</literal> structure through which EJB method
                              invocations pass. The first interceptor in the chain is invoked when the
                                  <literal>MBeanServer</literal> passes a method invocation to the container. The last
                              interceptor invokes the business method on the bean. We will discuss the
                                  <literal>Interceptor</literal> interface latter in this chapter when we talk about the
                              container plugin framework. Generally, care must be taken when changing an existing standard
                              EJB interceptor configuration as the EJB contract regarding security, transactions,
                              persistence, and thread safety derive from the interceptors.</para>
                      </section>
                      <section>
                          <title>The instance-pool element</title>
                          <para>The <literal>instance-pool</literal> element specifies the fully qualified class name of
                              an <literal>org.jboss.ejb.InstancePool</literal> interface implementation to use as the
                              container <literal>InstancePool</literal>. We will discuss the InstancePool interface in
                              detail latter in this chapter when we talk about the container plugin framework.</para>
                      </section>
                      <section>
                          <title>The container-pool-conf element</title>
                          <para>The <literal>container-pool-conf</literal> is passed to the
                              <literal>InstancePool</literal> implementation class given by the
                              <literal>instance-pool</literal> element if it implements the <literal>XmlLoadable</literal>
                              interface. All current JBoss <literal>InstancePool</literal> implementations derive from the
                                  <literal>org.jboss.ejb.plugins.AbstractInstancePool</literal> class which provides
                              support for elements shown in <xref linkend="ch5.container-pool.fig"/>. </para>
                          <figure id="ch5.container-pool.fig">
                              <title>The container-pool-conf element DTD</title>
                              <mediaobject>
                                  <imageobject>
                                      <imagedata fileref="images/jboss_4_0_container_pool_conf.jpg"/>
                                  </imageobject>
                              </mediaobject>
                          </figure>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">MinimumSize</emphasis>: The <literal>MinimumSize</literal>
                                      element gives the minimum number of instances to keep in the pool, although JBoss
                                      does not currently seed an <literal>InstancePool</literal> to the
                                          <literal>MinimumSize</literal> value.</para>
                              </listitem>
                              <listitem>
                                  <para><emphasis role="bold">MaximumSize</emphasis>: The <literal>MaximumSize</literal>
                                      specifies the maximum number of pool instances that are allowed. The default use of
                                          <literal>MaximumSize</literal> may not be what you expect. The pool
                                          <literal>MaximumSize</literal> is the maximum number of EJB instances that are
                                      kept available, but additional instances can be created if the number of concurrent
                                      requests exceeds the <literal>MaximumSize</literal> value. </para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">strictMaximumSize</emphasis>: If you want to limit the maximum
                                      concurrency of an EJB to the pool <literal>MaximumSize</literal>, you need to set
                                      the <literal>strictMaximumSize</literal> element to true. When
                                          <literal>strictMaximumSize</literal> is true, only
                                      <literal>MaximumSize</literal> EJB instances may be active. When there are
                                          <literal>MaximumSize</literal> active instances, any subsequent requests will be
                                      blocked until an instance is freed back to the pool. The default value for
                                          <literal>strictMaximumSize</literal> is false. </para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">strictTimeout</emphasis>: How long a request blocks waiting
                                      for an instance pool object is controlled by the <literal>strictTimeout</literal>
                                      element. The <literal>strictTimeout</literal> defines the time in milliseconds to
                                      wait for an instance to be returned to the pool when there are
                                      <literal>MaximumSize</literal> active instances. A value less than or equal to 0
                                      will mean not to wait at all. When a request times out waiting for an instance a
                                          <literal>java.rmi.ServerException</literal> is generated and the call aborted.
                                      This is parsed as a <literal>Long</literal> so the maximum possible wait time is
                                      9,223,372,036,854,775,807 or about 292,471,208 years, and this is the default
                                  value.</para>
                              </listitem>
                          </itemizedlist>
                      </section>
                      <section>
                          <title>The instance-cache element</title>
                          <para>The <literal>instance-cache</literal> element specifies the fully qualified class name of
                              the <literal>org.jboss.ejb.InstanceCache</literal> interface implementation. This element is
                              only meaningful for entity and stateful session beans as these are the only EJB types that
                              have an associated identity. We will discuss the <literal>InstanceCache</literal> interface
                              in detail latter in this chapter when we talk about the container plugin framework.</para>
                      </section>
                      <section>
                          <title>The container-cache-conf element</title>
                          <para>The <literal>container-cache-conf</literal> element is passed to the
                                  <literal>InstanceCache</literal> implementation if it supports the
                              <literal>XmlLoadable</literal> interface. All current JBoss <literal>InstanceCache</literal>
                              implementations derive from the
                              <literal>org.jboss.ejb.plugins.AbstractInstanceCache</literal> class which provides support
                              for the <literal>XmlLoadable</literal> interface and uses the
                              <literal>cache-policy</literal> child element as the fully qualified class name of an
                                  <literal>org.jboss.util.CachePolicy</literal> implementation that is used as the
                              instance cache store. The <literal>cache-policy-conf</literal> child element is passed to
                              the <literal>CachePolicy</literal> implementation if it supports the
                              <literal>XmlLoadable</literal> interface. If it does not, the
                              <literal>cache-policy-conf</literal> will silently be ignored.</para>
                          <para>There are two JBoss implementations of CachePolicy used by the
                              <literal>standardjboss.xml</literal> configuration that support the current array of
                                  <literal>cache-policy-conf</literal> child elements. The classes are
                                  <literal>org.jboss.ejb.plugins.LRUEnterpriseContextCachePolicy</literal> and
                                  <literal>org.jboss.ejb.plugins.LRUStatefulContextCachePolicy</literal>. The
                                  <literal>LRUEnterpriseContextCachePolicy</literal> is used by entity bean containers
                              while the <literal>LRUStatefulContextCachePolicy</literal> is used by stateful session bean
                              containers. Both cache policies support the following <literal>cache-policy-conf</literal>
                              child elements, shown in <xref linkend="ch5.container-cache.fig"/>.</para>
                          <figure id="ch5.container-cache.fig">
                              <title>The container-cache-conf element DTD</title>
                              <mediaobject>
                                  <imageobject>
                                      <imagedata fileref="images/jboss_4_0_container_cache_conf.jpg"/>
                                  </imageobject>
                              </mediaobject>
                          </figure>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">min-capacity</emphasis>: specifies the minimum capacity of
                                      this cache</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">max-capacity</emphasis>: specifies the maximum capacity of the
                                      cache, which cannot be less than <literal>min-capacity</literal>.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">overager-period</emphasis>: specifies the period in seconds
                                      between runs of the overager task. The purpose of the overager task is to see if the
                                      cache contains beans with an age greater than the <literal>max-bean-age</literal>
                                      element value. Any beans meeting this criterion will be passivated.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">max-bean-age</emphasis>: specifies the maximum period of
                                      inactivity in seconds a bean can have before it will be passivated by the overager
                                      process.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">resizer-period</emphasis>: specifies the period in seconds
                                      between runs of the resizer task. The purpose of the resizer task is to contract or
                                      expand the cache capacity based on the remaining three element values in the
                                      following way. When the resizer task executes it checks the current period between
                                      cache misses, and if the period is less than the
                                      <literal>min-cache-miss-period</literal> value the cache is expanded up to the
                                          <literal>max-capacity</literal> value using the
                                      <literal>cache-load-factor</literal>. If instead the period between cache misses is
                                      greater than the <literal>max-cache-miss-period</literal> value the cache is
                                      contracted using the <literal>cache-load-factor</literal>.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">max-cache-miss-period</emphasis>: specifies the time period in
                                      seconds in which a cache miss should signal that the cache capacity be contracted.
                                      It is equivalent to the minimum miss rate that will be tolerated before the cache is
                                      contracted.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">min-cache-miss-period</emphasis>: specifies the time period in
                                      seconds in which a cache miss should signal that the cache capacity be expanded. It
                                      is equivalent to the maximum miss rate that will be tolerated before the cache is
                                      expanded.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">cache-load-factor</emphasis>: specifies the factor by which
                                      the cache capacity is contracted and expanded. The factor should be less than 1.
                                      When the cache is contracted the capacity is reduced so that the current ratio of
                                      beans to cache capacity is equal to the cache-load-factor value. When the cache is
                                      expanded the new capacity is determined as <literal>current-capacity *
                                          1/cache-load-factor</literal>. The actual expansion factor may be as high as 2
                                      based on an internal algorithm based on the number of cache misses. The higher the
                                      cache miss rate the closer the true expansion factor will be to 2.</para>
                              </listitem>
                          </itemizedlist>
                          <para>The <literal>LRUStatefulContextCachePolicy</literal> also supports the remaining child
                              elements:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">remover-period</emphasis>: specifies the period in seconds
                                      between runs of the remover task. The remover task removes passivated beans that
                                      have not been accessed in more than <literal>max-bean-life</literal> seconds. This
                                      task prevents stateful session beans that were not removed by users from filling up
                                      the passivation store.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">max-bean-life</emphasis>: specifies the maximum period of
                                      inactivity in seconds that a bean can exist before being removed from the
                                      passivation store.</para>
                              </listitem>
                          </itemizedlist>
                          <para>An alternative cache policy implementation is the
                                  <literal>org.jboss.ejb.plugins.NoPassivationCachePolicy</literal> class, which simply
                              never passivates instances. It uses an in-memory <literal>HashMap</literal> implementation
                              that never discards instances unless they are explicitly removed. This class does not
                              support any of the <literal>cache-policy-conf</literal> configuration elements.</para>
                      </section>
                      <section>
                          <title>The persistence-manager element</title>
                          <para>The <literal>persistence-manager</literal> element value specifies the fully qualified
                              class name of the persistence manager implementation. The type of the implementation depends
                              on the type of EJB. For stateful session beans it must be an implementation of the
                                  <literal>org.jboss.ejb.StatefulSessionPersistenceManager</literal> interface. For BMP
                              entity beans it must be an implementation of the
                                  <literal>org.jboss.ejb.EntityPersistenceManager</literal> interface, while for CMP
                              entity beans it must be an implementation of the
                                  <literal>org.jboss.ejb.EntityPersistenceStore</literal> interface.</para>
                      </section>
                      <section>
                          <title>The web-class-loader Element</title>
                          <para>The <literal>web-class-loader</literal> element specifies a subclass of
                                  <literal>org.jboss.web.WebClassLoader</literal> that is used in conjunction with the
                                  <literal>WebService</literal> MBean to allow dynamic loading of resources and classes
                              from deployed ears, EJB JARs and WARs. A <literal>WebClassLoader</literal> is associated
                              with a <literal>Container</literal> and must have an
                                  <literal>org.jboss.mx.loading.UnifiedClassLoader</literal> as its parent. It overrides
                              the <literal>getURLs()</literal> method to return a different set of URLs for remote loading
                              than what is used for local loading.</para>
                          <para>
                              <literal>WebClaossLoader</literal> has two methods meant to be overridden by subclasses:
                                  <literal>getKey()</literal> and <literal>getBytes()</literal>. The latter is a no-op in
                              this implementation and should be overridden by subclasses with bytecode generation ability,
                              such as the classloader used by the iiop module.</para>
                          <para>
                              <literal>WebClassLoader</literal> subclasses must have a constructor with the same signature
                              as the <literal>WebClassLoader(ObjectName containerName, UnifiedClassLoader
                              parent)</literal> constructor.</para>
                      </section>
                      <section>
                          <title>The locking-policy element</title>
                          <para>The <literal>locking-policy</literal> element gives the fully qualified class name of the
                              EJB lock implementation to use. This class must implement the
                                  <literal>org.jboss.ejb.BeanLock</literal> interface. The current JBoss versions include:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <emphasis role="bold"
                                      >org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock</emphasis>: an implementation
                                      that holds threads awaiting the transactional lock to be freed in a fair FIFO queue.
                                      Non-transactional threads are also put into this wait queue as well. This class pops
                                      the next waiting transaction from the queue and notifies only those threads waiting
                                      associated with that transaction. The <literal>QueuedPessimisticEJBLock</literal> is
                                      the current default used by the standard configurations.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold"
                                      >org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLockNoADE</emphasis>: This behaves
                                      the same as the <literal>QueuedPessimisticEJBLock</literal> except that deadlock
                                      detection is disabled. </para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">org.jboss.ejb.plugins.lock.SimpleReadWriteEJBLock</emphasis>:
                                      This lock allows multiple read locks concurrently. Once a writer has requested the
                                      lock, future read-lock requests whose transactions do not already have the read lock
                                      will block until all writers are done; then all the waiting readers will
                                      concurrently go (depending on the reentrant setting / methodLock). A reader who
                                      promotes gets first crack at the write lock, ahead of other waiting writers. If
                                      there is already a reader that is promoting, we throw an inconsistent read
                                      exception. Of course, writers have to wait for all read-locks to release before
                                      taking the write lock.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">org.jboss.ejb.plugins.lock.NoLock</emphasis>: an anti-locking
                                      policy used with the instance per transaction container configurations.</para>
                              </listitem>
                          </itemizedlist>
                          <para>Locking and deadlock detection will be discussed in more detail in <xref
                                  linkend="ch5.entitylock.sect"/>.</para>
                      </section>
                      <section>
                          <title>The commit-option and optiond-refresh-rate elements</title>
                          <para>The commit-option value specifies the EJB entity bean persistent storage commit option. It
                              must be one of <literal>A</literal>, <literal>B</literal>, <literal>C</literal> or
                                  <literal>D</literal>. </para>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">A</emphasis>: the container caches the beans state between
                                      transactions. This option assumes that the container is the only user accessing the
                                      persistent store. This assumption allows the container to synchronize the in-memory
                                      state from the persistent storage only when absolutely necessary. This occurs before
                                      the first business method executes on a found bean or after the bean is passivated
                                      and reactivated to serve another business method. This behavior is independent of
                                      whether the business method executes inside a transaction context.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">B</emphasis>: the container caches the bean state between
                                      transactions. However, unlike option <literal>A</literal> the container does not
                                      assume exclusive access to the persistent store. Therefore, the container will
                                      synchronize the in-memory state at the beginning of each transaction. Thus, business
                                      methods executing in a transaction context don't see much benefit from the container
                                      caching the bean, whereas business methods executing outside a transaction context
                                      (transaction attributes Never, NotSupported or Supports) access the cached (and
                                      potentially invalid) state of the bean.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">C</emphasis>: the container does not cache bean instances. The
                                      in-memory state must be synchronized on every transaction start. For business
                                      methods executing outside a transaction the synchronization is still performed, but
                                      the <literal>ejbLoad</literal> executes in the same transaction context as that of
                                      the caller.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">D</emphasis>: is a JBoss-specific commit option which is not
                                      described in the EJB specification. It is a lazy read scheme where bean state is
                                      cached between transactions as with option <literal>A</literal>, but the state is
                                      periodically resynchronized with that of the persistent store. The default time
                                      between reloads is 30 seconds, but may configured using the
                                          <literal>optiond-refresh-rate</literal> element.</para>
                              </listitem>
                          </itemizedlist>
                      </section>
                      <section>
                          <title>The security-domain element</title>
                          <para>The <literal>security-domain</literal> element specifies the JNDI name of the object that
                              implements the <literal>org.jboss.security.AuthenticationManager</literal> and
                                  <literal>org.jboss.security.RealmMapping</literal> interfaces. It is more typical to
                              specify the <literal>security-domain</literal> under the <literal>jboss</literal> root
                              element so that all EJBs in a given deployment are secured in the same manner. However, it
                              is possible to configure the security domain for each bean configuration. The details of the
                              security manager interfaces and configuring the security layer are discussed in <xref
                                  linkend="ch8.chapter"/>.</para>
                      </section>
                      <section>
                          <title>cluster-config</title>
                          <para>The <literal>cluster-config</literal> element allows to specify cluster specific settings
                              for all EJBs that use the container configuration. Specficiation of the cluster
                              configuration may be done at the container configuration level or at the individual EJB
                              deployment level.</para>
                          <figure>
                              <title>The cluster-config and related elements</title>
                              <mediaobject>
                                  <imageobject>
                                      <imagedata align="center" fileref="images/jboss_4_0_cluster_config.jpg"/>
                                  </imageobject>
                              </mediaobject>
                          </figure>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">partition-name</emphasis>: The
                                      <literal>partition-name</literal> element indicates where to find the
                                          <literal>org.jboss.ha.framework.interfaces.HAPartition</literal> interface to be
                                      used by the container to exchange clustering information. This is not the full JNDI
                                      name under which <literal>HAPartition</literal> is bound. Rather, it should
                                      correspond to the <literal>PartitionName</literal> attribute of the
                                          <literal>ClusterPartitionMBean</literal> service that is managing the desired
                                      cluster. The actual JNDI name of the <literal>HAPartition</literal> binding will be
                                      formed by appending <literal>/HASessionState/</literal> to the partition-name value.
                                      The default value is <literal>DefaultPartition</literal>.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">home-load-balance-policy</emphasis>: The
                                          <literal>home-load-balance-policy</literal> element indicates the Java class
                                      name to be used to load balance calls made on the home proxy. The class must
                                      implement the <literal>org.jboss.ha.framework.interface.LoadBalancePolicy</literal>
                                      interface. The default policy is
                                          <literal>org.jboss.ha.framework.interfaces.RoundRobin</literal>.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">bean-load-balance-policy</emphasis>: The
                                          <literal>bean-load-balance-policy</literal> element indicates the java class
                                      name to be used to load balance calls in the bean proxy. The class must implement
                                      the <literal>org.jboss.ha.framework.interface.LoadBalancePolicy</literal> interface.
                                      For entity beans and stateful session beans, the default is
                                          <literal>org.jboss.ha.framework.interfaces.FirstAvailavble</literal>. For
                                      stateless session beans,
                                      <literal>org.jboss.ha.framework.interfaces.RoundRobin</literal>. </para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">session-state-manager-jndi-name</emphasis>: The
                                          <literal>session-state-manager-jndi-name</literal> element indicates the name of
                                      the <literal>org.jboss.ha.framework.interfaces.HASessionState</literal> to be used
                                      by the container as a backend for state session management in the cluster. Unlike
                                      the partition-name element, this is a JNDI name under which the
                                          <literal>HASessionState</literal> implementation is bound. The default location
                                      used is <literal>/HASessionState/Default</literal>.</para>
                              </listitem>
                          </itemizedlist>
                      </section>
                      <section>
                          <title>The depends element</title>
                          <para>The <literal>depends</literal> element gives a JMX <literal>ObjectName</literal> of a
                              service on which the container or EJB depends. Specification of explicit dependencies on
                              other services avoids having to rely on the deployment order being after the required
                              services are started.</para>
                      </section>
                  </section>
              </section>
              <section>
                  <title>Container Plug-in Framework </title>
                  <para>The JBoss EJB container uses a framework pattern that allows one to change implementations of
                      various aspects of the container behavior. The container itself does not perform any significant
                      work other than connecting the various behavioral components together. Implementations of the
                      behavioral components are referred to as plugins, because you can plug in a new implementation by
                      changing a container configuration. Examples of plug-in behavior you may want to change include
                      persistence management, object pooling, object caching, container invokers and interceptors. There
                      are four subclasses of the <literal>org.jboss.ejb.Container</literal> class, each one implementing a
                      particular bean type:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">org.jboss.ejb.EntityContainer</emphasis>: handles
                                  <literal>javax.ejb.EntityBean</literal> types</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">org.jboss.ejb.StatelessSessionContainer</emphasis>: handles Stateless
                                  <literal>javax.ejb.SessionBean</literal> types</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">org.jboss.ejb.StatefulSessionContainer</emphasis>: handles Stateful
                                  <literal>javax.ejb.SessionBean</literal> types</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">org.jboss.ejb.MessageDrivenContainer</emphasis> handles
                                  <literal>javax.ejb.MessageDrivenBean</literal> types </para>
                      </listitem>
                  </itemizedlist>
                  <para>The EJB containers delegate much of their behavior to components known as container plug-ins. The
                      interfaces that make up the container plugin points include the following:</para>
                  <itemizedlist spacing="compact">
                      <listitem>
                          <para>org.jboss.ejb.ContainerPlugin</para>
                      </listitem>
                      <listitem>
                          <para>org.jboss.ejb.ContainerInvoker</para>
                      </listitem>
                      <listitem>
                          <para>org.jboss.ejb.Interceptor</para>
                      </listitem>
                      <listitem>
                          <para>org.jboss.ejb.InstancePool</para>
                      </listitem>
                      <listitem>
                          <para>org.jboss.ejb.InstanceCache</para>
                      </listitem>
                      <listitem>
                          <para>org.jboss.ejb.EntityPersistanceManager</para>
                      </listitem>
                      <listitem>
                          <para>org.jboss.ejb.EntityPersistanceStore</para>
                      </listitem>
                      <listitem>
                          <para>org.jboss.ejb.StatefulSessionPersistenceManager</para>
                      </listitem>
                  </itemizedlist>
                  <para>The container's main responsibility is to manage its plug-ins. This means ensuring that the
                      plug-ins have all the information they need to implement their functionality.</para>
                  <section>
                      <title>org.jboss.ejb.ContainerPlugin</title>
                      <para>The <literal>ContainerPlugin</literal> interface is the parent interface of all container
                          plug-in interfaces. It provides a callback that allows a container to provide each of its
                          plug-ins a pointer to the container the plug-in is working on behalf of. The
                              <literal>ContainerPlugin</literal> interface is given below.</para>
                      <example>
                          <title>The org.jboss.ejb.ContainerPlugin interface</title>
                          <programlisting>public interface ContainerPlugin
      extends Service, AllowedOperationsFlags
  {
      /** 
       * This callback is set by the container so that the plugin
       * may access its container
       *
       * @param con the container which owns the plugin
       */
      public void setContainer(Container con);
  }   </programlisting>
                      </example>
                  </section>
                  <section>
                      <title>org.jboss.ejb.Interceptor</title>
                      <para>The <literal>Interceptor</literal> interface enables one to build a chain of method
                          interceptors through which each EJB method invocation must pass. The
                          <literal>Interceptor</literal> interface is given below.</para>
                      <example>
                          <title>The org.jboss.ejb.Interceptor interface</title>
                          <programlisting>import org.jboss.invocation.Invocation;
                      
  public interface Interceptor 
      extends ContainerPlugin
  {
      public void setNext(Interceptor interceptor);
      public Interceptor getNext();
      public Object invokeHome(Invocation mi) throws Exception;
      public Object invoke(Invocation mi) throws Exception;
  } </programlisting>
                      </example>
                      <para>All interceptors defined in the container configuration are created and added to the container
                          interceptor chain by the <literal>EJBDeployer</literal>. The last interceptor is not added by
                          the deployer but rather by the container itself because this is the interceptor that interacts
                          with the EJB bean implementation.</para>
                      <para>The order of the interceptor in the chain is important. The idea behind ordering is that
                          interceptors that are not tied to a particular <literal>EnterpriseContext</literal> instance are
                          positioned before interceptors that interact with caches and pools.</para>
                      <para>Implementers of the <literal>Interceptor</literal> interface form a linked-list like structure
                          through which the <literal>Invocation</literal> object is passed. The first interceptor in the
                          chain is invoked when an invoker passes a <literal>Invocation</literal> to the container via the
                          JMX bus. The last interceptor invokes the business method on the bean. There are usually on the
                          order of five interceptors in a chain depending on the bean type and container configuration.
                              <literal>Interceptor</literal> semantic complexity ranges from simple to complex. An example
                          of a simple interceptor would be <literal>LoggingInterceptor</literal>, while a complex example
                          is <literal>EntitySynchronizationInterceptor</literal>.</para>
                      <para>One of the main advantages of an interceptor pattern is flexibility in the arrangement of
                          interceptors. Another advantage is the clear functional distinction between different
                          interceptors. For example, logic for transaction and security is cleanly separated between the
                              <literal>TXInterceptor</literal> and <literal>SecurityInterceptor</literal> respectively.</para>
                      <para>If any of the interceptors fail, the call is terminated at that point. This is a fail-quickly
                          type of semantic. For example, if a secured EJB is accessed without proper permissions, the call
                          will fail as the <literal>SecurityInterceptor</literal> before any transactions are started or
                          instances caches are updated.</para>
                  </section>
                  <section>
                      <title>org.jboss.ejb.InstancePool</title>
                      <para>An <literal>InstancePool</literal> is used to manage the EJB instances that are not associated
                          with any identity. The pools actually manage subclasses of the
                              <literal>org.jboss.ejb.EnterpriseContext</literal> objects that aggregate unassociated bean
                          instances and related data.</para>
                      <example>
                          <title> The org.jboss.ejb.InstancePool interface</title>
                          <programlisting>public interface InstancePool
      extends ContainerPlugin
  {
      /** 
       * Get an instance without identity. Can be used
       * by finders and create-methods, or stateless beans
       *
       * @return Context /w instance
       * @exception RemoteException
       */
      public EnterpriseContext get() throws Exception;
      
      /** Return an anonymous instance after invocation.
       *
       * @param ctx
       */
      public void free(EnterpriseContext ctx);
      
      /**
       * Discard an anonymous instance after invocation.
       * This is called if the instance should not be reused,
       * perhaps due to some exception being thrown from it.
       *
       * @param ctx
       */
      public void discard(EnterpriseContext ctx);
      
      /**
       * Return the size of the pool.
       *
       * @return the size of the pool.
       */
      public int getCurrentSize();
      
      /**
       * Get the maximum size of the pool.
       *
       * @return the size of the pool.
       */
      public int getMaxSize();
  }</programlisting>
                      </example>
                      <para>Depending on the configuration, a container may choose to have a certain size of the pool
                          contain recycled instances, or it may choose to instantiate and initialize an instance on
                          demand.</para>
                      <para>The pool is used by the <literal>InstanceCache</literal> implementation to acquire free
                          instances for activation, and it is used by interceptors to acquire instances to be used for
                          Home interface methods (create and finder calls).</para>
                  </section>
                  <section>
                      <title>org.jboss.ebj.InstanceCache</title>
                      <para>The container <literal>InstanceCache</literal> implementation handles all EJB-instances that
                          are in an active state, meaning bean instances that have an identity attached to them. Only
                          entity and stateful session beans are cached, as these are the only bean types that have state
                          between method invocations. The cache key of an entity bean is the bean primary key. The cache
                          key for a stateful session bean is the session id. </para>
                      <example>
                          <title>The org.jboss.ejb.InstanceCache interface</title>
                          <programlisting>public interface InstanceCache 
      extends ContainerPlugin
  {
      /**
       * Gets a bean instance from this cache given the identity.
       * This method may involve activation if the instance is not
       * in the cache.
       * Implementation should have O(1) complexity.
       * This method is never called for stateless session beans.
       *
       * @param id the primary key of the bean
       * @return the EnterpriseContext related to the given id
       * @exception RemoteException in case of illegal calls
       * (concurrent / reentrant), NoSuchObjectException if
       * the bean cannot be found.
       * @see #release
       */
      public EnterpriseContext get(Object id)
  	throws RemoteException, NoSuchObjectException;
      
      /**
       * Inserts an active bean instance after creation or activation.
       * Implementation should guarantee proper locking and O(1) complexity.
       *
       * @param ctx the EnterpriseContext to insert in the cache
       * @see #remove
       */
      public void insert(EnterpriseContext ctx);
      
      /**
       * Releases the given bean instance from this cache.
       * This method may passivate the bean to get it out of the cache.
       * Implementation should return almost immediately leaving the
       * passivation to be executed by another thread.
       *
       * @param ctx the EnterpriseContext to release
       * @see #get
       */
      public void release(EnterpriseContext ctx);
      
      /**
       * Removes a bean instance from this cache given the identity.
       * Implementation should have O(1) complexity and guarantee
       * proper locking.
       *
       * @param id the pimary key of the bean
       * @see #insert
       */
      public void remove(Object id);
      
      /**
       * Checks whether an instance corresponding to a particular
       * id is active
       *
       * @param id the pimary key of the bean
       * @see #insert
       */
      public boolean isActive(Object id);    
  }</programlisting>
                      </example>
                      <para>In addition to managing the list of active instances, the <literal>InstanceCache</literal> is
                          also responsible for activating and passivating instances. If an instance with a given identity
                          is requested, and it is not currently active, the <literal>InstanceCache</literal> must use the
                              <literal>InstancePool</literal> to acquire a free instance, followed by the persistence
                          manager to activate the instance. Similarly, if the <literal>InstanceCache</literal> decides to
                          passivate an active instance, it must call the persistence manager to passivate it and release
                          the instance to the <literal>InstancePool</literal>.</para>
                  </section>
                  <section>
                      <title>org.jboss.ejb.EntityPersistenceManager</title>
                      <para>The <literal>EntityPersistenceManager</literal> is responsible for the persistence of
                          EntityBeans. This includes the following:</para>
                      <itemizedlist spacing="compact">
                          <listitem>
                              <para>Creating an EJB instance in a storage</para>
                          </listitem>
                          <listitem>
                              <para>Loading the state of a given primary key into an EJB instance</para>
                          </listitem>
                          <listitem>
                              <para>Storing the state of a given EJB instance</para>
                          </listitem>
                          <listitem>
                              <para>Removing an EJB instance from storage</para>
                          </listitem>
                          <listitem>
                              <para>Activating the state of an EJB instance</para>
                          </listitem>
                          <listitem>
                              <para>Passivating the state of an EJB instance</para>
                          </listitem>
                      </itemizedlist>
                      <example>
                          <title> The org.jboss.ejb.EntityPersistenceManager interface</title>
                          <programlisting>public interface EntityPersistenceManager 
      extends ContainerPlugin
  {
      /**
       * Returns a new instance of the bean class or a subclass of the
       * bean class.
       *
       * @return the new instance
       */
      Object createBeanClassInstance() throws Exception;
                      
      /**
       * This method is called whenever an entity is to be created. The
       * persistence manager is responsible for calling the ejbCreate method
       * on the instance and to handle the results properly wrt the persistent
       * store.
       *
       * @param m the create method in the home interface that was
       * called
       * @param args any create parameters
       * @param instance the instance being used for this create call
       */
      void createEntity(Method m,
  		      Object[] args,
  		      EntityEnterpriseContext instance)
  	throws Exception;
      
      /**
       * This method is called whenever an entity is to be created. The
       * persistence manager is responsible for calling the ejbPostCreate method
       * on the instance and to handle the results properly wrt the persistent
       * store.
       *
       * @param m the create method in the home interface that was
       * called
       * @param args any create parameters
       * @param instance the instance being used for this create call
       */
      void postCreateEntity(Method m,
  			  Object[] args,
  			  EntityEnterpriseContext instance)
  	throws Exception;
      
      /**
       * This method is called when single entities are to be found. The
       * persistence manager must find out whether the wanted instance is
       * available in the persistence store, and if so it shall use the
       * ContainerInvoker plugin to create an EJBObject to the instance, which
       * is to be returned as result.
       *
       * @param finderMethod the find method in the home interface that was
       * called
       * @param args any finder parameters
       * @param instance the instance to use for the finder call
       * @return an EJBObject representing the found entity
       */
      Object findEntity(Method finderMethod,
  		      Object[] args,
  		      EntityEnterpriseContext instance)
  	throws Exception;
      
      /**
       * This method is called when collections of entities are to be
       * found. The persistence manager must find out whether the wanted
       * instances are available in the persistence store, and if so it
       * shall use the ContainerInvoker plugin to create EJBObjects to
       * the instances, which are to be returned as result.
       *
       * @param finderMethod the find method in the home interface that was
       * called
       * @param args any finder parameters
       * @param instance the instance to use for the finder call
       * @return an EJBObject collection representing the found
       * entities
       */
      Collection findEntities(Method finderMethod,
  			    Object[] args,
  			    EntityEnterpriseContext instance)
                       throws Exception;
      
      /**
       * This method is called when an entity shall be activated. The
       * persistence manager must call the ejbActivate method on the
       * instance.
       *
       * @param instance the instance to use for the activation
       *
       * @throws RemoteException thrown if some system exception occurs
       */
      void activateEntity(EntityEnterpriseContext instance)
  	throws RemoteException;
                      
      /**
       * This method is called whenever an entity shall be load from the
       * underlying storage. The persistence manager must load the state
       * from the underlying storage and then call ejbLoad on the
       * supplied instance.
       *
       * @param instance the instance to synchronize
       *
       * @throws RemoteException thrown if some system exception occurs
       */
      void loadEntity(EntityEnterpriseContext instance)
  	throws RemoteException;
      
      /**
       * This method is used to determine if an entity should be stored.
       *
       * @param instance the instance to check
       * @return true, if the entity has been modified
       * @throws Exception thrown if some system exception occurs
       */
      boolean isModified(EntityEnterpriseContext instance) throws Exception;
      
      /**
       * This method is called whenever an entity shall be stored to the
       * underlying storage. The persistence manager must call ejbStore
       * on the supplied instance and then store the state to the
       * underlying storage.
       *
       * @param instance the instance to synchronize
       *
       * @throws RemoteException thrown if some system exception occurs
       */
      void storeEntity(EntityEnterpriseContext instance)
  	throws RemoteException;
      
      /**
       * This method is called when an entity shall be passivate. The
       * persistence manager must call the ejbPassivate method on the
       * instance.
       *
       * @param instance the instance to passivate
       *
       * @throws RemoteException thrown if some system exception occurs
       */
      void passivateEntity(EntityEnterpriseContext instance)
  	throws RemoteException;
      
      /**
       * This method is called when an entity shall be removed from the
       * underlying storage. The persistence manager must call ejbRemove
       * on the instance and then remove its state from the underlying
       * storage.
       *
       * @param instance the instance to remove
       *
       * @throws RemoteException thrown if some system exception occurs
       * @throws RemoveException thrown if the instance could not be removed
       */
      void removeEntity(EntityEnterpriseContext instance)
  	throws RemoteException, RemoveException;
  }</programlisting>
                      </example>
                  </section>
                  <section>
                      <title>The org.jboss.ejb.EntityPersistenceStore interface</title>
                      <para>As per the EJB 2.1 specification, JBoss supports two entity bean persistence semantics:
                          container managed persistence (CMP) and bean managed persistence (BMP). The CMP implementation
                          uses an implementation of the <literal>org.jboss.ejb.EntityPersistanceStore</literal> interface.
                          By default this is the <literal>org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager</literal> which
                          is the entry point for the CMP2 persistence engine. The
                          <literal>EntityPersistanceStore</literal> interface is shown below.</para>
                      <example>
                          <title> The org.jboss.ejb.EntityPersistanceStore interface</title>
                          <programlisting>public interface EntityPersistenceStore 
      extends ContainerPlugin
  {
      /**
       * Returns a new instance of the bean class or a subclass of the
       * bean class.
       *
       * @return the new instance
       *
       * @throws Exception
       */
      Object createBeanClassInstance() 
          throws Exception;
      
      /**
       * Initializes the instance context.
       *
       * &lt;p&gt;This method is called before createEntity, and should
       * reset the value of all cmpFields to 0 or null.
       *
       * @param ctx
       *
       * @throws RemoteException
       */
      void initEntity(EntityEnterpriseContext ctx);
      
      /**
       * This method is called whenever an entity is to be created.  The
       * persistence manager is responsible for handling the results
       * properly wrt the persistent store.
       *
       * @param m the create method in the home interface that was
       * called
       * @param args any create parameters
       * @param instance the instance being used for this create call
       * @return The primary key computed by CMP PM or null for BMP
       *
       * @throws Exception
       */
      Object createEntity(Method m,
  			Object[] args,
  			EntityEnterpriseContext instance)
          throws Exception;
      
      /**
       * This method is called when single entities are to be found. The
       * persistence manager must find out whether the wanted instance
       * is available in the persistence store, if so it returns the
       * primary key of the object.
       *
       * @param finderMethod the find method in the home interface that was
       * called
       * @param args any finder parameters
       * @param instance the instance to use for the finder call
       * @return a primary key representing the found entity
       *
       * @throws RemoteException thrown if some system exception occurs
       * @throws FinderException thrown if some heuristic problem occurs
       */
      Object findEntity(Method finderMethod,
  		      Object[] args,
  		      EntityEnterpriseContext instance)
          throws Exception;
      
      /**
       * This method is called when collections of entities are to be
       * found. The persistence manager must find out whether the wanted
       * instances are available in the persistence store, and if so it
       * must return a collection of primaryKeys.
       *
       * @param finderMethod the find method in the home interface that was
       * called
       * @param args any finder parameters
       * @param instance the instance to use for the finder call
       * @return an primary key collection representing the found
       * entities
       *
       * @throws RemoteException thrown if some system exception occurs
       * @throws FinderException thrown if some heuristic problem occurs
       */
      Collection findEntities(Method finderMethod,
  			    Object[] args,
  			    EntityEnterpriseContext instance)
          throws Exception;
      
      /**
       * This method is called when an entity shall be activated.
       *
       * &lt;p&gt;With the PersistenceManager factorization most EJB
       * calls should not exists However this calls permits us to
       * introduce optimizations in the persistence store. Particularly
       * the context has a "PersistenceContext" that a PersistenceStore
       * can use (JAWS does for smart updates) and this is as good a
       * callback as any other to set it up.
       * @param instance the instance to use for the activation
       *
       * @throws RemoteException thrown if some system exception occurs
       */
      void activateEntity(EntityEnterpriseContext instance)
          throws RemoteException;
      
      /**
       * This method is called whenever an entity shall be load from the
       * underlying storage. The persistence manager must load the state
       * from the underlying storage and then call ejbLoad on the
       * supplied instance.
       *
       * @param instance the instance to synchronize
       *
       * @throws RemoteException thrown if some system exception occurs
       */
      void loadEntity(EntityEnterpriseContext instance)
          throws RemoteException;
      
      /**
       * This method is used to determine if an entity should be stored.
       *
       * @param instance the instance to check
       * @return true, if the entity has been modified
       * @throws Exception thrown if some system exception occurs
       */
      boolean isModified(EntityEnterpriseContext instance)
          throws Exception;
      
      /**
       * This method is called whenever an entity shall be stored to the
       * underlying storage. The persistence manager must call ejbStore
       * on the supplied instance and then store the state to the
       * underlying storage.
       *
       * @param instance the instance to synchronize
       *
       * @throws RemoteException thrown if some system exception occurs
       */
      void storeEntity(EntityEnterpriseContext instance)
          throws RemoteException;
      
      /**
       * This method is called when an entity shall be passivate. The
       * persistence manager must call the ejbPassivate method on the
       * instance.
       *
       * &lt;p&gt;See the activate discussion for the reason for
       * exposing EJB callback * calls to the store.
       *
       * @param instance the instance to passivate
       *
       * @throws RemoteException thrown if some system exception occurs
       */
      void passivateEntity(EntityEnterpriseContext instance)
          throws RemoteException;
      
      /**
       * This method is called when an entity shall be removed from the
       * underlying storage. The persistence manager must call ejbRemove
       * on the instance and then remove its state from the underlying
       * storage.
       *
       * @param instance the instance to remove
       *
       * @throws RemoteException thrown if some system exception occurs
       * @throws RemoveException thrown if the instance could not be removed
       */
      void removeEntity(EntityEnterpriseContext instance)
          throws RemoteException, RemoveException;
  }</programlisting>
                      </example>
                      <para>The default BMP implementation of the <literal>EntityPersistenceManager</literal> interface is
                              <literal>org.jboss.ejb.plugins.BMPPersistenceManager</literal>. The BMP persistence manager
                          is fairly simple since all persistence logic is in the entity bean itself. The only duty of the
                          persistence manager is to perform container callbacks.</para>
                  </section>
                  <section>
                      <title>org.jboss.ejb.StatefulSessionPersistenceManager</title>
                      <para>The <literal>StatefulSessionPersistenceManager</literal> is responsible for the persistence of
                          stateful <literal>SessionBeans</literal>. This includes the following:</para>
                      <itemizedlist spacing="compact">
                          <listitem>
                              <para>Creating stateful sessions in a storage</para>
                          </listitem>
                          <listitem>
                              <para>Activating stateful sessions from a storage</para>
                          </listitem>
                          <listitem>
                              <para>Passivating stateful sessions to a storage</para>
                          </listitem>
                          <listitem>
                              <para>Removing stateful sessions from a storage</para>
                          </listitem>
                      </itemizedlist>
                      <para>The <literal>StatefulSessionPersistenceManager</literal> interface is shown below.</para>
                      <example>
                          <title>The org.jboss.ejb.StatefulSessionPersistenceManager interface</title>
                          <programlisting>public interface StatefulSessionPersistenceManager 
      extends ContainerPlugin
  {
      public void createSession(Method m, Object[] args,
  			      StatefulSessionEnterpriseContext ctx)
  	throws Exception;
      
      public void activateSession(StatefulSessionEnterpriseContext ctx)
  	throws RemoteException;
      
      public void passivateSession(StatefulSessionEnterpriseContext ctx)
  	throws RemoteException;
      
      public void removeSession(StatefulSessionEnterpriseContext ctx)
  	throws RemoteException, RemoveException;
      
      public void removePassivated(Object key);
  }</programlisting>
                      </example>
                      <para>The default implementation of the <literal>StatefulSessionPersistenceManager</literal>
                          interface is <literal>org.jboss.ejb.plugins.StatefulSessionFilePersistenceManager</literal>. As
                          its name implies, <literal>StatefulSessionFilePersistenceManager</literal> utilizes the file
                          system to persist stateful session beans. More specifically, the persistence manager serializes
                          beans in a flat file whose name is composed of the bean name and session id with a
                          <literal>.ser</literal> extension. The persistence manager restores a bean's state during
                          activation and respectively stores its state during passivation from the bean's
                          <literal>.ser</literal> file.</para>
                  </section>
              </section>
          </section>
          <section id="ch5.entitylock.sect">
              <title>Entity Bean Locking and Deadlock Detection</title>
              <para>This section provides information on what entity bean locking is and how entity beans are accessed and
                  locked within JBoss. It also describes the problems you may encounter as you use entity beans within
                  your system and how to combat these issues. Deadlocking is formally defined and examined. And, finally,
                  we walk you through how to fine tune your system in terms of entity bean locking.</para>
              <section>
                  <title>Why JBoss Needs Locking</title>
                  <para>Locking is about protecting the integrity of your data. Sometimes you need to be sure that only
                      one user can update critical data at one time. Sometimes, access to sensitive objects in your system
                      need to be serialized so that data is not corrupted by concurrent reads and writes. Databases
                      traditionally provide this sort of functionality with transactional scopes and table and row locking
                      facilities.</para>
                  <para>Entity beans are a great way to provide an object-oriented interface to relational data. Beyond
                      that, they can improve performance by taking the load off of the database through caching and
                      delaying updates until absolutely needed so that the database efficiency can be maximized. But, with
                      caching, data integrity is a problem, so some form of application server level locking is needed for
                      entity beans to provide the transaction isolation properties that you are used to with traditional
                      databases.</para>
              </section>
              <section>
                  <title>Entity Bean Lifecycle</title>
                  <para>With the default configuration of JBoss there is only one active instance of a given entity bean
                      in memory at one time. This applies for every cache configuration and every type of
                          <literal>commit-option</literal>. The lifecycle for this instance is different for every
                      commit-option though.</para>
                  <itemizedlist>
                      <listitem>
                          <para>For commit option <emphasis>A</emphasis>, this instance is cached and used between
                              transactions.</para>
                      </listitem>
                      <listitem>
                          <para>For commit option <emphasis>B</emphasis>, this instance is cached and used between
                              transactions, but is marked as dirty at the end of a transaction. This means that at the
                              start of a new transaction <literal>ejbLoad</literal> must be called.</para>
                      </listitem>
                      <listitem>
                          <para>For commit option <emphasis>C</emphasis>, this instance is marked as dirty, released from
                              the cache, and marked for passivation at the end of a transaction.</para>
                      </listitem>
                      <listitem>
                          <para>For commit option <emphasis>D</emphasis>, a background refresh thread periodically calls
                                  <literal>ejbLoad</literal> on stale beans within the cache. Otherwise, this option works
                              in the same way as <emphasis>A</emphasis>.</para>
                      </listitem>
                  </itemizedlist>
                  <para>When a bean is marked for passivation, the bean is placed in a passivation queue. Each entity bean
                      container has a passivation thread that periodically passivates beans that have been placed in the
                      passivation queue. A bean is pulled out of the passivation queue and reused if the application
                      requests access to a bean of the same primary key.</para>
                  <para>On an exception or transaction rollback, the entity bean instance is thrown out of cache entirely.
                      It is not put into the passivation queue and is not reused by an instance pool. Except for the
                      passivation queue, there is no entity bean instance pooling.</para>
              </section>
              <section>
                  <title>Default Locking Behavior</title>
                  <para> Entity bean locking is totally decoupled from the entity bean instance. The logic for locking is
                      totally isolated and managed in a separate lock object. Because there is only one allowed instance
                      of a given entity bean active at one time, JBoss employs two types of locks to ensure data integrity
                      and to conform to the EJB spec.</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">Method Lock</emphasis>: The method lock ensures that only one thread
                              of execution at a time can invoke on a given Entity Bean. This is required by the EJB
                          spec.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Transaction Lock</emphasis>: A transaction lock ensures that only one
                              transaction at a time has access to a give Entity Bean. This ensures the ACID properties of
                              transactions at the application server level. Since, by default, there is only one active
                              instance of any given Entity Bean at one time, JBoss must protect this instance from dirty
                              reads and dirty writes. So, the default entity bean locking behavior will lock an entity
                              bean within a transaction until it completes. This means that if any method at all is
                              invoked on an entity bean within a transaction, no other transaction can have access to this
                              bean until the holding transaction commits or is rolled back.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>Pluggable Interceptors and Locking Policy</title>
                  <para>We saw that the basic entity bean lifecycle and behavior is defined by the container configuration
                      defined in <literal>standardjboss.xml</literal> descriptor. Let's look at the
                          <literal>container-interceptors</literal> definition for the <emphasis>Standard CMP 2.x
                          EntityBean</emphasis> configuration.</para>
  
                  <programlisting>&lt;container-interceptors&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.LogInterceptor&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.SecurityInterceptor&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.TxInterceptorCMT&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.CallValidationInterceptor&lt;/interceptor&gt;
      &lt;interceptor metricsEnabled=&quot;true&quot;&gt;org.jboss.ejb.plugins.MetricsInterceptor&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.EntityCreationInterceptor&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.EntityLockInterceptor&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.EntityInstanceInterceptor&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.EntityReentranceInterceptor&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.resource.connectionmanager.CachedConnectionInterceptor&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.EntitySynchronizationInterceptor&lt;/interceptor&gt;
      &lt;interceptor&gt;org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor&lt;/interceptor&gt;
  &lt;/container-interceptors&gt;
  </programlisting>
  
                  <para>The interceptors shown above define most of the behavior of the entity bean. Below is an
                      explanation of the interceptors that are relevant to this section.</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">EntityLockInterceptor</emphasis>: This interceptor's role is to
                              schedule any locks that must be acquired before the invocation is allowed to proceed. This
                              interceptor is very lightweight and delegates all locking behavior to a pluggable locking
                              policy.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">EntityInstanceInterceptor</emphasis>: The job of this interceptor is
                              to find the entity bean within the cache or create a new one. This interceptor also ensures
                              that there is only one active instance of a bean in memory at one time.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">EntitySynchronizationInterceptor</emphasis>: The role of this
                              interceptor is to synchronize the state of the cache with the underlying storage. It does
                              this with the <literal>ejbLoad</literal> and <literal>ejbStore</literal> semantics of the
                              EJB specification. In the presence of a transaction this is triggered by transaction
                              demarcation. It registers a callback with the underlying transaction monitor through the JTA
                              interfaces. If there is no transaction the policy is to store state upon returning from
                              invocation. The synchronization polices <emphasis>A</emphasis>, <emphasis>B</emphasis> and
                                  <emphasis>C</emphasis> of the specification are taken care of here as well as the JBoss
                              specific commit-option <emphasis>D</emphasis>.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>Deadlock </title>
                  <para>Finding deadlock problems and resolving them is the topic of this section. We will describe what
                      deadlocking MBeans, how you can detect it within your application, and how you can resolve
                      deadlocks. Deadlock can occur when two or more threads have locks on shared resources. <xref
                          linkend="ch5.deadlockdef.fig"/> illustrates a simple deadlock scenario. Here, <literal>Thread
                      1</literal> has the lock for <literal>Bean A</literal>, and <literal>Thread 2</literal> has the lock
                      for <literal>Bean B</literal>. At a later time, <literal>Thread 1</literal> tries to lock
                          <literal>Bean B</literal> and blocks because <literal>Thread 2</literal> has it. Likewise, as
                          <literal>Thread 2</literal> tries to lock A it also blocks because <literal>Thread 1</literal>
                      has the lock. At this point both threads are deadlocked waiting for access to the resource already
                      locked by the other thread.</para>
                  <figure id="ch5.deadlockdef.fig">
                      <title>Deadlock definition example</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/deadlock-definition.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The default locking policy of JBoss is to lock an Entity bean when an invocation occurs in the
                      context of a transaction until the transaction completes. Because of this, it is very easy to
                      encounter deadlock if you have long running transactions that access many entity beans, or if you
                      are not careful about ordering the access to them. Various techniques and advanced configurations
                      can be used to avoid deadlocking problems. They are discussed later in this section.</para>
                  <section>
                      <title>Deadlock Detection</title>
                      <para>Fortunately, JBoss is able to perform deadlock detection. JBoss holds a global internal graph
                          of waiting transactions and what transactions they are blocking on. Whenever a thread determines
                          that it cannot acquire an entity bean lock, it figures out what transaction currently holds the
                          lock on the bean and add itself to the blocked transaction graph. An example of what the graph
                          may look like is given in <xref linkend="ch5.txdead.table"/>.</para>
                      <table id="ch5.txdead.table">
                          <title>An example blocked transaction table</title>
                          <tgroup cols="2">
                              <thead>
                                  <row>
                                      <entry>Blocking TX</entry>
                                      <entry>Tx that holds needed lock</entry>
                                  </row>
                              </thead>
                              <tbody>
                                  <row>
                                      <entry>Tx1</entry>
                                      <entry>Tx2</entry>
                                  </row>
                                  <row>
                                      <entry>Tx3</entry>
                                      <entry>Tx4</entry>
                                  </row>
                                  <row>
                                      <entry>Tx4</entry>
                                      <entry>Tx1</entry>
                                  </row>
                              </tbody>
                          </tgroup>
                      </table>
                      <para>Before the thread actually blocks it tries to detect whether there is deadlock problem. It
                          does this by traversing the block transaction graph. As it traverses the graph, it keeps track
                          of what transactions are blocked. If it sees a blocked node more than once in the graph, then it
                          knows there is deadlock and will throw an <literal>ApplicationDeadlockException</literal>. This
                          exception will cause a transaction rollback which will cause all locks that transaction holds to
                          be released. </para>
                  </section>
                  <section>
                      <title>Catching ApplicationDeadlockException</title>
                      <para>Since JBoss can detect application deadlock, you should write your application so that it can
                          retry a transaction if the invocation fails because of the
                          <literal>ApplicationDeadlockException</literal>. Unfortunately, this exception can be deeply
                          embedded within a <literal>RemoteException</literal>, so you have to search for it in your catch
                          block. For example:</para>
                      <programlisting>try {
      // ...
  } catch (RemoteException ex) {
      Throwable cause = null;
      RemoteException rex = ex;
      while (rex.detail != null) {
          cause = rex.detail;
          if (cause instanceof ApplicationDeadlockException) {
  	        // ... We have deadlock, force a retry of the transaction.
              break;
          }
          if (cause instanceof RemoteException) {
              rex = (RemoteException)cause;
          }
      }
  }</programlisting>
                  </section>
                  <section>
                      <title>Viewing Lock Information</title>
                      <para>The <literal>EntityLockMonitor</literal> MBean service allows one to view basic locking
                          statistics as well as printing out the state of the transaction locking table. To enable this
                          monitor uncomment its configuration in the <literal>conf/jboss-service.xml</literal>:</para>
                      <programlisting>&lt;mbean code="org.jboss.monitor.EntityLockMonitor"
         name="jboss.monitor:name=EntityLockMonitor"/&gt;</programlisting>
                      <para>The <literal>EntityLockMonitor</literal> has no configurable attributes. It does have the
                          following read-only attributes:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">MedianWaitTime</emphasis>: The median value of all times threads
                                  had to wait to acquire a lock.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">AverageContenders</emphasis>: The ratio of the total number of
                                  contentions to the sum of all threads that had to wait for a lock.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">TotalContentions</emphasis>: The total number of threads that had
                                  to wait to acquire the transaction lock. This happens when a thread attempts to acquire
                                  a lock that is associated with another transaction</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">MaxContenders</emphasis>: The maximum number of threads that were
                                  waiting to acquire the transaction lock.</para>
                          </listitem>
                      </itemizedlist>
                      <para>It also has the following operations:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">clearMonitor</emphasis>: This operation resets the lock monitor
                                  state by zeroing all counters.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">printLockMonitor</emphasis>: This operation prints out a table of
                                  all EJB locks that lists the <literal>ejbName</literal> of the bean, the total time
                                  spent waiting for the lock, the count of times the lock was waited on and the number of
                                  transactions that timed out waiting for the lock.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
              </section>
              <section>
                  <title>Advanced Configurations and Optimizations</title>
                  <para>The default locking behavior of entity beans can cause deadlock. Since access to an entity bean
                      locks the bean into the transaction, this also can present a huge performance/throughput problem for
                      your application. This section walks through various techniques and configurations that you can use
                      to optimize performance and reduce the possibility of deadlock.</para>
                  <section>
                      <title>Short-lived Transactions</title>
                      <para>Make your transactions as short-lived and fine-grained as possible. The shorter the
                          transaction you have, the less likelihood you will have concurrent access collisions and your
                          application throughput will go up.</para>
                  </section>
                  <section>
                      <title>Ordered Access</title>
                      <para>Ordering the access to your entity beans can help lessen the likelihood of deadlock. This
                          means making sure that the entity beans in your system are always accessed in the same exact
                          order. In most cases, user applications are just too complicated to use this approach and more
                          advanced configurations are needed.</para>
                  </section>
                  <section>
                      <title>Read-Only Beans</title>
                      <para>Entity beans can be marked as read-only. When a bean is marked as read-only, it never takes
                          part in a transaction. This means that it is never transactionally locked. Using commit-option
                              <emphasis>D</emphasis> with this option is sometimes very useful when your read-only bean's
                          data is sometimes updated by an external source.</para>
                      <para>To mark a bean as read-only, use the <literal>read-only</literal> flag in the
                              <literal>jboss.xml</literal> deployment descriptor.</para>
                      <example>
                          <title>Marking an entity bean read-only using jboss.xml</title>
                          <programlisting>&lt;jboss&gt;
      &lt;enterprise-beans&gt;
          &lt;entity&gt;
              &lt;ejb-name&gt;MyEntityBean&lt;/ejb-name&gt;
              &lt;jndi-name&gt;MyEntityHomeRemote&lt;/jndi-name&gt;
              &lt;read-only&gt;True&lt;/read-only&gt;
          &lt;/entity&gt;
      &lt;/enterprise-beans&gt;
  &lt;/jboss&gt;</programlisting>
                      </example>
                  </section>
                  <section>
                      <title>Explicitly Defining Read-Only Methods</title>
                      <para>After reading and understanding the default locking behavior of entity beans, you're probably
                          wondering, "Why lock the bean if its not modifying the data?" JBoss allows you to define what
                          methods on your entity bean are read only so that it will not lock the bean within the
                          transaction if only these types of methods are called. You can define these read only methods
                          within a <literal>jboss.xml</literal> deployment descriptor. Wildcards are allowed for method
                          names. The following is an example of declaring all getter methods and the
                              <literal>anotherReadOnlyMethod</literal> as read-only.</para>
                      <example>
                          <title>Defining entity bean methods as read only</title>
                          <programlisting>&lt;jboss&gt;
      &lt;enterprise-beans&gt;
          &lt;entity&gt;
              &lt;ejb-name&gt;nextgen.EnterpriseEntity&lt;/ejb-name&gt;
              &lt;jndi-name&gt;nextgen.EnterpriseEntity&lt;/jndi-name&gt;
              &lt;method-attributes&gt;
                  &lt;method&gt;
                      &lt;method-name&gt;get*&lt;/method-name&gt;
                      &lt;read-only&gt;true&lt;/read-only&gt;
                  &lt;/method&gt;
                  &lt;method&gt;
                      &lt;method-name&gt;anotherReadOnlyMethod&lt;/method-name&gt;
                      &lt;read-only&gt;true&lt;/read-only&gt;
                  &lt;/method&gt;
              &lt;/method-attributes&gt;
          &lt;/entity&gt;
      &lt;/enterprise-beans&gt;
  &lt;/jboss&gt; </programlisting>
                      </example>
                  </section>
                  <section>
                      <title>Instance Per Transaction Policy</title>
                      <para>The Instance Per Transaction policy is an advanced configuration that can totally wipe away
                          deadlock and throughput problems caused by JBoss's default locking policy. The default Entity
                          Bean locking policy is to only allow one active instance of a bean. The Instance Per Transaction
                          policy breaks this requirement by allocating a new instance of a bean per transaction and
                          dropping this instance at the end of the transaction. Because each transaction has its own copy
                          of the bean, there is no need for transaction based locking.</para>
                      <para>This option does sound great but does have some drawbacks right now. First, the transactional
                          isolation behavior of this option is equivalent to <literal>READ_COMMITTED</literal>. This can
                          create repeatable reads when they are not desired. In other words, a transaction could have a
                          copy of a stale bean. Second, this configuration option currently requires commit-option
                              <emphasis>B</emphasis> or <emphasis>C</emphasis> which can be a performance drain since an
                          ejbLoad must happen at the beginning of the transaction. But, if your application currently
                          requires commit-option <emphasis>B</emphasis> or <emphasis>C</emphasis> anyways, then this is
                          the way to go. The JBoss developers are currently exploring ways to allow commit-option
                              <emphasis>A</emphasis> as well (which would allow the use of caching for this option).</para>
                      <para>JBoss has container configurations named <literal>Instance Per Transaction CMP 2.x
                          EntityBean</literal> and <literal>Instance Per Transaction BMP EntityBean</literal> defined in
                          the standardjboss.xml that implement this locking policy. To use this configuration, you just
                          have to reference the name of the container configuration to use with your bean in the jboss.xml
                          deployment descriptor as show below.</para>
                      <example>
                          <title>An example of using the Instance Per Transaction policy.</title>
                          <programlisting>&lt;jboss&gt;
      &lt;enterprise-beans&gt;
          &lt;entity&gt;
              &lt;ejb-name&gt;MyCMP2Bean&lt;/ejb-name&gt;
              &lt;jndi-name&gt;MyCMP2&lt;/jndi-name&gt;
              &lt;configuration-name&gt;
                  Instance Per Transaction CMP 2.x EntityBean
              &lt;/configuration-name&gt;
          &lt;/entity&gt;
          &lt;entity&gt;
              &lt;ejb-name&gt;MyBMPBean&lt;/ejb-name&gt;
              &lt;jndi-name&gt;MyBMP&lt;/jndi-name&gt;
              &lt;configuration-name&gt;
                  Instance Per Transaction BMP EntityBean
              &lt;/configuration-name&gt;
          &lt;/entity&gt;
      &lt;/enterprise-beans&gt;
  &lt;/jboss&gt;</programlisting>
                      </example>
                  </section>
              </section>
              <section>
                  <title>Running Within a Cluster</title>
                  <para>Currently there is no distributed locking capability for entity beans within the cluster. This
                      functionality has been delegated to the database and must be supported by the application developer.
                      For clustered entity beans, it is suggested to use commit-option <emphasis>B</emphasis> or
                          <emphasis>C</emphasis> in combination with a row locking mechanism. For CMP, there is a
                      row-locking configuration option. This option will use a SQL <literal>select for update</literal>
                      when the bean is loaded from the database. With commit-option <emphasis>B</emphasis> or
                      <emphasis>C</emphasis>, this implements a transactional lock that can be used across the cluster.
                      For BMP, you must explicitly implement the select for update invocation within the BMP's
                          <literal>ejbLoad</literal> method.</para>
              </section>
              <section>
                  <title>Troubleshooting</title>
                  <para>This section will describe some common locking problems and their solution.</para>
                  <section>
                      <title>Locking Behavior Not Working</title>
                      <para>Many JBoss users observe that locking does not seem to be working and see concurrent access to
                          their beans, and thus dirty reads. Here are some common reasons for this:</para>
                      <itemizedlist>
                          <listitem>
                              <para>If you have custom <literal>container-configurations</literal>, make sure you have
                                  updated these configurations.</para>
                          </listitem>
                          <listitem>
                              <para>Make absolutely sure that you have implemented <literal>equals</literal> and
                                      <literal>hashCode</literal> correctly from custom/complex primary key
                              classes.</para>
                          </listitem>
                          <listitem>
                              <para>Make absolutely sure that your custom/complex primary key classes serialize correctly.
                                  One common mistake is assuming that member variable initializations will be executed
                                  when a primary key is unmarshalled.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>IllegalStateException</title>
                      <para>An IllegalStateException with the message "removing bean lock and it has tx set!" usually
                          means that you have not implemented <literal>equals</literal> and/or <literal>hashCode</literal>
                          correctly for your custom/complex primary key class, or that your primary key class is not
                          implemented correctly for serialization.</para>
                  </section>
                  <section>
                      <title>Hangs and Transaction Timeouts</title>
                      <para>One long outstanding bug of JBoss is that on a transaction timeout, that transaction is only
                          marked for a rollback and not actually rolled back. This responsibility is delegated to the
                          invocation thread. This can cause major problems if the invocation thread hangs indefinitely
                          since things like entity bean locks will never be released. The solution to this problem is not
                          a good one. You really just need to avoid doing stuff within a transaction that could hang
                          indefinitely. One common mistake is making connections across the internet or running a
                          web-crawler within a transaction.</para>
                  </section>
              </section>
          </section>
  
          <section id="ch5.timer">
              <title>EJB Timer Configuration</title>
  
              <para>The J2EE timer service allows for any EJB object to register for a timer callback either at a
                  designated time in the future. Timer events can be used for auditing, reporting or other cleanup tasks
                  that need to need to happen at some given time in the future. Timer events are intended to be persistent
                  and should be executed even in the event of a server failure. Coding to EJB timers is a standard part of
                  the J2EE specification, so we won't explore the programming model. We will, instead, look at the
                  configuration of the timer service in JBoss so that you can understand how to make timers work best in
                  your environment </para>
  
              <para>The EJB timer service is configure by several related MBeans in the
                  <literal>ejb-deployer.xml</literal> file. The primary MBean is the <literal>EJBTimerService</literal>
                  MBean. </para>
  
              <programlisting>&lt;mbean code=&quot;org.jboss.ejb.txtimer.EJBTimerServiceImpl&quot; name=&quot;jboss.ejb:service=EJBTimerService&quot;&gt;
      &lt;attribute name=&quot;RetryPolicy&quot;&gt;jboss.ejb:service=EJBTimerService,retryPolicy=fixedDelay&lt;/attribute&gt;
      &lt;attribute name=&quot;PersistencePolicy&quot;&gt;jboss.ejb:service=EJBTimerService,persistencePolicy=database&lt;/attribute&gt;
      &lt;attribute name=&quot;TimerIdGeneratorClassName&quot;&gt;org.jboss.ejb.txtimer.BigIntegerTimerIdGenerator&lt;/attribute&gt;
      &lt;attribute name=&quot;TimedObjectInvokerClassName&quot;&gt;org.jboss.ejb.txtimer.TimedObjectInvokerImpl&lt;/attribute&gt;
  &lt;/mbean&gt; </programlisting>
  
              <para>The <literal>EJBTimerService</literal> has the following configurable attributes: </para>
  
  
              <itemizedlist>
                  <listitem>
                      <para><emphasis role="bold">RetryPolicy</emphasis>: This is name of the MBean that implements the
                          retry policy. The MBean must support the <literal>org.jboss.ejb.txtimer.RetryPolicy
                          interface</literal>. JBoss provides one implementation,
                          <literal>FixedDelayRetryPolicy</literal>, which will be described later. </para>
                  </listitem>
                  <listitem>
                      <para><emphasis role="bold">PersistencePolicy</emphasis>: This is the name of the MBean that
                          implements the the persistence strategy for saving timer events. The MBean must support the
                              <literal>org.jboss.ejb.txtimer.PersistencePolicy</literal> interface. JBoss provides two
                          implementations, NoopPersistencePolicy and DatabasePersistencePolicy, which will be described
                          later. </para>
                  </listitem>
                  <listitem>
                      <para><emphasis role="bold">TimerIdGeneratorClassName</emphasis>: This is the name of a class that
                          provides the timer ID generator strategy. This class must implement the
                              <literal>org.jboss.ejb.txtimer.TimerIdGenerator</literal> interface. JBoss provides the
                              <literal>org.jboss.ejb.txtimer.BigIntegerTimerIdGenerator</literal> implementation. </para>
                  </listitem>
                  <listitem>
                      <para><emphasis role="bold">TimedObjectInvokerClassname</emphasis>: This is the name of a class that
                          provides the timer method invocation strategy. This class must implement the
                              <literal>org.jboss.ejb.txtimer.TimedObjectInvoker</literal> interface. JBoss provides the
                              <literal>org.jboss.ejb.txtimer.TimedObjectInvokerImpl</literal> implementation. </para>
                  </listitem>
  
              </itemizedlist>
  
  
              <para>The retry policy MBean definition used is shown here: </para>
              <programlisting>&lt;mbean code=&quot;org.jboss.ejb.txtimer.FixedDelayRetryPolicy&quot;
         name=&quot;jboss.ejb:service=EJBTimerService,retryPolicy=fixedDelay&quot;&gt;
      &lt;attribute name=&quot;Delay&quot;&gt;100&lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
  
              <para>The retry policy takes one configuration value:</para>
  
              <itemizedlist>
                  <listitem>
                      <para><emphasis role="bold">Delay</emphasis>: This is the delay (ms) before retrying a failed timer
                          execution. The default delay is 100ms. </para>
                  </listitem>
              </itemizedlist>
  
  
  
              <para> If EJB timers do not need to be persisted, the <literal>NoopPersistence</literal> policy can be used.
                  This MBean is commented out by default, but when enabled will look like this: </para>
  
              <programlisting>&lt;mbean code=&quot;org.jboss.ejb.txtimer.NoopPersistencePolicy&quot; 
         name=&quot;jboss.ejb:service=EJBTimerService,persistencePolicy=noop&quot;/&gt;</programlisting>
  
  
              <para>Most applications that use timers will want timers to be persisted. For that the
                      <literal>DatabasePersitencePolicy</literal> MBean should be used. </para>
  
              <programlisting>&lt;mbean code=&quot;org.jboss.ejb.txtimer.DatabasePersistencePolicy&quot; 
         name=&quot;jboss.ejb:service=EJBTimerService,persistencePolicy=database&quot;&gt;
      &lt;!-- DataSource JNDI name --&gt;
      &lt;depends optional-attribute-name=&quot;DataSource&quot;&gt;jboss.jca:service=DataSourceBinding,name=DefaultDS&lt;/depends&gt;
      &lt;!-- The plugin that handles database persistence --&gt;
      &lt;attribute name=&quot;DatabasePersistencePlugin&quot;&gt;org.jboss.ejb.txtimer.GeneralPurposeDatabasePersistencePlugin&lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
  
  
              <itemizedlist>
                  <listitem>
                      <para><emphasis role="bold">DataSource</emphasis>: This is the MBean for the DataSource that timer
                          data will be written to. </para>
                  </listitem>
  
                  <listitem>
                      <para><emphasis role="bold">DatabasePersistencePlugin</emphasis>: This is the name of the class the
                          implements the persistence strategy. This should be
                              <literal>org.jboss.ejb.txtimer.GeneralPurposeDatabasePersistencePlugin</literal>. </para>
                  </listitem>
              </itemizedlist>
  
          </section>
      </chapter>
  
      <chapter id="ch6.chapt">
          <title>Messaging on JBoss</title>
          <subtitle>JMS Configuration and Architecture</subtitle>
          <para>The JMS API stands for Java Message Service Application Programming Interface, and it is used by
              applications to send asynchronous <emphasis>business-quality</emphasis> messages to other applications. In
              the messaging world, messages are not sent directly to other applications. Instead, messages are sent to
              destinations, known as queues or topics. Applications sending messages do not need to worry if the receiving
              applications are up and running, and conversely, receiving applications do not need to worry about the
              sending application's status. Both senders, and receivers only interact with the destinations.</para>
          <para>The JMS API is the standardized interface to a JMS provider, sometimes called a Message Oriented
              Middleware (MOM) system. JBoss comes with a JMS 1.1 compliant JMS provider called JBoss Messaging or
              JBossMQ. When you use the JMS API with JBoss, you are using the JBoss Messaging engine transparently. JBoss
              Messaging fully implements the JMS specification; therefore, the best JBoss Messaging user guide is the JMS
              specification. For more information about the JMS API please visit the JMS Tutorial or JMS Downloads
              &amp; Specifications.</para>
          <para>This chapter focuses on the JBoss specific aspects of using JMS and message driven beans as well as the
              JBoss Messaging configuration and MBeans.</para>
          <section>
              <title>JMS Examples</title>
              <para>In this section we discuss the basics needed to use the JBoss JMS implementation. JMS leaves the
                  details of accessing JMS connection factories and destinations as provider specific details. What you
                  need to know to use the JBoss Messaging layer is:</para>
              <itemizedlist>
                  <listitem>
                      <para>The location of the queue and topic connect factories: In JBoss both connection factory
                          implementations are located under the JNDI name <literal>ConnectionFactory</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>How to lookup JMS destinations (queues and topics): Destinations are configured via MBeans as
                          we will see when we discuss the messaging MBeans. JBoss comes with a few queues and topics
                          preconfigured. You can find them under the <literal>jboss.mq.destination</literal> domain in the
                          JMX Console..</para>
                  </listitem>
                  <listitem>
                      <para>Which JARS JMS requires: These include <literal>concurrent.jar</literal>,
                              <literal>jbossmq-client.jar</literal>, <literal>jboss-common-client.jar</literal>,
                              <literal>jboss-system-client.jar</literal>, <literal>jnp-client.jar</literal> and
                              <literal>log4j.jar</literal>.</para>
                  </listitem>
              </itemizedlist>
              <para>In the following sections we will look at examples of the various JMS messaging models and message
                  driven beans. The chapter example source is located under the
                  <literal>src/main/org/jboss/chap6</literal> directory of the book examples.</para>
              <section>
                  <title>A Point-To-Point Example</title>
                  <para>Let's start out with a point-to-point (P2P) example. In the P2P model, a sender delivers messages
                      to a queue and a single receiver pulls the message off of the queue. The receiver does not need to
                      be listening to the queue at the time the message is sent. <xref linkend="ch6.p2pjmsclient.ex"/>
                      shows a complete P2P example that sends a <literal>javax.jms.TextMessage</literal> to the queue
                          <literal>queue/testQueue</literal> and asynchronously receives the message from the same queue.</para>
                  <example id="ch6.p2pjmsclient.ex">
                      <title>A P2P JMS client example</title>
                      <programlisting>package org.jboss.chap6.ex1;
  
  import javax.jms.JMSException;
  import javax.jms.Message;
  import javax.jms.MessageListener;
  import javax.jms.Queue;
  import javax.jms.QueueConnection;
  import javax.jms.QueueConnectionFactory;
  import javax.jms.QueueReceiver;
  import javax.jms.QueueSender;
  import javax.jms.QueueSession;
  import javax.jms.TextMessage;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  import EDU.oswego.cs.dl.util.concurrent.CountDown;
  import org.apache.log4j.Logger;
  import org.jboss.util.ChapterExRepository;
  
  /** 
   * A complete JMS client example program that sends a
   * TextMessage to a Queue and asynchronously receives the
   * message from the same Queue.
   * 
   * @author  Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class SendRecvClient
  {
      static Logger log;
      static CountDown done = new CountDown(1);
      
      QueueConnection conn;
      QueueSession session;
      Queue que;
      
      public static class ExListener 
          implements MessageListener
      {
          public void onMessage(Message msg)
          {
              done.release();
              TextMessage tm = (TextMessage) msg;
              try {
                  log.info("onMessage, recv text=" + tm.getText());
              } catch(Throwable t) {
                  t.printStackTrace();
              }
          }
      }
      
      public void setupPTP()
          throws JMSException, 
                 NamingException
      {
          InitialContext iniCtx = new InitialContext();
          Object tmp = iniCtx.lookup("ConnectionFactory");
          QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;
          conn = qcf.createQueueConnection();
          que = (Queue) iniCtx.lookup("queue/testQueue");
          session = conn.createQueueSession(false,
                                            QueueSession.AUTO_ACKNOWLEDGE);
          conn.start();
      }
      
      public void sendRecvAsync(String text)
          throws JMSException, 
                 NamingException
      {
          log.info("Begin sendRecvAsync");
          // Setup the PTP connection, session
          setupPTP();
  
          // Set the async listener
          QueueReceiver recv = session.createReceiver(que);
          recv.setMessageListener(new ExListener());
  
          // Send a text msg
          QueueSender send = session.createSender(que);
          TextMessage tm = session.createTextMessage(text);
          send.send(tm);
          log.info("sendRecvAsync, sent text=" + tm.getText());
          send.close();
          log.info("End sendRecvAsync");
      }
      
      public void stop()
          throws JMSException
      {
          conn.stop();
          session.close();
          conn.close();
      }
      
      public static void main(String args[]) 
          throws Exception
      {
          ChapterExRepository.init(SendRecvClient.class);
          log = Logger.getLogger("SendRecvClient");
          
          log.info("Begin SendRecvClient, now=" + System.currentTimeMillis());
          SendRecvClient client = new SendRecvClient();
          client.sendRecvAsync("A text msg");
          client.done.acquire();
          client.stop();
          log.info("End SendRecvClient");
          System.exit(0);
      }
  }</programlisting>
                  </example>
                  <para>The client may be run using the following command line:</para>
                  <programlisting>[examples]$ ant -Dchap=chap6 -Dex=1p2p run-example
  ...
  run-example1p2p:
       [java] [INFO,SendRecvClient] Begin SendRecvClient, now=1102808673386
       [java] [INFO,SendRecvClient] Begin sendRecvAsync
       [java] [INFO,SendRecvClient] onMessage, recv text=A text msg
       [java] [INFO,SendRecvClient] sendRecvAsync, sent text=A text msg
       [java] [INFO,SendRecvClient] End sendRecvAsync
       [java] [INFO,SendRecvClient] End SendRecvClient</programlisting>
              </section>
              <section>
                  <title>A Pub-Sub Example</title>
                  <para>The JMS publish/subscribe (Pub-Sub) message model is a one-to-many model. A publisher sends a
                      message to a topic and all active subscribers of the topic receive the message. Subscribers that are
                      not actively listening to the topic will miss the published message. shows a complete JMS client
                      that sends a <literal>javax.jms.TextMessage</literal> to a topic and asynchronously receives the
                      message from the same topic.</para>
                  <example>
                      <title>A Pub-Sub JMS client example</title>
                      <programlisting>package org.jboss.chap6.ex1;
  
  import javax.jms.JMSException;
  import javax.jms.Message;
  import javax.jms.MessageListener;
  import javax.jms.Topic;
  import javax.jms.TopicConnection;
  import javax.jms.TopicConnectionFactory;
  import javax.jms.TopicPublisher;
  import javax.jms.TopicSubscriber;
  import javax.jms.TopicSession;
  import javax.jms.TextMessage;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  import EDU.oswego.cs.dl.util.concurrent.CountDown;
  
  /**
   *  A complete JMS client example program that sends a TextMessage to
   *  a Topic and asynchronously receives the message from the same
   *  Topic.
   * 
   *  @author Scott.Stark at jboss.org
   *  @version $Revision: 1.1 $
   */
  
  public class TopicSendRecvClient
  {
      static CountDown done = new CountDown(1);
      TopicConnection conn = null;
      TopicSession session = null;
      Topic topic = null;
      
      public static class ExListener implements MessageListener
      {
          public void onMessage(Message msg)
          {
              done.release();
              TextMessage tm = (TextMessage) msg;
              try {
                  System.out.println("onMessage, recv text=" + tm.getText());
              } catch(Throwable t) {
                  t.printStackTrace();
              }
          }
      }
      
      public void setupPubSub()
          throws JMSException, NamingException
      {
          InitialContext iniCtx = new InitialContext();
          Object tmp = iniCtx.lookup("ConnectionFactory");
          TopicConnectionFactory tcf = (TopicConnectionFactory) tmp;
          conn = tcf.createTopicConnection();
          topic = (Topic) iniCtx.lookup("topic/testTopic");
          session = conn.createTopicSession(false,
                                            TopicSession.AUTO_ACKNOWLEDGE);
          conn.start();
      }
      
      public void sendRecvAsync(String text)
          throws JMSException, NamingException
      {
          System.out.println("Begin sendRecvAsync");
          // Setup the PubSub connection, session
          setupPubSub();
          // Set the async listener
          
          TopicSubscriber recv = session.createSubscriber(topic);
          recv.setMessageListener(new ExListener());
          // Send a text msg
          TopicPublisher send = session.createPublisher(topic);
          TextMessage tm = session.createTextMessage(text);
          send.publish(tm);
          System.out.println("sendRecvAsync, sent text=" + tm.getText());
          send.close();
          System.out.println("End sendRecvAsync");
      }
      
      public void stop() throws JMSException
      {
          conn.stop();
          session.close();
          conn.close();
      }
      
      public static void main(String args[]) throws Exception
      {
          System.out.println("Begin TopicSendRecvClient, now=" + 
                             System.currentTimeMillis());
          TopicSendRecvClient client = new TopicSendRecvClient();
          client.sendRecvAsync("A text msg, now="+System.currentTimeMillis());
          client.done.acquire();
          client.stop();
          System.out.println("End TopicSendRecvClient");
          System.exit(0);
      }
      
  }</programlisting>
                  </example>
                  <para>The client may be run using the following command line:</para>
                  <programlisting>[examples]$ ant -Dchap=chap6 -Dex=1ps run-example
  ...
  run-example1ps:
       [java] Begin TopicSendRecvClient, now=1102809427043
       [java] Begin sendRecvAsync
       [java] onMessage, recv text=A text msg, now=1102809427071
       [java] sendRecvAsync, sent text=A text msg, now=1102809427071
       [java] End sendRecvAsync
       [java] End TopicSendRecvClient</programlisting>
                  <para>Now let's break the publisher and subscribers into separate programs to demonstrate that
                      subscribers only receive messages while they are listening to a topic. <xref
                          linkend="ch6.jmspubclient.ex"/> shows a variation of the previous pub-sub client that only
                      publishes messages to the <literal>topic/testTopic</literal> topic. The subscriber only client is
                      shown in <xref linkend="ch6.jmspubclient.ex"/>.</para>
                  <example id="ch6.jmspubclient.ex">
                      <title>A JMS publisher client</title>
                      <programlisting>package org.jboss.chap6.ex1;
  
  import javax.jms.JMSException;
  import javax.jms.Message;
  import javax.jms.MessageListener;
  import javax.jms.Topic;
  import javax.jms.TopicConnection;
  import javax.jms.TopicConnectionFactory;
  import javax.jms.TopicPublisher;
  import javax.jms.TopicSlistubscriber;
  import javax.jms.TopicSession;
  import javax.jms.TextMessage;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  /** 
   *  A JMS client example program that sends a TextMessage to a Topic
   *    
   *  @author Scott.Stark at jboss.org
   *  @version $Revision: 1.1 $
   */
  public class TopicSendClient
  {
      TopicConnection conn = null;
      TopicSession session = null;
      Topic topic = null;
      
      public void setupPubSub()
          throws JMSException, NamingException
      {
          InitialContext iniCtx = new InitialContext();
          Object tmp = iniCtx.lookup("ConnectionFactory");
          TopicConnectionFactory tcf = (TopicConnectionFactory) tmp;
          conn = tcf.createTopicConnection();
          topic = (Topic) iniCtx.lookup("topic/testTopic");
          session = conn.createTopicSession(false,
                                            TopicSession.AUTO_ACKNOWLEDGE);
          conn.start();
      }
      
      public void sendAsync(String text)
          throws JMSException, NamingException
      {
          System.out.println("Begin sendAsync");
          // Setup the pub/sub connection, session
          setupPubSub();
          // Send a text msg
          TopicPublisher send = session.createPublisher(topic);
          TextMessage tm = session.createTextMessage(text);
          send.publish(tm);
          System.out.println("sendAsync, sent text=" +  tm.getText());
          send.close();
          System.out.println("End sendAsync");
      }
      
      public void stop() 
          throws JMSException
      {
          conn.stop();
          session.close();
          conn.close();
      }
      
      public static void main(String args[]) 
          throws Exception
      {
          System.out.println("Begin TopicSendClient, now=" + 
  		                   System.currentTimeMillis());
          TopicSendClient client = new TopicSendClient();
  	    client.sendAsync("A text msg, now="+System.currentTimeMillis());
          client.stop();
          System.out.println("End TopicSendClient");
          System.exit(0);
      }
      
  }</programlisting>
                  </example>
                  <example id="ch6.jmssubclient.ex">
                      <title>A JMS subscriber client</title>
                      <programlisting>package org.jboss.chap6.ex1;
  
  import javax.jms.JMSException;
  import javax.jms.Message;
  import javax.jms.MessageListener;
  import javax.jms.Topic;
  import javax.jms.TopicConnection;
  import javax.jms.TopicConnectionFactory;
  import javax.jms.TopicPublisher;
  import javax.jms.TopicSubscriber;
  import javax.jms.TopicSession;
  import javax.jms.TextMessage;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  /**
   * A JMS client example program that synchronously receives a message a Topic
   *  
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class TopicRecvClient
  {
      TopicConnection conn = null;
      TopicSession session = null;
      Topic topic = null;
      
      public void setupPubSub()
          throws JMSException, NamingException
      {
          InitialContext iniCtx = new InitialContext();
          Object tmp = iniCtx.lookup("ConnectionFactory");
          TopicConnectionFactory tcf = (TopicConnectionFactory) tmp;
          conn = tcf.createTopicConnection();
          topic = (Topic) iniCtx.lookup("topic/testTopic");
          session = conn.createTopicSession(false,
                                            TopicSession.AUTO_ACKNOWLEDGE);
          conn.start();
      }
      
      public void recvSync()
          throws JMSException, NamingException
      {
          System.out.println("Begin recvSync");
          // Setup the pub/sub connection, session
          setupPubSub();
  
          // Wait upto 5 seconds for the message
          TopicSubscriber recv = session.createSubscriber(topic);
          Message msg = recv.receive(5000);
          if (msg == null) {
              System.out.println("Timed out waiting for msg");
          } else {
              System.out.println("TopicSubscriber.recv, msgt="+msg);
          }
      }
      
      public void stop()
          throws JMSException
      {
          conn.stop();
          session.close();
          conn.close();
      }
      
      public static void main(String args[]) 
          throws Exception
      {
          System.out.println("Begin TopicRecvClient, now=" +
                             System.currentTimeMillis());
          TopicRecvClient client = new TopicRecvClient();
          client.recvSync();
          client.stop();
          System.out.println("End TopicRecvClient");
          System.exit(0);
      }
      
  }</programlisting>
                  </example>
                  <para>Run the <literal>TopicSendClient</literal> followed by the <literal>TopicRecvClient</literal> as
                      follows:</para>
                  <programlisting>[examples]$ ant -Dchap=chap6 -Dex=1ps2 run-example
  ...
  run-example1ps2:
       [java] Begin TopicSendClient, now=1102810007899
       [java] Begin sendAsync
       [java] sendAsync, sent text=A text msg, now=1102810007909
       [java] End sendAsync
       [java] End TopicSendClient
       [java] Begin TopicRecvClient, now=1102810011524
       [java] Begin recvSync
       [java] Timed out waiting for msg
       [java] End TopicRecvClient</programlisting>
                  <para>The output shows that the topic subscriber client (<literal>TopicRecvClient</literal>) fails to
                      receive the message sent by the publisher due to a timeout.</para>
              </section>
              <section>
                  <title>A Pub-Sub With Durable Topic Example</title>
                  <para>JMS supports a messaging model that is a cross between the P2P and pub-sub models. When a pub-sub
                      client wants to receive all messages posted to the topic it subscribes to even when it is not
                      actively listening to the topic, the client may achieve this behavior using a durable topic. Let's
                      look at a variation of the preceding subscriber client that uses a durable topic to ensure that it
                      receives all messages, include those published when the client is not listening to the topic. <xref
                          linkend="ch6.durabletopic.ex"/> shows the durable topic client with the key differences between
                      the <xref linkend="ch6.jmssubclient.ex"/> client highlighted in bold.</para>
                  <example id="ch6.durabletopic.ex">
                      <title>A durable topic JMS client example</title>
                      <programlisting>package org.jboss.chap6.ex1;
  
  import javax.jms.JMSException;
  import javax.jms.Message;
  import javax.jms.MessageListener;
  import javax.jms.Topic;
  import javax.jms.TopicConnection;
  import javax.jms.TopicConnectionFactory;
  import javax.jms.TopicPublisher;
  import javax.jms.TopicSubscriber;
  import javax.jms.TopicSession;
  import javax.jms.TextMessage;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  /**
   *  A JMS client example program that synchronously receives a message a Topic
   *     
   *  @author Scott.Stark at jboss.org
   *  @version $Revision: 1.1 $
   */
  public class DurableTopicRecvClient
  {
      TopicConnection conn = null;
      TopicSession session = null;
      Topic topic = null;
      
      public void setupPubSub()
          throws JMSException, NamingException
      {
          InitialContext iniCtx = new InitialContext();
          Object tmp = iniCtx.lookup("ConnectionFactory");
  
          TopicConnectionFactory tcf = (TopicConnectionFactory) tmp;
          conn = tcf.createTopicConnection("john", "needle");
          topic = (Topic) iniCtx.lookup("topic/testTopic");
  
          session = conn.createTopicSession(false,
                                            TopicSession.AUTO_ACKNOWLEDGE);
          conn.start();
      }
      
      public void recvSync()
          throws JMSException, NamingException
      {
          System.out.println("Begin recvSync");
          // Setup the pub/sub connection, session
          setupPubSub();
          // Wait upto 5 seconds for the message
          TopicSubscriber recv = session.createDurableSubscriber(topic, "chap6-ex1dtps");
          Message msg = recv.receive(5000);
          if (msg == null) {
              System.out.println("Timed out waiting for msg");
          } else {
              System.out.println("DurableTopicRecvClient.recv, msgt=" + msg);
          } 
      }
      
      public void stop() 
          throws JMSException
      {
          conn.stop();
          session.close();
          conn.close();
      }
      
      public static void main(String args[]) 
          throws Exception
      {
          System.out.println("Begin DurableTopicRecvClient, now=" + 
                             System.currentTimeMillis());
          DurableTopicRecvClient client = new DurableTopicRecvClient();
          client.recvSync();
          client.stop();
          System.out.println("End DurableTopicRecvClient");
          System.exit(0);
      }
      
  }</programlisting>
                  </example>
                  <para>Now run the previous topic publisher with the durable topic subscriber as follows:</para>
                  <programlisting>[examples]$ ant -Dchap=chap6 -Dex=1psdt run-example
  ...                
  run-example1psdt:
       [java] Begin DurableTopicSetup
       [java] End DurableTopicSetup
       [java] Begin TopicSendClient, now=1102899834273
       [java] Begin sendAsync
       [java] sendAsync, sent text=A text msg, now=1102899834345
       [java] End sendAsync
       [java] End TopicSendClient
       [java] Begin DurableTopicRecvClient, now=1102899840043
       [java] Begin recvSync
       [java] DurableTopicRecvClient.recv, msgt=SpyTextMessage {
       [java] Header { 
       [java]    jmsDestination  : TOPIC.testTopic.DurableSubscription[
                 clientId=DurableSubscriberExample name=chap6-ex1dtps selector=null]
       [java]    jmsDeliveryMode : 2
       [java]    jmsExpiration   : 0
       [java]    jmsPriority     : 4
       [java]    jmsMessageID    : ID:3-11028998375501
       [java]    jmsTimeStamp    : 1102899837550
       [java]    jmsCorrelationID: null
       [java]    jmsReplyTo      : null
       [java]    jmsType         : null
       [java]    jmsRedelivered  : false
       [java]    jmsProperties   : {}
       [java]    jmsPropReadWrite: false
       [java]    msgReadOnly     : true
       [java]    producerClientId: ID:3
       [java] }
       [java] Body {
       [java]    text            :A text msg, now=1102899834345
       [java] }
       [java] }
       [java] End DurableTopicRecvClient</programlisting>
                  <para>Items of note for the durable topic example include:</para>
                  <itemizedlist>
                      <listitem>
                          <para>The <literal>TopicConnectionFactory</literal> creation in the durable topic client used a
                              username and password, and the <literal>TopicSubscriber</literal> creation was done using
                              the <literal>createDurableSubscriber(Topic, String)</literal> method. This is a requirement
                              of durable topic subscribers. The messaging server needs to know what client is requesting
                              the durable topic and what the name of the durable topic subscription is. We will discuss
                              the details of durable topic setup in the configuration section.</para>
                      </listitem>
                      <listitem>
                          <para>An <literal>org.jboss.chap6.DurableTopicSetup</literal> client was run prior to the
                                  <literal>TopicSendClient</literal>. The reason for this is a durable topic subscriber
                              must have registered a subscription at some point in the past in order for the messaging
                              server to save messages. JBoss supports dynamic durable topic subscribers and the
                                  <literal>DurableTopicSetup</literal> client simply creates a durable subscription
                              receiver and the exits. This leaves an active durable topic subscriber on the
                                  <literal>topic/testTopic</literal> and the messaging server knows that any messages
                              posted to this topic must be saved for latter delivery.</para>
                      </listitem>
                      <listitem>
                          <para>The <literal>TopicSendClient</literal> does not change for the durable topic. The notion
                              of a durable topic is a subscriber only notion.</para>
                      </listitem>
                      <listitem>
                          <para>The <literal>DurableTopicRecvClient</literal> sees the message published to the
                                  <literal>topic/testTopic</literal> even though it was not listening to the topic at the
                              time the message was published.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>A Point-To-Point With MDB Example</title>
                  <para>
                      <xref linkend="ch6.textmessage.ex"/> shows an message driven bean (MDB) that transforms the
                          <literal>TextMessages</literal> it receives and sends the transformed messages to the queue
                      found in the incoming message <literal>JMSReplyTo</literal> header.</para>
                  <example id="ch6.textmessage.ex">
                      <title>A TextMessage processing MDB</title>
                      <programlisting>package org.jboss.chap6.ex2;
                  
  import javax.ejb.MessageDrivenBean;
  import javax.ejb.MessageDrivenContext;
  import javax.ejb.EJBException;
  import javax.jms.JMSException;
  import javax.jms.Message;
  import javax.jms.MessageListener;
  import javax.jms.Queue;
  import javax.jms.QueueConnection;
  import javax.jms.QueueConnectionFactory;
  import javax.jms.QueueSender;
  import javax.jms.QueueSession;
  import javax.jms.TextMessage;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  /** 
   * An MDB that transforms the TextMessages it receives and send the
   * transformed messages to the Queue found in the incoming message
   * JMSReplyTo header.
   * 
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class TextMDB 
      implements MessageDrivenBean, MessageListener
  {
      private MessageDrivenContext ctx = null;
      private QueueConnection conn;
      private QueueSession session;
      
      public TextMDB()
      {
          System.out.println("TextMDB.ctor, this="+hashCode());
      }
      
      public void setMessageDrivenContext(MessageDrivenContext ctx)
      {
          this.ctx = ctx;
          System.out.println("TextMDB.setMessageDrivenContext, this=" + 
                             hashCode());
      }
      
      public void ejbCreate()
      {
          System.out.println("TextMDB.ejbCreate, this="+hashCode());
          try {
              setupPTP();
          } catch (Exception e) {
              throw new EJBException("Failed to init TextMDB", e);
          }
      }
  
      public void ejbRemove()
      {
          System.out.println("TextMDB.ejbRemove, this="+hashCode());
          ctx = null;
          try {
              if (session != null) {
                  session.close();
              }
              if (conn != null) {
                  conn.close();
              }
          } catch(JMSException e) {
              e.printStackTrace();
          }
      }
                  
      public void onMessage(Message msg)
      {
          System.out.println("TextMDB.onMessage, this="+hashCode());
          try {
              TextMessage tm = (TextMessage) msg;
              String text = tm.getText() + "processed by: "+hashCode();
              Queue dest = (Queue) msg.getJMSReplyTo();
              sendReply(text, dest);
          } catch(Throwable t) {
              t.printStackTrace();
          }
      }
                  
      private void setupPTP()
          throws JMSException, NamingException
      {
          InitialContext iniCtx = new InitialContext();
          Object tmp = iniCtx.lookup("java:comp/env/jms/QCF");
          QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;
          conn = qcf.createQueueConnection();
          session = conn.createQueueSession(false,
                                            QueueSession.AUTO_ACKNOWLEDGE);
          conn.start();
      }
  
      private void sendReply(String text, Queue dest)
          throws JMSException
      {
          System.out.println("TextMDB.sendReply, this=" + 
                             hashCode() + ", dest="+dest);
          QueueSender sender = session.createSender(dest);
          TextMessage tm = session.createTextMessage(text);
          sender.send(tm);
          sender.close();
      }
  }</programlisting>
                  </example>
                  <para>The MDB <literal>ejb-jar.xml</literal> and <literal>jboss.xml</literal> deployment descriptors are
                      shown in <xref linkend="ch6.mdbejbjar.ex"/> and <xref linkend="ch6.mdbjboss.ex"/>.</para>
                  <example id="ch6.mdbejbjar.ex">
                      <title>The MDB ejb-jar.xml descriptor</title>
                      <programlisting>&lt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE ejb-jar PUBLIC 
            "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
            "http://java.sun.com/dtd/ejb-jar_2_0.dtd"&gt;
  &lt;ejb-jar&gt;
      &lt;enterprise-beans&gt;
          &lt;message-driven&gt;
              &lt;ejb-name&gt;TextMDB&lt;/ejb-name&gt;
              &lt;ejb-class&gt;org.jboss.chap6.ex2.TextMDB&lt;/ejb-class&gt;
              &lt;transaction-type&gt;Container&lt;/transaction-type&gt;
              &lt;acknowledge-mode&gt;AUTO_ACKNOWLEDGE&lt;/acknowledge-mode&gt;
              &lt;message-driven-destination&gt;
                  &lt;destination-type&gt;javax.jms.Queue&lt;/destination-type&gt;
              &lt;/message-driven-destination&gt;
              &lt;res-ref-name&gt;jms/QCF&lt;/res-ref-name&gt;
              &lt;resource-ref&gt;
                  &lt;res-type&gt;javax.jms.QueueConnectionFactory&lt;/res-type&gt;
                  &lt;res-auth&gt;Container&lt;/res-auth&gt;
              &lt;/resource-ref&gt;
          &lt;/message-driven&gt;
      &lt;/enterprise-beans&gt;
  &lt;/ejb-jar&gt;
  </programlisting>
                  </example>
                  <example id="ch6.mdbjboss.ex">
                      <title>The MDB jboss.xml descriptor</title>
                      <programlisting>&lt;?xml version="1.0"?&gt;
  &lt;jboss&gt;
      &lt;enterprise-beans&gt;
          &lt;message-driven&gt;
              &lt;ejb-name&gt;TextMDB&lt;/ejb-name&gt;
              &lt;destination-jndi-name&gt;queue/B&lt;/destination-jndi-name&gt;
              &lt;resource-ref&gt;
                  &lt;res-ref-name&gt;jms/QCF&lt;/res-ref-name&gt;
                  &lt;jndi-name&gt;ConnectionFactory&lt;/jndi-name&gt;
              &lt;/resource-ref&gt;
          &lt;/message-driven&gt;
      &lt;/enterprise-beans&gt;
  &lt;/jboss&gt;</programlisting>
                  </example>
                  <para>
                      <xref linkend="ch6.textmdbclient.ex"/> shows a variation of the P2P client that sends several
                      messages to the <literal>queue/B</literal> destination and asynchronously receives the messages as
                      modified by <literal>TextMDB</literal> from queue <literal>A</literal>.</para>
                  <example id="ch6.textmdbclient.ex">
                      <title>A JMS client that interacts with the TextMDB</title>
                      <programlisting>package org.jboss.chap6.ex2;
  
  import javax.jms.JMSException;
  import javax.jms.Message;
  import javax.jms.MessageListener;
  import javax.jms.Queue;
  import javax.jms.QueueConnection;
  import javax.jms.QueueConnectionFactory;
  import javax.jms.QueueReceiver;
  import javax.jms.QueueSender;
  import javax.jms.QueueSession;
  import javax.jms.TextMessage;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  import EDU.oswego.cs.dl.util.concurrent.CountDown;
  
  /**
   *  A complete JMS client example program that sends N TextMessages to
   *  a Queue B and asynchronously receives the messages as modified by
   *  TextMDB from Queue A.
   *
   *  @author Scott.Stark at jboss.org
   *  @version $Revision: 1.1 $
   */
  public class SendRecvClient
  {
      static final int N = 10;
      static CountDown done = new CountDown(N);
  
      QueueConnection conn;
      QueueSession session;
      Queue queA;
      Queue queB;
      
      public static class ExListener 
          implements MessageListener
      {
          public void onMessage(Message msg)
          {
              done.release();
              TextMessage tm = (TextMessage) msg;
              try {
                  System.out.println("onMessage, recv text="+tm.getText());
              } catch(Throwable t) {
                  t.printStackTrace();
              }
          }
      }
      
      public void setupPTP()
          throws JMSException, NamingException
      {
          InitialContext iniCtx = new InitialContext();
          Object tmp = iniCtx.lookup("ConnectionFactory");
          QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;
          conn = qcf.createQueueConnection();
          queA = (Queue) iniCtx.lookup("queue/A");
          queB = (Queue) iniCtx.lookup("queue/B");
          session = conn.createQueueSession(false,
                                            QueueSession.AUTO_ACKNOWLEDGE);
          conn.start();
      }
      
      public void sendRecvAsync(String textBase)
          throws JMSException, NamingException, InterruptedException
      {
          System.out.println("Begin sendRecvAsync");
  
          // Setup the PTP connection, session
          setupPTP();
  
          // Set the async listener for queA
          QueueReceiver recv = session.createReceiver(queA);
          recv.setMessageListener(new ExListener());
  
          // Send a few text msgs to queB
          QueueSender send = session.createSender(queB);
  
          for(int m = 0; m &lt; 10; m ++) {
              TextMessage tm = session.createTextMessage(textBase+"#"+m);
              tm.setJMSReplyTo(queA);
              send.send(tm);
              System.out.println("sendRecvAsync, sent text=" + tm.getText());
          }
          System.out.println("End sendRecvAsync");
      }
      
      public void stop() 
          throws JMSException
      {
          conn.stop();
          session.close();
          conn.close();
      }
      
      public static void main(String args[]) 
          throws Exception
      {
          System.out.println("Begin SendRecvClient,now=" + 
                             System.currentTimeMillis());
          SendRecvClient client = new SendRecvClient();
          client.sendRecvAsync("A text msg");
          client.done.acquire();
          client.stop();
          System.exit(0);
          System.out.println("End SendRecvClient");
      }
      
  }</programlisting>
                  </example>
                  <para>Run the client as follows:</para>
                  <programlisting>[examples]$ ant -Dchap=chap6 -Dex=2 run-example
  ...
  run-example2:
       [copy] Copying 1 file to /tmp/jboss-4.0.2/server/default/deploy
       [echo] Waiting 5 seconds for deploy...
       [java] Begin SendRecvClient, now=1102900541558
       [java] Begin sendRecvAsync
       [java] sendRecvAsync, sent text=A text msg#0
       [java] sendRecvAsync, sent text=A text msg#1
       [java] sendRecvAsync, sent text=A text msg#2
       [java] sendRecvAsync, sent text=A text msg#3
       [java] sendRecvAsync, sent text=A text msg#4
       [java] sendRecvAsync, sent text=A text msg#5
       [java] sendRecvAsync, sent text=A text msg#6
       [java] sendRecvAsync, sent text=A text msg#7
       [java] sendRecvAsync, sent text=A text msg#8
       [java] sendRecvAsync, sent text=A text msg#9
       [java] End sendRecvAsync
       [java] onMessage, recv text=A text msg#0processed by: 12855623
       [java] onMessage, recv text=A text msg#5processed by: 9399816
       [java] onMessage, recv text=A text msg#9processed by: 6598158
       [java] onMessage, recv text=A text msg#3processed by: 8153998
       [java] onMessage, recv text=A text msg#4processed by: 10118602
       [java] onMessage, recv text=A text msg#2processed by: 1792333
       [java] onMessage, recv text=A text msg#7processed by: 14251014
       [java] onMessage, recv text=A text msg#1processed by: 10775981
       [java] onMessage, recv text=A text msg#8processed by: 6056676
       [java] onMessage, recv text=A text msg#6processed by: 15679078</programlisting>
                  <para>The corresponding JBoss server console output is:</para>
                  <programlisting>19:15:40,232 INFO  [EjbModule] Deploying TextMDB
  19:15:41,498 INFO  [EJBDeployer] Deployed: file:/private/tmp/jboss-4.0.2/server/default/deplo
  y/chap6-ex2.jar
  19:15:45,606 INFO  [TextMDB] TextMDB.ctor, this=10775981
  19:15:45,620 INFO  [TextMDB] TextMDB.ctor, this=1792333
  19:15:45,627 INFO  [TextMDB] TextMDB.setMessageDrivenContext, this=10775981
  19:15:45,638 INFO  [TextMDB] TextMDB.ejbCreate, this=10775981
  19:15:45,640 INFO  [TextMDB] TextMDB.setMessageDrivenContext, this=1792333
  19:15:45,640 INFO  [TextMDB] TextMDB.ejbCreate, this=1792333
  19:15:45,649 INFO  [TextMDB] TextMDB.ctor, this=12855623
  19:15:45,658 INFO  [TextMDB] TextMDB.setMessageDrivenContext, this=12855623
  19:15:45,661 INFO  [TextMDB] TextMDB.ejbCreate, this=12855623
  19:15:45,742 INFO  [TextMDB] TextMDB.ctor, this=8153998
  19:15:45,744 INFO  [TextMDB] TextMDB.setMessageDrivenContext, this=8153998
  19:15:45,744 INFO  [TextMDB] TextMDB.ejbCreate, this=8153998
  19:15:45,763 INFO  [TextMDB] TextMDB.ctor, this=10118602
  19:15:45,764 INFO  [TextMDB] TextMDB.setMessageDrivenContext, this=10118602
  19:15:45,764 INFO  [TextMDB] TextMDB.ejbCreate, this=10118602
  19:15:45,777 INFO  [TextMDB] TextMDB.ctor, this=9399816
  19:15:45,779 INFO  [TextMDB] TextMDB.setMessageDrivenContext, this=9399816
  19:15:45,779 INFO  [TextMDB] TextMDB.ejbCreate, this=9399816
  19:15:45,792 INFO  [TextMDB] TextMDB.ctor, this=15679078
  19:15:45,798 INFO  [TextMDB] TextMDB.setMessageDrivenContext, this=15679078
  19:15:45,799 INFO  [TextMDB] TextMDB.ejbCreate, this=15679078
  19:15:45,815 INFO  [TextMDB] TextMDB.ctor, this=14251014
  19:15:45,816 INFO  [TextMDB] TextMDB.setMessageDrivenContext, this=14251014
  19:15:45,817 INFO  [TextMDB] TextMDB.ejbCreate, this=14251014
  19:15:45,829 INFO  [TextMDB] TextMDB.ctor, this=6056676
  19:15:45,831 INFO  [TextMDB] TextMDB.setMessageDrivenContext, this=6056676
  19:15:45,864 INFO  [TextMDB] TextMDB.ctor, this=6598158
  19:15:45,903 INFO  [TextMDB] TextMDB.ejbCreate, this=6056676
  19:15:45,906 INFO  [TextMDB] TextMDB.setMessageDrivenContext, this=6598158
  19:15:45,906 INFO  [TextMDB] TextMDB.ejbCreate, this=6598158
  19:15:46,236 INFO  [TextMDB] TextMDB.onMessage, this=12855623
  19:15:46,238 INFO  [TextMDB] TextMDB.sendReply, this=12855623, dest=QUEUE.A
  19:15:46,734 INFO  [TextMDB] TextMDB.onMessage, this=9399816
  19:15:46,736 INFO  [TextMDB] TextMDB.onMessage, this=8153998
  19:15:46,737 INFO  [TextMDB] TextMDB.onMessage, this=6598158
  19:15:46,768 INFO  [TextMDB] TextMDB.sendReply, this=9399816, dest=QUEUE.A
  19:15:46,768 INFO  [TextMDB] TextMDB.sendReply, this=6598158, dest=QUEUE.A
  19:15:46,774 INFO  [TextMDB] TextMDB.sendReply, this=8153998, dest=QUEUE.A
  19:15:46,903 INFO  [TextMDB] TextMDB.onMessage, this=10118602
  19:15:46,904 INFO  [TextMDB] TextMDB.sendReply, this=10118602, dest=QUEUE.A
  19:15:46,927 INFO  [TextMDB] TextMDB.onMessage, this=1792333
  19:15:46,928 INFO  [TextMDB] TextMDB.sendReply, this=1792333, dest=QUEUE.A
  19:15:47,002 INFO  [TextMDB] TextMDB.onMessage, this=14251014
  19:15:47,007 INFO  [TextMDB] TextMDB.sendReply, this=14251014, dest=QUEUE.A
  19:15:47,051 INFO  [TextMDB] TextMDB.onMessage, this=10775981
  19:15:47,051 INFO  [TextMDB] TextMDB.sendReply, this=10775981, dest=QUEUE.A
  19:15:47,060 INFO  [TextMDB] TextMDB.onMessage, this=6056676
  19:15:47,061 INFO  [TextMDB] TextMDB.sendReply, this=6056676, dest=QUEUE.A
  19:15:47,064 INFO  [TextMDB] TextMDB.onMessage, this=15679078
  19:15:47,065 INFO  [TextMDB] TextMDB.sendReply, this=15679078, dest=QUEUE.A</programlisting>
                  <para>Items of note in this example include:</para>
                  <itemizedlist>
                      <listitem>
                          <para>The JMS client has no explicit knowledge that it is dealing with an MDB. The client simply
                              uses the standard JMS APIs to send messages to a queue and receive messages from another
                              queue.</para>
                      </listitem>
                      <listitem>
                          <para>The MDB declares whether it will listen to a queue or topic in the
                              <literal>ejb-jar.xml</literal> descriptor. The name of the queue or topic must be specified
                              using a <literal>jboss.xml</literal> descriptor. In this example the MDB also sends messages
                              to a JMS queue. MDBs may act as queue senders or topic publishers within their
                                  <literal>onMessage</literal> callback.</para>
                      </listitem>
                      <listitem>
                          <para>The messages received by the client include a "processed by: NNN" suffix, where NNN is the
                                  <literal>hashCode</literal> value of the MDB instance that processed the message. This
                              shows that many MDBs may actively process messages posted to a destination. Concurrent
                              processing is one of the benefits of MDBs.</para>
                      </listitem>
                  </itemizedlist>
              </section>
          </section>
          <section>
              <title>JBoss Messaging Overview</title>
              <para>JBossMQ is composed of several services working together to provide JMS API level services to client
                  applications. The services that make up the JBossMQ JMS implementation are introduced in this section.</para>
              <section>
                  <title>Invocation Layer</title>
                  <para>The Invocation Layer (IL) services are responsible for handling the communication protocols that
                      clients use to send and receive messages. JBossMQ can support running different types of Invocation
                      Layers concurrently. All Invocation Layers support bidirectional communication which allows clients
                      to send and receive messages concurrently. ILs only handle the transport details of messaging. They
                      delegate messages to the JMS server JMX gateway service known as the invoker. This is similar to how
                      the detached invokers expose the EJB container via different transports.</para>
                  <para>Each IL service binds a JMS connection factory to a specific location in the JNDI tree. Clients
                      choose the protocol they wish to use by the JNDI location used to obtain the JMS connection factory.
                      JBossMQ currently has several different invocation layers. </para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">UIL2 IL</emphasis>: The Unified Invocation Layer version 2(UIL2) is
                              the preferred invocation layer for remote messaging. A multiplexing layer is used to provide
                              bidirectional communication. The multiplexing layer creates two virtual sockets over one
                              physical socket. This allows communication with clients that cannot have a connection
                              created from the server back to the client due to firewall or other restrictions. Unlike the
                              older UIL invocation layer which used a blocking round-trip message at the socket level, the
                              UIL2 protocol uses true asynchronous send and receive messaging at the transport level,
                              providing for improved throughput and utilization.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">JVM IL</emphasis>: The Java Virtual Machine (JVM) Invocation Layer was
                              developed to cut out the TCP/IP overhead when the JMS client is running in the same JVM as
                              the server. This IL uses direct method calls for the server to service the client requests.
                              This increases efficiency since no sockets are created and there is no need for the
                              associated worker threads. This is the IL that should be used by Message Driven Beans (MDB)
                              or any other component that runs in the same virtual machine as the server such as servlets,
                              MBeans, or EJBs.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">HTTP IL</emphasis>: The HTTP Invocation Layer (HTTPIL) allows for
                              accessing the JBossMQ service over the HTTP or HTTPS protocols. This IL relies on the
                              servlet deployed in the <literal>deploy/jms/jbossmq-httpil.sar</literal> to handle the http
                              traffic. This IL is useful for access to JMS through a firewall when the only port allowed
                              requires HTTP.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>Security Manager</title>
                  <para>The JBossMQ <literal>SecurityManager</literal> is the service that enforces an access control list
                      to guard access to your destinations. This subsystem works closely with the
                      <literal>StateManager</literal> service.</para>
              </section>
              <section>
                  <title>Destination Manager</title>
                  <para>The <literal>DestinationManager</literal> can be thought as being the central service in JBossMQ.
                      It keeps track of all the destinations that have been created on the server. It also keeps track of
                      the other key services such as the <literal>MessageCache</literal>, <literal>StateManager</literal>,
                      and <literal>PersistenceManager</literal>.</para>
              </section>
              <section>
                  <title>Message Cache</title>
                  <para>Messages created in the server are passed to the <literal>MessageCache</literal> for memory
                      management. JVM memory usage goes up as messages are added to a destination that does not have any
                      receivers. These messages are held in the main memory until the receiver picks them up. If the
                          <literal>MessageCache</literal> notices that the JVM memory usage starts passing the defined
                      limits, the <literal>MessageCache</literal> starts moving those messages from memory to persistent
                      storage on disk. The <literal>MessageCache</literal> uses a least recently used (LRU) algorithm to
                      determine which messages should go to disk.</para>
              </section>
              <section>
                  <title>State Manager</title>
                  <para>The <literal>StateManager</literal> (SM) is in charge of keeping track of who is allowed to log
                      into the server and what their durable subscriptions are.</para>
              </section>
              <section>
                  <title>Persistence Manager</title>
                  <para>The <literal>PersistenceManager</literal> (PM) is used by a destination to store messages marked
                      as being persistent. JBossMQ has several different implementations of the persistent manager, but
                      only one can be enabled per server instance. You should enable the persistence manager that best
                      matches your requirements.</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">JDBC2 persistence manager</emphasis>: The JDBC2 persistence manager
                              allows you to store persistent messages to a relational database using JDBC. The performance
                              of this PM is directly related to the performance that can be obtained from the database.
                              This PM has a very low memory overhead compared to the other persistence managers.
                              Furthermore it is also highly integrated with the <literal>MessageCache</literal> to provide
                              efficient persistence on a system that has a very active <literal>MessageCache</literal>.
                          </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Null Persistence Manager</emphasis>: A wrapper persistence manager
                              that can delegate to a real persistence manager. Configuration on the destinations decide
                              whether persistence and caching is actually performed. The example configuration can be
                              found in <literal>docs/examples/jms</literal>. To use the null persistence manager backed by
                              a real persistence manager, you need to change the <literal>ObjectName</literal> of the real
                              persistence manager and link the new name to the null persistence manager.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>Destinations</title>
                  <para>A destination is the object on the JBossMQ server that clients use to send and receive messages.
                      There are two types of destination objects, <literal>Queues</literal> and <literal>Topics</literal>.
                      References to the destinations created by JBossMQ are stored in JNDI.</para>
                  <section>
                      <title>Queues</title>
                      <para>Clients that are in the point-to-point paradigm typically use queues. They expect that message
                          sent to a queue will be receive by only one other client once and only once. If multiple clients
                          are receiving messages from a single queue, the messages will be load balanced across the
                          receivers. Queue objects, by default, will be stored under the JNDI <literal>queue/</literal>
                          sub context.</para>
                  </section>
                  <section>
                      <title>Topics</title>
                      <para>Topics are used in the publish-subscribe paradigm. When a client publishes a message to a
                          topic, he expects that a copy of the message will be delivered to each client that has
                          subscribed to the topic. Topic messages are delivered in the same manner a television show is
                          delivered. Unless you have the TV on and are watching the show, you will miss it. Similarly, if
                          the client is not up, running and receiving messages from the topics, it will miss messages
                          published to the topic. To get around this problem of missing messages, clients can start a
                          durable subscription. This is like having a VCR record a show you cannot watch at its scheduled
                          time so that you can see what you missed when you turn your TV back on.</para>
                  </section>
              </section>
          </section>
          <section>
              <title>JBoss Messaging Configuration and MBeans</title>
              <para>This section defines the MBean services that correspond to the components introduced in the previous
                  section along with their MBean attributes. The configuration and service files that make up the JBossMQ
                  system include:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">deploy/hsqldb-jdbc-state-service.xml</emphasis>: This configures the JDBC
                          state service for storing state in the embedded Hypersonic database.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">deploy/jms/hsqldb-jdbc2-service.xml</emphasis>: This service descriptor
                          configures the <literal>DestinationManager</literal>, <literal>MessageCache</literal>, and jdbc2
                              <literal>PersistenceManager</literal> for the embedded Hypersonic database.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">deploy/jms/jbossmq-destinations-service.xml</emphasis>: This service
                          describes defines default JMS queue and topic destination configurations used by the testsuite
                          unit tests. You can add/remove destinations to this file, or deploy another
                              <literal>*-service.xml</literal> descriptor with the destination configurations.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">jbossmq-httpil.sar</emphasis>: This SAR file configures the HTTP
                          invocation layer. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">deploy/jms/jbossmq-service.xml</emphasis>: This service descriptor
                          configures the core JBossMQ MBeans like the <literal>Invoker</literal>,
                          <literal>SecurityManager</literal>, <literal>DynamicStateManager</literal>, and core interceptor
                          stack. It also defines the MDB default dead letter queue <literal>DLQ</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">deploy/jms/jms-ds.xml</emphasis>: This is a JCA connection factory and JMS
                          provider MDB integration services configuration which sets JBossMQ as the JMS provider.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">deploy/jms/jms-ra.rar</emphasis>: This is a JCA resource adaptor for JMS
                          providers.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">deploy/jms/jvm-il-service.xml</emphasis>: This service descriptor
                          configures the <literal>JVMServerILService</literal> which provides the JVM IL transport.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">deploy/jms/rmi-il-service.xml</emphasis>: This service descriptor
                          configures the <literal>RMIServerILService</literal> which provides the RMI IL. The queue and
                          topic connection factory for this IL is bound under the name
                          <literal>RMIConnectionFactory</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">deploy/jms/uil2-service.xml</emphasis>: This service descriptor configures
                          the <literal>UILServerILService</literal> which provides the UIL2 transport. The queue and topic
                          connection factory for this IL is bound under the name <literal>UIL2ConnectionFactory</literal>
                          as well as <literal>UILConnectionFactory</literal> to replace the deprecated version 1 UIL
                          service.</para>
                  </listitem>
              </itemizedlist>
              <para>We will discuss the associated MBeans in the following subsections.</para>
              <section>
                  <title>org.jboss.mq.il.jvm.JVMServerILService</title>
                  <para>The <literal>org.jboss.mq.il.jvm.JVMServerILService</literal> MBean is used to configure the JVM
                      IL. The configurable attributes are as follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">Invoker</emphasis>: This attribute specifies JMX ObjectName of the JMS
                              entry point service that is used to pass incoming requests to the JMS server. This is not
                              something you would typically change from the <literal>jboss.mq:service=Invoker</literal>
                              setting unless you change the entry point service.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ConnectionFactoryJNDIRef</emphasis>: The JNDI location that this IL
                              will bind a <literal>ConnectionFactory</literal> setup to use this IL.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">XAConnectionFactoryJNDIRef</emphasis>: The JNDI location that this IL
                              will bind a <literal>XAConnectionFactory</literal> setup to use this IL.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">PingPeriod</emphasis>: How often, in milliseconds, the client should
                              send a ping message to the server to validate that the connection is still valid. If this is
                              set to zero, then no ping message will be sent. Since it is impossible for JVM IL connection
                              to go bad, it is recommended that you keep this set to 0.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>org.jboss.mq.il.uil2.UILServerILService</title>
                  <para>The <literal>org.jboss.mq.il.uil2.UILServerILService</literal> is used to configure the UIL2 IL.
                      The configurable attributes are as follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">Invoker</emphasis>: This attribute specifies JMX
                              <literal>ObjectName</literal> of the JMS entry point service that is used to pass incoming
                              requests to the JMS server. This is not something you would typically change from the
                                  <literal>jboss.mq:service=Invoker</literal> setting unless you change the entry point
                              service.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ConnectionFactoryJNDIRef</emphasis>: The JNDI location that this IL
                              will bind a <literal>ConnectionFactory</literal> setup to use this IL.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">XAConnectionFactoryJNDIRef</emphasis>: The JNDI location that this IL
                              will bind a <literal>XAConnectionFactory</literal> setup to use this IL.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">PingPeriod</emphasis>: How often, in milliseconds, the client should
                              send a ping message to the server to validate that the connection is still valid. If this is
                              set to zero, then no ping message will be sent.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ReadTimeout</emphasis>: The period in milliseconds is passed onto as
                              the <literal>SoTimeout</literal> value of the UIL2 socket. This allows detection of dead
                              sockets that are not responsive and are not capable of receiving ping messages. Note that
                              this setting should be longer in duration than the <literal>PingPeriod</literal>
                          setting.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">BufferSize</emphasis>: The size in bytes used as the buffer over the
                              basic socket streams. This corresponds to the
                              <literal>java.io.BufferedOutputStream</literal> buffer size.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ChunkSize</emphasis>: The size in bytes between stream listener
                              notifications. The UIL2 layer uses the
                                  <literal>org.jboss.util.stream.NotifyingBufferedOutputStream</literal> and
                                  <literal>NotifyingBufferedInputStream</literal> implementations that support the notion
                              of a heartbeat that is triggered based on data read/written to the stream. Whenever
                                  <literal>ChunkSize</literal> bytes are read/written to a stream. This allows serves as a
                              ping or keepalive notification when large reads or writes require a duration greater than
                              the <literal>PingPeriod</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ServerBindPort</emphasis>: The protocol listening port for this IL. If
                              not specified default is 0, which means that a random port will be chosen.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">BindAddress</emphasis>: The specific address this IL listens on. This
                              can be used on a multi-homed host for a <literal>java.net.ServerSocket</literal> that will
                              only accept connection requests on one of its addresses.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">EnableTcpNoDelay</emphasis>: <literal>TcpNoDelay</literal> causes
                              TCP/IP packets to be sent as soon as the request is flushed. This may improve request
                              response times. Otherwise request packets may be buffered by the operating system to create
                              larger IP packets.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ServerSocketFactory</emphasis>: The
                                  <literal>javax.net.ServerSocketFactory</literal> implementation class name to use to
                              create the service <literal>java.net.ServerSocket</literal>. If not specified the default
                              factory will be obtained from
                          <literal>javax.net.ServerSocketFactory.getDefault()</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ClientAddress</emphasis>: The address passed to the client as the
                              address that should be used to connect to the server.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ClientSocketFactory</emphasis>: The
                              <literal>javax.net.SocketFactory</literal> implementation class name to use on the client.
                              If not specified the default factory will be obtained from
                                  <literal>javax.net.SocketFactory.getDefault()</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SecurityDomain</emphasis>: Specify the security domain name to use
                              with JBoss SSL aware socket factories. This is the JNDI name of the security manager
                              implementation as described for the <literal>security-domain</literal> element of the
                                  <literal>jboss.xml</literal> and <literal>jboss-web.xml</literal> descriptors in <xref
                                  linkend="ch8.declarativesecurity2.sect"/>.</para>
                      </listitem>
                  </itemizedlist>
                  <section>
                      <title>Configuring UIL2 for SSL</title>
                      <para>The UIL2 service support the use of SSL through custom socket factories that integrate JSSE
                          using the security domain associated with the IL service. An example UIL2 service descriptor
                          fragment that illustrates the use of the custom JBoss SSL socket factories is shown in <xref
                              linkend="ch6.uil2config.ex"/>.</para>
                      <example id="ch6.uil2config.ex">
                          <title>An example UIL2 config fragment for using SSL</title>
                          <programlisting>&lt;mbean code="org.jboss.mq.il.uil2.UILServerILService"
      name="jboss.mq:service=InvocationLayer,type=HTTPSUIL2"&gt;
      &lt;depends optional-attribute-name="Invoker"&gt;jboss.mq:service=Invoker&lt;/depends&gt;
      &lt;attribute name="ConnectionFactoryJNDIRef"&gt;SSLConnectionFactory&lt;/attribute&gt;
      &lt;attribute name="XAConnectionFactoryJNDIRef"&gt;SSLXAConnectionFactory&lt;/attribute&gt;
      
      &lt;!-- ... --&gt;
  
      &lt;!-- SSL Socket Factories --&gt;
      &lt;attribute name="ClientSocketFactory"&gt;
          org.jboss.security.ssl.ClientSocketFactory
      &lt;/attribute&gt;
      &lt;attribute name="ServerSocketFactory"&gt;
          org.jboss.security.ssl.DomainServerSocketFactory
      &lt;/attribute&gt;
      &lt;!-- Security domain - see below --&gt;
      &lt;attribute name="SecurityDomain"&gt;java:/jaas/SSL&lt;/attribute&gt;
  &lt;/mbean&gt;
  
  &lt;!-- Configures the keystore on the "SSL" security domain
       This mbean is better placed in conf/jboss-service.xml where it
       can be used by other services, but it will work from anywhere.
       Use keytool from the sdk to create the keystore. --&gt;
       
  &lt;mbean code="org.jboss.security.plugins.JaasSecurityDomain"
         name="jboss.security:service=JaasSecurityDomain,domain=SSL"&gt;
      &lt;!-- This must correlate with the java:/jaas/SSL above --&gt;
      &lt;constructor&gt;
          &lt;arg type="java.lang.String" value="SSL"/&gt;
      &lt;/constructor&gt;
      &lt;!-- The location of the keystore resource: loads from the
           classpath and the server conf dir is a good default --&gt;
      &lt;attribute name="KeyStoreURL"&gt;resource:uil2.keystore&lt;/attribute&gt;
      &lt;attribute name="KeyStorePass"&gt;changeme&lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
                      </example>
                  </section>
                  <section>
                      <title>JMS client properties for the UIL2 transport</title>
                      <para> There are several system properties that a JMS client using the UIL2 transport can set to
                          control the client connection back to the server</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">org.jboss.mq.il.uil2.useServerHost</emphasis>: This system
                                  property allows a client to connect to the server
                                  <literal>InetAddress.getHostName</literal> rather than
                                      the<literal>InetAddress.getHostAddress</literal> value. This will only make a
                                  difference if name resolution differs between the server and client environments.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">org.jboss.mq.il.uil2.localAddr</emphasis>: This system property
                                  allows a client to define the local interface to which its sockets should be
                              bound.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">org.jboss.mq.il.uil2.localPort</emphasis>: This system property
                                  allows a client to define the local port to which its sockets should be bound</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">org.jboss.mq.il.uil2.serverAddr</emphasis>: This system property
                                  allows a client to override the address to which it attempts to connect to. This is
                                  useful for networks where NAT is occcurring between the client and JMS server.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">org.jboss.mq.il.uil2.serverPort</emphasis>: This system property
                                  allows a client to override the port to which it attempts to connect. This is useful for
                                  networks where port forwarding is occurring between the client and jms server.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">org.jboss.mq.il.uil2.retryCount</emphasis>: This system property
                                  controls the number of attempts to retry connecting to the JMS server. Retries are only
                                  made for <literal>java.net.ConnectException</literal> failures. A value &lt;= 0
                                  means no retry attempts will be made.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">org.jboss.mq.il.uil2.retryDelay</emphasis>: This system property
                                  controls the delay in milliseconds between retries due to
                                  <literal>ConnectException</literal> failures.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
              </section>
              <section>
                  <title>org.jboss.mq.il.http.HTTPServerILService</title>
                  <para>The <literal>org.jboss.mq.il.http.HTTPServerILService</literal> is used to manage the HTTP/S IL.
                      This IL allows for the use of the JMS service over HTTP or HTTPS connections. The relies on the
                      servlet deployed in the <literal>deploy/jms/jbossmq-httpil.sar</literal> to handle the HTTP traffic.
                      The configurable attributes are as follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">TimeOut</emphasis>: The default timeout in seconds that the client
                              HTTP requests will wait for messages. This can be overridden on the client by setting the
                              system property <literal>org.jboss.mq.il.http.timeout</literal> to the number of
                          seconds.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">RestInterval</emphasis>: The number of seconds the client will sleep
                              after each request. The default is 0, but you can set this value in conjunction with the
                                  <literal>TimeOut</literal> value to implement a pure timed based polling mechanism. For
                              example, you could simply do a short lived request by setting the <literal>TimeOut</literal>
                              value to 0 and then setting the <literal>RestInterval</literal> to 60. This would cause the
                              client to send a single non-blocking request to the server, return any messages if
                              available, then sleep for 60 seconds, before issuing another request. Like the
                                  <literal>TimeOut</literal> value, this can be explicitly overridden on a given client by
                              specifying the <literal>org.jboss.mq.il.http.restinterval</literal> with the number of
                              seconds you wish to wait between requests.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">URL</emphasis>: Set the servlet URL. This value takes precedence over
                              any individual values set (i.e. the <literal>URLPrefix</literal>,
                              <literal>URLSuffix</literal>, <literal>URLPort</literal>, etc.) It my be a actual URL or a
                              property name which will be used on the client side to resolve the proper URL by calling
                                  <literal>System.getProperty(propertyname)</literal>. If not specified the URL will be
                              formed from <literal>URLPrefix + URLHostName + ":" + URLPort + "/" +
                          URLSuffix</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">URLPrefix</emphasis>: The prefix portion of the servlet URL.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">URLHostName</emphasis>: The hostname portion of the servlet
                          URL.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">URLPort</emphasis>: The port portion of the URL.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">URLSuffix</emphasis>: The trailing path portion of the URL.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">UseHostName</emphasis>: A flag that if set to true the default setting
                              for the <literal>URLHostName</literal> attribute will be taken from
                                  <literal>InetAddress.getLocalHost().getHostName()</literal>. If false the default
                              setting for the <literal>URLHostName</literal> attribute will be taken from
                                  <literal>InetAddress.getLocalHost().getHostAddress()</literal>.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>org.jboss.mq.server.jmx.Invoker</title>
                  <para>The <literal>org.jboss.mq.server.jmx.Invoker</literal> is used to pass IL requests down to the
                      destination manager service through an interceptor stack. The configurable attributes are as
                      follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">NextInterceptor</emphasis>: The JMX <literal>ObjectName</literal> of
                              the next request interceptor. This attribute is used by all the interceptors to create the
                              interceptor stack. The last interceptor in the chain should be the
                                  <literal>DestinationManager</literal>.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>org.jboss.mq.server.jmx.InterceptorLoader</title>
                  <para>The <literal>org.jboss.mq.server.jmx.InterceptorLoader</literal> is used to load a generic
                      interceptor and make it part of the interceptor stack. This MBean is typically used to load custom
                      interceptors like <literal>org.jboss.mq.server.TracingInterceptor</literal>, which is can be used to
                      efficiently log all client requests via trace level log messages. The configurable attributes are as
                      follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">NextInterceptor</emphasis>: The JMX <literal>ObjectName</literal> of
                              the next request interceptor. This attribute is used by all the interceptors to create the
                              interceptor stack. The last interceptor in the chain should be the
                                  <literal>DestinationManager</literal>. This attribute should be setup via a
                                  <literal>&lt;depends optional-attribute-name="NextInterceptor"&gt;</literal> XML
                              tag.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">InterceptorClass</emphasis>: The class name of the interceptor that
                              will be loaded and made part of the interceptor stack. This class specified here must extend
                              the <literal>org.jboss.mq.server.JMSServerInterceptor</literal> class.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>org.jboss.mq.sm.jdbc.JDBCStateManager</title>
                  <para>The <literal>JDBCStateManager</literal> MBean is used as the default state manager assigned to the
                      DestinationManager service. It stores user and durable subscriber information in the database. The
                      configurable attributes are as follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">ConnectionManager</emphasis>: This is the
                              <literal>ObjectName</literal> of the datasource that the JDBC state manager will write to.
                              For Hypersonic, it is
                          <literal>jboss.jca:service=DataSourceBinding,name=DefaultDS</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SqlProperties</emphasis>: The <literal>SqlProperties</literal> define
                              the SQL statements to be used to persist JMS state data. If the underlying database is
                              changed, the SQL statements used may need to change.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>org.jboss.mq.security.SecurityManager</title>
                  <para>If the <literal>org.jboss.mq.security.SecurityManager</literal> is part of the interceptor stack,
                      then it will enforce the access control lists assigned to the destinations. The
                          <literal>SecurityManager</literal> uses JAAS, and as such requires that at application policy be
                      setup for in the JBoss <literal>login-config.xml</literal> file. The default configuration is shown
                      below.</para>
                  <programlisting>&lt;application-policy name=&quot;jbossmq&quot;&gt;
      &lt;authentication&gt;
          &lt;login-module code=&quot;org.jboss.security.auth.spi.DatabaseServerLoginModule&quot;         
                        flag=&quot;required&quot;&gt;
              &lt;module-option name=&quot;unauthenticatedIdentity&quot;&gt;guest&lt;/module-option&gt;
              &lt;module-option name=&quot;dsJndiName&quot;&gt;java:/DefaultDS&lt;/module-option&gt;
              &lt;module-option name=&quot;principalsQuery&quot;&gt;SELECT PASSWD FROM JMS_USERS
                  WHERE USERID=?&lt;/module-option&gt;
              &lt;module-option name=&quot;rolesQuery&quot;&gt;SELECT ROLEID, &apos;Roles&apos; FROM
                  JMS_ROLES WHERE USERID=?&lt;/module-option&gt;
          &lt;/login-module&gt;
      &lt;/authentication&gt;
  &lt;/application-policy&gt;</programlisting>
                  <para>The configurable attributes of the SecurityManager are as follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">NextInterceptor</emphasis>: The JMX <literal>ObjectName</literal> of
                              the next request interceptor. This attribute is used by all the interceptors to create the
                              interceptor stack. The last interceptor in the chain should be the
                                  <literal>DestinationManager</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SecurityDomain</emphasis>: Specify the security domain name to use for
                              authentication and role based authorization. This is the JNDI name of the JAAS domain to be
                              used to perform authentication and authorization against. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">DefaultSecurityConfig</emphasis>: This element specifies the default
                              security configuration settings for destinations. This applies to temporary queues and
                              topics as well as queues and topics that do not specifically specify a security
                              configuration. The <literal>DefaultSecurityConfig</literal> should declare some number of
                                  <literal>role</literal> elements which represent each role that is allowed access to a
                              destination. Each <literal>role</literal> should have the following attributes: <itemizedlist>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">name</emphasis>: The <literal>name</literal> attribute
                                          defines the name of the role.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">create</emphasis>: The <literal>create</literal> attribute
                                          is a true/false value that indicates whether the role has the ability to create
                                          durable subscriptions on the topic.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">read</emphasis>: The <literal>read</literal> attribute is
                                          a true/false value that indicates whether the role can receive messages from the
                                          destination.</para>
                                  </listitem>
                                  <listitem>
                                      <para>
                                          <emphasis role="bold">write</emphasis>: The <literal>write</literal> attribute
                                          is a true/false value that indicates whether the role can send messages to the
                                          destination.</para>
                                  </listitem>
                              </itemizedlist>
                          </para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>org.jboss.mq.server.jmx.DestinationManager</title>
                  <para>The <literal>org.jboss.mq.server.jmx.DestinationManager</literal> must be the last interceptor in
                      the interceptor stack. The configurable attributes are as follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">PersistenceManager</emphasis>: The JMX <literal>ObjectName</literal>
                              of the persistence manager service the server should use. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">StateManager</emphasis>: The JMX <literal>ObjectName</literal> of the
                              state manager service the server should use. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MessageCache</emphasis>: The JMX <literal>ObjectName</literal> of the
                              message cache service the server should use. </para>
                      </listitem>
                  </itemizedlist>
                  <para>Additional read-only attributes and operations that support monitoring include:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">ClientCount</emphasis>: The number of clients connected to the
                          server.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Clients</emphasis>: A
                                  <literal>java.util.Map&lt;org.jboss.mq.ConnectionToken,
                                  org.jboss.mq.server.ClientConsumer&gt;</literal> instances for the clients connected
                              to the server.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MessageCounter</emphasis>: An array of
                              org.jboss.mq.server.MessageCounter instances that provide statistics for a JMS
                          destination.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">listMessageCounter()</emphasis>: This operation generates an HTML
                              table that contains:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">Type</emphasis>: Either <literal>Queue</literal> or
                                          <literal>Topic</literal> indicating the destination type.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">Name</emphasis>: The name of the destination.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">Subscription</emphasis>: The subscription ID for a
                                  topic.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">Durable</emphasis>: A boolean indicating if the topic
                                      subscription is durable.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">Count</emphasis>: The number of message delivered to the
                                      destination.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">CountDelta</emphasis>: The change in message count since the
                                      previous access of count.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">Depth</emphasis>: The number of messages in the
                                  destination.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">DepthDelta</emphasis>: The change in the number of messages in
                                      the destination since the previous access of depth.</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">Last Add</emphasis>: The date/time string in
                                          <literal>DateFormat.SHORT</literal>/<literal>DateFormat.MEDIUM</literal> format
                                      of the last time a message was added to the destination.</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">resetMessageCounter()</emphasis>: This zeros all destination counts
                              and last added times.</para>
                      </listitem>
                  </itemizedlist>
                  <para> Queues and topics can be created and destroyed at runtime through the
                      <literal>DestinationManager</literal> MBean. The <literal>DestinationManager</literal> provides
                          <literal>createQueue</literal> and <literal>createTopic</literal> operations for this. Both
                      methods have a one argument version which takes the destination name and a two argument version
                      which takes the destination and the JNDI name of the destination. Queues and topics can be removed
                      using the <literal>destroyQueue</literal> and <literal>destroyTopic</literal> operations, both of
                      which take a destination name is input. </para>
              </section>
              <section>
                  <title>org.jboss.mq.server.MessageCache</title>
                  <para>The server determines when to move messages to secondary storage by using the
                          <literal>org.jboss.mq.server.MessageCache</literal> MBean. The configurable attributes are as
                      follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">CacheStore</emphasis>: The JMX <literal>ObjectName</literal> of the
                              service that will act as the cache store. The cache store is used by the
                                  <literal>MessageCache</literal> to move messages to persistent storage. The value you
                              set here typically depends on the type of persistence manager you are using.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">HighMemoryMark</emphasis>: The amount of JVM heap memory in megabytes
                              that must be reached before the <literal>MessageCache</literal> starts to move messages to
                              secondary storage.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MaxMemoryMark</emphasis>: The maximum amount of JVM heap memory in
                              megabytes that the <literal>MessageCache</literal> considers to be the max memory mark. As
                              memory usage approaches the max memory mark, the <literal>MessageCache</literal> will move
                              messages to persistent storage so that the number of messages kept in memory approaches
                              zero.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MakeSoftReferences</emphasis>: This controls whether or not the
                              message cache will keep soft references to messages that need to be removed. The default is
                              true.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MinimumHard</emphasis>: The minimum number of the in memory cache.
                              JBoss won't try to go below this number of messages in the cache. The default value is 1.
                          </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MaximumHard</emphasis>: The upper bound on the number of hard
                              references to messages in the cache. JBoss will soften messages to reduce the number of hard
                              references to this level. A value of 0 means that there is no size based upper bound. The
                              default is 0. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SoftenWaitMillis</emphasis>: The maximum wait time before checking
                              whether messages need softening. The default is 1000 milliseconds (1 second).</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SoftenNoMoreOftenThanMillis</emphasis>: The minimum amount of time
                              between checks to soften messages. A value of 0 means that this check should be skipped. The
                              default is 0 milliseconds.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SoftenAtLeastEveryMillis</emphasis>: The maximum amount of time
                              between checks to soften messages. A value of 0 means that this check should be skipped. The
                              default is 0.</para>
                      </listitem>
                  </itemizedlist>
                  <para>Additional read-only cache attribute that provide statistics include:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">CacheHits</emphasis>: The number of times a hard referenced message
                              was accessed</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">CacheMisses</emphasis>: The number of times a softened message was
                              accessed.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">HardRefCacheSize</emphasis>: The number of messages in the cache that
                              are not softened.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SoftRefCacheSize</emphasis>: The number of messages that are currently
                              softened.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SoftenedSize</emphasis>: The total number of messages softened since
                              the last boot. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">TotalCacheSize</emphasis>: The total number of messages that are being
                              managed by the cache.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>org.jboss.mq.pm.jdbc2.PersistenceManager</title>
                  <para>The <literal>org.jboss.mq.pm.jdbc.PersistenceManager</literal> should be used as the persistence
                      manager assigned to the <literal>DestinationManager</literal> if you wish to store messages in a
                      database. This PM has been tested against the HypersonSQL, MS SQL, Oracle, MySQL and Postgres
                      databases. The configurable attributes are as follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">MessageCache</emphasis>: The JMX <literal>ObjectName</literal> of the
                                  <literal>MessageCache</literal> that has been assigned to the
                                  <literal>DestinationManager</literal>..</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ConnectionManager</emphasis>: The JMX <literal>ObjectName</literal> of
                              the JCA data source that will be used to obtain JDBC connections. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ConnectionRetryAttempts</emphasis>: An integer count used to allow the
                              PM to retry attempts at getting a connection to the JDBC store. There is a 1500 millisecond
                              delay between each connection failed connection attempt and the next attempt. This must be
                              greater than or equal to 1 and defaults to 5.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SqlProperties</emphasis>: A property list is used to define the SQL
                              Queries and other JDBC2 Persistence Manager options. You will need to adjust these
                              properties if you which to run against another database other than Hypersonic. <xref
                                  linkend="ch6.pmdefault.ex"/> shows default setting for this attribute for the Hypersonic
                              database. </para>
                      </listitem>
                  </itemizedlist>
                  <example id="ch6.pmdefault.ex">
                      <title>Default JDBC2 PeristenceManager SqlProperties</title>
                      <programlisting>&lt;attribute name=&quot;SqlProperties&quot;&gt;
        CREATE_TABLES_ON_STARTUP = TRUE
        CREATE_USER_TABLE = CREATE TABLE JMS_USERS \
             (USERID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, \
             CLIENTID VARCHAR(128), PRIMARY KEY(USERID))
        CREATE_ROLE_TABLE = CREATE TABLE JMS_ROLES \
             (ROLEID VARCHAR(32) NOT NULL, USERID VARCHAR(32) NOT NULL, \
                      PRIMARY KEY(USERID, ROLEID))
        CREATE_SUBSCRIPTION_TABLE = CREATE TABLE JMS_SUBSCRIPTIONS \
             (CLIENTID VARCHAR(128) NOT NULL, \                  
             SUBNAME VARCHAR(128) NOT NULL, TOPIC VARCHAR(255) NOT NULL, \                    
             SELECTOR VARCHAR(255), PRIMARY KEY(CLIENTID, SUBNAME))
        GET_SUBSCRIPTION = SELECT TOPIC, SELECTOR FROM JMS_SUBSCRIPTIONS \
             WHERE CLIENTID=? AND SUBNAME=?
        LOCK_SUBSCRIPTION = SELECT TOPIC, SELECTOR FROM JMS_SUBSCRIPTIONS \
             WHERE CLIENTID=? AND SUBNAME=?
        GET_SUBSCRIPTIONS_FOR_TOPIC = 
             SELECT CLIENTID, SUBNAME, SELECTOR FROM JMS_SUBSCRIPTIONS WHERE TOPIC=?
        INSERT_SUBSCRIPTION = \
             INSERT INTO JMS_SUBSCRIPTIONS (CLIENTID, SUBNAME, TOPIC, SELECTOR) VALUES(?,?,?,?)
        UPDATE_SUBSCRIPTION = \
             UPDATE JMS_SUBSCRIPTIONS SET TOPIC=?, SELECTOR=? WHERE CLIENTID=? AND SUBNAME=?
        REMOVE_SUBSCRIPTION = DELETE FROM JMS_SUBSCRIPTIONS WHERE CLIENTID=? AND SUBNAME=?
        GET_USER_BY_CLIENTID = SELECT USERID, PASSWD, CLIENTID FROM JMS_USERS WHERE CLIENTID=?
        GET_USER = SELECT PASSWD, CLIENTID FROM JMS_USERS WHERE USERID=?
        POPULATE.TABLES.01 = INSERT INTO JMS_USERS (USERID, PASSWD) \
                      VALUES (&apos;guest&apos;, &apos;guest&apos;)
        POPULATE.TABLES.02 = INSERT INTO JMS_USERS (USERID, PASSWD) \
                      VALUES (&apos;j2ee&apos;, &apos;j2ee&apos;)
        POPULATE.TABLES.03 = INSERT INTO JMS_USERS (USERID, PASSWD, CLIENTID) \
                      VALUES (&apos;john&apos;, &apos;needle&apos;, &apos;DurableSubscriberExample&apos;)
        POPULATE.TABLES.04 = INSERT INTO JMS_USERS (USERID, PASSWD) \
                      VALUES (&apos;nobody&apos;, &apos;nobody&apos;)
        POPULATE.TABLES.05 = INSERT INTO JMS_USERS (USERID, PASSWD) \
                      VALUES (&apos;dynsub&apos;, &apos;dynsub&apos;)
        POPULATE.TABLES.06 = INSERT INTO JMS_ROLES (ROLEID, USERID) \
                      VALUES (&apos;guest&apos;,&apos;guest&apos;)
        POPULATE.TABLES.07 = INSERT INTO JMS_ROLES (ROLEID, USERID) \
                      VALUES (&apos;j2ee&apos;,&apos;guest&apos;)
        POPULATE.TABLES.08 = INSERT INTO JMS_ROLES (ROLEID, USERID) \
                      VALUES (&apos;john&apos;,&apos;guest&apos;)
        POPULATE.TABLES.09 = INSERT INTO JMS_ROLES (ROLEID, USERID) \
                      VALUES (&apos;subscriber&apos;,&apos;john&apos;)
        POPULATE.TABLES.10 = INSERT INTO JMS_ROLES (ROLEID, USERID) \
                      VALUES (&apos;publisher&apos;,&apos;john&apos;)
        POPULATE.TABLES.11 = INSERT INTO JMS_ROLES (ROLEID, USERID) \
                      VALUES (&apos;publisher&apos;,&apos;dynsub&apos;)
        POPULATE.TABLES.12 = INSERT INTO JMS_ROLES (ROLEID, USERID) \
                      VALUES (&apos;durpublisher&apos;,&apos;john&apos;)
        POPULATE.TABLES.13 = INSERT INTO JMS_ROLES (ROLEID, USERID) \
                      VALUES (&apos;durpublisher&apos;,&apos;dynsub&apos;)
        POPULATE.TABLES.14 = INSERT INTO JMS_ROLES (ROLEID, USERID) \
                      VALUES (&apos;noacc&apos;,&apos;nobody&apos;)
  &lt;/attribute&gt; </programlisting>
                  </example>
                  <para>
                      <xref linkend="ch6.pmoracle.ex"/> shows an alternate setting for Oracle. </para>
                  <example id="ch6.pmoracle.ex">
                      <title>A sample JDBC2 PeristenceManager SqlProperties for Oracle</title>
                      <programlisting>&lt;attribute name=&quot;SqlProperties&quot;&gt;
        BLOB_TYPE=BINARYSTREAM_BLOB
        INSERT_TX = INSERT INTO JMS_TRANSACTIONS (TXID) values(?)
        INSERT_MESSAGE = \
            INSERT INTO JMS_MESSAGES (MESSAGEID, DESTINATION, MESSAGEBLOB, TXID, TXOP) \
            VALUES(?,?,?,?,?)
        SELECT_ALL_UNCOMMITED_TXS = SELECT TXID FROM JMS_TRANSACTIONS
        SELECT_MAX_TX = SELECT MAX(TXID) FROM JMS_MESSAGES
        SELECT_MESSAGES_IN_DEST = \
            SELECT MESSAGEID, MESSAGEBLOB FROM JMS_MESSAGES WHERE DESTINATION=?
        SELECT_MESSAGE = \
            SELECT MESSAGEID, MESSAGEBLOB FROM JMS_MESSAGES WHERE MESSAGEID=? AND DESTINATION=?
        MARK_MESSAGE = \
            UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE MESSAGEID=? AND DESTINATION=?
        UPDATE_MESSAGE = \
            UPDATE JMS_MESSAGES SET MESSAGEBLOB=? WHERE MESSAGEID=? AND DESTINATION=?
        UPDATE_MARKED_MESSAGES = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE TXOP=?
        UPDATE_MARKED_MESSAGES_WITH_TX = \
            UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE TXOP=? AND TXID=?
        DELETE_MARKED_MESSAGES_WITH_TX = \
            DELETE FROM JMS_MESSAGES MESS WHERE TXOP=:1 AND EXISTS \
            (SELECT TXID FROM JMS_TRANSACTIONS TX WHERE TX.TXID = MESS.TXID)
        DELETE_TX = DELETE FROM JMS_TRANSACTIONS WHERE TXID = ?
        DELETE_MARKED_MESSAGES = DELETE FROM JMS_MESSAGES WHERE TXID=? AND TXOP=?
        DELETE_TEMPORARY_MESSAGES = DELETE FROM JMS_MESSAGES WHERE TXOP=&apos;T&apos;
        DELETE_MESSAGE = DELETE FROM JMS_MESSAGES WHERE MESSAGEID=? AND DESTINATION=?
        CREATE_MESSAGE_TABLE = CREATE TABLE JMS_MESSAGES ( MESSAGEID INTEGER NOT NULL, \
           DESTINATION VARCHAR(255) NOT NULL, TXID INTEGER, TXOP CHAR(1), \
           MESSAGEBLOB BLOB, PRIMARY KEY (MESSAGEID, DESTINATION) )
        CREATE_IDX_MESSAGE_TXOP_TXID = \
           CREATE INDEX JMS_MESSAGES_TXOP_TXID ON JMS_MESSAGES (TXOP, TXID)
        CREATE_IDX_MESSAGE_DESTINATION = \
           CREATE INDEX JMS_MESSAGES_DESTINATION ON JMS_MESSAGES (DESTINATION)
        CREATE_TX_TABLE = CREATE TABLE JMS_TRANSACTIONS ( TXID INTEGER, PRIMARY KEY (TXID) )
        CREATE_TABLES_ON_STARTUP = TRUE
  &lt;/attribute&gt;</programlisting>
                  </example>
                  <para>Additional examples can be found in the <literal>docs/examples/jms</literal> directory of the
                      distribution.</para>
              </section>
              <section>
                  <title>Destination MBeans</title>
                  <para>This section describes the destination MBeans used in the
                          <literal>jbossmq-destinations-service.xml</literal> and <literal>jbossmq-service.xml</literal>
                      descriptors.</para>
                  <section>
                      <title>org.jboss.mq.server.jmx.Queue</title>
                      <para>The <literal>Queue</literal> is used to define a queue destination in JBoss. The following
                          shows the configuration of one of the default JBoss queues. </para>
                      <programlisting>&lt;mbean code=&quot;org.jboss.mq.server.jmx.Queue&quot; 
         name=&quot;jboss.mq.destination:service=Queue,name=testQueue&quot;&gt;
      &lt;depends optional-attribute-name=&quot;DestinationManager&quot;&gt;
          jboss.mq:service=DestinationManager
      &lt;/depends&gt;
      &lt;depends optional-attribute-name=&quot;SecurityManager&quot;&gt;
          jboss.mq:service=SecurityManager
      &lt;/depends&gt;
      &lt;attribute name=&quot;MessageCounterHistoryDayLimit&quot;&gt;-1&lt;/attribute&gt;
      &lt;attribute name=&quot;SecurityConf&quot;&gt;
          &lt;security&gt;
              &lt;role name=&quot;guest&quot;     read=&quot;true&quot;  write=&quot;true&quot;/&gt;
              &lt;role name=&quot;publisher&quot; read=&quot;true&quot;  write=&quot;true&quot; create=&quot;false&quot;/&gt;
              &lt;role name=&quot;noacc&quot;     read=&quot;false&quot; write=&quot;false&quot; create=&quot;false&quot;/&gt;
          &lt;/security&gt;
      &lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
                      <para>The <literal>name</literal> attribute of the JMX object name of this MBean is used to
                          determine the destination name. For example. In the case of the queue we just looked at, the
                          name of the queue is <literal>testQueue</literal>. The configurable attributes are as follows:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">DestinationManager</emphasis>: The JMX ObjectName of the
                                  destination manager service for the server. This attribute should be set via a
                                      <literal>&lt;depends
                                  optional-attribute-name="DestinationManager"&gt;</literal> XML tag.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">SecurityManager</emphasis>: The JMX <literal>ObjectName</literal>
                                  of the security manager service that is being used to validate client requests.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">SecurityConf</emphasis>: This element specifies a XML fragment
                                  which describes the access control list to be used by the
                                  <literal>SecurityManager</literal> to authorize client operations against the
                                  destination. The content model is the same as for the <literal>SecurityManager</literal>
                                  <literal>SecurityConf</literal> attribute.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">JNDIName</emphasis>: The location in JNDI to which the queue
                                  object will be bound. If this is not set it will be bound under the
                                  <literal>queue</literal> context using the name of the queue. For the
                                  <literal>testQueue</literal> shown above, the JNDI name would be
                                      <literal>queue/testQueue</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">MaxDepth</emphasis>: The <literal>MaxDepth</literal> is an upper
                                  limit to the backlog of messages that can exist for a destination. If exceeded, attempts
                                  to add new messages will result in a
                                  <literal>org.jboss.mq.DestinationFullException</literal>. The
                                  <literal>MaxDepth</literal> can still be exceeded in a number of situations, e.g. when a
                                  message is placed back into the queue. Also transactions performing read committed
                                  processing, look at the current size of queue, ignoring any messages that may be added
                                  as a result of the current transaction or other transactions. This is because we don't
                                  want the transaction to fail during the commit phase when the message is physically
                                  added to the queue.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">MessageCounterHistoryDayLimit</emphasis>: Sets the destination
                                  message counter history day limit with a value less than 0 indicating unlimited history,
                                  a 0 value disabling history and a value greater than 0 giving the history days
                              count.</para>
                          </listitem>
                      </itemizedlist>
                      <para>Additional read-only attributes that provide statistics information include:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">MessageCounter</emphasis>: An array of
                                      <literal>org.jboss.mq.server.MessageCounter</literal> instances that provide
                                  statistics for this destination.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">QueueDepth</emphasis>: The current backlog of waiting
                              messages.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ReceiversCount</emphasis>: The number of receivers currently
                                  associated with the queue.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ScheduledMessageCount</emphasis>: The number of messages waiting
                                  in the queue for their scheduled delivery time to arrive.</para>
                          </listitem>
                      </itemizedlist>
                      <para>The following are some of the operations available on queues.</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">listMessageCounter()</emphasis>: This operation generates an HTML
                                  table that contains the same data we as the <literal>listMessageCounter</literal>
                                  operation on the <literal>DestinationManager</literal>, but only for this one queue.
                              </para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">resetMessageCounter()</emphasis>: This zeros all destination
                                  counts and last added times.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">listMessageCounterHistory()</emphasis>: This operation display an
                                  HTML table showing the hourly message counts per hour for each day in the
                              history.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">resetMessageCounterHistory()</emphasis>: This operation resets the
                                  day history message counts.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">removeAllMessages()</emphasis>: This method removes all the
                                  messages on the queue. </para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>org.jboss.mq.server.jmx.Topic</title>
                      <para>The <literal>org.jboss.mq.server.jmx.Topic</literal> is used to define a topic destination in
                          JBoss. The following shows the configuration of one of the default JBoss topics. </para>
                      <programlisting>&lt;mbean code=&quot;org.jboss.mq.server.jmx.Topic&quot;
         name=&quot;jboss.mq.destination:service=Topic,name=testTopic&quot;&gt;
      &lt;depends optional-attribute-name=&quot;DestinationManager&quot;&gt;
          jboss.mq:service=DestinationManager
      &lt;/depends&gt;
      &lt;depends optional-attribute-name=&quot;SecurityManager&quot;&gt;
          jboss.mq:service=SecurityManager
      &lt;/depends&gt;
      &lt;attribute name=&quot;SecurityConf&quot;&gt;
          &lt;security&gt;
              &lt;role name=&quot;guest&quot;        read=&quot;true&quot; write=&quot;true&quot; /&gt;
              &lt;role name=&quot;publisher&quot;    read=&quot;true&quot; write=&quot;true&quot; create=&quot;false&quot; /&gt;
              &lt;role name=&quot;durpublisher&quot; read=&quot;true&quot; write=&quot;true&quot; create=&quot;true&quot; /&gt;
          &lt;/security&gt;
      &lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
                      <para>The <literal>name</literal> attribute of the JMX object name of this MBean is used to
                          determine the destination name. For example, in the case of the topic we just looked at, the
                          name of the topic is <literal>testTopic</literal>. The configurable attributes are as follows:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">DestinationManager</emphasis>: The JMX object name of the
                                  destination manager configured for the server. </para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">SecurityManager</emphasis>: The JMX object name of the security
                                  manager that is being used to validate client requests. </para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">SecurityConf</emphasis>: This element specifies a XML fragment
                                  which describes the access control list to be used by the
                                  <literal>SecurityManager</literal> to authorize client operations against the
                                  destination. The content model is the same as that for the <literal>SecurityManager</literal>
                                  <literal>SecurityConf</literal> attribute.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">JNDIName</emphasis>: The location in JNDI to which the topic
                                  object will be bound. If this is not set it will be bound under the
                                  <literal>topic</literal> context using the name of the queue. For the
                                  <literal>testTopic</literal> shown above, the JNDI name would be
                                      <literal>topic/testTopic</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">MaxDepth</emphasis>: The <literal>MaxDepth</literal> is an upper
                                  limit to the backlog of messages that can exist for a destination, and if exceeded,
                                  attempts to add new messages will result in a
                                      <literal>org.jboss.mq.DestinationFullException</literal>. The
                                  <literal>MaxDepth</literal> can still be exceeded in a number of situations, e.g. when a
                                  message is knacked back into the queue. Also transactions performing read committed
                                  processing, look at the current size of queue, ignoring any messages that may be added
                                  as a result of the current transaction or other transactions. This is because we don't
                                  want the transaction to fail during the commit phase when the message is physically
                                  added to the topic.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">MessageCounterHistoryDayLimit</emphasis>: Sets the destination
                                  message counter history day limit with a value &lt; 0 indicating unlimited history,
                                  a 0 value disabling history, and a value &gt; 0 giving the history days
                              count.</para>
                          </listitem>
                      </itemizedlist>
                      <para>Additional read-only attributes that provide statistics information include:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">AllMessageCount</emphasis>: The message count across all queue
                                  types associated with the topic.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">AllSubscriptionsCount</emphasis>: The count of durable and
                                  non-durable subscriptions.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">DurableMessageCount</emphasis>: The count of messages in durable
                                  subscription queues.</para>
                          </listitem>
                          <listitem>
                              <para>d <emphasis role="bold">DurableSubscriptionsCount</emphasis>: The count of durable
                                  subscribers.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">MessageCounter</emphasis>: An array of
                                      <literal>org.jboss.mq.server.MessageCounter</literal> instances that provide
                                  statistics for this destination.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">NonDurableMessageCount</emphasis>: The count on messages in
                                  non-durable subscription queues.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">NonDurableSubscriptionsCount</emphasis>: The count of non-durable
                                  subscribers.</para>
                          </listitem>
                      </itemizedlist>
                      <para>The following are some of the operations available on topics.</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">listMessageCounter()</emphasis>: This operation generates an HTML
                                  table that contains the same data we as the <literal>listMessageCounter</literal>
                                  operation on the <literal>DestinationManager</literal>, but only for this one topic.
                                  Message counters are only maintained for each active subscription, durable or otherwise.
                              </para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">resetMessageCounter()</emphasis>: This zeros all destination
                                  counts and last added times.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">listMessageCounterHistory()</emphasis>: This operation display an
                                  HTML table showing the hourly message counts per hour for each day of history.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">resetMessageCounterHistory()</emphasis>: This operation resets the
                                  day history message counts.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
              </section>
          </section>
          <section>
              <title>Specifying the MDB JMS Provider</title>
              <para>Up to this point we have looked at the standard JMS client/server architecture. The JMS specification
                  defines an advanced set of interfaces that allow for concurrent processing of a destination's messages,
                  and collectively this functionality is referred to as application server facilities (ASF). Two of the
                  interfaces that support concurrent message processing, <literal>javax.jms.ServerSessionPool</literal>
                  and <literal>javax.jms.ServerSession</literal>, must be provided by the application server in which the
                  processing will occur. Thus, the set of components that make up the JBossMQ ASF involves both JBossMQ
                  components as well as JBoss server components. The JBoss server MDB container utilizes the JMS service's
                  ASF to concurrently process messages sent to MDBs.</para>
              <para>The responsibilities of the ASF domains are well defined by the JMS specification and so we won't go
                  into a discussion of how the ASF components are implemented. Rather, we want to discuss how ASF
                  components used by the JBoss MDB layer are integrated using MBeans that allow either the application
                  server interfaces, or the JMS provider interfaces to be replaced with alternate implementations.</para>
              <para>Let's start with the <literal>org.jboss.jms.jndi.JMSProviderLoader</literal> MBean. This MBean is
                  responsible for loading an instance of the <literal>org.jboss.jms.jndi.JMSProviderAdaptor</literal>
                  interface into the JBoss server and binding it into JNDI. The <literal>JMSProviderAdaptor</literal>
                  interface is an abstraction that defines how to get the root JNDI context for the JMS provider, and an
                  interface for getting and setting the JNDI names for the <literal>Context.PROVIDER_URL</literal> for the
                  root <literal>InitialContext</literal>, and the <literal>QueueConnectionFactory</literal> and
                      <literal>TopicConnectionFactory</literal> locations in the root context. This is all that is really
                  necessary to bootstrap use of a JMS provider. By abstracting this information into an interface,
                  alternate JMS ASF provider implementations can be used with the JBoss MDB container. The
                      <literal>org.jboss.jms.jndi.JBossMQProvider</literal> is the default implementation of
                      <literal>JMSProviderAdaptor</literal> interface, and provides the adaptor for the JBossMQ JMS
                  provider. To replace the JBossMQ provider with an alternate JMS ASF implementation, simply create an
                  implementation of the <literal>JMSProviderAdaptor</literal> interface and configure the
                  JMSProviderLoader with the class name of the implementation. We'll see an example of this in the
                  configuration section.</para>
              <para>In addition to being able to replace the JMS provider used for MDBs, you can also replace the
                  javax.jms.ServerSessionPool interface implementation. This is possible by configuring the class name of
                  the <literal>org.jboss.jms.asf.ServerSessionPoolFactory</literal> implementation using the
                      <literal>org.jboss.jms.asf.ServerSessionPoolLoader</literal> MBean
                  <literal>PoolFactoryClass</literal> attribute. The default <literal>ServerSessionPoolFactory</literal>
                  factory implementation is the JBoss <literal>org.jboss.jms.asf.StdServerSessionPoolFactory</literal>
                  class.</para>
              <section>
                  <title>org.jboss.jms.jndi.JMSProviderLoader MBean</title>
                  <para>The <literal>JMSProviderLoader</literal> MBean service creates a JMS provider adaptor and binds it
                      into JNDI. A JMS provider adaptor is a class that implements the
                          <literal>org.jboss.jms.jndi.JMSProviderAdapter</literal> interface. It is used by the message
                      driven bean container to access a JMS service provider in a provider independent manner. The
                      configurable attributes of the <literal>JMSProviderLoader</literal> service are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">ProviderName</emphasis>: A unique name for the JMS provider. This will
                              be used to bind the <literal>JMSProviderAdapter</literal> instance into JNDI under
                                  <literal>java:/&lt;ProviderName&gt;</literal> unless overridden by the
                                  <literal>AdapterJNDIName</literal> attribute.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ProviderAdapterClass</emphasis>: The fully qualified class name of the
                              org.jboss.jms.jndi.JMSProviderAdapter<literal/> interface to create an instance of.</para>
                      </listitem>
  
                      <listitem>
                          <para>
                              <emphasis role="bold">FactoryRef</emphasis>: The JNDI name under which the provider
                                  <literal>javax.jms.ConnectionFactory</literal> will be bound.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">QueueFactoryRef</emphasis>: The JNDI name under which the provider
                                  <literal>javax.jms.QueueConnectionFactory</literal> will be bound.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">TopicFactoryRef</emphasis>: The JNDI name under which the
                                  <literal>javax.jms.TopicConnectionFactory</literal> will be bound.</para>
                      </listitem>
                      <listitem>
                          <para><emphasis role="bold">Properties</emphasis>: The JNDI properties of the initial context
                              used to look up the factories.</para>
                      </listitem>
                  </itemizedlist>
                  <example>
                      <title>A JMSProviderLoader for accessing a remote JBossMQ server</title>
                      <programlisting>&lt;mbean code="org.jboss.jms.jndi.JMSProviderLoader"
         name="jboss.mq:service=JMSProviderLoader,name=RemoteJBossMQProvider"&gt;
      &lt;attribute name="ProviderName"&gt;RemoteJMSProvider&lt;/attribute&gt;
      &lt;attribute name="ProviderUrl"&gt;&lt;/attribute&gt;
      &lt;attribute name="ProviderAdapterClass"&gt;
          org.jboss.jms.jndi.JBossMQProvider
      &lt;/attribute&gt;
      &lt;attribute name="FactoryRef"&gt;XAConnectionFactory&lt;/attribute&gt;
      &lt;attribute name="QueueFactoryRef"&gt;XAConnectionFactory&lt;/attribute&gt;
      &lt;attribute name="TopicFactoryRef"&gt;XAConnectionFactory&lt;/attribute&gt;
      &lt;attribute name=&quot;Properties&gt;
          java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
          java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
          java.naming.provider.url=jnp://remotehost:1099
      &lt;/attribute&gt;
  &lt;/mbean&gt; </programlisting>
                  </example>
                  <para>The RemoteJMSProvider can be referenced on the MDB invoker config as shown in the
                          <literal>jboss.xml</literal> fragment given in <xref linkend="ch6.mdbadapt.ex"/>.</para>
                  <example id="ch6.mdbadapt.ex">
                      <title> A jboss.xml fragment for specifying the MDB JMS provider adaptor</title>
                      <programlisting>&lt;proxy-factory-config&gt;
      &lt;JMSProviderAdapterJNDI&gt;RemoteJMSProvider&lt;/JMSProviderAdapterJNDI&gt;
      &lt;ServerSessionPoolFactoryJNDI&gt;StdJMSPool&lt;/ServerSessionPoolFactoryJNDI&gt;
      &lt;MaximumSize&gt;15&lt;/MaximumSize&gt;
      &lt;MaxMessages&gt;1&lt;/MaxMessages&gt;
      &lt;MDBConfig&gt;
          &lt;ReconnectIntervalSec&gt;10&lt;/ReconnectIntervalSec&gt;
          &lt;DLQConfig&gt;
              &lt;DestinationQueue&gt;queue/DLQ&lt;/DestinationQueue&gt;
              &lt;MaxTimesRedelivered&gt;10&lt;/MaxTimesRedelivered&gt;
              &lt;TimeToLive&gt;0&lt;/TimeToLive&gt;
          &lt;/DLQConfig&gt;
      &lt;/MDBConfig&gt;
  &lt;/proxy-factory-config&gt;</programlisting>
                  </example>
                  <para>Incidentally, because one can specify multiple <literal>invoker-proxy-binding</literal> elements,
                      this allows an MDB to listen to the same queue/topic on multiple servers by configuring multiple
                      bindings with different <literal>JMSProviderAdapterJNDI</literal> settings.</para>
                  <para>Alternatively, one can integrate the JMS provider using JCA configuration like that shown in <xref
                          linkend="ch6.jmsdsjca.ex"/>.</para>
                  <example id="ch6.jmsdsjca.ex">
                      <title>A jms-ds.xml descriptor for integrating a JMS provider adaptor via JCA</title>
                      <programlisting>&lt;tx-connection-factory&gt;
      &lt;jndi-name&gt;RemoteJmsXA&lt;/jndi-name&gt;
      &lt;xa-transaction/&gt;
      &lt;adapter-display-name&gt;JMS Adapter&lt;/adapter-display-name&gt;
      &lt;config-property name="JMSProviderAdapterJNDI"
                       type="java.lang.String"&gt;RemoteJMSProvider&lt;/config-property&gt;
      &lt;config-property name="SessionDefaultType"
                       type="java.lang.String"&gt;javax.jms.Topic&lt;/config-property&gt;
                   
      &lt;security-domain-and-application&gt;JmsXARealm&lt;/security-domain-and-application&gt;
  &lt;/tx-connection-factory&gt;</programlisting>
                  </example>
              </section>
              <section>
                  <title>org.jboss.jms.asf.ServerSessionPoolLoader MBean</title>
                  <para>The <literal>ServerSessionPoolLoader</literal> MBean service manages a factory for
                          <literal>javax.jms.ServerSessionPool</literal> objects used by the message driven bean
                      container. The configurable attributes of the <literal>ServerSessionPoolLoader</literal> service
                      are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">PoolName</emphasis>: A unique name for the session pool. This will be
                              used to bind the <literal>ServerSessionPoolFactory</literal> instance into JNDI under
                                  <literal>java:/PoolName</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">PoolFactoryClass</emphasis>: The fully qualified class name of the
                                  <literal>org.jboss.jms.asf.ServerSessionPoolFactory</literal> interface to create an
                              instance of.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">XidFactory</emphasis>: The JMX <literal>ObjectName</literal> of the
                              service to use for generating <literal>javax.transaction.xa.Xid</literal> values for local
                              transactions when two phase commit is not required. The <literal>XidFactory</literal> MBean
                              must provide an <literal>Instance</literal> operation which returns a
                                  <literal>org.jboss.tm.XidFactoryMBean</literal> instance.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>Integrating non-JBoss JMS Providers</title>
                  <para>We have mentioned that one can replace the JBossMQ JMS implementation with a foreign
                      implementation. Here we summarize the various approaches one can take to do the replacement:</para>
                  <itemizedlist>
                      <listitem>
                          <para>Replace the JMSProviderLoader JBossMQProvider class with one that instantiates the correct
                              JNDI context for communicating with the foreign JMS providers managed objects.</para>
                      </listitem>
                      <listitem>
                          <para>Use the <literal>ExternalContext</literal> MBean to federate the foreign JMS providers
                              managed objects into the JBoss JNDI tree.</para>
                      </listitem>
                      <listitem>
                          <para>Use MBeans to instantiate the foreign JMS objects into the JBoss JNDI tree. An example of
                              this approach can be found for Websphere MQ at <ulink
                                  url="http://wiki.jboss.org/wiki/Wiki.jsp?page=IntegrationWithWebSphereMQSeries"/>.
                          </para>
                      </listitem>
                  </itemizedlist>
              </section>
          </section>
      </chapter>
  
  
  
      <chapter id="ch7.chapt">
          <title>Connectors on JBoss</title>
          <subtitle>The JCA Configuration and Architecture</subtitle>
          <para>This chapter discusses the JBoss server implementation of the J2EE Connector Architecture (JCA). JCA is a
              resource manager integration API whose goal is to standardize access to non-relational resources in the same
              way the JDBC API standardized access to relational data. The purpose of this chapter is to introduce the
              utility of the JCA APIs and then describe the architecture of JCA in JBoss </para>
          <section>
              <title>JCA Overview</title>
              <para>J2EE 1.4 contains a connector architecture (JCA) specification that allows for the integration of
                  transacted and secure resource adaptors into a J2EE application server environment. The JCA
                  specification describes the notion of such resource managers as Enterprise Information Systems (EIS).
                  Examples of EIS systems include enterprise resource planning packages, mainframe transaction processing,
                  non-Java legacy applications, etc.</para>
              <para>The reason for focusing on EIS is primarily because the notions of transactions, security, and
                  scalability are requirements in enterprise software systems. However, the JCA is applicable to any
                  resource that needs to integrate into JBoss in a secure, scalable and transacted manner. In this
                  introduction we will focus on resource adapters as a generic notion rather than something specific to
                  the EIS environment.</para>
              <para>The connector architecture defines a standard SPI (Service Provider Interface) for integrating the
                  transaction, security and connection management facilities of an application server with those of a
                  resource manager. The SPI defines the system level contract between the resource adaptor and the
                  application server.</para>
              <para>The connector architecture also defines a Common Client Interface (CCI) for accessing resources. The
                  CCI is targeted at EIS development tools and other sophisticated users of integrated resources. The CCI
                  provides a way to minimize the EIS specific code required by such tools. Typically J2EE developers will
                  access a resource using such a tool, or a resource specific interface rather than using CCI directly.
                  The reason is that the CCI is not a type specific API. To be used effectively it must be used in
                  conjunction with metadata that describes how to map from the generic CCI API to the resource manager
                  specific data types used internally by the resource manager.</para>
              <para>The purpose of the connector architecture is to enable a resource vendor to provide a standard adaptor
                  for its product. A resource adaptor is a system-level software driver that is used by a Java application
                  to connect to resource. The resource adaptor plugs into an application server and provides connectivity
                  between the resource manager, the application server, and the enterprise application. A resource vendor
                  need only implement a JCA compliant adaptor once to allow use of the resource manager in any JCA capable
                  application server.</para>
              <para>An application server vendor extends its architecture once to support the connector architecture and
                  is then assured of seamless connectivity to multiple resource managers. Likewise, a resource manager
                  vendor provides one standard resource adaptor and it has the capability to plug in to any application
                  server that supports the connector architecture.</para>
              <figure id="ch7.j2eejca.fig">
                  <title>The relationship between a J2EE application server and a JCA resource adaptor</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/jca-ra.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>
                  <xref linkend="ch7.j2eejca.fig"/> illustrates that the application server is extended to provide support
                  for the JCA SPI to allow a resource adaptor to integrate with the server connection pooling, transaction
                  management and security management facilities. This integration API defines a three-part system
                  contract.</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">Connection management</emphasis>: a contract that allows the application
                          server to pool resource connections. The purpose of the pool management is to allow for
                          scalability. Resource connections are typically expense objects to create and pooling them
                          allows for more effective reuse and management.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Transaction Management</emphasis>: a contract that allows the application
                          server transaction manager to manage transactions that engage resource managers.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Security Management</emphasis>: a contract that enables secured access to
                          resource managers.</para>
                  </listitem>
              </itemizedlist>
              <para>The resource adaptor implements the resource manager side of the system contract. This entails using
                  the application server connection pooling, providing transaction resource information and using the
                  security integration information. The resource adaptor also exposes the resource manager to the
                  application server components. This can be done using the CCI and/or a resource adaptor specific API.</para>
              <para>The application component integrates into the application server using a standard J2EE container to
                  component contract. For an EJB component this contract is defined by the EJB specification. The
                  application component interacts with the resource adaptor in the same way as it would with any other
                  standard resource factory, for example, a <literal>javax.sql.DataSource</literal> JDBC resource factory.
                  The only difference with a JCA resource adaptor is that the client has the option of using the resource
                  adaptor independent CCI API if the resource adaptor supports this.</para>
              <para>
                  <xref linkend="ch7.jcaspec.fig"/> (from the JCA 1.5 specification) illustrates the relationship between
                  the JCA architecture participants in terms of how they relate to the JCA SPI, CCI and JTA packages. </para>
              <figure id="ch7.jcaspec.fig">
                  <title>The JCA 1.0 specification class diagram for the connection management architecture.</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/Chap7-5.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>The JBossCX architecture provides the implementation of the application server specific classes. <xref
                      linkend="ch7.jcaspec.fig"/> shows that this comes down to the implementation of the
                      <literal>javax.resource.spi.ConnectionManager</literal> and
                      <literal>javax.resource.spi.ConnectionEventListener</literal> interfaces. The key aspects of this
                  implementation are discussed in the following section on the JBossCX architecture.</para>
          </section>
          <section>
              <title>An Overview of the JBossCX Architecture</title>
              <para>The JBossCX framework provides the application server architecture extension required for the use of
                  JCA resource adaptors. This is primarily a connection pooling and management extension along with a
                  number of MBeans for loading resource adaptors into the JBoss server.</para>
  
              <para>There are three coupled MBeans that make up a RAR deployment. These are the
                      <literal>org.jboss.resource.deployment.RARDeployment</literal>,
                      <literal>org.jboss.resource.connectionmanager.RARDeployment</literal>, and
                      <literal>org.jboss.resource.connectionmanager.BaseConnectionManager2</literal>. The
                      <literal>org.jboss.resource.deployment.RARDeployment</literal> is simply an encapsulation of the
                  metadata of a RAR <literal>META-INF/ra.xml</literal> descriptor. It exposes this information as a
                  DynamicMBean simply to make it available to the
                      <literal>org.jboss.resource.connectionmanager.RARDeployment</literal> MBean.</para>
              <para>The RARDeployer service handles the deployment of archives files containing resource adaptors (RARs).
                  It creathes the <literal>org.jboss.resource.deployment.RARDeployment</literal> MBeans when a RAR file is
                  deployed. Deploying the RAR file is the first step in making the resource adaptor available to
                  application components. For each deployed RAR, one or more connection factories must be configured and
                  bound into JNDI. This task performed using a JBoss service descriptor that sets up a
                      <literal>org.jboss.resource.connectionmanager.BaseConnectionManager2</literal> MBean implementation
                  with a <literal>org.jboss.resource.connectionmgr.RARDeployment</literal> dependent.</para>
              <section>
                  <title>BaseConnectionManager2 MBean</title>
                  <para>The <literal>org.jboss.resource.connectionmanager.BaseConnectionManager2</literal> MBean is a base
                      class for the various types of connection managers required by the JCA spec. Subclasses include
                          <literal>NoTxConnectionManager</literal>, <literal>LocalTxConnectionManager</literal> and
                          <literal>XATxConnectionManager</literal>. These correspond to resource adaptors that support no
                      transactions, local transaction and XA transaction respectively. You choose which subclass to use
                      based on the type of transaction semantics you want, provided the JCA resource adaptor supports the
                      corresponding transaction capability.</para>
                  <para>The common attributes supported by the BaseConnectionManager2 MBean are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">ManagedConnectionPool</emphasis>: This specifies the ObjectName of the
                              MBean representing the pool for this connection manager. The MBean must have an
                                  <literal>ManagedConnectionPool</literal> attribute that is an implementation of the
                                  <literal>org.jboss.resource.connectionmanager.ManagedConnectionPool</literal> interface.
                              Normally it will be an embedded MBean in a depends tag rather than an
                              <literal>ObjectName</literal> reference to an existing MBean. The default MBean for use is
                              the <literal>org.jboss.resource.connectionmanager.JBossManagedConnectionPool</literal>. Its
                              configurable attributes are discussed below.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">CachedConnectionManager</emphasis>: This specifies the
                                  <literal>ObjectName</literal> of the <literal>CachedConnectionManager</literal> MBean
                              implementation used by the connection manager. Normally this is specified using a depends
                              tag with the <literal>ObjectName</literal> of the unique
                              <literal>CachedConnectionManager</literal> for the server. The name
                                  <literal>jboss.jca:service=CachedConnectionManager</literal> is the standard setting to
                              use.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SecurityDomainJndiName</emphasis>: This specifies the JNDI name of the
                              security domain to use for authentication and authorization of resource connections. This is
                              typically of the form <literal>java:/jaas/&lt;domain&gt;</literal> where the
                                  <literal>&lt;domain&gt;</literal> value is the name of an entry in the
                                  <literal>conf/login-config.xml</literal> JAAS login module configuration file. This
                              defines which JAAS login modules execute to perform authentication. <xref
                                  linkend="ch8.chapter"/> has more information on the security settings.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">JaasSecurityManagerService</emphasis>: This is the
                              <literal>ObjectName</literal> of the security manager service. This should be set to the
                              security manager MBean name as defined in the <literal>conf/jboss-service.xml</literal>
                              descriptor, and currently this is
                              <literal>jboss.security:service=JaasSecurityManager</literal>. This attribute will likely be
                              removed in the future.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>RARDeployment MBean</title>
                  <para>The <literal>org.jboss.resource.connectionmanager.RARDeployment</literal> MBean manages
                      configuration and instantiation <literal>ManagedConnectionFactory</literal> instance. It does this
                      using the resource adaptor metadata settings from the RAR <literal>META-INF/ra.xml</literal>
                      descriptor along with the <literal>RARDeployment</literal> attributes. The configurable attributes
                      are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">OldRarDeployment</emphasis>: This is the <literal>ObjectName</literal>
                              of the <literal>org.jboss.resource.RarDeployment</literal> MBean that contains the resource
                              adaptor metadata. The form of this name is
                                  <literal>jboss.jca:service=RARDeployment,name=&lt;ra-display-name&gt;</literal>
                              where the <literal>&lt;ra-display-name&gt;</literal> is the
                              <literal>ra.xml</literal> descriptor <literal>display-name</literal> attribute value. The
                                  <literal>RARDeployer</literal> creates this when it deploys a RAR file. This attribute
                              will likely be removed in the future.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ManagedConnectionFactoryProperties</emphasis>: This is a collection of
                              (name, type, value) triples that define attributes of the
                              <literal>ManagedConnectionFactory</literal> instance. Therefore, the names of the attributes
                              depend on the resource adaptor <literal>ManagedConnectionFactory</literal> instance. The
                              following example shows the structure of the content of this attribute.</para>
                          <programlisting>&lt;properties&gt;
      &lt;config-property&gt;
          &lt;config-property-name&gt;Attr0Name&lt;/config-property-name&gt;
          &lt;config-property-type&gt;Attr0Type&lt;/config-property-type&gt;
          &lt;config-property-value&gt;Attr0Value&lt;/config-property-value&gt;
      &lt;/config-property&gt;
      &lt;config-property&gt;
          &lt;config-property-name&gt;Attr1Name&lt;/config-property-name&gt;
          &lt;config-property-type&gt;Attr2Type&lt;/config-property-type&gt;
          &lt;config-property-value&gt;Attr2Value&lt;/config-property-value&gt;
      &lt;/config-property&gt; 
      ...
  &lt;/properties&gt;  </programlisting>
                          <para>
                              <literal>AttrXName</literal> is the Xth attribute name, <literal>AttrXType</literal> is the
                              fully qualified Java type of the attribute, and <literal>AttrXValue</literal> is the string
                              representation of the value. The conversion from string to <literal>AttrXType</literal> is
                              done using the <literal>java.beans.PropertyEditor</literal> class for the
                              <literal>AttrXType</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">JndiName</emphasis>: This is the JNDI name under which the resource
                              adaptor will be made available. Clients of the resource adaptor use this name to obtain
                              either the <literal>javax.resource.cci.ConnectionFactory</literal> or resource adaptor
                              specific connection factory. The full JNDI name will be
                                  <literal>java:/&lt;JndiName&gt;</literal> meaning that the
                              <literal>JndiName</literal> attribute value will be prefixed with <literal>java:/</literal>.
                              This prevents use of the connection factory outside of the JBoss server VM. In the future
                              this restriction may be configurable.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>JBossManagedConnectionPool MBean</title>
                  <para>The <literal>org.jboss.resource.connectionmanager.JBossManagedConnectionPool</literal> MBean is a
                      connection pooling MBean. It is typically used as the embedded MBean value of the
                          <literal>BaseConnectionManager2</literal>
                      <literal>ManagedConnectionPool</literal> attribute. When you setup a connection manager MBean you
                      typically embed the pool configuration in the connection manager descriptor. The configurable
                      attributes of the <literal>JBossManagedConnectionPool</literal> are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">ManagedConnectionFactoryName</emphasis>: This specifies the
                                  <literal>ObjectName</literal> of the MBean that creates
                                  <literal>javax.resource.spi.ManagedConnectionFactory</literal> instances. Normally this
                              is configured as an embedded MBean in a depends element rather than a separate MBean
                              reference using the <literal>RARDeployment</literal> MBean. The MBean must provide an
                              appropriate <literal>startManagedConnectionFactory</literal> operation. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MinSize</emphasis>: This attribute indicates the minimum number of
                              connections this pool should hold. These are not created until a <literal>Subject</literal>
                              is known from a request for a connection. <literal>MinSize</literal> connections will be
                              created for each sub-pool.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">MaxSize</emphasis>: This attribute indicates the maximum number of
                              connections for a pool. No more than MaxSize connections will be created in each
                          sub-pool.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">BlockingTimeoutMillis</emphasis>: This attribute indicates the maximum
                              time to block while waiting for a connection before throwing an exception. Note that this
                              blocks only while waiting for a permit for a connection, and will never throw an exception
                              if creating a new connection takes an inordinately long time.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">IdleTiemoutMinutes</emphasis>: This attribute indicates the maximum
                              time a connection may be idle before being closed. The actual maximum time depends also on
                              the idle remover thread scan time, which is 1/2 the smallest idle timeout of any
                          pool.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">NoTxSeparatePools</emphasis>: Setting this to true doubles the
                              available pools. One pool is for connections used outside a transaction the other inside a
                              transaction. The actual pools are lazily constructed on first use. This is only relevant
                              when setting the pool parameters associated with the
                              <literal>LocalTxConnectionManager</literal> and <literal>XATxConnectionManager</literal>.
                              Its use case is for Oracle (and possibly other vendors) XA implementations that don't like
                              using an XA connection with and without a JTA transaction.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Criteria</emphasis>: This attribute indicates if the JAAS
                                  <literal>javax.security.auth.Subject</literal> from security domain associated with the
                              connection, or app supplied parameters (such as from <literal>getConnection(user,
                              pw)</literal>) are used to distinguish connections in the pool. The allowed values are:</para>
                          <itemizedlist spacing="compact">
                              <listitem>
                                  <para>
                                      <emphasis role="bold">ByContainer</emphasis>: use <literal>Subject</literal>
                                  </para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">ByApplication</emphasis>: use application supplied parameters
                                      only</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">ByContainerAndApplication</emphasis>: use both</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <emphasis role="bold">ByNothing</emphasis>: all connections are equivalent, usually
                                      if adapter supports reauthentication</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>CachedConnectionManager MBean</title>
                  <para>The <literal>org.jboss.resource.connectionmanager.CachedConnectionManager</literal> MBean manages
                      associations between meta-aware objects (those accessed through interceptor chains) and connection
                      handles, as well as between user transactions and connection handles. Normally there should only be
                      one such MBean, and this is configured in the core <literal>jboss-service.xml</literal> descriptor.
                      It is used by <literal>CachedConnectionInterceptor</literal>, JTA <literal>UserTransaction</literal>
                      implementation and all <literal>BaseConnectionManager2</literal> instances. The configurable
                      attributes of the <literal>CachedConnectionManager</literal> MBean are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">SpecCompliant</emphasis>: Enable this boolean attribute for spec
                              compliant non-shareable connections reconnect processing. This allows a connection to be
                              opened in one call and used in another. Note that specifying this behavior disables
                              connection close processing.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Debug</emphasis>: Enable this boolean property for connection close
                              processing. At the completion of an EJB method invocation, unclosed connections are
                              registered with a transaction synchronization. If the transaction ends without the
                              connection being closed, an error is reported and JBoss closes the connection. This is a
                              development feature that should be turned off in production for optimal performance.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">TransactionManagerServiceName</emphasis>: This attribute specifies the
                              JMX <literal>ObjectName</literal> of the JTA transaction manager service. Connection close
                              processing is now synchronized with the transaction manager and this attribute specifies the
                              transaction manager to use.</para>
                      </listitem>
                  </itemizedlist>
              </section>
              <section>
                  <title>A Sample Skeleton JCA Resource Adaptor</title>
                  <para>To conclude our discussion of the JBoss JCA framework we will create and deploy a single
                      non-transacted resource adaptor that simply provides a skeleton implementation that stubs out the
                      required interfaces and logs all method calls. We will not discuss the details of the requirements
                      of a resource adaptor provider as these are discussed in detail in the JCA specification. The
                      purpose of the adaptor is to demonstrate the steps required to create and deploy a RAR in JBoss, and
                      to see how JBoss interacts with the adaptor.</para>
                  <para>The adaptor we will create could be used as the starting point for a non-transacted file system
                      adaptor. The source to the example adaptor can be found in the
                      <literal>src/main/org/jboss/chap7/ex1</literal> directory of the book examples. A class diagram that
                      shows the mapping from the required <literal>javax.resource.spi</literal> interfaces to the resource
                      adaptor implementation is given in <xref linkend="ch7.fsrar.fig"/>.</para>
                  <figure id="ch7.fsrar.fig">
                      <title>The file system RAR class diagram</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/Chap7-7.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>We will build the adaptor, deploy it to the JBoss server and then run an example client against an
                      EJB that uses the resource adaptor to demonstrate the basic steps in a complete context. We'll then
                      take a look at the JBoss server log to see how the JBoss JCA framework interacts with the resource
                      adaptor to help you better understand the components in the JCA system level contract.</para>
                  <para>To build the example and deploy the RAR to the JBoss server <literal>deploy/lib</literal>
                      directory, execute the following Ant command in the book examples directory.</para>
                  <programlisting>[examples]$ ant -Dchap=chap7 build-chap</programlisting>
                  <para>The deployed files include a <literal>chap7-ex1.sar</literal> and a
                      <literal>notxfs-service.xml</literal> service descriptor. The example resource adaptor deployment
                      descriptor is shown in <xref linkend="ch7.notxfsrardd.ex"/>.</para>
                  <example id="ch7.notxfsrardd.ex">
                      <title>The nontransactional file system resource adaptor deployment descriptor.</title>
                      <programlisting>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  &lt;connector xmlns=&quot;http://java.sun.com/xml/ns/j2ee&quot;
      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
      xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/j2ee 
                          http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd&quot; version=&quot;1.5&quot;&gt;
      &lt;display-name&gt;File System Adapter&lt;/display-name&gt;
      &lt;vendor-name&gt;JBoss&lt;/vendor-name&gt;
      &lt;eis-type&gt;FileSystem&lt;/eis-type&gt;
      &lt;resourceadapter-version&gt;1.0&lt;/resourceadapter-version&gt;
      &lt;license&gt;
          &lt;description&gt;LGPL&lt;/description&gt;
          &lt;license-required&gt;false&lt;/license-required&gt;
      &lt;/license&gt;
      &lt;resourceadapter&gt;
          &lt;resourceadapter-class&gt;
              org.jboss.resource.deployment.DummyResourceAdapter
          &lt;/resourceadapter-class&gt;
          &lt;outbound-resourceadapter&gt;
              &lt;connection-definition&gt;
                  <emphasis role="bold">&lt;managedconnectionfactory-class&gt;
                      org.jboss.chap7.ex1.ra.FSManagedConnectionFactory
                  &lt;/managedconnectionfactory-class&gt;</emphasis>
                  &lt;config-property&gt;
                      &lt;config-property-name&gt;FileSystemRootDir&lt;/config-property-name&gt;
                      &lt;config-property-type&gt;java.lang.String&lt;/config-property-type&gt;
                      &lt;config-property-value&gt;/tmp/db/fs_store&lt;/config-property-value&gt;
                  &lt;/config-property&gt;
                  &lt;config-property&gt;
                      &lt;config-property-name&gt;UserName&lt;/config-property-name&gt;
                      &lt;config-property-type&gt;java.lang.String&lt;/config-property-type&gt;
                      &lt;config-property-value/&gt;
                  &lt;/config-property&gt;
                  &lt;config-property&gt;
                      &lt;config-property-name&gt;Password&lt;/config-property-name&gt;
                      &lt;config-property-type&gt;java.lang.String&lt;/config-property-type&gt;
                      &lt;config-property-value/&gt;
                  &lt;/config-property&gt;
                  <emphasis role="bold">&lt;connectionfactory-interface&gt;
                      org.jboss.chap7.ex1.ra.DirContextFactory
                  &lt;/connectionfactory-interface&gt;
                  &lt;connectionfactory-impl-class&gt;
                      org.jboss.chap7.ex1.ra.DirContextFactoryImpl
                  &lt;/connectionfactory-impl-class&gt;
                  &lt;connection-interface&gt;
                      javax.naming.directory.DirContext
                  &lt;/connection-interface&gt;
                  &lt;connection-impl-class&gt;
                      org.jboss.chap7.ex1.ra.FSDirContext 
                  &lt;/connection-impl-class&gt;</emphasis>
              &lt;/connection-definition&gt;
              &lt;transaction-support&gt;NoTransaction&lt;/transaction-support&gt;
              &lt;authentication-mechanism&gt;
                  &lt;authentication-mechanism-type&gt;BasicPassword&lt;/authentication-mechanism-type&gt;
                  &lt;credential-interface&gt;
                      javax.resource.spi.security.PasswordCredential
                  &lt;/credential-interface&gt;
              &lt;/authentication-mechanism&gt;
              <emphasis role="bold">&lt;reauthentication-support&gt;true&lt;/reauthentication-support&gt;</emphasis>
          &lt;/outbound-resourceadapter&gt;
          &lt;security-permission&gt;
              &lt;description&gt; Read/Write access is required to the contents of the
                  FileSystemRootDir &lt;/description&gt;
              &lt;security-permission-spec&gt; permission java.io.FilePermission
                  &quot;/tmp/db/fs_store/*&quot;, &quot;read,write&quot;; 
              &lt;/security-permission-spec&gt;
          &lt;/security-permission&gt;
      &lt;/resourceadapter&gt;
  &lt;/connector&gt;</programlisting>
                  </example>
                  <para>The key items in the resource adaptor deployment descriptor are highlighted in bold. These define
                      the classes of the resource adaptor, and the elements are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">managedconnectionfactory-class</emphasis>: The implementation of the
                                  <literal>ManagedConnectionFactory</literal> interface,
                                  <literal>org.jboss.chap7.ex1.ra.FSManagedConnectionFactory</literal>
                          </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">connectionfactory-interface</emphasis>: This is the interface that
                              clients will obtain when they lookup the connection factory instance from JNDI, here a
                              proprietary resource adaptor value,
                              <literal>org.jboss.chap7.ex1.ra.DirContextFactory</literal>. This value will be needed when
                              we create the JBoss <literal>ds.xml</literal> to use the resource. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">connectionfactory-impl-class</emphasis>: This is the class that
                              provides the implementation of the <literal>connectionfactory-interface</literal>,
                                  <literal>org.jboss.chap7.ex1.ra.DirContextFactoryImpl</literal>. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">connection-interface</emphasis>: This is the interface for the
                              connections returned by the resource adaptor connection factory, here the JNDI
                                  <literal>javax.naming.directory.DirContext</literal> interface.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">connection-impl-class</emphasis>: This is he class that provides the
                                  <literal>connection-interface</literal> implementation,
                                  <literal>org.jboss.chap7.ex1.ra.FSDirContext</literal>. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">transaction-support</emphasis>: The level of transaction support, here
                              defined as <literal>NoTransaction</literal>, meaning the file system resource adaptor does
                              not do transactional work.</para>
                      </listitem>
                  </itemizedlist>
                  <para> The RAR classes and deployment descriptor only define a resource adaptor. To use the resource
                      adaptor it must be integrated into the JBoss application server using a <literal>ds.xml</literal>
                      descriptor file. An example of this for the file system adaptor is shown in <xref
                          linkend="ch7.notxfs.ex"/>. </para>
                  <example id="ch7.notxfs.ex">
                      <title>The notxfs-ds.xml resource adaptor MBeans service descriptor.</title>
                      <programlisting>&lt;!DOCTYPE connection-factories PUBLIC
            &quot;-//JBoss//DTD JBOSS JCA Config 1.5//EN&quot;
            &quot;http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd&quot;&gt;
  &lt;!--   
         The non-transaction FileSystem resource adaptor service configuration
  --&gt;
  &lt;connection-factories&gt;
      &lt;no-tx-connection-factory&gt;
          &lt;jndi-name&gt;NoTransFS&lt;/jndi-name&gt;
          &lt;rar-name&gt;chap7-ex1.rar&lt;/rar-name&gt;
          &lt;connection-definition&gt;
               org.jboss.chap7.ex1.ra.DirContextFactory
          &lt;/connection-definition&gt;
          &lt;config-property name=&quot;FileSystemRootDir&quot;
                           type=&quot;java.lang.String&quot;&gt;/tmp/db/fs_store&lt;/config-property&gt;
      &lt;/no-tx-connection-factory&gt;
  &lt;/connection-factories&gt;</programlisting>
                  </example>
                  <para> The main attributes are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">jndi-name</emphasis>: This specifies where the connection factory will
                              be bound into JNDI. For this deployment that binding will be
                              <literal>java:/NoTransFS</literal>. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">rar-name</emphasis>: This is the name of the RAR file that contains
                              the definition for the resource we want to provide. For nested RAR files, the name would
                              look like <literal>myapplication.ear#my.rar</literal>. In this example, it is simply
                                  <literal>chap7-ex1.rar</literal>. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">connection-definition</emphasis>: This is the connection factory
                              interface class. It should match the <literal>connectionfactory-interface</literal> in the
                                  <literal>ra.xml</literal> file. Here our connection factory interface is
                                  <literal>org.jboss.chap7.ex1.ra.DirContextFactory</literal>. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">config-property</emphasis>: This can be used to provide non-default
                              settings to the resource adaptor connection factory. Here the
                              <literal>FileSystemRootDir</literal> is being set to <literal>/tmp/db/fs_store</literal>.
                              This overrides the default value in the <literal>ra.xml</literal> file.</para>
                      </listitem>
                  </itemizedlist>
                  <para>To deploy the RAR and connection manager configuration to the JBoss server, run the following:</para>
                  <programlisting>[examples]$ ant -Dchap=chap7 config</programlisting>
                  <para>The server console will display some logging output indicating that the resource adaptor has been
                      deployed. </para>
                  <para>Now we want to test access of the resource adaptor by a J2EE component. To do this we have created
                      a trivial stateless session bean that has a single method called <literal>echo</literal>. Inside of
                      the <literal>echo</literal> method the EJB accesses the resource adaptor connection factory, creates
                      a connection, and then immediately closes the connection. The <literal>echo</literal> method code is
                      shown below.</para>
                  <example id="ch7.ssbechomethod.ex">
                      <title>The stateless session bean echo method code that shows the access of the resource adaptor
                          connection factory.</title>
                      <programlisting>public String echo(String arg)
  {
      log.info(&quot;echo, arg=&quot;+arg);
      try {
          InitialContext ctx = new InitialContext();
          Object         ref = ctx.lookup(&quot;java:comp/env/ra/DirContextFactory&quot;);
          log.info(&quot;echo, ra/DirContextFactory=&quot; + ref);
  
          DirContextFactory dcf = (DirContextFactory) ref;
          log.info(&quot;echo, found dcf=&quot; + dcf);
  
          DirContext dc = dcf.getConnection();
          log.info(&quot;echo, lookup dc=&quot; + dc);
  
          dc.close();
      } catch(NamingException e) {
          log.error(&quot;Failed during JNDI access&quot;, e);
      }
      return arg;
  }</programlisting>
                  </example>
                  <para>The EJB is not using the CCI interface to access the resource adaptor. Rather, it is using the
                      resource adaptor specific API based on the proprietary <literal>DirContextFactory</literal>
                      interface that returns a JNDI <literal>DirContext</literal> object as the connection object. The
                      example EJB is simply exercising the system contract layer by looking up the resource adaptor
                      connection factory, creating a connection to the resource and closing the connection. The EJB does
                      not actually do anything with the connection, as this would only exercise the resource adaptor
                      implementation since this is a non-transactional resource.</para>
                  <para>Run the test client which calls the <literal>EchoBean.echo</literal> method by running Ant as
                      follows from the examples directory:</para>
                  <programlisting>[examples]$ ant -Dchap=chap7 -Dex=1 run-example</programlisting>
                  <para>You'll see some output from the bean in the system console, but much more detailed logging output
                      can be found in the <literal>server/default/log/server.log</literal> file. Don't worry if you see
                      exceptions. They are just stack traces to highlight the call path into parts of the adaptor. To help
                      understand the interaction between the adaptor and the JBoss JCA layer, we'll summarize the events
                      seen in the log using a sequence diagram. <xref linkend="ch7.cxrarseq.fig"/> is a sequence diagram
                      that summarizes the events that occur when the <literal>EchoBean</literal> accesses the resource
                      adaptor connection factory from JNDI and creates a connection.</para>
                  <figure id="ch7.cxrarseq.fig">
                      <title>A sequence diagram illustrating the key interactions between the JBossCX framework and the
                          example resource adaptor that result when the EchoBean accesses the resource adaptor connection
                          factory.</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/Chap7-8.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The starting point is the client's invocation of the <literal>EchoBean.echo</literal> method. For
                      the sake of conciseness of the diagram, the client is shown directly invoking the EchoBean.echo
                      method when in reality the JBoss EJB container handles the invocation. There are three distinct
                      interactions between the <literal>EchoBean</literal> and the resource adaptor; the lookup of the
                      connection factory, the creation of a connection, and the close of the connection.</para>
                  <para>The lookup of the resource adaptor connection factory is illustrated by the 1.1 sequences of
                      events. The events are:</para>
                  <itemizedlist>
                      <listitem>
                          <para>1, the echo method invokes the <literal>getConnection</literal> method on the resource
                              adaptor connection factory obtained from the JNDI lookup on the
                                  <literal>java:comp/env/ra/DirContextFactory</literal> name which is a link to the
                                  <literal>java:/NoTransFS</literal> location.</para>
                      </listitem>
                      <listitem>
                          <para>1.1, the <literal>DirContextFactoryImpl</literal> class asks its associated
                                  <literal>ConnectionManager</literal> to allocate a connection. It passes in the
                                  <literal>ManagedConnectionFactory</literal> and <literal>FSRequestInfo</literal> that
                              were associated with the <literal>DirContextFactoryImpl</literal> during its
                          construction.</para>
                      </listitem>
                      <listitem>
                          <para>1.1.1, the <literal>ConnectionManager</literal> invokes its
                              <literal>getManagedConnection</literal> method with the current <literal>Subject</literal>
                              and <literal>FSRequestInfo</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>1.1.1.1, the <literal>ConnectionManager</literal> asks its object pool for a connection
                              object. The <literal>JBossManagedConnectionPool$BasePool</literal> is get the key for the
                              connection and then asks the matching <literal>InternalPool</literal> for a
                          connection.</para>
                      </listitem>
                      <listitem>
                          <para>1.1.1.1.1, Since no connections have been created the pool must create a new connection.
                              This is done by requesting a new managed connection from the
                                  <literal>ManagedConnectionFactory</literal>. The <literal>Subject</literal> associated
                              with the pool as well as the <literal>FSRequestInfo</literal> data are passed as arguments
                              to the <literal>createManagedConnection</literal> method invocation.</para>
                      </listitem>
                      <listitem>
                          <para>1.1.1.1.1.1, the <literal>ConnectionFactory</literal> creates a new
                                  <literal>FSManagedConnection</literal> instance and passes in the
                              <literal>Subject</literal> and <literal>FSRequestInfo</literal> data.</para>
                      </listitem>
                      <listitem>
                          <para>1.1.1.2, a <literal>javax.resource.spi.ConnectionListener</literal> instance is created.
                              The type of listener created is based on the type of <literal>ConnectionManager</literal>.
                              In this case it is an
                                  <literal>org.jboss.resource.connectionmgr.BaseConnectionManager2$NoTransactionListener</literal>
                              instance.</para>
                      </listitem>
                      <listitem>
                          <para>1.1.1.2.1, the listener registers as a
                              <literal>javax.resource.spi.ConnectionEventListener</literal> with the
                                  <literal>ManagedConnection</literal> instance created in 1.2.1.1.</para>
                      </listitem>
                      <listitem>
                          <para>1.1.2, the <literal>ManagedConnection</literal> is asked for the underlying resource
                              manager connection. The <literal>Subject</literal> and <literal>FSRequestInfo</literal> data
                              are passed as arguments to the <literal>getConnection</literal> method invocation.</para>
                      </listitem>
                      <listitem>
                          <para>The resulting connection object is cast to a
                              <literal>javax.naming.directory.DirContext</literal> instance since this is the public
                              interface defined by the resource adaptor.</para>
                      </listitem>
                      <listitem>
                          <para>After the <literal>EchoBean</literal> has obtained the <literal>DirContext</literal> for
                              the resource adaptor, it simply closes the connection to indicate its interaction with the
                              resource manager is complete.</para>
                      </listitem>
                  </itemizedlist>
                  <para>This concludes the resource adaptor example. Our investigation into the interaction between the
                      JBossCX layer and a trivial resource adaptor should give you sufficient understanding of the steps
                      required to configure any resource adaptor. The example adaptor can also serve as a starting point
                      for the creation of your own custom resource adaptors if you need to integrate non-JDBC resources
                      into the JBoss server environment.</para>
              </section>
          </section>
          <section id="ch7.jdbc.sect">
              <title>Configuring JDBC DataSources</title>
              <para>Rather than configuring the connection manager factory related MBeans discussed in the previous
                  section via a mbean services deployment descriptor, JBoss provides a simplified datasource centric
                  descriptor. This is transformed into the standard <literal>jboss-service.xml</literal> MBean services
                  deployment descriptor using a XSL transform applied by the
                  <literal>org.jboss.deployment.XSLSubDeployer</literal> included in the <literal>jboss-jca.sar</literal>
                  deployment. The simplified configuration descriptor is deployed the same as other deployable components.
                  The descriptor must be named using a <literal>*-ds.xml</literal> pattern in order to be recognized by
                  the <literal>XSLSubDeployer</literal>.</para>
              <para>The schema for the top-level datasource elements of the <literal>*-ds.xml</literal> configuration
                  deployment file is shown in <xref linkend="ch7.jcads.fig"/>.</para>
              <figure id="ch7.jcads.fig">
                  <title>The simplified JCA DataSource configuration descriptor top-level schema elements</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/jboss_ds.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>Multiple datasource configurations may be specified in a configuration deployment file. The child
                  elements of the datasources root are:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">mbean</emphasis>: Any number mbean elements may be specified to define
                          MBean services that should be included in the <literal>jboss-service.xml</literal> descriptor
                          that results from the transformation. This may be used to configure services used by the
                          datasources.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">no-tx-datasource</emphasis>: This element is used to specify the
                              (<literal>org.jboss.resource.connectionmanager</literal>)
                          <literal>NoTxConnectionManager</literal> service configuration.
                          <literal>NoTxConnectionManager</literal> is a JCA connection manager with no transaction
                          support. The <literal>no-tx-datasource</literal> child element schema is given in <xref
                              linkend="ch7.nontxconf.fig"/>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">local-tx-datasource</emphasis>: This element is used to specify the
                              (<literal>org.jboss.resource.connectionmanager</literal>)
                          <literal>LocalTxConnectionManager</literal> service configuration.
                              <literal>LocalTxConnectionManager</literal> implements a
                          <literal>ConnectionEventListener</literal> that implements <literal>XAResource</literal> to
                          manage transactions through the transaction manager. To ensure that all work in a local
                          transaction occurs over the same <literal>ManagedConnection</literal>, it includes a xid to
                              <literal>ManagedConnection</literal> map. When a Connection is requested or a transaction
                          started with a connection handle in use, it checks to see if a
                          <literal>ManagedConnection</literal> already exists enrolled in the global transaction and uses
                          it if found. Otherwise, a free <literal>ManagedConnection</literal> has its
                              <literal>LocalTransaction</literal> started and is used. The
                          <literal>local-tx-datasource</literal> child element schema is given in <xref
                              linkend="ch7.txconf.fig"/>
                      </para>
  
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">xa-datasource</emphasis>: This element is used to specify the
                              (<literal>org.jboss.resource.connectionmanager</literal>)
                          <literal>XATxConnectionManager</literal> service configuration.
                          <literal>XATxConnectionManager</literal> implements a <literal>ConnectionEventListener</literal>
                          that obtains the <literal>XAResource</literal> to manage transactions through the transaction
                          manager from the adaptor <literal>ManagedConnection</literal>. To ensure that all work in a
                          local transaction occurs over the same <literal>ManagedConnection</literal>, it includes a xid
                          to <literal>ManagedConnection</literal> map. When a <literal>Connection</literal> is requested
                          or a transaction started with a connection handle in use, it checks to see if a
                              <literal>ManagedConnection</literal> already exists enrolled in the global transaction and
                          uses it if found. Otherwise, a free <literal>ManagedConnection</literal> has its
                              <literal>LocalTransaction</literal> started and is used. The
                          <literal>xa-datasource</literal> child element schema is given in <xref linkend="ch7.xaconf.fig"
                          />.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">ha-local-tx-datasource</emphasis>: This element is identical to
                              <literal>local-tx-datasource</literal>, with the addition of the experimental datasource
                          failover capability allowing JBoss to failover to an alternate database in the event of a
                          database failure. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">ha-xa-datasource</emphasis>: This element is identical to
                              <literal>xa-datasource</literal>, with the addition of the experimental datasource failover
                          capability allowing JBoss to failover to an alternate database in the event of a database
                          failure. </para>
                  </listitem>
              </itemizedlist>
              <figure id="ch7.nontxconf.fig">
                  <title>The non-transactional DataSource configuration schema</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/jboss_ds_no_tx.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <figure id="ch7.txconf.fig">
                  <title>The non-XA DataSource configuration schema</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/jboss_ds_local_tx.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <figure id="ch7.xaconf.fig">
                  <title>The XA DataSource configuration schema</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/jboss_ds_xa.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <figure id="ch7.hatxconf.fig">
                  <title>The schema for the experimental non-XA DataSource with failover</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/jboss_ds_ha_local.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <figure id="ch7.haxaconf.fig">
                  <title>The schema for the experimental XA Datasource with failover</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/jboss_ds_ha_xa.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>Elements that are common to all datasources include:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">jndi-name</emphasis>: The JNDI name under which the
                          <literal>DataSource</literal> wrapper will be bound. Note that this name is relative to the
                              <literal>java:/</literal> context, unless <literal>use-java-context</literal> is set to
                          false. <literal>DataSource</literal> wrappers are not usable outside of the server VM, so they
                          are normally bound under the <literal>java:/</literal>, which isn't shared outside the local
                      VM.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">use-java-context</emphasis>: If this is set to false the the datasource
                          will be bound in the global JNDI context rather than the <literal>java:</literal> context.
                      </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">user-name</emphasis>: This element specifies the default username used
                          when creating a new connection. The actual username may be overridden by the application code
                              <literal>getConnection</literal> parameters or the connection creation context JAAS
                      Subject.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">password</emphasis>: This element specifies the default password used when
                          creating a new connection. The actual password may be overridden by the application code
                              <literal>getConnection</literal> parameters or the connection creation context JAAS
                      Subject.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">application-managed-security</emphasis>: Specifying this element indicates
                          that connections in the pool should be distinguished by application code supplied parameters,
                          such as from <literal>getConnection(user, pw)</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">security-domain</emphasis>: Specifying this element indicates that
                          connections in the pool should be distinguished by JAAS Subject based information. The content
                          of the <literal>security-domain</literal> is the name of the JAAS security manager that will
                          handle authentication. This name correlates to the JAAS <literal>login-config.xml</literal>
                          descriptor <literal>application-policy/name</literal> attribute.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">security-domain-and-application</emphasis>: Specifying this element
                          indicates that connections in the pool should be distinguished both by application code supplied
                          parameters and JAAS Subject based information. The content of the
                          <literal>security-domain</literal> is the name of the JAAS security manager that will handle
                          authentication. This name correlates to the JAAS <literal>login-config.xml</literal> descriptor
                              <literal>application-policy/name</literal> attribute.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">min-pool-size</emphasis>: This element specifies the minimum number of
                          connections a pool should hold. These pool instances are not created until an initial request
                          for a connection is made. This default to 0.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">max-pool-size</emphasis>: This element specifies the maximum number of
                          connections for a pool. No more than the <literal>max-pool-size</literal> number of connections
                          will be created in a pool. This defaults to 20.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">blocking-timeout-millis</emphasis>: This element specifies the maximum
                          time in milliseconds to block while waiting for a connection before throwing an exception. Note
                          that this blocks only while waiting for a permit for a connection, and will never throw an
                          exception if creating a new connection takes an inordinately long time. The default is
                      5000.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">idle-timeout-minutes</emphasis>: This element specifies the maximum time
                          in minutes a connection may be idle before being closed. The actual maximum time depends also on
                          the <literal>IdleRemover</literal> scan time, which is 1/2 the smallest idle-timeout-minutes of
                          any pool.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">new-connection-sql</emphasis>: This is a SQL statement that should be
                          executed when a new connection is created. This can be used to configure a connection with
                          database specific settings not configurable via connection properties.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">check-valid-connection-sql</emphasis>: This is a SQL statement that should
                          be run on a connection before it is returned from the pool to test its validity to test for
                          stale pool connections. An example statement could be: <literal>select count(*) from
                          x</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">exception-sorter-class-name</emphasis>: This specifies a class that
                          implements the <literal>org.jboss.resource.adapter.jdbc.ExceptionSorter</literal> interface to
                          examine database exceptions to determine whether or not the exception indicates a connection
                          error. Current implementations include:</para>
                      <itemizedlist spacing="compact">
                          <listitem>
                              <para>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</para>
                          </listitem>
                          <listitem>
                              <para>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</para>
                          </listitem>
                          <listitem>
                              <para>org.jboss.resource.adapter.jdbc.vendor.SybaseExceptionSorter</para>
                          </listitem>
                          <listitem>
                              <para>org.jboss.resource.adapter.jdbc.vendor.InformixExceptionSorte</para>
                          </listitem>
  
                      </itemizedlist>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">valid-connection-checker-class-name</emphasis>: This specifies a class
                          that implements the <literal>org.jboss.resource.adapter.jdbc.ValidConnectionChecker</literal>
                          interface to provide a <literal>SQLException isValidConnection(Connection e)</literal> method
                          that is called with a connection that is to be returned from the pool to test its validity. This
                          overrides the <literal>check-valid-connection-sql</literal> when present. The only provided
                          implementation is
                          <literal>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</literal>. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">track-statements</emphasis>: This boolean element specifies whether to
                          check for unclosed statements when a connection is returned to the pool. If true, a warning
                          message is issued for each unclosed statement. If the log4j category
                              <literal>org.jboss.resource.adapter.jdbc.WrappedConnection</literal> has trace level
                          enabled, a stack trace of the connection close call is logged as well. This is a debug feature
                          that can be turned off in production.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">prepared-statement-cache-size</emphasis>: This element specifies the
                          number of prepared statements per connection in an LRU cache, which is keyed by the SQL query.
                          Setting this to zero disables the cache.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">depends</emphasis>: The <literal>depends</literal> element specifies the
                          JMX <literal>ObjectName</literal> string of a service that the connection manager services
                          depend on. The connection manager service will not be started until the dependent services have
                          been started.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">type-mapping</emphasis>: This element declares a default type mapping for
                          this datasource. The type mapping should match a <literal>type-mapping/name</literal> element
                          from <literal>standardjbosscmp-jdbc.xml</literal>. </para>
                  </listitem>
              </itemizedlist>
              <para>Additional common child elements for both <literal>no-tx-datasource</literal> and
                      <literal>local-tx-datasource</literal> include:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">connection-url</emphasis>: This is the JDBC driver connection URL string,
                          for example, <literal>jdbc:hsqldb:hsql://localhost:1701</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">driver-class</emphasis>: This is the fully qualified name of the JDBC
                          driver class, for example, <literal>org.hsqldb.jdbcDriver</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">connection-property</emphasis>: The <literal>connection-property</literal>
                          element allows you to pass in arbitrary connection properties to the
                              <literal>java.sql.Driver.connect(url, props)</literal> method. Each
                              <literal>connection-property</literal> specifies a string name/value pair with the property
                          name coming from the name attribute and the value coming from the element content.</para>
                  </listitem>
              </itemizedlist>
              <para>Elements in common to the <literal>local-tx-datasource</literal> and <literal>xa-datasource</literal>
                  are:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">transaction-isolation</emphasis>: This element specifies the
                              <literal>java.sql.Connection</literal> transaction isolation level to use. The constants
                          defined in the Connection interface are the possible element content values and include:</para>
                      <itemizedlist spacing="compact">
                          <listitem>
                              <para>TRANSACTION_READ_UNCOMMITTED</para>
                          </listitem>
                          <listitem>
                              <para>TRANSACTION_READ_COMMITTED</para>
                          </listitem>
                          <listitem>
                              <para>TRANSACTION_REPEATABLE_READ</para>
                          </listitem>
                          <listitem>
                              <para>TRANSACTION_SERIALIZABLE</para>
                          </listitem>
                          <listitem>
                              <para>TRANSACTION_NONE</para>
                          </listitem>
                      </itemizedlist>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">no-tx-separate-pools</emphasis>: The presence of this element indicates
                          that two connection pools are required to isolate connections used with JTA transaction from
                          those used without a JTA transaction. The pools are lazily constructed on first use. Its use
                          case is for Oracle (and possibly other vendors) XA implementations that don't like using an XA
                          connection with and without a JTA transaction.</para>
                  </listitem>
              </itemizedlist>
              <para>The unique <literal>xa-datasource</literal> child elements are:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">track-connection-by-tx</emphasis>: Specifying a true value for this
                          element makes the connection manager keep an xid to connection map and only put the connection
                          back in the pool when the transaction completes and all the connection handles are closed or
                          disassociated (by the method calls returning). As a side effect, we never suspend and resume the
                          xid on the connection's <literal>XAResource</literal>. This is the same connection tracking
                          behavior used for local transactions.</para>
                      <para>The XA spec implies that any connection may be enrolled in any transaction using any xid for
                          that transaction at any time from any thread (suspending other transactions if necessary). The
                          original JCA implementation assumed this and aggressively delisted connections and put them back
                          in the pool as soon as control left the EJB they were used in or handles were closed. Since some
                          other transaction could be using the connection the next time work needed to be done on the
                          original transaction, there is no way to get the original connection back. It turns out that
                          most <literal>XADataSource</literal> driver vendors do not support this, and require that all
                          work done under a particular xid go through the same connection.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">xa-datasource-class</emphasis>: The fully qualified name of the
                              <literal>javax.sql.XADataSource</literal> implementation class, for example,
                              <literal>com.informix.jdbcx.IfxXADataSource</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">xa-datasource-property</emphasis>: The
                          <literal>xa-datasource-property</literal> element allows for specification of the properties to
                          assign to the <literal>XADataSource</literal> implementation class. Each property is identified
                          by the name attribute and the property value is given by the
                          <literal>xa-datasource-property</literal> element content. The property is mapped onto the
                              <literal>XADataSource</literal> implementation by looking for a JavaBeans style getter
                          method for the property name. If found, the value of the property is set using the JavaBeans
                          setter with the element text translated to the true property type using the
                              <literal>java.beans.PropertyEditor</literal> for the type.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">isSameRM-override-value</emphasis>: A boolean flag that allows one to
                          override the behavior of the <literal>javax.transaction.xa.XAResource.isSameRM(XAResource
                          xaRes)</literal> method behavior on the XA managed connection. If specified, this value is used
                          unconditionally as the <literal>isSameRM(xaRes)</literal> return value regardless of the
                              <literal>xaRes</literal> parameter.</para>
                  </listitem>
              </itemizedlist>
  
  
              <para> The failover options common to <literal>ha-xa-datasource</literal> and
                      <literal>ha-local-tx-datasource</literal> are:</para>
  
  
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">url-delimeter</emphasis>: This element specifies a character used to
                          separate multiple JDBC URLs. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">url-property</emphasis>: In the case of XA datasources, this property
                          specifies the name of the <literal>xa-datasource-property</literal> that contains the list of
                          JDBC URLs to use. </para>
                  </listitem>
              </itemizedlist>
  
  
              <para>Example configurations for many third-party JDBC drivers are included in the
                      <literal>JBOSS_DIST/docs/examples/jca</literal> directory. Current example configurations include:</para>
              <itemizedlist spacing="compact">
                  <listitem>
                      <para>asapxcess-jb3.2-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>cicsr9s-service.xml</para>
                  </listitem>
                  <listitem>
                      <para>db2-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>db2-xa-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>facets-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>fast-objects-jboss32-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>firebird-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>firstsql-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>firstsql-xa-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>generic-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>hsqldb-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>informix-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>informix-xa-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>jdatastore-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>jms-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>jsql-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>lido-versant-service.xml</para>
                  </listitem>
                  <listitem>
                      <para>mimer-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>mimer-xa-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>msaccess-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>mssql-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>mssql-xa-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>mysql-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>oracle-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>oracle-xa-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>postgres-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>sapdb-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>sapr3-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>solid-ds.xml</para>
                  </listitem>
                  <listitem>
                      <para>sybase-ds.xml</para>
                  </listitem>
              </itemizedlist>
          </section>
          <section id="ch7.genericjca.sect">
              <title>Configuring Generic JCA Adaptors</title>
              <para>The XSLSubDeployer also supports the deployment of arbitrary non-JDBC JCA resource adaptors. The
                  schema for the top-level connection factory elements of the <literal>*-ds.xml</literal> configuration
                  deployment file is shown in <xref linkend="ch7.jcafactory.fig"/>.</para>
              <figure id="ch7.jcafactory.fig">
                  <title>The simplified JCA adaptor connection factory configuration descriptor top-level schema elements</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/jboss_ds_connection_factories.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>Multiple connection factory configurations may be specified in a configuration deployment file. The
                  child elements of the <literal>connection-factories</literal> root are:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">mbean</emphasis>: Any number mbean elements may be specified to define
                          MBean services that should be included in the <literal>jboss-service.xml</literal> descriptor
                          that results from the transformation. This may be used to configure additional services used by
                          the adaptor.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">no-tx-connection-factory</emphasis>: this element is used to specify the
                              (<literal>org.jboss.resource.connectionmanager</literal>)
                          <literal>NoTxConnectionManager</literal> service configuration.
                          <literal>NoTxConnectionManager</literal> is a JCA connection manager with no transaction
                          support. The <literal>no-tx-connection-factory</literal> child element schema is given in <xref
                              linkend="ch7.notxschema.fig"/>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">tx-connection-factory</emphasis>: this element is used to specify the
                              (<literal>org.jboss.resource.connectionmanager</literal>)
                          <literal>TxConnectionManager</literal> service configuration. The
                          <literal>tx-connection-factory</literal> child element schema is given in <xref
                              linkend="ch7.txschema.fig"/>.</para>
                  </listitem>
              </itemizedlist>
              <figure id="ch7.notxschema.fig">
                  <title>The no-tx-connection-factory element schema</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/jboss_ds_no_tx_connection_factory.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <figure id="ch7.txschema.fig">
                  <title>The tx-connection-factory element schema</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/jboss_ds_tx_connection_factory.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>The majority of the elements are the same as those of the datasources configuration. The element
                  unique to the connection factory configuration include:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">adaptor-display-name</emphasis>: A human readable display name to assign
                          to the connection manager MBean.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">local-transaction</emphasis>: This element specifies that the
                              <literal>tx-connection-factory</literal> supports local transactions. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">xa-transaction</emphasis>: This element specifies that the
                              <literal>tx-connection-factory</literal> supports XA transactions.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">track-connection-by-tx</emphasis>: This element specifies that a
                          connection should be used only on a single transaction and that a transaction should only be
                          associated with one connection.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">rar-name</emphasis>: This is the name of the RAR file that contains the
                          definition for the resource we want to provide. For nested RAR files, the name would look like
                              <literal>myapplication.ear#my.rar</literal>. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">connection-definition</emphasis>: This is the connection factory interface
                          class. It should match the <literal>connectionfactory-interface</literal> in the
                          <literal>ra.xml</literal> file.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">config-property</emphasis>: Any number of properties to supply to the
                              <literal>ManagedConnectionFactory</literal> (MCF) MBean service configuration. Each
                              <literal>config-property</literal> element specifies the value of a MCF property. The
                              <literal>config-property</literal> element has two required attributes:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">name</emphasis>: The name of the property</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">type</emphasis>: The fully qualified type of the property</para>
                          </listitem>
                      </itemizedlist>
                      <para>The content of the <literal>config-property</literal> element provides the string
                          representation of the property value. This will be converted to the true property type using the
                          associated type <literal>PropertyEditor</literal>.</para>
                  </listitem>
              </itemizedlist>
          </section>
      </chapter>
  
  
      <chapter id="ch8.chapter">
          <title>Security on JBoss</title>
          <subtitle>J2EE Security Configuration and Architecture</subtitle>
          <para>Security is a fundamental part of any enterprise application. You need to be able to restrict who is
              allowed to access your applications and control what operations application users may perform. The J2EE
              specifications define a simple role-based security model for EJBs and web components. The JBoss component
              framework that handles security is the JBossSX extension framework. The JBossSX security extension provides
              support for both the role-based declarative J2EE security model and integration of custom security via a
              security proxy layer. The default implementation of the declarative security model is based on Java
              Authentication and Authorization Service (JAAS) login modules and subjects. The security proxy layer allows
              custom security that cannot be described using the declarative model to be added to an EJB in a way that is
              independent of the EJB business object. Before getting into the JBoss security implementation details, we
              will review EJB and servlet specification security models, as well as JAAS to establish the foundation for
              these details.</para>
          <section>
              <title>J2EE Declarative Security Overview</title>
              <para>The J2EE security model declarative in that you describe the security roles and permissions in a
                  standard XML descriptor rather than embedding security into your business component. This isolates
                  security from business-level code because security tends to be more a function of where the component is
                  deployed than an inherent aspect of the component's business logic. For example, consider an ATM
                  component that is to be used to access a bank account. The security requirements, roles and permissions
                  will vary independently of how you access the bank account, based on what bank is managing the account,
                  where the ATM is located, and so on.</para>
              <para>Securing a J2EE application is based on the specification of the application security requirements via
                  the standard J2EE deployment descriptors. You secure access to EJBs and web components in an enterprise
                  application by using the <literal>ejb-jar.xml</literal> and <literal>web.xml</literal> deployment
                  descriptors. The following sections look at the purpose and usage of the various security elements.</para>
              <section>
                  <title>Security References</title>
                  <para>Both EJBs and servlets can declare one or more <literal>security-role-ref</literal> elements as
                      shown in <xref linkend="ch8.sec-role-ref.fig"/>. This element declares that a component is using the
                          <literal>role-name</literal> value as an argument to the
                      <literal>isCallerInRole(String)</literal> method. By using the <literal>isCallerInRole</literal>
                      method, a component can verify whether the caller is in a role that has been declared with a
                          <literal>security-role-ref/role-name</literal> element. The <literal>role-name</literal> element
                      value must link to a <literal>security-role</literal> element through the
                      <literal>role-link</literal> element. The typical use of <literal>isCallerInRole</literal> is to
                      perform a security check that cannot be defined by using the role-based
                      <literal>method-permissions</literal> elements. </para>
                  <figure id="ch8.sec-role-ref.fig">
                      <title>The security-role-ref element</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata fileref="images/j2ee_security_role_ref.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>
                      <xref linkend="ch8.ejbjarsec.ex"/> shows the use of <literal>security-role-ref</literal> in an
                          <literal>ejb-jar.xml</literal>.</para>
                  <example id="ch8.ejbjarsec.ex">
                      <title>An ejb-jar.xml descriptor fragment that illustrates the security-role-ref element usage.</title>
                      <programlisting>&lt;!-- A sample ejb-jar.xml fragment --&gt;
  &lt;ejb-jar&gt;
    &lt;enterprise-beans&gt;
      &lt;session&gt;
        &lt;ejb-name&gt;ASessionBean&lt;/ejb-name&gt;
        ...
        &lt;security-role-ref&gt;
            &lt;role-name&gt;TheRoleICheck&lt;/role-name&gt;
            &lt;role-link&gt;TheApplicationRole&lt;/role-link&gt;
        &lt;/security-role-ref&gt;
      &lt;/session&gt;
    &lt;/enterprise-beans&gt;
    ...
  &lt;/ejb-jar&gt;</programlisting>
                  </example>
                  <para>
                      <xref linkend="ch8.webxmlsec.ex"/> shows the use of <literal>security-role-ref</literal> in a
                          <literal>web.xml</literal>.</para>
                  <example id="ch8.webxmlsec.ex">
                      <title>An example web.xml descriptor fragment that illustrates the security-role-ref element usage.</title>
                      <programlisting>&lt;web-app&gt;
      &lt;servlet&gt;
          &lt;servlet-name&gt;AServlet&lt;/servlet-name&gt;
          ...
          &lt;security-role-ref&gt;
              &lt;role-name&gt;TheServletRole&lt;/role-name&gt;
              &lt;role-link&gt;TheApplicationRole&lt;/role-link&gt;
          &lt;/security-role-ref&gt;
      &lt;/servlet&gt;
      ...
  &lt;/web-app&gt;</programlisting>
                  </example>
              </section>
              <section>
                  <title>Security Identity</title>
                  <para>An EJB has the capability to specify what identity an EJB should use when it invokes methods on
                      other components using the <literal>security-identity</literal> element, shown in <xref
                          linkend="ch8.security-identity.fig"/>
                  </para>
                  <figure id="ch8.security-identity.fig">
                      <title>The security-identity element</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata fileref="images/j2ee_security_identity.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para> The invocation identity can be that of the current caller, or it can be a specific role. The
                      application assembler uses the <literal>security-identity</literal> element with a
                          <literal>use-caller-identity</literal> child element to indicate that the current caller's
                      identity should be propagated as the security identity for method invocations made by the EJB.
                      Propagation of the caller's identity is the default used in the absence of an explicit
                          <literal>security-identity</literal> element declaration.</para>
                  <para>Alternatively, the application assembler can use the <literal>run-as/role-name</literal> child
                      element to specify that a specific security role given by the <literal>role-name</literal> value
                      should be used as the security identity for method invocations made by the EJB. Note that this does
                      not change the caller's identity as seen by the <literal>EJBContext.getCallerPrincipal()</literal>
                      method. Rather, the caller's security roles are set to the single role specified by the
                          <literal>run-as/role-name</literal> element value. One use case for the
                      <literal>run-as</literal> element is to prevent external clients from accessing internal EJBs. You
                      accomplish this by assigning the internal EJB <literal>method-permission</literal> elements that
                      restrict access to a role never assigned to an external client. EJBs that need to use internal EJB
                      are then configured with a <literal>run-as/role-name</literal> equal to the restricted role. The
                      following descriptor fragment that illustrates <literal>security-identity</literal> element usage.</para>
                  <programlisting>&lt;!-- A sample ejb-jar.xml fragment --&gt;
  &lt;ejb-jar&gt;
      &lt;enterprise-beans&gt;
          &lt;session&gt;
              &lt;ejb-name&gt;ASessionBean&lt;/ejb-name&gt;
              &lt;!-- ... --&gt;
              &lt;security-identity&gt;
                  &lt;use-caller-identity/&gt;
              &lt;/security-identity&gt;
          &lt;/session&gt;
          &lt;session&gt;
              &lt;ejb-name&gt;RunAsBean&lt;/ejb-name&gt;
              &lt;!-- ... --&gt;
              &lt;security-identity&gt;
                  &lt;run-as&gt;
                      &lt;description&gt;A private internal role&lt;/description&gt;
                      &lt;role-name&gt;InternalRole&lt;/role-name&gt;
                  &lt;/run-as&gt;
              &lt;/security-identity&gt;
          &lt;/session&gt;
      &lt;/enterprise-beans&gt;
      &lt;!-- ... --&gt;
  &lt;/ejb-jar&gt;</programlisting>
                  <para>When you use <literal>run-as</literal> to assign a specific role to outgoing calls, JBoss
                      associates a principal named <literal>anonymous</literal>. If you want another prinicipal to be
                      associated with the call, you need to associate a <literal>run-as-principal</literal> with the bean
                      in the <literal>jboss.xml</literal> file. The following fragment associates a principal named
                          <literal>internal</literal> with <literal>RunAsBean</literal> from the prior example.</para>
                  <programlisting>&lt;session&gt;
      &lt;ejb-name&gt;RunAsBean&lt;/ejb-name&gt;
      &lt;security-identity&gt;
          &lt;run-as-principal&gt;internal&lt;/run-as-principal&gt;
      &lt;/security-identity&gt;
  &lt;/session&gt;</programlisting>
                  <para>The <literal>run-as</literal> element is also available in servlet definitions in a
                          <literal>web.xml</literal> file. The following example shows how to assign the role
                          <literal>InternalRole</literal> to a servlet:</para>
                  <programlisting>&lt;servlet&gt;
      &lt;servlet-name&gt;AServlet&lt;/servlet-name&gt;
      &lt;!-- ... --&gt;
      &lt;run-as&gt; 
          &lt;role-name&gt;InternalRole&lt;/role-name&gt;
      &lt;/run-as&gt;
  &lt;/servlet&gt;</programlisting>
                  <para> Calls from this servlet will be associated with the anonymous <literal>principal</literal>. The
                          <literal>run-as-principal</literal> element is available in the <literal>jboss-web.xml</literal>
                      file to assign a specific principal to go along with the <literal>run-as</literal> role. The
                      following fragment shows how to associate a principal named <literal>internal</literal> to the
                      servlet in the prior example. </para>
                  <programlisting>&lt;servlet&gt;
      &lt;servlet-name&gt;AServlet&lt;/servlet-name&gt;
      &lt;run-as-principal&gt;internal&lt;/run-as-principal&gt;
  &lt;/servlet&gt;</programlisting>
              </section>
              <section>
                  <title>Security roles</title>
                  <para>The security role name referenced by either the <literal>security-role-ref</literal> or
                          <literal>security-identity</literal> element needs to map to one of the application's declared
                      roles. An application assembler defines logical security roles by declaring
                      <literal>security-role</literal> elements. The <literal>role-name</literal> value is a logical
                      application role name like Administrator, Architect, SalesManager, etc.</para>
                  <para>The J2EE specifications note that it is important to keep in mind that the security roles in the
                      deployment descriptor are used to define the logical security view of an application. Roles defined
                      in the J2EE deployment descriptors should not be confused with the user groups, users, principals,
                      and other concepts that exist in the target enterprise's operational environment. The deployment
                      descriptor roles are application constructs with application domain-specific names. For example, a
                      banking application might use role names such as BankManager, Teller, or Customer.</para>
                  <figure>
                      <title>The security-role element</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata fileref="images/j2ee_security_role.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>In JBoss, a <literal>security-role</literal> element is only used to map
                          <literal>security-role-ref/role-name</literal> values to the logical role that the component
                      role references. The user's assigned roles are a dynamic function of the application's security
                      manager, as you will see when we discuss the JBossSX implementation details. JBoss does not require
                      the definition of <literal>security-role</literal> elements in order to declare method permissions.
                      However, the specification of <literal>security-role</literal> elements is still a recommended
                      practice to ensure portability across application servers and for deployment descriptor maintenance.
                          <xref linkend="ch8.ejbsecrole.fig"/> shows the usage of the <literal>security-role</literal> in
                      an <literal>ejb-jar.xml</literal> file. </para>
                  <example id="ch8.ejbsecrole.fig">
                      <title>An ejb-jar.xml descriptor fragment that illustrates the security-role element usage.</title>
                      <programlisting>&lt;!-- A sample ejb-jar.xml fragment --&gt;
  &lt;ejb-jar&gt;
      &lt;!-- ... --&gt;
      &lt;assembly-descriptor&gt;
          &lt;security-role&gt;
              &lt;description&gt;The single application role&lt;/description&gt;
              &lt;role-name&gt;TheApplicationRole&lt;/role-name&gt;
          &lt;/security-role&gt;
      &lt;/assembly-descriptor&gt;
  &lt;/ejb-jar&gt;</programlisting>
                  </example>
                  <para>
                      <xref linkend="ch8.websecrole.fig"/> shows the usage of the <literal>security-role</literal> in an
                          <literal>web.xml</literal> file.</para>
                  <example id="ch8.websecrole.fig">
                      <title>An example web.xml descriptor fragment that illustrates the security-role element usage.</title>
                      <programlisting>&lt;!-- A sample web.xml fragment --&gt;
  &lt;web-app&gt;
      &lt;!-- ... --&gt;
      &lt;security-role&gt;
          &lt;description&gt;The single application role&lt;/description&gt;
          &lt;role-name&gt;TheApplicationRole&lt;/role-name&gt;
      &lt;/security-role&gt;
  &lt;/web-app&gt;</programlisting>
                  </example>
              </section>
              <section>
                  <title>EJB method permissions</title>
                  <para>An application assembler can set the roles that are allowed to invoke an EJB's home and remote
                      interface methods through method-permission element declarations. </para>
                  <figure>
                      <title>The method-permissions element</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata fileref="images/j2ee_method_permission.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>Each <literal>method-permission</literal> element contains one or more role-name child elements
                      that define the logical roles that are allowed to access the EJB methods as identified by method
                      child elements. You can also specify an <literal>unchecked</literal> element instead of the
                          <literal>role-name</literal> element to declare that any authenticated user can access the
                      methods identified by method child elements. In addition, you can declare that no one should have
                      access to a method that has the <literal>exclude-list</literal> element. If an EJB has methods that
                      have not been declared as accessible by a role using a <literal>method-permission</literal> element,
                      the EJB methods default to being excluded from use. This is equivalent to defaulting the methods
                      into the <literal>exclude-list</literal>.</para>
                  <figure>
                      <title>The method element</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata fileref="images/j2ee_method.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>There are three supported styles of method element declarations.</para>
                  <para>The first is used for referring to all the home and component interface methods of the named
                      enterprise bean:</para>
                  <programlisting>&lt;method&gt;
      &lt;ejb-name&gt;EJBNAME&lt;/ejb-name&gt;
      &lt;method-name&gt;*&lt;/method-name&gt;
  &lt;/method&gt;</programlisting>
                  <para>The second style is used for referring to a specified method of the home or component interface of
                      the named enterprise bean:</para>
                  <programlisting>&lt;method&gt;
      &lt;ejb-name&gt;EJBNAME&lt;/ejb-name&gt;
      &lt;method-name&gt;METHOD&lt;/method-name&gt;
                  &lt;/method&gt;</programlisting>
                  <para> If there are multiple methods with the same overloaded name, this style refers to all of the
                      overloaded methods.</para>
                  <para>The third style is used to refer to a specified method within a set of methods with an overloaded
                      name:</para>
                  <programlisting>&lt;method&gt;
      &lt;ejb-name&gt;EJBNAME&lt;/ejb-name&gt;
      &lt;method-name&gt;METHOD&lt;/method-name&gt;
      &lt;method-params&gt;
          &lt;method-param&gt;PARAMETER_1&lt;/method-param&gt;
          &lt;!-- ... --&gt;
          &lt;method-param&gt;PARAMETER_N&lt;/method-param&gt;
      &lt;/method-params&gt;
  &lt;/method&gt;</programlisting>
                  <para>The method must be defined in the specified enterprise bean's home or remote interface. The
                      method-param element values are the fully qualified name of the corresponding method parameter type.
                      If there are multiple methods with the same overloaded signature, the permission applies to all of
                      the matching overloaded methods.</para>
                  <para>The optional <literal>method-intf</literal> element can be used to differentiate methods with the
                      same name and signature that are defined in both the home and remote interfaces of an enterprise
                      bean. </para>
                  <para>
                      <xref linkend="ch8.ejbjarmethodperm.ex"/> provides complete examples of the
                          <literal>method-permission</literal> element usage.</para>
                  <example id="ch8.ejbjarmethodperm.ex">
                      <title>An ejb-jar.xml descriptor fragment that illustrates the method-permission element usage.</title>
                      <programlisting>&lt;ejb-jar&gt;
      &lt;assembly-descriptor&gt;
          &lt;method-permission&gt;
              &lt;description&gt;The employee and temp-employee roles may access any
                  method of the EmployeeService bean &lt;/description&gt;
              &lt;role-name&gt;employee&lt;/role-name&gt;
              &lt;role-name&gt;temp-employee&lt;/role-name&gt;
              &lt;method&gt;
                  &lt;ejb-name&gt;EmployeeService&lt;/ejb-name&gt;
                  &lt;method-name&gt;*&lt;/method-name&gt;
              &lt;/method&gt;
          &lt;/method-permission&gt;
          &lt;method-permission&gt;
              &lt;description&gt;The employee role may access the findByPrimaryKey,
                  getEmployeeInfo, and the updateEmployeeInfo(String) method of
                  the AardvarkPayroll bean &lt;/description&gt;
              &lt;role-name&gt;employee&lt;/role-name&gt;
              &lt;method&gt;
                  &lt;ejb-name&gt;AardvarkPayroll&lt;/ejb-name&gt;
                  &lt;method-name&gt;findByPrimaryKey&lt;/method-name&gt;
              &lt;/method&gt;
              &lt;method&gt;
                  &lt;ejb-name&gt;AardvarkPayroll&lt;/ejb-name&gt;
                  &lt;method-name&gt;getEmployeeInfo&lt;/method-name&gt;
              &lt;/method&gt;
              &lt;method&gt;
                  &lt;ejb-name&gt;AardvarkPayroll&lt;/ejb-name&gt;
                  &lt;method-name&gt;updateEmployeeInfo&lt;/method-name&gt;
                  &lt;method-params&gt;
                      &lt;method-param&gt;java.lang.String&lt;/method-param&gt;
                  &lt;/method-params&gt;
              &lt;/method&gt;
          &lt;/method-permission&gt;
          &lt;method-permission&gt;
              &lt;description&gt;The admin role may access any method of the
                  EmployeeServiceAdmin bean &lt;/description&gt;
              &lt;role-name&gt;admin&lt;/role-name&gt;
              &lt;method&gt;
                  &lt;ejb-name&gt;EmployeeServiceAdmin&lt;/ejb-name&gt;
                  &lt;method-name&gt;*&lt;/method-name&gt;
              &lt;/method&gt;
          &lt;/method-permission&gt;
          &lt;method-permission&gt;
              &lt;description&gt;Any authenticated user may access any method of the
                  EmployeeServiceHelp bean&lt;/description&gt;
              &lt;unchecked/&gt;
              &lt;method&gt;
                  &lt;ejb-name&gt;EmployeeServiceHelp&lt;/ejb-name&gt;
                  &lt;method-name&gt;*&lt;/method-name&gt;
              &lt;/method&gt;
          &lt;/method-permission&gt;
          &lt;exclude-list&gt;
              &lt;description&gt;No fireTheCTO methods of the EmployeeFiring bean may be
                  used in this deployment&lt;/description&gt;
              &lt;method&gt;
                  &lt;ejb-name&gt;EmployeeFiring&lt;/ejb-name&gt;
                  &lt;method-name&gt;fireTheCTO&lt;/method-name&gt;
              &lt;/method&gt;
          &lt;/exclude-list&gt;
      &lt;/assembly-descriptor&gt;
  &lt;/ejb-jar&gt;</programlisting>
                  </example>
              </section>
              <section>
                  <title>Web Content Security Constraints</title>
                  <para>In a web application, security is defined by the roles that are allowed access to content by a URL
                      pattern that identifies the protected content. This set of information is declared by using the
                          <literal>web.xml</literal>
                      <literal>security-constraint</literal> element. </para>
                  <figure>
                      <title>The security-constraint element</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata fileref="images/webapp_security_constraint.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The content to be secured is declared using one or more <literal>web-resource-collection</literal>
                      elements. Each <literal>web-resource-collection</literal> element contains an optional series of
                          <literal>url-pattern</literal> elements followed by an optional series of
                      <literal>http-method</literal> elements. The <literal>url-pattern</literal> element value specifies
                      a URL pattern against which a request URL must match for the request to correspond to an attempt to
                      access secured content. The <literal>http-method</literal> element value specifies a type of HTTP
                      request to allow.</para>
                  <para>The optional <literal>user-data-constraint</literal> element specifies the requirements for the
                      transport layer of the client to server connection. The requirement may be for content integrity
                      (preventing data tampering in the communication process) or for confidentiality (preventing reading
                      while in transit). The transport-guarantee element value specifies the degree to which communication
                      between the client and server should be protected. Its values are <literal>NONE</literal>,
                          <literal>INTEGRAL</literal>, and <literal>CONFIDENTIAL</literal>. A value of
                      <literal>NONE</literal> means that the application does not require any transport guarantees. A
                      value of <literal>INTEGRAL</literal> means that the application requires the data sent between the
                      client and server to be sent in such a way that it can't be changed in transit. A value of
                          <literal>CONFIDENTIAL</literal> means that the application requires the data to be transmitted
                      in a fashion that prevents other entities from observing the contents of the transmission. In most
                      cases, the presence of the <literal>INTEGRAL</literal> or <literal>CONFIDENTIAL</literal> flag
                      indicates that the use of SSL is required.</para>
                  <para>The optional <literal>login-config</literal> element is used to configure the authentication
                      method that should be used, the realm name that should be used for rhw application, and the
                      attributes that are needed by the form login mechanism. </para>
                  <figure>
                      <title>The login-config element</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata fileref="images/webapp_login_config.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The <literal>auth-method</literal> child element specifies the authentication mechanism for the
                      web application. As a prerequisite to gaining access to any web resources that are protected by an
                      authorization constraint, a user must have authenticated using the configured mechanism. Legal
                          <literal>auth-method</literal> values are <literal>BASIC</literal>, <literal>DIGEST</literal>,
                          <literal>FORM</literal>, and <literal>CLIENT-CERT</literal>. The <literal>realm-name</literal>
                      child element specifies the realm name to use in HTTP basic and digest authorization. The
                          <literal>form-login-config</literal> child element specifies the log in as well as error pages
                      that should be used in form-based login. If the <literal>auth-method</literal> value is not
                          <literal>FORM</literal>, then <literal>form-login-config</literal> and its child elements are
                      ignored.</para>
                  <para>As an example, the <literal>web.xml</literal> descriptor fragment given in <xref
                          linkend="ch8.websecconst.ex"/> indicates that any URL lying under the web application's
                          <literal>/restricted</literal> path requires an <literal>AuthorizedUser</literal> role. There is
                      no required transport guarantee and the authentication method used for obtaining the user identity
                      is BASIC HTTP authentication.</para>
                  <example id="ch8.websecconst.ex">
                      <title> A web.xml descriptor fragment which illustrates the use of the security-constraint and
                          related elements.</title>
                      <programlisting>&lt;web-app&gt;
      &lt;!-- ... --&gt;
      &lt;security-constraint&gt;
          &lt;web-resource-collection&gt;
              &lt;web-resource-name&gt;Secure Content&lt;/web-resource-name&gt;
              &lt;url-pattern&gt;/restricted/*&lt;/url-pattern&gt;
          &lt;/web-resource-collection&gt;
          &lt;auth-constraint&gt;
              &lt;role-name&gt;AuthorizedUser&lt;/role-name&gt;
          &lt;/auth-constraint&gt;
          &lt;user-data-constraint&gt;
              &lt;transport-guarantee&gt;NONE&lt;/transport-guarantee&gt;
          &lt;/user-data-constraint&gt;
      &lt;/security-constraint&gt;
      &lt;!-- ... --&gt;
      &lt;login-config&gt;
          &lt;auth-method&gt;BASIC&lt;/auth-method&gt;
          &lt;realm-name&gt;The Restricted Zone&lt;/realm-name&gt;
      &lt;/login-config&gt;
      &lt;!-- ... --&gt;
      &lt;security-role&gt;
          &lt;description&gt;The role required to access restricted content &lt;/description&gt;
          &lt;role-name&gt;AuthorizedUser&lt;/role-name&gt;
      &lt;/security-role&gt;
  &lt;/web-app&gt;</programlisting>
                  </example>
              </section>
              <section id="ch8.declarativesecurity.sect">
                  <title>Enabling Declarative Security in JBoss</title>
                  <para>The J2EE security elements that have been covered so far describe the security requirements only
                      from the application's perspective. Because J2EE security elements declare logical roles, the
                      application deployer maps the roles from the application domain onto the deployment environment. The
                      J2EE specifications omit these application server-specific details. In JBoss, mapping the
                      application roles onto the deployment environment entails specifying a security manager that
                      implements the J2EE security model using JBoss server specific deployment descriptors. The details
                      behind the security configuration are discussed in <xref linkend="ch8.securitymodel.sect"/>.</para>
              </section>
          </section>
          <section>
              <title>An Introduction to JAAS</title>
              <para>The JBossSX framework is based on the JAAS API. It is important that you understand the basic elements
                  of the JAAS API to understand the implementation details of JBossSX. The following sections provide an
                  introduction to JAAS to prepare you for the JBossSX architecture discussion later in this chapter. </para>
              <section>
                  <title>What is JAAS?</title>
                  <para>The JAAS 1.0 API consists of a set of Java packages designed for user authentication and
                      authorization. It implements a Java version of the standard Pluggable Authentication Module (PAM)
                      framework and compatibly extends the Java 2 Platform's access control architecture to support
                      user-based authorization. JAAS was first released as an extension package for JDK 1.3 and is bundled
                      with JDK 1.4+. Because the JBossSX framework uses only the authentication capabilities of JAAS to
                      implement the declarative role-based J2EE security model, this introduction focuses on only that
                      topic.</para>
                  <para>JAAS authentication is performed in a pluggable fashion. This permits Java applications to remain
                      independent from underlying authentication technologies and allows the JBossSX security manager to
                      work in different security infrastructures. Integration with a security infrastructure can be
                      achieved without changing the JBossSX security manager implementation. All that needs to change is
                      the configuration of the authentication stack that JAAS uses.</para>
                  <section>
                      <title>The JAAS Core Classes</title>
                      <para>The JAAS core classes can be broken down into three categories: common, authentication, and
                          authorization. The following list presents only the common and authentication classes because
                          these are the specific classes used to implement the functionality of JBossSX covered in this
                          chapter.</para>
                      <para>The are the common classes:</para>
                      <itemizedlist spacing="compact">
                          <listitem>
                              <para>
                                  <literal>Subject</literal> (<literal>javax.security.auth.Subject</literal>)</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <literal>Principal</literal> (<literal>java.security.Principal</literal>)</para>
                          </listitem>
                      </itemizedlist>
                      <para>These are the authentication classes:</para>
                      <itemizedlist spacing="compact">
                          <listitem>
                              <para>
                                  <literal>Callback</literal>
                              (<literal>javax.security.auth.callback.Callback</literal>)</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <literal>CallbackHandler</literal>
                                      (<literal>javax.security.auth.callback.CallbackHandler</literal>)</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <literal>Configuration</literal>
                                  (<literal>javax.security.auth.login.Configuration</literal>)</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <literal>LoginContext</literal>
                                  (<literal>javax.security.auth.login.LoginContext</literal>)</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <literal>LoginModule</literal>
                              (<literal>javax.security.auth.spi.LoginModule</literal>)</para>
                          </listitem>
                      </itemizedlist>
                      <section>
                          <title>The Subject and Principal Classes</title>
                          <para>To authorize access to resources, applications first need to authenticate the request's
                              source. The JAAS framework defines the term subject to represent a request's source. The
                                  <literal>Subject</literal> class is the central class in JAAS. A
                              <literal>Subject</literal> represents information for a single entity, such as a person or
                              service. It encompasses the entity's principals, public credentials, and private
                              credentials. The JAAS APIs use the existing Java 2
                              <literal>java.security.Principal</literal> interface to represent a principal, which is
                              essentially just a typed name.</para>
                          <para>During the authentication process, a subject is populated with associated identities, or
                              principals. A subject may have many principals. For example, a person may have a name
                              principal (John Doe), a social security number principal (123-45-6789), and a username
                              principal (johnd), all of which help distinguish the subject from other subjects. To
                              retrieve the principals associated with a subject, two methods are available:</para>
                          <programlisting>public Set getPrincipals() {...}
  public Set getPrincipals(Class c) {...} </programlisting>
                          <para>The first method returns all principals contained in the subject. The second method
                              returns only those principals that are instances of class <literal>c</literal> or one of its
                              subclasses. An empty set is returned if the subject has no matching principals. Note that
                              the <literal>java.security.acl.Group</literal> interface is a subinterface of
                                  <literal>java.security.Principal</literal>, so an instance in the principals set may
                              represent a logical grouping of other principals or groups of principals.</para>
                      </section>
                      <section>
                          <title>Authentication of a Subject</title>
                          <para>Authentication of a subject requires a JAAS login. The login procedure consists of the
                              following steps:</para>
                          <orderedlist>
                              <listitem>
                                  <para>An application instantiates a <literal>LoginContext</literal> and passes in the
                                      name of the login configuration and a <literal>CallbackHandler</literal> to populate
                                      the <literal>Callback</literal> objects, as required by the configuration
                                          <literal>LoginModule</literal>s.</para>
                              </listitem>
                              <listitem>
                                  <para>The <literal>LoginContext</literal> consults a <literal>Configuration</literal> to
                                      load all the <literal>LoginModules</literal> included in the named login
                                      configuration. If no such named configuration exists the <literal>other</literal>
                                      configuration is used as a default.</para>
                              </listitem>
                              <listitem>
                                  <para>The application invokes the <literal>LoginContext.login</literal> method.</para>
                              </listitem>
                              <listitem>
                                  <para>The login method invokes all the loaded <literal>LoginModule</literal>s. As each
                                          <literal>LoginModule</literal> attempts to authenticate the subject, it invokes
                                      the handle method on the associated <literal>CallbackHandler</literal> to obtain the
                                      information required for the authentication process. The required information is
                                      passed to the handle method in the form of an array of <literal>Callback</literal>
                                      objects. Upon success, the <literal>LoginModule</literal>s associate relevant
                                      principals and credentials with the subject.</para>
                              </listitem>
                              <listitem>
                                  <para>The <literal>LoginContext</literal> returns the authentication status to the
                                      application. Success is represented by a return from the login method. Failure is
                                      represented through a LoginException being thrown by the login method.</para>
                              </listitem>
                              <listitem>
                                  <para>If authentication succeeds, the application retrieves the authenticated subject
                                      using the <literal>LoginContext.getSubject</literal> method.</para>
                              </listitem>
                              <listitem>
                                  <para>After the scope of the subject authentication is complete, all principals and
                                      related information associated with the subject by the login method can be removed
                                      by invoking the <literal>LoginContext.logout</literal> method.</para>
                              </listitem>
                          </orderedlist>
                          <para>The <literal>LoginContext</literal> class provides the basic methods for authenticating
                              subjects and offers a way to develop an application that is independent of the underlying
                              authentication technology. The <literal>LoginContext</literal> consults a
                                  <literal>Configuration</literal> to determine the authentication services configured for
                              a particular application. <literal>LoginModule</literal> classes represent the
                              authentication services. Therefore, you can plug different login modules into an application
                              without changing the application itself. The following code shows the steps required by an
                              application to authenticate a subject.</para>
                          <programlisting>CallbackHandler handler = new MyHandler();
  LoginContext lc = new LoginContext("some-config", handler);
  
  try {
      lc.login();
      Subject subject = lc.getSubject();
  } catch(LoginException e) {
      System.out.println("authentication failed");
      e.printStackTrace();
  }
                          
  // Perform work as authenticated Subject
  // ...
  
  // Scope of work complete, logout to remove authentication info
  try {
      lc.logout();
  } catch(LoginException e) {
      System.out.println("logout failed");
      e.printStackTrace();
  }
                          
  // A sample MyHandler class
  class MyHandler 
      implements CallbackHandler
  {
      public void handle(Callback[] callbacks) throws
          IOException, UnsupportedCallbackException
      {
          for (int i = 0; i &lt; callbacks.length; i++) {
              if (callbacks[i] instanceof NameCallback) {
                  NameCallback nc = (NameCallback)callbacks[i];
                  nc.setName(username);
              } else if (callbacks[i] instanceof PasswordCallback) {
                  PasswordCallback pc = (PasswordCallback)callbacks[i];
                  pc.setPassword(password);
              } else {
                  throw new UnsupportedCallbackException(callbacks[i],
                                                         "Unrecognized Callback");
              }
          }
      }
  }</programlisting>
                          <para>Developers integrate with an authentication technology by creating an implementation of
                              the <literal>LoginModule</literal> interface. This allows an administrator to plug different
                              authentication technologies into an application. You can chain together multiple
                                  <literal>LoginModule</literal>s to allow for more than one authentication technology to
                              participate in the authentication process. For example, one <literal>LoginModule</literal>
                              may perform username/password-based authentication, while another may interface to hardware
                              devices such as smart card readers or biometric authenticators.</para>
                          <para>The life cycle of a <literal>LoginModule</literal> is driven by the
                              <literal>LoginContext</literal> object against which the client creates and issues the login
                              method. The process consists of two phases. The steps of the process are as follows:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>The <literal>LoginContext</literal> creates each configured
                                      <literal>LoginModule</literal> using its public no-arg constructor.</para>
                              </listitem>
                              <listitem>
                                  <para>Each <literal>LoginModule</literal> is initialized with a call to its initialize
                                      method. The <literal>Subject</literal> argument is guaranteed to be non-null. The
                                      signature of the initialize method is: <literal>public void initialize(Subject
                                          subject, CallbackHandler callbackHandler, Map sharedState, Map
                                      options)</literal>.</para>
                              </listitem>
                              <listitem>
                                  <para>The <literal>login</literal> method is called to start the authentication process.
                                      For example, a method implementation might prompt the user for a username and
                                      password and then verify the information against data stored in a naming service
                                      such as NIS or LDAP. Alternative implementations might interface to smart cards and
                                      biometric devices, or simply extract user information from the underlying operating
                                      system. The validation of user identity by each <literal>LoginModule</literal> is
                                      considered phase 1 of JAAS authentication. The signature of the
                                      <literal>login</literal> method is <literal>boolean login() throws
                                      LoginException</literal>. A <literal>LoginException</literal> indicates failure. A
                                      return value of true indicates that the method succeeded, whereas a return valueof
                                      false indicates that the login module should be ignored.</para>
                              </listitem>
                              <listitem>
                                  <para>If the <literal>LoginContext</literal>'s overall authentication succeeds,
                                          <literal>commit</literal> is invoked on each <literal>LoginModule</literal>. If
                                      phase 1 succeeds for a <literal>LoginModule</literal>, then the commit method
                                      continues with phase 2 and associates the relevant principals, public credentials,
                                      and/or private credentials with the subject. If phase 1 fails for a
                                          <literal>LoginModule</literal>, then <literal>commit</literal> removes any
                                      previously stored authentication state, such as usernames or passwords. The
                                      signature of the <literal>commit</literal> method is: <literal>boolean commit()
                                          throws LoginException</literal>. Failure to complete the commit phase is
                                      indicated by throwing a <literal>LoginException</literal>. A return of true
                                      indicates that the method succeeded, whereas a return of false indicates that the
                                      login module should be ignored.</para>
                              </listitem>
                              <listitem>
                                  <para>If the <literal>LoginContext</literal>'s overall authentication fails, then the
                                          <literal>abort</literal> method is invoked on each
                                      <literal>LoginModule</literal>. The <literal>abort</literal> method removes or
                                      destroys any authentication state created by the login or initialize methods. The
                                      signature of the <literal>abort</literal> method is <literal>boolean abort() throws
                                          LoginException</literal>. Failure to complete the <literal>abort</literal> phase
                                      is indicated by throwing a <literal>LoginException</literal>. A return of true
                                      indicates that the method succeeded, whereas a return of false indicates that the
                                      login module should be ignored.</para>
                              </listitem>
                              <listitem>
                                  <para>To remove the authentication state after a successful login, the application
                                      invokes <literal>logout</literal> on the <literal>LoginContext</literal>. This in
                                      turn results in a <literal>logout</literal> method invocation on each
                                          <literal>LoginModule</literal>. The <literal>logout</literal> method removes the
                                      principals and credentials originally associated with the subject during the
                                          <literal>commit</literal> operation. Credentials should be destroyed upon
                                      removal. The signature of the <literal>logout</literal> method is: <literal>boolean
                                          logout() throws LoginException</literal>. Failure to complete the logout process
                                      is indicated by throwing a <literal>LoginException</literal>. A return of true
                                      indicates that the method succeeded, whereas a return of false indicates that the
                                      login module should be ignored.</para>
                              </listitem>
                          </itemizedlist>
                          <para>When a <literal>LoginModule</literal> must communicate with the user to obtain
                              authentication information, it uses a <literal>CallbackHandler</literal> object.
                              Applications implement the <literal>CallbackHandler</literal> interface and pass it to the
                              LoginContext, which forwards it directly to the underlying login modules. Login modules use
                              the <literal>CallbackHandler</literal> both to gather input from users, such as a password
                              or smart card PIN, and to supply information to users, such as status information. By
                              allowing the application to specify the <literal>CallbackHandler</literal>, underlying
                                  <literal>LoginModule</literal>s remain independent from the different ways applications
                              interact with users. For example, a <literal>CallbackHandler</literal>'s implementation for
                              a GUI application might display a window to solicit user input. On the other hand, a
                                  <literal>callbackhandler</literal>'s implementation for a non-GUI environment, such as
                              an application server, might simply obtain credential information by using an application
                              server API. The <literal>callbackhandler</literal> interface has one method to implement:</para>
                          <programlisting>void handle(Callback[] callbacks)
      throws java.io.IOException, 
             UnsupportedCallbackException;</programlisting>
                          <para>The <literal>Callback</literal> interface is the last authentication class we will look
                              at. This is a tagging interface for which several default implementations are provided,
                              including the <literal>NameCallback</literal> and <literal>PasswordCallback</literal> used
                              in an earlier example. A <literal>LoginModule</literal> uses a <literal>Callback</literal>
                              to request information required by the authentication mechanism.
                              <literal>LoginModule</literal>s pass an array of <literal>Callback</literal>s directly to
                              the <literal>CallbackHandler.handle</literal> method during the authentication's login
                              phase. If a <literal>callbackhandler</literal> does not understand how to use a
                                  <literal>Callback</literal> object passed into the handle method, it throws an
                                  <literal>UnsupportedCallbackException</literal> to abort the login call.</para>
                      </section>
                  </section>
              </section>
          </section>
          <section id="ch8.securitymodel.sect">
              <title>The JBoss Security Model</title>
              <para>Similar to the rest of the JBoss architecture, security at the lowest level is defined as a set of
                  interfaces for which alternate implementations may be provided. Three basic interfaces define the JBoss
                  server security layer: <literal>org.jboss.security.AuthenticationManager</literal>,
                      <literal>org.jboss.security.RealmMapping</literal>, and
                  <literal>org.jboss.security.SecurityProxy</literal>. <xref linkend="ch8.secmodel.fig"/> shows a class
                  diagram of the security interfaces and their relationship to the EJB container architecture.</para>
              <figure id="ch8.secmodel.fig">
                  <title>The key security model interfaces and their relationship to the JBoss server EJB container
                      elements.</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/Chap8-6.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>The light blue classes represent the security interfaces while the yellow classes represent the EJB
                  container layer. The two interfaces required for the implementation of the J2EE security model are
                      <literal>org.jboss.security.AuthenticationManager</literal> and
                      <literal>org.jboss.security.RealmMapping</literal>. The roles of the security interfaces presented
                  in <xref linkend="ch8.secmodel.fig"/> are summarized in the following list.</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">AuthenticationManager</emphasis>: This interface is responsible for
                          validating credentials associated with principals. Principals are identities, such as usernames,
                          employee numbers, and social security numbers. Credentials are proof of the identity, such as
                          passwords, session keys, and digital signatures. The <literal>isValid</literal> method is
                          invoked to determine whether a user identity and associated credentials as known in the
                          operational environment are valid proof of the user's identity.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">RealmMapping</emphasis>: This interface is responsible for principal
                          mapping and role mapping. The <literal>getPrincipal</literal> method takes a user identity as
                          known in the operational environment and returns the application domain identity. The
                              <literal>doesUserHaveRole</literal> method validates that the user identity in the operation
                          environment has been assigned the indicated role from the application domain.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">SecurityProxy</emphasis>: This interface describes the requirements for a
                          custom <literal>SecurityProxyInterceptor</literal> plugin. A <literal>SecurityProxy</literal>
                          allows for the externalization of custom security checks on a per-method basis for both the EJB
                          home and remote interface methods.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">SubjectSecurityManager</emphasis>: This is a subinterface of
                              <literal>AuthenticationManager</literal> that adds accessor methods for obtaining the
                          security domain name of the security manager and the current thread's authenticated
                              <literal>Subject</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">SecurityDomain</emphasis>: This is an extension of the
                              <literal>AuthenticationManager</literal>, <literal>RealmMapping</literal>, and
                              <literal>SubjectSecurityManager</literal> interfaces. It is a move to a comprehensive
                          security interface based on the JAAS Subject, a <literal>java.security.KeyStore</literal>, and
                          the JSSE <literal>com.sun.net.ssl.KeyManagerFactory</literal> and
                              <literal>com.sun.net.ssl.TrustManagerFactory</literal> interfaces. This interface is a work
                          in progress that will be the basis of a multi-domain security architecture that will better
                          support ASP style deployments of applications and resources.</para>
                  </listitem>
              </itemizedlist>
              <para>Note that the <literal>AuthenticationManager</literal>, <literal>RealmMapping</literal> and
                      <literal>SecurityProxy</literal> interfaces have no association to JAAS related classes. Although
                  the JBossSX framework is heavily dependent on JAAS, the basic security interfaces required for
                  implementation of the J2EE security model are not. The JBossSX framework is simply an implementation of
                  the basic security plug-in interfaces that are based on JAAS. The component diagram presented in <xref
                      linkend="ch8.jbosssx.fig"/> illustrates this fact. The implication of this plug-in architecture is
                  that you are free to replace the JAAS-based JBossSX implementation classes with your own custom security
                  manager implementation that does not make use of JAAS, if you so desire. You'll see how to do this when
                  you look at the JBossSX MBeans available for the configuration of JBossSX in <xref
                      linkend="ch8.jbosssx.fig"/>.</para>
              <figure id="ch8.jbosssx.fig">
                  <title>The relationship between the JBossSX framework implementation classes and the JBoss server EJB
                      container layer.</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/Chap8-7.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <section id="ch8.declarativesecurity2.sect">
                  <title>Enabling Declarative Security in JBoss Revisited</title>
                  <para>Earlier in this chapter, the discussion of the J2EE standard security model ended with a
                      requirement for the use of JBoss server-specific deployment descriptor to enable security. The
                      details of this configuration are presented here. <xref linkend="ch8.secelems.fig"/> shows the
                      JBoss-specific EJB and web application deployment descriptor's security-related elements.</para>
                  <figure id="ch8.secelems.fig">
                      <title>The security element subsets of the JBoss server jboss.xml and jboss-web.xml deployment
                          descriptors.</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/Chap8-8.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>The value of a <literal>security-domain</literal> element specifies the JNDI name of the security
                      manager interface implementation that JBoss uses for the EJB and web containers. This is an object
                      that implements both of the <literal>AuthenticationManager</literal> and
                      <literal>RealmMapping</literal> interfaces. When specified as a top-level element it defines what
                      security domain in effect for all EJBs in the deployment unit. This is the typical usage because
                      mixing security managers within a deployment unit complicates inter-component operation and
                      administration.</para>
                  <para>To specify the security domain for an individual EJB, you specify the
                      <literal>security-domain</literal> at the container configuration level. This will override any
                      top-level security-domain element.</para>
                  <para>The <literal>unauthenticated-principal</literal> element specifies the name to use for the
                          <literal>Principal</literal> object returned by the
                      <literal>EJBContext.getUserPrincipal</literal> method when an unauthenticated user invokes an EJB.
                      Note that this conveys no special permissions to an unauthenticated caller. Its primary purpose is
                      to allow unsecured servlets and JSP pages to invoke unsecured EJBs and allow the target EJB to
                      obtain a non-null <literal>Principal</literal> for the caller using the
                      <literal>getUserPrincipal</literal> method. This is a J2EE specification requirement.</para>
                  <para>The <literal>security-proxy</literal> element identifies a custom security proxy implementation
                      that allows per-request security checks outside the scope of the EJB declarative security model
                      without embedding security logic into the EJB implementation. This may be an implementation of the
                          <literal>org.jboss.security.SecurityProxy</literal> interface, or just an object that implements
                      methods in the home, remote, local home or local interfaces of the EJB to secure without
                      implementing any common interface. If the given class does not implement the
                      <literal>SecurityProxy</literal> interface, the instance must be wrapped in a
                      <literal>SecurityProxy</literal> implementation that delegates the method invocations to the object.
                      The <literal>org.jboss.security.SubjectSecurityProxy</literal> is an example
                      <literal>SecurityProxy</literal> implementation used by the default JBossSX installation.</para>
                  <para>Take a look at a simple example of a custom <literal>SecurityProxy</literal> in the context of a
                      trivial stateless session bean. The custom <literal>SecurityProxy</literal> validates that no one
                      invokes the bean's <literal>echo</literal> method with a four-letter word as its argument. This is a
                      check that is not possible with role-based security; you cannot define a
                          <literal>FourLetterEchoInvoker</literal> role because the security context is the method
                      argument, not a property of the caller. The code for the custom <literal>SecurityProxy</literal> is
                      given in <xref linkend="ch8.echo1.ex"/>, and the full source code is available in the
                          <literal>src/main/org/jboss/chap8/ex1</literal> directory of the book examples.</para>
                  <example id="ch8.echo1.ex">
                      <title>The example 1 custom EchoSecurityProxy implementation that enforces the echo argument-based
                          security constraint.</title>
                      <programlisting>package org.jboss.chap8.ex1;
                  
  import java.lang.reflect.Method;
  import javax.ejb.EJBContext;
                  
  import org.apache.log4j.Category;
                  
  import org.jboss.security.SecurityProxy;
                  
  /** A simple example of a custom SecurityProxy implementation
   *  that demonstrates method argument based security checks.
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class EchoSecurityProxy implements SecurityProxy
  {
      Category log = Category.getInstance(EchoSecurityProxy.class);
      Method echo;
      
      public void init(Class beanHome, Class beanRemote,
                       Object securityMgr)
          throws InstantiationException
      {
          log.debug("init, beanHome="+beanHome
                    + ", beanRemote="+beanRemote
                    + ", securityMgr="+securityMgr);
          // Get the echo method for equality testing in invoke
          try {
              Class[] params = {String.class};
              echo = beanRemote.getDeclaredMethod("echo", params);
          } catch(Exception e) {
              String msg = "Failed to finde an echo(String) method";
              log.error(msg, e);
              throw new InstantiationException(msg);
          }
      }
      
      public void setEJBContext(EJBContext ctx)
      {
          log.debug("setEJBContext, ctx="+ctx);
      }
      
      public void invokeHome(Method m, Object[] args)
          throws SecurityException
      {
          // We don't validate access to home methods
      }
  
      public void invoke(Method m, Object[] args, Object bean)
          throws SecurityException
      {
          log.debug("invoke, m="+m);
          // Check for the echo method
          if (m.equals(echo)) {
              // Validate that the msg arg is not 4 letter word
              String arg = (String) args[0];
              if (arg == null || arg.length() == 4)
                  throw new SecurityException("No 4 letter words");
          }
          // We are not responsible for doing the invoke
      }
  }           
                  </programlisting>
                  </example>
                  <para>The <literal>EchoSecurityProxy</literal> checks that the method to be invoked on the bean instance
                      corresponds to the <literal>echo(String)</literal> method loaded the init method. If there is a
                      match, the method argument is obtained and its length compared against 4 or null. Either case
                      results in a <literal>SecurityException</literal> being thrown. Certainly this is a contrived
                      example, but only in its application. It is a common requirement that applications must perform
                      security checks based on the value of method arguments. The point of the example is to demonstrate
                      how custom security beyond the scope of the standard declarative security model can be introduced
                      independent of the bean implementation. This allows the specification and coding of the security
                      requirements to be delegated to security experts. Since the security proxy layer can be done
                      independent of the bean implementation, security can be changed to match the deployment environment
                      requirements.</para>
                  <para> The associated <literal>jboss.xml</literal> descriptor that installs the
                          <literal>EchoSecurityProxy</literal> as the custom proxy for the <literal>EchoBean</literal> is
                      given in <xref linkend="ch8.echo1dd.ex"/>.</para>
                  <example id="ch8.echo1dd.ex">
                      <title>The jboss.xml descriptor, which configures the EchoSecurityProxy as the custom security proxy
                          for the EchoBean.</title>
                      <programlisting>&lt;jboss&gt;
      &lt;security-domain&gt;java:/jaas/other&lt;/security-domain&gt;
                  
      &lt;enterprise-beans&gt;
          &lt;session&gt;
              &lt;ejb-name&gt;EchoBean&lt;/ejb-name&gt;
              &lt;security-proxy&gt;org.jboss.chap8.ex1.EchoSecurityProxy&lt;/security-proxy&gt;
          &lt;/session&gt;
      &lt;/enterprise-beans&gt;
  &lt;/jboss&gt; </programlisting>
                  </example>
                  <para>Now test the custom proxy by running a client that attempts to invoke the
                      <literal>EchoBean.echo</literal> method with the arguments <literal>Hello</literal> and
                          <literal>Four</literal> as illustrated in this fragment:</para>
                  <programlisting>public class ExClient
  {
      public static void main(String args[])
          throws Exception
      {
          Logger log = Logger.getLogger("ExClient");
          log.info("Looking up EchoBean");
  
          InitialContext iniCtx = new InitialContext();
          Object ref = iniCtx.lookup("EchoBean");
          EchoHome home = (EchoHome) ref;
          Echo echo = home.create();
  
          log.info("Created Echo");
          log.info("Echo.echo('Hello') = "+echo.echo("Hello"));
          log.info("Echo.echo('Four') = "+echo.echo("Four"));
      }
  }  </programlisting>
                  <para>The first call should succeed, while the second should fail due to the fact that
                      <literal>Four</literal> is a four-letter word. Run the client as follows using Ant from the examples
                      directory:</para>
                  <programlisting>[examples]$ ant -Dchap=chap8 -Dex=1 run-example
  run-example1:
       [copy] Copying 1 file to /tmp/jboss-4.0.1/server/default/deploy
       [echo] Waiting for 5 seconds for deploy...
       [java] [INFO,ExClient] Looking up EchoBean
       [java] [INFO,ExClient] Created Echo
       [java] [INFO,ExClient] Echo.echo('Hello') = Hello
       [java] Exception in thread "main" java.rmi.ServerException: RemoteException occurred in 
              server thread; nested exception is: 
       [java]     java.rmi.AccessException: SecurityException; nested exception is: 
       [java]     java.lang.SecurityException: No 4 letter words
  ...
       [java]     at org.jboss.chap8.ex1.ExClient.main(ExClient.java:25)
       [java] Caused by: java.rmi.AccessException: SecurityException; nested exception is: 
       [java]     java.lang.SecurityException: No 4 letter words
  ...</programlisting>
                  <para>The result is that the <literal>echo('Hello')</literal> method call succeeds as expected and the
                          <literal>echo('Four')</literal> method call results in a rather messy looking exception, which
                      is also expected. The above output has been truncated to fit in the book. The key part to the
                      exception is that the <literal>SecurityException("No 4 letter words")</literal> generated by the
                          <literal>EchoSecurityProxy</literal> was thrown to abort the attempted method invocation as
                      desired.</para>
              </section>
          </section>
          <section id="ch8.extensionarchitecture.sect">
              <title>The JBoss Security Extension Architecture</title>
              <para>The preceding discussion of the general JBoss security layer has stated that the JBossSX security
                  extension framework is an implementation of the security layer interfaces. This is the primary purpose
                  of the JBossSX framework. The details of the implementation are interesting in that it offers a great
                  deal of customization for integration into existing security infrastructures. A security infrastructure
                  can be anything from a database or LDAP server to a sophisticated security software suite. The
                  integration flexibility is achieved using the pluggable authentication model available in the JAAS
                  framework.</para>
              <para>The heart of the JBossSX framework is
                  <literal>org.jboss.security.plugins.JaasSecurityManager</literal>. This is the default implementation of
                  the <literal>AuthenticationManager</literal> and <literal>RealmMapping</literal> interfaces. <xref
                      linkend="ch8.secdomaindd.fig"/> shows how the <literal>JaasSecurityManager</literal> integrates into
                  the EJB and web container layers based on the <literal>security-domain</literal> element of the
                  corresponding component deployment descriptor.</para>
              <figure id="ch8.secdomaindd.fig">
                  <title>The relationship between the security-domain component deployment descriptor value, the component
                      container and the JaasSecurityManager.</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/Chap8-9.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>
                  <xref linkend="ch8.secdomaindd.fig"/> depicts an enterprise application that contains both EJBs and web
                  content secured under the security domain <literal>jwdomain</literal>. The EJB and web containers have a
                  request interceptor architecture that includes a security interceptor, which enforces the container
                  security model. At deployment time, the <literal>security-domain</literal> element value in the
                      <literal>jboss.xml</literal> and <literal>jboss-web.xml</literal> descriptors is used to obtain the
                  security manager instance associated with the container. The security interceptor then uses the security
                  manager to perform its role. When a secured component is requested, the security interceptor delegates
                  security checks to the security manager instance associated with the container.</para>
              <para>The JBossSX <literal>JaasSecurityManager</literal> implementation performs security checks based on
                  the information associated with the <literal>Subject</literal> instance that results from executing the
                  JAAS login modules configured under the name matching the <literal>security-domain</literal> element
                  value. We will drill into the <literal>JaasSecurityManager</literal> implementation and its use of JAAS
                  in the following section.</para>
              <section>
                  <title>How the JaasSecurityManager Uses JAAS</title>
                  <para>The <literal>JaasSecurityManager</literal> uses the JAAS packages to implement the
                          <literal>AuthenticationManager</literal> and <literal>RealmMapping</literal> interface behavior.
                      In particular, its behavior derives from the execution of the login module instances that are
                      configured under the name that matches the security domain to which the
                      <literal>JaasSecurityManager</literal> has been assigned. The login modules implement the security
                      domain's principal authentication and role-mapping behavior. Thus, you can use the
                          <literal>JaasSecurityManager</literal> across different security domains simply by plugging in
                      different login module configurations for the domains.</para>
                  <para>To illustrate the details of the <literal>JaasSecurityManager</literal>'s usage of the JAAS
                      authentication process, you will walk through a client invocation of an EJB home method invocation.
                      The prerequisite setting is that the EJB has been deployed in the JBoss server and its home
                      interface methods have been secured using <literal>method-permission</literal> elements in the
                          <literal>ejb-jar.xml</literal> descriptor, and it has been assigned a security domain named
                          <literal>jwdomain</literal> using the <literal>jboss.xml</literal> descriptor
                          <literal>security-domain</literal> element.</para>
                  <figure id="ch8.authsteps.fig">
                      <title>An illustration of the steps involved in the authentication and authorization of a secured
                          EJB home method invocation.</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/authsteps.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <para>
                      <xref linkend="ch8.authsteps.fig"/> provides a view of the client to server communication we will
                      discuss. The numbered steps shown are:</para>
                  <orderedlist>
                      <listitem>
                          <para>The client first has to perform a JAAS login to establish the principal and credentials
                              for authentication, and this is labeled <emphasis>Client Side Login</emphasis> in the
                              figure. This is how clients establish their login identities in JBoss. Support for
                              presenting the login information via JNDI <literal>InitialContext</literal> properties is
                              provided via an alternate configuration. A JAAS login entails creating a
                                  <literal>LoginContext</literal> instance and passing the name of the configuration to
                              use. The configuration name is <literal>other</literal>. This one-time login associates the
                              login principal and credentials with all subsequent EJB method invocations. Note that the
                              process might not authenticate the user. The nature of the client-side login depends on the
                              login module configuration that the client uses. In this example, the
                              <literal>other</literal> client-side login configuration entry is set up to use the
                                  <literal>ClientLoginModule</literal> module (an
                                  <literal>org.jboss.security.ClientLoginModule</literal>). This is the default client
                              side module that simply binds the username and password to the JBoss EJB invocation layer
                              for later authentication on the server. The identity of the client is not authenticated on
                              the client.</para>
                      </listitem>
                      <listitem>
                          <para>Later, the client obtains the EJB home interface and attempts to create a bean. This event
                              is labeled as <emphasis>Home Method Invocation</emphasis>. This results in a home interface
                              method invocation being sent to the JBoss server. The invocation includes the method
                              arguments passed by the client along with the user identity and credentials from the
                              client-side JAAS login performed in step 1.</para>
                      </listitem>
                      <listitem>
                          <para>On the server side, the security interceptor first requires authentication of the user
                              invoking the call, which, as on the client side, involves a JAAS login.</para>
                      </listitem>
                      <listitem>
                          <para>The security domain under which the EJB is secured determines the choice of login modules.
                              The security domain name is used as the login configuration entry name passed to the
                                  <literal>LoginContext</literal> constructor. The EJB security domain is
                                  <literal>jwdomain</literal>. If the JAAS login authenticates the user, a JAAS
                                  <literal>Subject</literal> is created that contains the following in its
                                  <literal>PrincipalsSet</literal>:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>A <literal>java.security.Principal</literal> that corresponds to the client
                                      identity as known in the deployment security environment.</para>
                              </listitem>
                              <listitem>
                                  <para>A <literal>java.security.acl.Group</literal> named <literal>Roles</literal> that
                                      contains the role names from the application domain to which the user has been
                                      assigned. <literal>org.jboss.security.SimplePrincipal</literal> objects are used to
                                      represent the role names; <literal>SimplePrincipal</literal> is a simple
                                      string-based implementation of <literal>Principal</literal>. These roles are used to
                                      validate the roles assigned to methods in <literal>ejb-jar.xml</literal> and the
                                          <literal>EJBContext.isCallerInRole(String)</literal> method
                                  implementation.</para>
                              </listitem>
                              <listitem>
                                  <para>An optional <literal>java.security.acl.Group</literal> named
                                          <literal>CallerPrincipal</literal>, which contains a single
                                          <literal>org.jboss.security.SimplePrincipal</literal> that corresponds to the
                                      identity of the application domain's caller. The <literal>CallerPrincipal</literal>
                                      sole group member will be the value returned by the
                                          <literal>EJBContext.getCallerPrincipal()</literal> method. The purpose of this
                                      mapping is to allow a <literal>Principal</literal> as known in the operational
                                      security environment to map to a <literal>Principal</literal> with a name known to
                                      the application. In the absence of a <literal>CallerPrincipal</literal> mapping the
                                      deployment security environment principal is used as the
                                      <literal>getCallerPrincipal</literal> method value. That is, the operational
                                      principal is the same as the application domain principal.</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                      <listitem>
                          <para>The final step of the security interceptor check is to verify that the authenticated user
                              has permission to invoke the requested method This is labeled as <emphasis>Server Side
                                  Authorization</emphasis> in <xref linkend="ch8.authsteps.fig"/>. Performing the
                              authorization this entails the following steps:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>Obtain the names of the roles allowed to access the EJB method from the EJB
                                      container. The role names are determined by <literal>ejb-jar.xml</literal>
                                      descriptor role-name elements of all <literal>method-permission</literal> elements
                                      containing the invoked method.</para>
                              </listitem>
                              <listitem>
                                  <para>If no roles have been assigned, or the method is specified in an
                                          <literal>exclude-list</literal> element, then access to the method is denied.
                                      Otherwise, the <literal>doesUserHaveRole</literal> method is invoked on the security
                                      manager by the security interceptor to see if the caller has one of the assigned
                                      role names. This method iterates through the role names and checks if the
                                      authenticated user's Subject <literal>Roles</literal> group contains a
                                          <literal>SimplePrincipal</literal> with the assigned role name. Access is
                                      allowed if any role name is a member of the <literal>Roles</literal> group. Access
                                      is denied if none of the role names are members.</para>
                              </listitem>
                              <listitem>
                                  <para>If the EJB was configured with a custom security proxy, the method invocation is
                                      delegated to it. If the security proxy wants to deny access to the caller, it will
                                      throw a <literal>java.lang.SecurityException</literal>. If no
                                          <literal>SecurityException</literal> is thrown, access to the EJB method is
                                      allowed and the method invocation passes to the next container interceptor. Note
                                      that the <literal>SecurityProxyInterceptor</literal> handles this check and this
                                      interceptor is not shown.</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                  </orderedlist>
                  <para>Every secured EJB method invocation, or secured web content access, requires the authentication
                      and authorization of the caller because security information is handled as a stateless attribute of
                      the request that must be presented and validated on each request. This can be an expensive operation
                      if the JAAS login involves client-to-server communication. Because of this, the
                          <literal>JaasSecurityManager</literal> supports the notion of an authentication cache that is
                      used to store principal and credential information from previous successful logins. You can specify
                      the authentication cache instance to use as part of the <literal>JaasSecurityManager</literal>
                      configuration as you will see when the associated MBean service is discussed in following section.
                      In the absence of any user-defined cache, a default cache that maintains credential information for
                      a configurable period of time is used.</para>
              </section>
              <section>
                  <title>The JaasSecurityManagerService MBean</title>
                  <para>The <literal>JaasSecurityManagerService</literal> MBean service manages security managers.
                      Although its name begins with <emphasis>Jaas</emphasis>, the security managers it handles need not
                      use JAAS in their implementation. The name arose from the fact that the default security manager
                      implementation is the <literal>JaasSecurityManager</literal>. The primary role of the
                          <literal>JaasSecurityManagerService</literal> is to externalize the security manager
                      implementation. You can change the security manager implementation by providing an alternate
                      implementation of the <literal>AuthenticationManager</literal> and <literal>RealmMapping</literal>
                      interfaces.</para>
                  <para>The second fundamental role of the <literal>JaasSecurityManagerService</literal> is to provide a
                      JNDI <literal>javax.naming.spi.ObjectFactory</literal> implementation to allow for simple code-free
                      management of the JNDI name to security manager implementation mapping. It has been mentioned that
                      security is enabled by specifying the JNDI name of the security manager implementation via the
                          <literal>security-domain</literal> deployment descriptor element. When you specify a JNDI name,
                      there has to be an object-binding there to use. To simplify the setup of the JNDI name to security
                      manager bindings, the <literal>JaasSecurityManagerService</literal> manages the association of
                      security manager instances to names by binding a next naming system reference with itself as the
                      JNDI ObjectFactory under the name <literal>java:/jaas</literal>. This allows one to use a naming
                      convention of the form <literal>java:/jaas/XYZ</literal> as the value for the
                          <literal>security-domain</literal> element, and the security manager instance for the
                          <literal>XYZ</literal> security domain will be created as needed for you. The security manager
                      for the domain <literal>XYZ</literal> is created on the first lookup against the
                          <literal>java:/jaas/XYZ</literal> binding by creating an instance of the class specified by the
                          <literal>SecurityManagerClassName</literal> attribute using a constructor that takes the name of
                      the security domain. For example, consider the following container security configuration snippet:</para>
                  <programlisting>&lt;jboss&gt;
      &lt;!-- Configure all containers to be secured under the "hades" security domain --&gt;
      &lt;security-domain&gt;java:/jaas/hades&lt;/security-domain&gt;
      &lt;!-- ... --&gt;
  &lt;/jboss&gt; </programlisting>
                  <para>Any lookup of the name <literal>java:/jaas/hades</literal> will return a security manager instance
                      that has been associated with the security domain named <literal>hades</literal>. This security
                      manager will implement the AuthenticationManager and RealmMapping security interfaces and will be of
                      the type specified by the <literal>JaasSecurityManagerService</literal>
                      <literal>SecurityManagerClassName</literal> attribute.</para>
                  <para>The <literal>JaasSecurityManagerService</literal> MBean is configured by default for use in the
                      standard JBoss distribution, and you can often use the default configuration as is. The configurable
                      attributes of the <literal>JaasSecurityManagerService</literal> include:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">SecurityManagerClassName</emphasis>: The name of the class that
                              provides the security manager implementation. The implementation must support both the
                                  <literal>org.jboss.security.AuthenticationManager</literal> and
                                  <literal>org.jboss.security.RealmMapping</literal> interfaces. If not specified this
                              defaults to the JAAS-based
                              <literal>org.jboss.security.plugins.JaasSecurityManager</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">CallbackHandlerClassName</emphasis>: The name of the class that
                              provides the <literal>javax.security.auth.callback.CallbackHandler</literal> implementation
                              used by the <literal>JaasSecurityManager</literal>. You can override the handler used by the
                                  <literal>JaasSecurityManager</literal> if the default implementation
                                  (<literal>org.jboss.security.auth.callback.SecurityAssociationHandler</literal>) does
                              not meet your needs. This is a rather deep configuration that generally should not be set
                              unless you know what you are doing.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SecurityProxyFactoryClassName</emphasis>: The name of the class that
                              provides the <literal>org.jboss.security.SecurityProxyFactory</literal> implementation. If
                              not specified this defaults to
                              <literal>org.jboss.security.SubjectSecurityProxyFactory</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">AuthenticationCacheJndiName</emphasis>: Specifies the location of the
                              security credential cache policy. This is first treated as an
                              <literal>ObjectFactory</literal> location capable of returning
                              <literal>CachePolicy</literal> instances on a per-security-domain basis. This is done by
                              appending the name of the security domain to this name when looking up the
                                  <literal>CachePolicy</literal> for a domain. If this fails, the location is treated as a
                              single <literal>CachePolicy</literal> for all security domains. As a default, a timed cache
                              policy is used.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">DefaultCacheTimeout</emphasis>: Specifies the default timed cache
                              policy timeout in seconds. The default value is 1800 seconds (30 minutes). The value you use
                              for the timeout is a tradeoff between frequent authentication operations and how long
                              credential information may be out of synch with respect to the security information store.
                              If you want to disable caching of security credentials, set this to 0 to force
                              authentication to occur every time. This has no affect if the
                                  <literal>AuthenticationCacheJndiName</literal> has been changed from the default
                          value.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">DefaultCacheResolution</emphasis>: Specifies the default timed cache
                              policy resolution in seconds. This controls the interval at which the cache current
                              timestamp is updated and should be less than the <literal>DefaultCacheTimeout</literal> in
                              order for the timeout to be meaningful. The default resolution is 60 seconds(1 minute). This
                              has no affect if the <literal>AuthenticationCacheJndiName</literal> has been changed from
                              the default value.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">DefaultUnauthenticatedPrincipal</emphasis>: Specifies the principal to
                              use for unauthenticated users. This setting makes it possible to set default permissions for
                              users who have not been authenticated. </para>
                      </listitem>
                  </itemizedlist>
                  <para>The <literal>JaasSecurityManagerService</literal> also supports a number of useful operations.
                      These include flushing any security domain authentication cache at runtime, getting the list of
                      active users in a security domain authentication cache, and any of the security manager interface
                      methods.</para>
                  <para>Flushing a security domain authentication cache can be used to drop all cached credentials when
                      the underlying store has been updated and you want the store state to be used immediately. The MBean
                      operation signature is: <literal>public void flushAuthenticationCache(String
                      securityDomain)</literal>.</para>
                  <para>This can be invoked programmatically using the following code snippet:</para>
                  <programlisting>MBeanServer server = ...;
  String jaasMgrName = "jboss.security:service=JaasSecurityManager";
  ObjectName jaasMgr = new ObjectName(jaasMgrName);
  Object[] params = {domainName};
  String[] signature = {"java.lang.String"};
  server.invoke(jaasMgr, "flushAuthenticationCache", params, signature);</programlisting>
                  <para>Getting the list of active users provides a snapshot of the <literal>Principals</literal> keys in
                      a security domain authentication cache that are not expired. The MBean operation signature is:
                          <literal>public List getAuthenticationCachePrincipals(String securityDomain)</literal>. </para>
                  <para>This can be invoked programmatically using the following code snippet:</para>
                  <programlisting>MBeanServer server = ...;
  String jaasMgrName = "jboss.security:service=JaasSecurityManager";
  ObjectName jaasMgr = new ObjectName(jaasMgrName);
  Object[] params = {domainName};
  String[] signature = {"java.lang.String"};
  List users = (List) server.invoke(jaasMgr, "getAuthenticationCachePrincipals", 
                                    params, signature);</programlisting>
                  <para>The security manager has a few additional access methods.</para>
                  <programlisting>public boolean isValid(String securityDomain, Principal principal, Object credential);
  public Principal getPrincipal(String securityDomain, Principal principal);
  public boolean doesUserHaveRole(String securityDomain, Principal principal, 
                                  Object credential, Set roles);
  public Set getUserRoles(String securityDomain, Principal principal, Object credential);</programlisting>
                  <para>They provide access to the corresponding <literal>AuthenticationManager</literal> and
                          <literal>RealmMapping</literal> interface method of the associated security domain named by the
                          <literal>securityDomain</literal> argument.</para>
              </section>
              <section>
                  <title>The JaasSecurityDomain MBean</title>
                  <para>The <literal>org.jboss.security.plugins.JaasSecurityDomain</literal> is an extension of
                          <literal>JaasSecurityManager</literal> that adds the notion of a <literal>KeyStore</literal>, a
                      JSSE <literal>KeyManagerFactory</literal> and a <literal>TrustManagerFactory</literal> for
                      supporting SSL and other cryptographic use cases. The additional configurable attributes of the
                          <literal>JaasSecurityDomain</literal> include:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">KeyStoreType</emphasis>: The type of the <literal>KeyStore</literal>
                              implementation. This is the type argument passed to the
                                  <literal>java.security.KeyStore.getInstance(String type)</literal> factory method. The
                              default is <literal>JKS</literal>. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">KeyStoreURL</emphasis>: A URL to the location of the
                              <literal>KeyStore</literal> database. This is used to obtain an
                              <literal>InputStream</literal> to initialize the <literal>KeyStore</literal>. If the string
                              is not a value URL, it is treated as a file.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">KeyStorePass</emphasis>: The password associated with the
                                  <literal>KeyStore</literal> database contents. The <literal>KeyStorePass</literal> is
                              also used in combination with the <literal>Salt</literal> and
                              <literal>IterationCount</literal> attributes to create a PBE secret key used with the
                              encode/decode operations. The <literal>KeyStorePass</literal> attribute value format is one
                              of the following:</para>
                          <itemizedlist>
                              <listitem>
                                  <para> The plaintext password for the <literal>KeyStore</literal> The
                                          <literal>toCharArray()</literal> value of the string is used without any
                                      manipulation.</para>
                              </listitem>
                              <listitem>
                                  <para>A command to execute to obtain the plaintext password. The format is
                                          <literal>{EXT}...</literal> where the <literal>...</literal> is the exact
                                      command line that will be passed to the <literal>Runtime.exec(String)</literal>
                                      method to execute a platform-specific command. The first line of the command output
                                      is used as the password.</para>
                              </listitem>
                              <listitem>
                                  <para>A class to create to obtain the plaintext password. The format is
                                          <literal>{CLASS}classname[:ctorarg]</literal> where the
                                      <literal>[:ctorarg]</literal> is an optional string that will be passed to the
                                      constructor when instantiating the <literal>classname</literal>. The password is
                                      obtained from classname by invoking a <literal>toCharArray()</literal> method if
                                      found, otherwise, the <literal>toString()</literal> method is used.</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">Salt</emphasis>: The <literal>PBEParameterSpec</literal> salt value.
                          </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">IterationCount</emphasis>: The <literal>PBEParameterSpec</literal>
                              iteration count value. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">TrustStoreType</emphasis>: The type of the
                              <literal>TrustStore</literal> implementation. This is the type argument passed to the
                                  <literal>java.security.KeyStore.getInstance(String type)</literal> factory method. The
                              default is <literal>JKS</literal>. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">TrustStoreURL</emphasis>: A URL to the location of the
                                  <literal>TrustStore</literal> database. This is used to obtain an
                              <literal>InputStream</literal> to initialize the <literal>KeyStore</literal>. If the string
                              is not a value URL, it is treated as a file.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">TrustStorePass</emphasis>: The password associated with the trust
                              store database contents. The <literal>TrustStorePass</literal> is a simple password and
                              doesn't have the same configuration options as the <literal>KeyStorePass</literal>. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ManagerServiceName</emphasis>: Sets the JMX object name string of the
                              security manager service MBean. This is used to register the defaults to register the
                                  <literal>JaasSecurityDomain</literal> as a the security manager under
                                  <literal>java:/jaas/&lt;domain&gt;</literal> where
                                  <literal>&lt;domain&gt;</literal> is the name passed to the MBean constructor.
                              The name defaults to <literal>jboss.security:service=JaasSecurityManager</literal>.</para>
                      </listitem>
                  </itemizedlist>
              </section>
  
          </section>
          <section id="ch8.domains.sect">
              <title>Defining Security Domains</title>
              <para>The standard way of configuring security domains for authentication and authorization in JBoss is to
                  use the XML login configuration file. The login configuration policy defines a set of named security
                  domains that each define a stack of login modules that will be called upon to authenticate and authorize
                  users. </para>
              <para> The XML configuration file conforms to the DTD given by <xref linkend="ch8.loginconfig.fig"/>. This
                  DTD can be found in <literal>docs/dtd/security_config.dtd</literal>.</para>
              <figure id="ch8.loginconfig.fig">
                  <title>The XMLLoginConfig DTD</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/security_config_policy.jpg"/>
                      </imageobject>
                  </mediaobject>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/security_config_login_module.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para> The following example shows a simple configuration named jmx-console that is backed by a single login
                  module. The login module is configured by a simple set of name/value configuration pairs that have
                  meaning to the login module in question. We'll see what these options mean later, for now we'll just be
                  concerned with the structure of the configuration file.</para>
              <programlisting>&lt;application-policy name=&quot;jmx-console&quot;&gt;
      &lt;authentication&gt;
          &lt;login-module code=&quot;org.jboss.security.auth.spi.UsersRolesLoginModule&quot; flag=&quot;required&quot;&gt;
              &lt;module-option name=&quot;usersProperties&quot;&gt;props/jmx-console-users.properties&lt;/module-option&gt;
              &lt;module-option name=&quot;rolesProperties&quot;&gt;props/jmx-console-roles.properties&lt;/module-option&gt;
          &lt;/login-module&gt;
      &lt;/authentication&gt;
  &lt;/application-policy&gt;</programlisting>
              <para>The <literal>name</literal> attribute of the <literal>application-policy</literal> is the login
                  configuration name. Applications policy elements will be bound by that name in JNDI under the the
                      <literal>java:/jaas</literal> context. Applications will link to security domains through this JNDI
                  name in their deployment descriptors. (See the <literal>security-domain</literal> elements in
                      <literal>jboss.xml</literal>, <literal>jboss-web.xml</literal> and
                  <literal>jboss-service.xml</literal> files for examples)</para>
              <para> The <literal>code</literal> attribute of the <literal>login-module</literal> element specifies the
                  class name of the login module implementation. The <literal>required</literal> flag attribute controls
                  the overall behavior of the authentication stack. The allowed values and meanings are:</para>
  
  
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">required</emphasis>: The login module is required to succeed for the
                          authentication to be successful. If any required module fails, the authentication will fail. The
                          remaining login modules in the stack will be called regardless of the outcome of the
                          authentication. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">requisite</emphasis>: The login module is required to succeed. If it
                          succeeds, authentication continues down the login stack. If it fails, control immediately
                          returns to the application.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">sufficient</emphasis>: The login module is not required to succeed. If it
                          does succeed, control immediately returns to the application. If it fails, authentication
                          continues down the login stack.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">optional</emphasis>: The login module is not required to succeed.
                          Authentication still continues to proceed down the login stack regardless of whether the login
                          module succeeds or fails.</para>
                  </listitem>
              </itemizedlist>
  
  
              <para>The following example shows the definition of a security domain that uses multiple login modules.
                  Since both modules are marked as sufficient, only one of them need to succeed for login to proceed. </para>
  
              <programlisting>&lt;application-policy name=&quot;todo&quot;&gt;
      &lt;authentication&gt;
          &lt;login-module code=&quot;org.jboss.security.auth.spi.LdapLoginModule&quot; 
                        flag=&quot;sufficient&quot;&gt;
              &lt;!-- LDAP configuration --&gt;
          &lt;/login-module&gt;
          &lt;login-module code=&quot;org.jboss.security.auth.spi.DatabaseServerLoginModule&quot; 
                        flag=&quot;sufficient&quot;&gt;
              &lt;!-- database configuration --&gt;
          &lt;/login-module&gt;
      &lt;/authentication&gt;
  &lt;/application-policy&gt;</programlisting>
  
  
              <para>Each login module has its own set of configuration options. These are set as name/value pairs using
                  the <literal>module-option</literal> elements. We'll cover module options in more depth when we look at
                  the individual login modules available in JBoss AS.</para>
  
  
  
              <section>
                  <title>Loading Security Domains</title>
  
                  <para>Authentication security domains are configured statically in the
                      <literal>conf/login-config.xml</literal> file. The <literal>XMLLoginConfig</literal> MBean is resp
                      onsible for loading security configurations from this configurations from a local configuration
                      file. The MBean is defined as shown below. </para>
  
                  <programlisting>&lt;mbean code=&quot;org.jboss.security.auth.login.XMLLoginConfig&quot;
         name=&quot;jboss.security:service=XMLLoginConfig&quot;&gt;
      &lt;attribute name=&quot;ConfigResource&quot;&gt;login-config.xml&lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
  
                  <para> The MBean supports the following attributes:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">ConfigURL</emphasis>: specifies the URL of the XML login configuration
                              file that should be loaded by this MBean on startup. This must be a valid URL string
                              representation.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ConfigResource</emphasis>: specifies the resource name of the XML
                              login configuration file that should be loaded by this MBean on startup. The name is treated
                              as a classpath resource for which a URL is located using the thread context class
                          loader.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">ValidateDTD</emphasis>: a flag indicating if the XML configuration
                              should be validated against its DTD. This defaults to true.</para>
                      </listitem>
                  </itemizedlist>
  
                  <para>The MBean also supports the following operations that allow one to dynamically extend the login
                      configurations at runtime. Note that any operation that attempts to alter login configuration
                      requires a <literal>javax.security.auth.AuthPermission("refreshLoginConfiguration")</literal> when
                      running with a security manager. The <literal>org.jboss.chap8.service.SecurityConfig</literal>
                      service demonstrates how this can be used to add/remove a deployment specific security configuration
                      dynamically.</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <literal>void addAppConfig(String appName, AppConfigurationEntry[] entries)</literal>: this
                              adds the given login module configuration stack to the current configuration under the given
                                  <literal>appName</literal>. This replaces any existing entry under that name.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <literal>void removeAppConfig(String appName)</literal>: this removes the login module
                              configuration registered under the given <literal>appName</literal>.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <literal>String[] loadConfig(URL configURL) throws Exception</literal>: this loads one or
                              more login configurations from a URL representing either an XML or legacy Sun login
                              configuration file. Note that all login configurations must be added or none will be added.
                              It returns the names of the login configurations that were added.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <literal>void removeConfigs(String[] appNames)</literal>: this removes the login
                              configurations specified <literal>appNames</literal> array.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <literal>String displayAppConfig(String appName)</literal>: this operation displays a simple
                              string format of the named configuration if it exists.</para>
                      </listitem>
                  </itemizedlist>
  
  
  
                  <para>The <literal>SecurityConfig</literal> MBean is responsible for selecting the
                          <literal>javax.security.auth.login.Configuration</literal> to be used. The default configuration
                      simply references the <literal>XMLLoginConfig</literal> MBean. </para>
  
  
                  <programlisting>  &lt;mbean code=&quot;org.jboss.security.plugins.SecurityConfig&quot; 
         name=&quot;jboss.security:service=SecurityConfig&quot;&gt;
      &lt;attribute name=&quot;LoginConfig&quot;&gt;jboss.security:service=XMLLoginConfig&lt;/attribute&gt;
                   &lt;/mbean&gt;</programlisting>
  
                  <para>There is one configurable attribute:</para>
  
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">LoginConfig</emphasis>: Specifies the JMX
                              <literal>ObjectName</literal> string of the MBean that provides the default JAAS login
                              configuration. When the <literal>SecurityConfig</literal> is started, this MBean is queried
                              for its <literal>javax.security.auth.login.Configuration</literal> by calling its
                                  <literal>getConfiguration(Configuration currentConfig)</literal> operation. If the
                                  <literal>LoginConfig</literal> attribute is not specified then the default Sun
                                  <literal>Configuration</literal> implementation described in the
                              <literal>Configuration</literal> class JavaDocs is used.</para>
                      </listitem>
                  </itemizedlist>
  
  
  
                  <para>In addition to allowing for a custom JAAS login configuration implementation, this service allows
                      configurations to be chained together in a stack at runtime. This allows one to push a login
                      configuration onto the stack and latter pop it. This is a feature used by the security unit tests to
                      install custom login configurations into a default JBoss installation. Pushing a new configuration
                      is done using:</para>
                  <programlisting>public void pushLoginConfig(String objectName) throws
                  JMException, MalformedObjectNameException;</programlisting>
                  <para>The <literal>objectName</literal> parameters specifies an MBean similar to the
                          <literal>LoginConfig</literal> attribute. The current login configuration may be removed using:</para>
                  <programlisting>public void popLoginConfig() throws JMException;</programlisting>
  
              </section>
  
  
              <section>
                  <title>The DynamicLoginConfig service</title>
                  <para>Security domains defined in the <literal>login-config.xml</literal> file are essentially static.
                      They are read when JBoss starts up, but there is no easy way to add a new security domain or change
                      the definition for an existing one. The <literal>DynamicLoginConfig</literal> service allows you to
                      dynamically deploy security domains. This allows you to specify JAAS login configuration as part of
                      a deployment (or just as a standalone service) rather than having to edit the static
                          <literal>login-config.xml</literal> file. </para>
                  <para>The service supports the following attributes:</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">AuthConfig</emphasis>: The resource path to the JAAS login
                              configuration file to use. This defaults to <literal>login-config.xml</literal>
                          </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">LoginConfigService</emphasis>: the <literal>XMLLoginConfig</literal>
                              service name to use for loading. This service must support a <literal>String
                              loadConfig(URL)</literal> operation to load the configurations. </para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SecurityManagerService</emphasis>: The
                              <literal>SecurityManagerService</literal> name used to flush the registered security
                              domains. This service must support a <literal>flushAuthenticationCache(String)</literal>
                              operation to flush the case for the argument security domain. Setting this triggers the
                              flush of the authentication caches when the service is stopped.</para>
                      </listitem>
                  </itemizedlist>
                  <para> Here is an example MBean definition using the <literal>DynamicLoginConfig</literal> service. </para>
                  <programlisting>&lt;server&gt;
      &lt;mbean code="org.jboss.security.auth.login.DynamicLoginConfig" name="..."&gt;
          &lt;attribute name="AuthConfig"&gt;login-config.xml&lt;/attribute&gt;
  
          &lt;!-- The service which supports dynamic processing of login-config.xml
           configurations.
          --&gt;
          &lt;depends optional-attribute-name="LoginConfigService"&gt;
              jboss.security:service=XMLLoginConfig &lt;/depends&gt;
  
          &lt;!-- Optionally specify the security mgr service to use when
           this service is stopped to flush the auth caches of the domains
           registered by this service.
          --&gt;
          &lt;depends optional-attribute-name="SecurityManagerService"&gt;
              jboss.security:service=JaasSecurityManager &lt;/depends&gt;
      &lt;/mbean&gt;
  &lt;/server&gt;</programlisting>
                  <para>This will load the specified <literal>AuthConfig</literal> resource using the specified
                          <literal>LoginConfigService</literal> MBean by invoking <literal>loadConfig</literal> with the
                      appropriate resource URL. When the service is stopped the configurations are removed. The resource
                      specified may be either an XML file, or a Sun JAAS login configuration.</para>
              </section>
  
  
              <section>
                  <title>Using JBoss Login Modules</title>
  
                  <para>JBoss includes several bundled login modules suitable for most user management needs. JBoss can
                      read user information from a relational database, an LDAP server or flat files. In addition to these
                      core login modules, JBoss provides several other login modules that provide user information for
                      very customized needs in JBoss. Before we explore the individual login modules, let's take a look at
                      a few login module configuration options that are common to multiple modules. </para>
  
                  <section>
                      <title>Password Stacking</title>
  
                      <para>Multiple login modules can be chained together in a stack, with each login module providing
                          both the authentication and authorization components. This works for many use cases, but
                          sometimes authentication and authorization are split across multiple user management stores. A
                          previous example showed how to combine LDAP and a relational database, allowing a user to be
                          authenticated by either system. However, consider the case where users are managed in a central
                          LDAP server but application-specific roles are stored in the application's relational database.
                          The password-stacking module option captures this relationship. </para>
  
                      <itemizedlist>
  
  
                          <listitem>
                              <para>
                                  <emphasis role="bold">password-stacking</emphasis>: When
                                  <literal>password-stacking</literal> option is set to <literal>useFirstPass</literal>,
                                  this module first looks for a shared username and password under the property names
                                      <literal>javax.security.auth.login.name</literal> and
                                      <literal>javax.security.auth.login.password</literal> respectively in the login
                                  module shared state map. If found these are used as the principal name and password. If
                                  not found the principal name and password are set by this login module and stored under
                                  the property names <literal>javax.security.auth.login.name</literal> and
                                      <literal>javax.security.auth.login.password</literal> respectively.</para>
                          </listitem>
                      </itemizedlist>
  
  
                      <para>To use password stacking, each login module should set <literal>password-stacking</literal> to
                              <literal>useFirstPass</literal>. If a previous module configured for password stacking has
                          authenticated the user, all the other stacking modules will consider the user authenticated and
                          only attempt to provide a set of roles for the authorization step.</para>
  
                      <para>The following listing shows how password stacking could be used:</para>
                      <programlisting>&lt;application-policy name=&quot;todo&quot;&gt;
      &lt;authentication&gt;
          &lt;login-module code=&quot;org.jboss.security.auth.spi.LdapLoginModule&quot; 
                        flag=&quot;required&quot;&gt;
              &lt;!-- LDAP configuration --&gt;
              &lt;module-option name=&quot;password-stacking&quot;&gt;useFirstPass&lt;/module-option&gt;
          &lt;/login-module&gt;
          &lt;login-module code=&quot;org.jboss.security.auth.spi.DatabaseServerLoginModule&quot; 
                        flag=&quot;required&quot;&gt;
              &lt;!-- database configuration --&gt;                
              &lt;module-option name=&quot;password-stacking&quot;&gt;useFirstPass&lt;/module-option&gt;
          &lt;/login-module&gt;
      &lt;/authentication&gt;
  &lt;/application-policy&gt;</programlisting>
  
                      <para>When using password stacking, it is usually appropriate to set all modules to be required to
                          make sure that all modules are considered and have chance to contribute roles to the
                          authorization process. </para>
  
                  </section>
  
  
  
  
                  <section>
                      <title>Password Hashing</title>
                      <para>Most of the login modules need to compare a client-supplied password to a password stored in a
                          user management system. These modules generally work with plain text passwords, but can also be
                          configured to support hashed passwords to prevent plain text passwords from being stored on the
                          server side. </para>
  
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">hashAlgorithm</emphasis>: The name of the
                                      <literal>java.security.MessageDigest</literal> algorithm to use to hash the
                                  password. There is no default so this option must be specified to enable hashing.
                                  Typical values are <literal>MD5</literal> and <literal>SHA</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">hashEncoding</emphasis>: The string format for the hashed pass and
                                  must be either <literal>base64</literal>, <literal>hex</literal> or
                                  <literal>rfc2617</literal>. The default is <literal>base64</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">hashCharset</emphasis>: The encoding used to convert the clear
                                  text password to a byte array. The platform default encoding is the default.</para>
                          </listitem>
                          <listitem>
                              <para><emphasis role="bold">hashUserPassword</emphasis>: This indicates that the hashing
                                  algorithm should be applied to the password the user submits. The hashed user password
                                  will be compared against the value in the login module, which is expected to be a hash
                                  of the password. The default is true. </para>
                          </listitem>
                          <listitem>
                              <para><emphasis role="bold">hashStorePassword</emphasis>: This indicates that the hashing
                                  algorithm should be applied to the password stored on the server side. This is used for
                                  digest authentication where the user submits a hash of the user password along with a
                                  request-specific tokens from the server to be comare. JBoss uses the hash algorithm (for
                                  digest, this would be <literal>rfc2617</literal>) to compute a server-side hash that
                                  should match the hashed value sent from the client. </para>
                          </listitem>
                          <!-- <listitem>
                      <para><emphasis role="bold">digestCallback</emphasis>:</para>
                  </listitem>
                  <listitem>
                      <para><emphasis role="bold">storeDigestCallback</emphasis>:</para>
                  </listitem>-->
                      </itemizedlist>
  
                      <para>The following is an login module configuration that assigns unauthenticated users the
                          principal name <literal>nobody</literal> and contains based64-encoded, MD5 hashes of the
                          passwords in a <literal>usersb64.properties</literal> file.</para>
                      <programlisting>&lt;policy&gt;
      &lt;application-policy name="testUsersRoles"&gt;
          &lt;authentication&gt;
              &lt;login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
                            flag="required"&gt;
                  &lt;module-option name="hashAlgorithm"&gt;MD5&lt;/module-option&gt;
                  &lt;module-option name="hashEncoding"&gt;base64&lt;/module-option&gt;          
              &lt;/login-module&gt;
          &lt;/authentication&gt;
      &lt;/application-policy&gt;
  &lt;/policy&gt;</programlisting>
  
  
                      <para>If you need to generate passwords in code, <literal>the org.jboss.security.Util</literal>
                          class provides a static helper method that will hash a password using a given encoding. </para>
  
  
                      <programlisting>String hashedPassword = Util.createPasswordHash(&quot;MD5&quot;,
                                                  Util.BASE64_ENCODING,
                                                  null,
                                                  null,
                                                  "password");   </programlisting>
  
                      <para>OpenSSL provides an alternative way to quickly generate hashed passwords. </para>
  
                      <programlisting>echo -n password | openssl dgst -md5 -binary | openssl base64</programlisting>
  
                      <para>In both cases, the text password should hash to "X03MO1qnZdYdgyfeuILPmQ==". This is the value
                          that would need to be stored in the user store.</para>
  
  
  
                  </section>
  
                  <section>
                      <title>Unauthenticated Identity</title>
                      <para> Not all requests come in authenticated. The unauthenticated identity is a login module
                          configuration option that assigns a specific identity (guest, for example) to requests that are
                          made with no associated authentication information. This can be used to allow unprotected
                          servlets to invoke methods on EJBs that do not require a specific role. Such a principal has no
                          associated roles and so can only access either unsecured EJBs or EJB methods that are associated
                          with the unchecked permission constraint. </para>
                      <itemizedlist>
  
  
                          <listitem>
                              <para>
                                  <emphasis role="bold">unauthenticatedIdentity</emphasis>: This defines the principal
                                  name that should be assigned to requests that contain no authentication information.
                              </para>
                          </listitem>
                      </itemizedlist>
                  </section>
  
  
                  <section id="ch8.filelogin.sect">
                      <title>UsersRolesLoginModule</title>
                      <para>The <literal>UsersRolesLoginModule</literal> is a simple login module that supports multiple
                          users and user roles loaded from Java properties files. The username-to-password mapping file is
                          called <literal>users.properties</literal> and the username-to-roles mapping file is called
                              <literal>roles.properties</literal>. The properties files are loaded during initialization
                          using the initialize method thread context class loader. This means that these files can be
                          placed into the J2EE deployment JAR, the JBoss configuration directory, or any directory on the
                          JBoss server or system classpath. The primary purpose of this login module is to easily test the
                          security settings of multiple users and roles using properties files deployed with the
                          application.</para>
                      <para>The <literal>users.properties</literal> file uses a <literal>username=password</literal>
                          format with each user entry on a separate line as show here:</para>
                      <programlisting>username1=password1
  username2=password2
  ...</programlisting>
                      <para>The <literal>roles.properties</literal> file uses as
                          <literal>username=role1,role2,...</literal> format with an optional group name value. For
                          example:</para>
                      <programlisting>username1=role1,role2,...
  username1.RoleGroup1=role3,role4,...
  username2=role1,role3,...</programlisting>
                      <para>The <literal>username.XXX</literal> form of property name is used to assign the username roles
                          to a particular named group of roles where the <literal>XXX</literal> portion of the property
                          name is the group name. The <literal>username=...</literal> form is an abbreviation for
                              <literal>username.Roles=...</literal>, where the <literal>Roles</literal> group name is the
                          standard name the <literal>JaasSecurityManager</literal> expects to contain the roles which
                          define the users permissions.</para>
                      <para>The following would be equivalent definitions for the <literal>jduke</literal> username:</para>
                      <programlisting>jduke=TheDuke,AnimatedCharacter
  jduke.Roles=TheDuke,AnimatedCharacter</programlisting>
                      <para>The supported login module configuration options include the following:</para>
                      <itemizedlist>
  
  
                          <listitem>
                              <para>
                                  <emphasis role="bold">usersProperties</emphasis>: The name of the properties resource
                                  containing the username to password mappings. This defaults to
                                  <literal>users.properties</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">rolesProperties</emphasis>: The name of the properties resource
                                  containing the username to roles mappings. This defaults to
                                  <literal>roles.properties</literal>.</para>
                          </listitem>
                      </itemizedlist>
  
                      <para>This login module supports password stacking, password hashing and unauthenticated identity.</para>
  
                  </section>
                  <section id="ch8.ldaplogin.sect">
                      <title>LdapLoginModule</title>
                      <para>The <literal>LdapLoginModule</literal> is a <literal>LoginModule</literal> implementation that
                          authenticates against an LDAP server. You would use the <literal>LdapLoginModule</literal> if
                          your username and credentials are stored in an LDAP server that is accessible using a JNDI LDAP
                          provider.</para>
                      <para>The LDAP connectivity information is provided as configuration options that are passed through
                          to the environment object used to create JNDI initial context. The standard LDAP JNDI properties
                          used include the following:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">java.naming.factory.initial</emphasis>: The classname of the
                                      <literal>InitialContextFactory</literal> implementation. This defaults to the Sun
                                  LDAP provider implementation <literal>com.sun.jndi.ldap.LdapCtxFactory</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">java.naming.provider.url</emphasis>: The LDAP URL for the LDAP
                                  server</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">java.naming.security.authentication</emphasis>: The security level
                                  to use. This defaults to <literal>simple</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">java.naming.security.protocol</emphasis>: The transport protocol
                                  to use for secure access, such as, SSL.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">java.naming.security.principal</emphasis>: The principal for
                                  authenticating the caller to the service. This is built from other properties as
                                  described below.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">java.naming.security.credentials</emphasis>: The value of the
                                  property depends on the authentication scheme. For example, it could be a hashed
                                  password, clear-text password, key, certificate, and so on.</para>
                          </listitem>
                      </itemizedlist>
                      <para>The supported login module configuration options include the following:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">principalDNPrefix</emphasis>: A prefix to add to the username to
                                  form the user distinguished name. See <literal>principalDNSuffix</literal> for more
                                  info.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">principalDNSuffix</emphasis>: A suffix to add to the username when
                                  forming the user distinguished name. This is useful if you prompt a user for a username
                                  and you don't want the user to have to enter the fully distinguished name. Using this
                                  property and <literal>principalDNSuffix</literal> the <literal>userDN</literal> will be
                                  formed as <literal>principalDNPrefix + username + principalDNSuffix</literal>
                              </para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">useObjectCredential</emphasis>: A true/false value that indicates
                                  that the credential should be obtained as an opaque <literal>Object</literal> using the
                                      <literal>org.jboss.security.auth.callback.ObjectCallback</literal> type of
                                      <literal>Callback</literal> rather than as a <literal>char[]</literal> password
                                  using a JAAS <literal>PasswordCallback</literal>. This allows for passing
                                      non-<literal>char[]</literal> credential information to the LDAP server.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">rolesCtxDN</emphasis>: The fixed distinguished name to the context
                                  to search for user roles.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">userRolesCtxDNAttributeName</emphasis>: The name of an attribute
                                  in the user object that contains the distinguished name to the context to search for
                                  user roles. This differs from <literal>rolesCtxDN</literal> in that the context to
                                  search for a user's roles can be unique for each user.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">roleAttributeID</emphasis>: The name of the attribute that
                                  contains the user roles. If not specified this defaults to
                              <literal>roles</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">roleAttributeIsDN</emphasis>: A flag indicating whether the
                                      <literal>roleAttributeID</literal> contains the fully distinguished name of a role
                                  object, or the role name. If false, the role name is taken from the value of
                                      <literal>roleAttributeID</literal>. If true, the role attribute represents the
                                  distinguished name of a role object. The role name is taken from the value of the
                                      <literal>roleNameAttributeId</literal> attribute of the context name by the
                                  distinguished name. In certain directory schemas (e.g., MS ActiveDirectory), role
                                  attributes in the user object are stored as DNs to role objects instead of as simple
                                  names, in which case, this property should be set to true. The default is false.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">roleNameAttributeID</emphasis>: The name of the attribute of the
                                  context pointed to by the <literal>roleCtxDN</literal> distinguished name value which
                                  contains the role name. If the <literal>roleAttributeIsDN</literal> property is set to
                                  true, this property is used to find the role object's name attribute. The default is
                                      <literal>group</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">uidAttributeID</emphasis>: The name of the attribute in the object
                                  containing the user roles that corresponds to the userid. This is used to locate the
                                  user roles. If not specified this defaults to <literal>uid</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">matchOnUserDN</emphasis>: A true/false flag indicating if the
                                  search for user roles should match on the user's fully distinguished name. If false,
                                  just the username is used as the match value against the
                                  <literal>uidAttributeName</literal> attribute. If true, the full
                                  <literal>userDN</literal> is used as the match value.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">unauthenticatedIdentity</emphasis>: The principal name that should
                                  be assigned to requests that contain no authentication information. This behavior is
                                  inherited from the <literal>UsernamePasswordLoginModule</literal> superclass.</para>
                          </listitem>
  
                          <listitem>
                              <para>
                                  <emphasis role="bold">allowEmptyPasswords</emphasis>: A flag indicating if empty (length
                                  0) passwords should be passed to the LDAP server. An empty password is treated as an
                                  anonymous login by some LDAP servers and this may not be a desirable feature. Set this
                                  to false to reject empty passwords or true to have the LDAP server validate the empty
                                  password. The default is true.</para>
                          </listitem>
                      </itemizedlist>
                      <para>The authentication of a user is performed by connecting to the LDAP server based on the login
                          module configuration options. Connecting to the LDAP server is done by creating an
                              <literal>InitialLdapContext</literal> with an environment composed of the LDAP JNDI
                          properties described previously in this section. The
                          <literal>Context.SECURITY_PRINCIPAL</literal> is set to the distinguished name of the user as
                          obtained by the callback handler in combination with the <literal>principalDNPrefix</literal>
                          and <literal>principalDNSuffix</literal> option values, and the
                              <literal>Context.SECURITY_CREDENTIALS</literal> property is either set to the
                              <literal>String</literal> password or the <literal>Object</literal> credential depending on
                          the <literal>useObjectCredential</literal> option.</para>
                      <para>Once authentication has succeeded by virtue of being able to create an
                              <literal>InitialLdapContext</literal> instance, the user's roles are queried by performing a
                          search on the <literal>rolesCtxDN</literal> location with search attributes set to the
                              <literal>roleAttributeName</literal> and <literal>uidAttributeName</literal> option values.
                          The roles names are obtaining by invoking the <literal>toString</literal> method on the role
                          attributes in the search result set.</para>
                      <para>The following is a sample <literal>login-config.xml</literal> entry.</para>
                      <programlisting>
      &lt;application-policy name=&quot;testLDAP&quot;&gt;
          &lt;authentication&gt;
              &lt;login-module code=&quot;org.jboss.security.auth.spi.LdapLoginModule&quot;
                            flag=&quot;required&quot;&gt;
                  &lt;module-option name=&quot;java.naming.factory.initial&quot;&gt; 
                      com.sun.jndi.ldap.LdapCtxFactory
                      &lt;/module-option&gt;
                  &lt;module-option name=&quot;java.naming.provider.url&quot;&gt;
                      ldap://ldaphost.jboss.org:1389/
                  &lt;/module-option&gt;
                  &lt;module-option name=&quot;java.naming.security.authentication&quot;&gt;
                      simple
                  &lt;/module-option&gt;
                  &lt;module-option name=&quot;principalDNPrefix&quot;&gt;uid=&lt;/module-option&gt;                    
                  &lt;module-option name=&quot;principalDNSuffix&quot;&gt;
                      ,ou=People,dc=jboss,dc=org
                  &lt;/module-option&gt;
  
                  &lt;module-option name=&quot;rolesCtxDN&quot;&gt;
                      ou=Roles,dc=jboss,dc=org
                  &lt;/module-option&gt;
                  &lt;module-option name=&quot;uidAttributeID&quot;&gt;member&lt;/module-option&gt;
                  &lt;module-option name=&quot;matchOnUserDN&quot;&gt;true&lt;/module-option&gt;
  
                  &lt;module-option name=&quot;roleAttributeID&quot;&gt;cn&lt;/module-option&gt;
                  &lt;module-option name=&quot;roleAttributeIsDN&quot;&gt;false &lt;/module-option&gt;
              &lt;/login-module&gt;
          &lt;/authentication&gt;
      &lt;/application-policy&gt;</programlisting>
                      <para>An LDIF file representing the structure of the directory this data operates against is shown
                          below. </para>
                      <programlisting>dn: dc=jboss,dc=org
  objectclass: top
  objectclass: dcObject
  objectclass: organization
  dc: jboss
  o: JBoss
  
  dn: ou=People,dc=jboss,dc=org
  objectclass: top
  objectclass: organizationalUnit
  ou: People
  
  dn: uid=jduke,ou=People,dc=jboss,dc=org
  objectclass: top
  objectclass: uidObject
  objectclass: person
  uid: jduke
  cn: Java Duke
  sn: Duke
  userPassword: theduke
  
  dn: ou=Roles,dc=jboss,dc=org
  objectclass: top
  objectclass: organizationalUnit
  ou: Roles
  
  dn: cn=JBossAdmin,ou=Roles,dc=jboss,dc=org
  objectclass: top
  objectclass: groupOfNames
  cn: JBossAdmin
  member: uid=jduke,ou=People,dc=jboss,dc=org
  description: the JBossAdmin group</programlisting>
                      <para>Looking back at the <literal>testLDAP</literal> login module configuration, the
                              <literal>java.naming.factory.initial</literal>, <literal>java.naming.factory.url</literal>
                          and <literal>java.naming.security</literal> options indicate the Sun LDAP JNDI provider
                          implementation will be used, the LDAP server is located on host
                          <literal>ldaphost.jboss.org</literal> on port 1389, and that the LDAP simple authentication
                          method will be use to connect to the LDAP server.</para>
                      <para>The login module attempts to connect to the LDAP server using a DN representing the user it is
                          trying to authenticate. This DN is constructed from the <literal>principalDNPrefix</literal>,
                          passed in, the username of the user and the <literal>principalDNSuffix</literal> as described
                          above. In this example, the username <literal>jduke</literal> would map to
                              <literal>uid=jduke,ou=People,dc=jboss,dc=org</literal>. We've assumed the LDAP server
                          authenticates users using the <literal>userPassword</literal> attribute of the user's entry
                              (<literal>theduke</literal> in this example). This is the way most LDAP servers work,
                          however, if your LDAP server handles authentication differently you will need to set the
                          authentication credentials in a way that makes sense for your server. </para>
                      <para>Once authentication succeeds, the roles on which authorization will be based are retrieved by
                          performing a subtree search of the <literal>rolesCtxDN</literal> for entries whose
                              <literal>uidAttributeID</literal> match the user. If <literal>matchOnUserDN</literal> is
                          true the search will be based on the full DN of the user. Otherwise the search will be based on
                          the actual user name entered. In this example, the search is under
                              <literal>ou=Roles,dc=jboss,dc=org</literal> for any entries that have a
                          <literal>member</literal> attribute equal to
                          <literal>uid=jduke,ou=People,dc=jboss,dc=org</literal>. The search would locate
                              <literal>cn=JBossAdmin</literal> under the roles entry. </para>
                      <para> The search returns the attribute specified in the <literal>roleAttributeID</literal> option.
                          In this example, the attribute is <literal>cn</literal>. The value returned would be
                              <literal>JBossAdmin</literal>, so the jduke user is assigned to the
                          <literal>JBossAdmin</literal> role. </para>
                      <para> It's often the case that a local LDAP server provides identity and authentication services
                          but is unable to use the authorization services. This is because application roles don't always
                          map well onto LDAP groups, and LDAP administrators are often hesitant to allow external
                          application-specific data in central LDAP servers. For this reason, the LDAP authentication
                          module is often paired with another login module, such as the database login module, that can
                          provide roles more suitable to the application being developed. </para>
  
  
                      <para>This login module also supports unauthenticated identity and password stacking. </para>
                  </section>
                  <section id="ch8.dabaseserverloginmodule.sect">
                      <title>DatabaseServerLoginModule</title>
                      <para>The <literal>DatabaseServerLoginModule</literal> is a JDBC based login module that supports
                          authentication and role mapping. You would use this login module if you have your username,
                          password and role information relational database. The
                          <literal>DatabaseServerLoginModule</literal> is based on two logical tables:</para>
                      <programlisting>Table Principals(PrincipalID text, Password text)
  Table Roles(PrincipalID text, Role text, RoleGroup text)</programlisting>
                      <para>The <literal>Principals</literal> table associates the user <literal>PrincipalID</literal>
                          with the valid password and the <literal>Roles</literal> table associates the user
                              <literal>PrincipalID</literal> with its role sets. The roles used for user permissions must
                          be contained in rows with a <literal>RoleGroup</literal> column value of
                          <literal>Roles</literal>. The tables are logical in that you can specify the SQL query that the
                          login module uses. All that is required is that the <literal>java.sql.ResultSet</literal> has
                          the same logical structure as the <literal>Principals</literal> and <literal>Roles</literal>
                          tables described previously. The actual names of the tables and columns are not relevant as the
                          results are accessed based on the column index. To clarify this notion, consider a database with
                          two tables, <literal>Principals</literal> and <literal>Roles</literal>, as already declared. The
                          following statements build the tables to contain a <literal>PrincipalID</literal>
                          <literal>java</literal> with a <literal>Password</literal> of <literal>echoman</literal> in the
                              <literal>Principals</literal> table, a <literal>PrincipalID</literal>
                          <literal>java</literal> with a role named <literal>Echo</literal> in the <literal>Roles</literal>
                          <literal>RoleGroup</literal> in the <literal>Roles</literal> table, and a <literal>PrincipalID</literal>
                          <literal>java</literal> with a role named <literal>caller_java</literal> in the
                              <literal>CallerPrincipal</literal>
                          <literal>RoleGroup</literal> in the <literal>Roles</literal> table:</para>
                      <programlisting>INSERT INTO Principals VALUES('java', 'echoman')
  INSERT INTO Roles VALUES('java', 'Echo', 'Roles')
  INSERT INTO Roles VALUES('java', 'caller_java', 'CallerPrincipal')</programlisting>
                      <para>The supported login module configuration options include the following:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">dsJndiName</emphasis>: The JNDI name for the
                                  <literal>DataSource</literal> of the database containing the logical
                                  <literal>Principals</literal> and <literal>Roles</literal> tables. If not specified this
                                  defaults to <literal>java:/DefaultDS</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">principalsQuery</emphasis>: The prepared statement query
                                  equivalent to: <literal>select Password from Principals where PrincipalID=?</literal>.
                                  If not specified this is the exact prepared statement that will be used.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">rolesQuery</emphasis>: The prepared statement query equivalent to:
                                      <literal>select Role, RoleGroup from Roles where PrincipalID=?</literal>. If not
                                  specified this is the exact prepared statement that will be used.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">ignorePasswordCase</emphasis>: A boolean flag indicating if the
                                  password comparison should ignore case. This can be useful for hashed password encoding
                                  where the case of the hashed password is not significant.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">principalClass</emphasis>: An option that specifies a
                                      <literal>Principal</literal> implementation class. This must support a constructor
                                  taking a string argument for the principal name.</para>
                          </listitem>
                      </itemizedlist>
                      <para>As an example <literal>DatabaseServerLoginModule</literal> configuration, consider a custom
                          table schema like the following:</para>
                      <programlisting>CREATE TABLE Users(username VARCHAR(64) PRIMARY KEY, passwd VARCHAR(64))
  CREATE TABLE UserRoles(username VARCHAR(64), userRoles VARCHAR(32))</programlisting>
                      <para>A corresponding <literal>login-config.xml</literal> entry would be:</para>
                      <programlisting>&lt;policy&gt;
      &lt;application-policy name="testDB"&gt;
          &lt;authentication&gt;
              &lt;login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule"
                               flag="required"&gt;
                  &lt;module-option name="dsJndiName"&gt;java:/MyDatabaseDS&lt;/module-option&gt;
                  &lt;module-option name="principalsQuery"&gt;
                      select passwd from Users username where username=?&lt;/module-option&gt;
                  &lt;module-option name="rolesQuery"&gt;
                      select userRoles, 'Roles' from UserRoles where username=?&lt;/module-option&gt;
              &lt;/login-module&gt;
          &lt;/authentication&gt;
      &lt;/application-policy&gt;
  &lt;/policy&gt;</programlisting>
  
                      <para>This module supports password stacking, password hashing and unathenticated identity.</para>
  
  
                  </section>
                  <section>
                      <title>BaseCertLoginModule</title>
                      <para> This is a login module which authenticates users based on X509 certificates. A typical use
                          case for this login module is <literal>CLIENT-CERT</literal> authentication in the web tier.
                          This login module only performs authentication. You need to combine it with another login module
                          capable of acquiring the authorization roles to completely define access to a secured web or EJB
                          component. Two subclasses of this login module, <literal>CertRolesLoginModule</literal> and
                              <literal>DatabaseCertLoginModule</literal> extend the behavior to obtain the authorization
                          roles from either a properties file or database. </para>
                      <para>The <literal>BaseCertLoginModule</literal> needs a <literal>KeyStore</literal> to perform user
                          validation. This is obtained through a <literal>org.jboss.security.SecurityDomain</literal>
                          implementation. Typically, the <literal>SecurityDomain</literal> implementation is configured
                          using the <literal>org.jboss.security.plugins.JaasSecurityDomain</literal> MBean as shown in
                          this <literal>jboss-service.xml</literal> configuration fragment: </para>
                      <programlisting>&lt;mbean code="org.jboss.security.plugins.JaasSecurityDomain"
         name="jboss.ch8:service=SecurityDomain"&gt;
      &lt;constructor&gt;
          &lt;arg type="java.lang.String" value="jmx-console"/&gt;
      &lt;/constructor&gt;
      &lt;attribute name="KeyStoreURL"&gt;resource:localhost.keystore&lt;/attribute&gt;
      &lt;attribute name="KeyStorePass"&gt;unit-tests-server&lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
                      <para>This creates a security domain with the name <literal>jmx-console</literal> whose
                              <literal>SecurityDomain</literal> implementation is available via JNDI under the name
                              <literal>java:/jaas/jmx-console</literal> following the JBossSX security domain naming
                          pattern. To secure a web application such as the <literal>jmx-console.war</literal> using client
                          certs and role based authorization, one would first modify the <literal>web.xml</literal> to
                          declare the resources to be secured, along with the allowed roles and security domain to be used
                          for authentication and authorization.</para>
                      <programlisting>&lt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE web-app PUBLIC
                    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
                    "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;
  &lt;web-app&gt; 
      ... 
      &lt;security-constraint&gt;
          &lt;web-resource-collection&gt;
              &lt;web-resource-name&gt;HtmlAdaptor&lt;/web-resource-name&gt;
              &lt;description&gt;An example security config that only allows users with
                  the role JBossAdmin to access the HTML JMX console web
                  application &lt;/description&gt;
              &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
              &lt;http-method&gt;GET&lt;/http-method&gt;
              &lt;http-method&gt;POST&lt;/http-method&gt;
          &lt;/web-resource-collection&gt;
          &lt;auth-constraint&gt;
              &lt;role-name&gt;JBossAdmin&lt;/role-name&gt;
          &lt;/auth-constraint&gt;
      &lt;/security-constraint&gt;
      &lt;login-config&gt;
          &lt;auth-method&gt;CLIENT-CERT&lt;/auth-method&gt;
          &lt;realm-name&gt;JBoss JMX Console&lt;/realm-name&gt;
      &lt;/login-config&gt;
      &lt;security-role&gt;
          &lt;role-name&gt;JBossAdmin&lt;/role-name&gt;
      &lt;/security-role&gt;
  &lt;/web-app&gt;</programlisting>
                      <para>Next we, need to specify the JBoss security domain in <literal>jboss-web.xml</literal>: </para>
                      <programlisting>&lt;jboss-web&gt;
      &lt;security-domain&gt;java:/jaas/jmx-console&lt;/security-domain&gt;
  &lt;/jboss-web&gt;</programlisting>
                      <para>Finally, you need to define the login module configuration for the jmx-console security domain
                          you just specified. This is done in the <literal>conf/login-config.xml</literal> file.</para>
                      <programlisting>&lt;application-policy name="jmx-console"&gt;
      &lt;authentication&gt;
          &lt;login-module code="org.jboss.security.auth.spi.BaseCertLoginModule" 
                        flag="required"&gt;
              &lt;module-option name="password-stacking"&gt;useFirstPass&lt;/module-option&gt;
              &lt;module-option name="securityDomain"&gt;java:/jaas/jmx-console&lt;/module-option&gt;
          &lt;/login-module&gt;
          &lt;login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" 
                        flag="required"&gt;
              &lt;module-option name="password-stacking"&gt;useFirstPass&lt;/module-option&gt;
              &lt;module-option name="usersProperties"&gt;jmx-console-users.properties&lt;/module-option&gt;
              &lt;module-option name="rolesProperties"&gt;jmx-console-roles.properties&lt;/module-option&gt;
          &lt;/login-module&gt;
      &lt;/authentication&gt;
  &lt;/application-policy&gt;</programlisting>
                      <para> Here the <literal>BaseCertLoginModule</literal> is used for authentication of the client
                          cert, and the <literal>UsersRolesLoginModule</literal> is only used for authorization due to the
                              <literal>password-stacking=useFirstPass</literal> option. Both the
                              <literal>localhost.keystore</literal> and the
                          <literal>jmx-console-roles.properties</literal> need an entry that maps to the principal
                          associated with the client cert. By default, the principal is created using the client
                          certificate distinguished name. Consider the following certificate:</para>
                      <programlisting>[starksm at banshee9100 conf]$ keytool -printcert -file unit-tests-client.export
  Owner: CN=unit-tests-client, OU=JBoss Inc., O=JBoss Inc., ST=Washington, C=US
  Issuer: CN=jboss.com, C=US, ST=Washington, L=Snoqualmie Pass, EMAILADDRESS=admin
  @jboss.com, OU=QA, O=JBoss Inc.
  Serial number: 100103
  Valid from: Wed May 26 07:34:34 PDT 2004 until: Thu May 26 07:34:34 PDT 2005
  Certificate fingerprints:
           MD5:  4A:9C:2B:CD:1B:50:AA:85:DD:89:F6:1D:F5:AF:9E:AB
           SHA1: DE:DE:86:59:05:6C:00:E8:CC:C0:16:D3:C2:68:BF:95:B8:83:E9:58
  </programlisting>
                      <para>The <literal>localhost.keystore</literal> would need this cert stored with an alias of
                              <literal>CN=unit-tests-client, OU=JBoss Inc., O=JBoss Inc., ST=Washington, C=US</literal>
                          and the <literal>jmx-console-roles.properties</literal> would also need an entry for the same
                          entry. Since the DN contains many characters that are normally treated as delimiters, you will
                          need to escape the problem characters using a backslash ('<literal>\</literal>') as shown here:</para>
                      <programlisting># A sample roles.properties file for use with the UsersRolesLoginModule
  CN\=unit-tests-client,\ OU\=JBoss\ Inc.,\ O\=JBoss\ Inc.,\ ST\=Washington,\ C\=US=JBossAdmin
  admin=JBossAdmin</programlisting>
                  </section>
  
  
                  <section>
                      <title>IdentityLoginModule</title>
                      <para>The <literal>IdentityLoginModule</literal> is a simple login module that associates a
                          hard-coded user name a to any subject authenticated against the module. It creates a
                              <literal>SimplePrincipal</literal> instance using the name specified by the
                              <literal>principal</literal> option. This login module is useful when you need to provide a
                          fixed identity to a service and in development environments when you want to test the security
                          associated with a given principal and associated roles.</para>
                      <para>The supported login module configuration options include:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">principal</emphasis>: This is the name to use for the
                                      <literal>SimplePrincipal</literal> all users are authenticated as. The principal
                                  name defaults to <literal>guest</literal> if no principal option is specified.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">roles</emphasis>: This is a comma-delimited list of roles that
                                  will be assigned to the user.</para>
                          </listitem>
                      </itemizedlist>
                      <para>A sample XMLLoginConfig configuration entry that would authenticate all users as the principal
                          named <literal>jduke</literal> and assign role names of <literal>TheDuke</literal>, and
                              <literal>AnimatedCharacter</literal> is:</para>
  
                      <programlisting>&lt;policy&gt;
      &lt;application-policy name="testIdentity"&gt;
          &lt;authentication&gt;
              &lt;login-module code="org.jboss.security.auth.spi.IdentityLoginModule"
                           flag="required"&gt;
                  &lt;module-option name="principal"&gt;jduke&lt;/module-option&gt;
                  &lt;module-option name="roles"&gt;TheDuke,AnimatedCharater&lt;/module-option&gt;
              &lt;/login-module&gt;
          &lt;/authentication&gt;
      &lt;/application-policy&gt;
  &lt;/policy&gt; </programlisting>
  
                      <para>This module supports password stacking.</para>
                  </section>
  
                  <section>
                      <title>RunAsLoginModule</title>
                      <para>JBoss has a helper login module called <literal>RunAsLoginModule</literal> that pushes a run
                          as role for the duration of the login phase of authentication, and pops the run as role in
                          either the commit or abort phase. The purpose of this login module is to provide a role for
                          other login modules that need to access secured resources in order to perform their
                          authentication. An example would be a login module that accesses an secured EJB. This login
                          module must be configured ahead of the login module(s) that need a run as role established.</para>
                      <para>The only login module configuration option is:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">roleName</emphasis>: the name of the role to use as the run as
                                  role during login phase. If not specified a default of <literal>nobody</literal> is
                                  used.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>ClientLoginModule</title>
                      <para>The <literal>ClientLoginModule</literal> is an implementation of
                          <literal>LoginModule</literal> for use by JBoss clients for the establishment of the caller
                          identity and credentials. This simply sets the
                              <literal>org.jboss.security.SecurityAssociation.principal</literal> to the value of the
                              <literal>NameCallback</literal> filled in by the <literal>callbackhandler</literal>, and the
                              <literal>org.jboss.security.SecurityAssociation.credential</literal> to the value of the
                              <literal>PasswordCallback</literal> filled in by the <literal>callbackhandler</literal>.
                          This is the only supported mechanism for a client to establish the current thread's caller. Both
                          stand-alone client applications and server environments, acting as JBoss EJB clients where the
                          security environment has not been configured to use JBossSX transparently, need to use the
                              <literal>ClientLoginModule</literal>. Of course, you could always set the
                              <literal>org.jboss.security.SecurityAssociation</literal> information directly, but this is
                          considered an internal API that is subject to change without notice.</para>
                      <para>Note that this login module does not perform any authentication. It merely copies the login
                          information provided to it into the JBoss server EJB invocation layer for subsequent
                          authentication on the server. If you need to perform client-side authentication of users you
                          would need to configure another login module in addition to the
                          <literal>ClientLoginModule</literal>.</para>
                      <para>The supported login module configuration options include the following:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">multi-threaded</emphasis>: When the multi-threaded option is set
                                  to true, each login thread has its own principal and credential storage. This is useful
                                  in client environments where multiple user identities are active in separate threads.
                                  When true, each separate thread must perform its own login. When set to false the login
                                  identity and credentials are global variables that apply to all threads in the VM. The
                                  default for this option is false.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">password-stacking</emphasis>: When
                                  <literal>password-stacking</literal> option is set to <literal>useFirstPass</literal>,
                                  this module first looks for a shared username and password using
                                      <literal>javax.security.auth.login.name</literal> and
                                      <literal>javax.security.auth.login.password</literal> respectively in the login
                                  module shared state map. This allows a module configured prior to this one to establish
                                  a valid username and password that should be passed to JBoss. You would use this option
                                  if you want to perform client-side authentication of clients using some other login
                                  module such as the <literal>LdapLoginModule</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">restore-login-identity</emphasis>: When
                                      <literal>restore-login-identity</literal> is true, the
                                  <literal>SecurityAssociation</literal> principal and credential seen on entry to the
                                      <literal>login()</literal> method are saved and restored on either abort or logout.
                                  When false (the default), the abort and logout simply clear the
                                      <literal>SecurityAssociation</literal>. A <literal>restore-login-identity</literal>
                                  of true is needed if one need to change identities and then restore the original caller
                                  identity.</para>
                          </listitem>
                      </itemizedlist>
                      <para>A sample login configuration for <literal>ClientLoginModule</literal> is the default
                          configuration entry found in the JBoss distribution <literal>client/auth.conf</literal> file.
                          The configuration is:</para>
                      <programlisting>other {
      // Put your login modules that work without jBoss here
                  
      // jBoss LoginModule
      org.jboss.security.ClientLoginModule required;
                 
      // Put your login modules that need jBoss here
  };  </programlisting>
                  </section>
              </section>
              <section id="ch8.custom.sect">
                  <title>Writing Custom Login Modules</title>
                  <para>If the login modules bundled with the JBossSX framework do not work with your security
                      environment, you can write your own custom login module implementation that does. Recall from the
                      section on the <literal>JaasSecurityManager</literal> architecture that the
                          <literal>JaasSecurityManager</literal> expected a particular usage pattern of the
                          <literal>Subject</literal> principals set. You need to understand the JAAS Subject class's
                      information storage features and the expected usage of these features to be able to write a login
                      module that works with the <literal>JaasSecurityManager</literal>. This section examines this
                      requirement and introduces two abstract base <literal>LoginModule</literal> implementations that can
                      help you implement your own custom login modules.</para>
                  <para>You can obtain security information associated with a <literal>Subject</literal> in six ways in
                      JBoss using the following methods:</para>
                  <programlisting>java.util.Set getPrincipals()
  java.util.Set getPrincipals(java.lang.Class c)
  java.util.Set getPrivateCredentials()
  java.util.Set getPrivateCredentials(java.lang.Class c)
  java.util.Set getPublicCredentials()
  java.util.Set getPublicCredentials(java.lang.Class c)</programlisting>
                  <para>For <literal>Subject</literal> identities and roles, JBossSX has selected the most natural choice:
                      the principals sets obtained via <literal>getPrincipals()</literal> and
                          <literal>getPrincipals(java.lang.Class)</literal>. The usage pattern is as follows:</para>
                  <itemizedlist>
                      <listitem>
                          <para>User identities (username, social security number, employee ID, and so on) are stored as
                                  <literal>java.security.Principal</literal> objects in the <literal>Subject</literal>
                              <literal>Principals</literal> set. The <literal>Principal</literal> implementation that
                              represents the user identity must base comparisons and equality on the name of the
                              principal. A suitable implementation is available as the
                                  <literal>org.jboss.security.SimplePrincipal</literal> class. Other
                              <literal>Principal</literal> instances may be added to the <literal>Subject</literal>
                              <literal>Principals</literal> set as needed.</para>
                      </listitem>
                      <listitem>
                          <para>The assigned user roles are also stored in the <literal>Principals</literal> set, but they
                              are grouped in named role sets using <literal>java.security.acl.Group</literal> instances.
                              The <literal>Group</literal> interface defines a collection of <literal>Principal</literal>s
                              and/or <literal>Group</literal>s, and is a subinterface of
                              <literal>java.security.Principal</literal>. Any number of role sets can be assigned to a
                                  <literal>Subject</literal>. Currently, the JBossSX framework uses two well-known role
                              sets with the names <literal>Roles</literal> and <literal>CallerPrincipal</literal>. The
                                  <literal>Roles</literal> Group is the collection of <literal>Principal</literal>s for
                              the named roles as known in the application domain under which the
                              <literal>Subject</literal> has been authenticated. This role set is used by methods like the
                                  <literal>EJBContext.isCallerInRole(String)</literal>, which EJBs can use to see if the
                              current caller belongs to the named application domain role. The security interceptor logic
                              that performs method permission checks also uses this role set. The <literal>CallerPrincipal</literal>
                              <literal>Group</literal> consists of the single <literal>Principal</literal> identity
                              assigned to the user in the application domain. The <literal>EJBContext.getCallerPrincipal()
                              </literal>method uses the <literal>CallerPrincipal</literal> to allow the application domain
                              to map from the operation environment identity to a user identity suitable for the
                              application. If a <literal>Subject</literal> does not have a <literal>CallerPrincipal</literal>
                              <literal>Group</literal>, the application identity is the same as operational environment
                              identity.</para>
                      </listitem>
                  </itemizedlist>
                  <section>
                      <title>Support for the Subject Usage Pattern</title>
                      <para>To simplify correct implementation of the <literal>Subject</literal> usage patterns described
                          in the preceding section, JBossSX includes two abstract login modules that handle the population
                          of the authenticated <literal>Subject</literal> with a template pattern that enforces correct
                              <literal>Subject</literal> usage. The most generic of the two is the
                              <literal>org.jboss.security.auth.spi.AbstractServerLoginModule</literal> class. It provides
                          a concrete implementation of the <literal>javax.security.auth.spi.LoginModule</literal>
                          interface and offers abstract methods for the key tasks specific to an operation environment
                          security infrastructure. The key details of the class are highlighted in the following class
                          fragment. The JavaDoc comments detail the responsibilities of subclasses.</para>
                      <programlisting>package org.jboss.security.auth.spi;
  /**
   *  This class implements the common functionality required for a JAAS
   *  server-side LoginModule and implements the JBossSX standard
   *  Subject usage pattern of storing identities and roles. Subclass
   *  this module to create your own custom LoginModule and override the
   *  login(), getRoleSets(), and getIdentity() methods.
   */
  public abstract class AbstractServerLoginModule
      implements javax.security.auth.spi.LoginModule
  {
      protected Subject subject;
      protected CallbackHandler callbackHandler;
      protected Map sharedState;
      protected Map options;
      protected Logger log;
  
      /** Flag indicating if the shared credential should be used */
      protected boolean useFirstPass;
      /** 
       * Flag indicating if the login phase succeeded. Subclasses that
       * override the login method must set this to true on successful
       * completion of login
       */
      protected boolean loginOk;
                  
      // ...
      /**
       * Initialize the login module. This stores the subject,
       * callbackHandler and sharedState and options for the login
       * session. Subclasses should override if they need to process
       * their own options. A call to super.initialize(...)  must be
       * made in the case of an override.
       *
       * &lt;p&gt;
       * The options are checked for the  &lt;em&gt;password-stacking&lt;/em&gt; parameter.
       * If this is set to "useFirstPass", the login identity will be taken from the
       * &lt;code&gt;javax.security.auth.login.name&lt;/code&gt; value of the sharedState map,
       * and the proof of identity from the
       * &lt;code&gt;javax.security.auth.login.password&lt;/code&gt; value of the sharedState map.
       *
       * @param subject the Subject to update after a successful login.
       * @param callbackHandler the CallbackHandler that will be used to obtain the
       * the user identity and credentials.
       * @param sharedState a Map shared between all configured login module instances
       * @param options the parameters passed to the login module.
       */
      public void initialize(Subject subject,
                             CallbackHandler callbackHandler,
                             Map sharedState,
                             Map options)
      {
          // ...
      }
      
  
      /**
       *  Looks for javax.security.auth.login.name and
       *  javax.security.auth.login.password values in the sharedState
       *  map if the useFirstPass option was true and returns true if
       *  they exist. If they do not or are null this method returns
       *  false.  
       *  Note that subclasses that override the login method
       *  must set the loginOk var to true if the login succeeds in
       *  order for the commit phase to populate the Subject. This
       *  implementation sets loginOk to true if the login() method
       *  returns true, otherwise, it sets loginOk to false.
       */
      public boolean login() 
          throws LoginException
      {
          // ...
      }
      
      /**
       *  Overridden by subclasses to return the Principal that
       *  corresponds to the user primary identity.
       */
      abstract protected Principal getIdentity();
                  
      /**
       *  Overridden by subclasses to return the Groups that correspond
       *  to the role sets assigned to the user. Subclasses should
       *  create at least a Group named "Roles" that contains the roles
       *  assigned to the user.  A second common group is
       *  "CallerPrincipal," which provides the application identity of
       *  the user rather than the security domain identity.
       * 
       *  @return Group[] containing the sets of roles
       */
      abstract protected Group[] getRoleSets() throws LoginException;
  }</programlisting>
                      <para>You'll need to pay attention to the <literal>loginOk</literal> instance variable. This must be
                          set to true if the login succeeds, false otherwise by any subclasses that override the login
                          method. Failure to set this variable correctly will result in the commit method either not
                          updating the subject when it should, or updating the subject when it should not. Tracking the
                          outcome of the login phase was added to allow login modules to be chained together with control
                          flags that do not require that the login module succeed in order for the overall login to
                          succeed.</para>
                      <para>The second abstract base login module suitable for custom login modules is the
                              <literal>org.jboss.security.auth.spi.UsernamePasswordLoginModule</literal>. This login
                          module further simplifies custom login module implementation by enforcing a string-based
                          username as the user identity and a <literal>char[]</literal> password as the authentication
                          credentials. It also supports the mapping of anonymous users (indicated by a null username and
                          password) to a principal with no roles. The key details of the class are highlighted in the
                          following class fragment. The JavaDoc comments detail the responsibilities of subclasses.</para>
                      <programlisting>package org.jboss.security.auth.spi;
  
  /**
   *  An abstract subclass of AbstractServerLoginModule that imposes a
   *  an identity == String username, credentials == String password
   *  view on the login process. Subclasses override the
   *  getUsersPassword() and getUsersRoles() methods to return the
   *  expected password and roles for the user.
   */
  public abstract class UsernamePasswordLoginModule
      extends AbstractServerLoginModule
  {
      /** The login identity */
      private Principal identity;
      /** The proof of login identity */
      private char[] credential;
      /** The principal to use when a null username and password are seen */
      private Principal unauthenticatedIdentity;
  
      /**
       * The message digest algorithm used to hash passwords. If null then
       * plain passwords will be used. */
      private String hashAlgorithm = null;
  
      /**
       *  The name of the charset/encoding to use when converting the
       * password String to a byte array. Default is the platform's
       * default encoding.
       */
       private String hashCharset = null;
  
      /** The string encoding format to use. Defaults to base64. */
      private String hashEncoding = null;
                  
      // ...
                  
      /** 
       *  Override the superclass method to look for an
       *  unauthenticatedIdentity property. This method first invokes
       *  the super version.
       *
       *  @param options,
       *  @option unauthenticatedIdentity: the name of the principal to
       *  assign and authenticate when a null username and password are
       *  seen.
       */
      public void initialize(Subject subject,
                             CallbackHandler callbackHandler,
                             Map sharedState,
                             Map options)
      {
          super.initialize(subject, callbackHandler, sharedState,
                           options);
          // Check for unauthenticatedIdentity option.
          Object option = options.get("unauthenticatedIdentity");
          String name = (String) option;
          if (name != null) {
              unauthenticatedIdentity = new SimplePrincipal(name);
          }
      }
                  
      // ...
                  
      /**
       *  A hook that allows subclasses to change the validation of the
       *  input password against the expected password. This version
       *  checks that neither inputPassword or expectedPassword are null
       *  and that inputPassword.equals(expectedPassword) is true;
       *
       *  @return true if the inputPassword is valid, false otherwise.
       */
      protected boolean validatePassword(String inputPassword,
                                         String expectedPassword)
      {
          if (inputPassword == null || expectedPassword == null) {
              return false;
          }
          return inputPassword.equals(expectedPassword);
      }
      
      /**
       *  Get the expected password for the current username available
       * via the getUsername() method. This is called from within the
       * login() method after the CallbackHandler has returned the
       * username and candidate password.
       *
       * @return the valid password String
       */
      abstract protected String getUsersPassword()
          throws LoginException;
  }</programlisting>
                      <para>The choice of subclassing the <literal>AbstractServerLoginModule</literal> versus
                              <literal>UsernamePasswordLoginModule</literal> is simply based on whether a string-based
                          username and credentials are usable for the authentication technology you are writing the login
                          module for. If the string-based semantic is valid, then subclass
                              <literal>UsernamePasswordLoginModule</literal>, otherwise subclass
                              <literal>AbstractServerLoginModule</literal>.</para>
                      <para>The steps you are required to perform when writing a custom login module are summarized in the
                          following depending on which base login module class you choose. When writing a custom login
                          module that integrates with your security infrastructure, you should start by subclassing
                              <literal>AbstractServerLoginModule</literal> or
                          <literal>UsernamePasswordLoginModule</literal> to ensure that your login module provides the
                          authenticated <literal>Principal</literal> information in the form expected by the JBossSX
                          security manager.</para>
                      <para>When subclassing the <literal>AbstractServerLoginModule</literal>, you need to override the
                          following:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <literal>void initialize(Subject, CallbackHandler, Map, Map)</literal>: if you have
                                  custom options to parse.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <literal>boolean login()</literal>: to perform the authentication activity. Be sure to
                                  set the <literal>loginOk</literal> instance variable to true if login succeeds, false if
                                  it fails.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <literal>Principal getIdentity()</literal>: to return the <literal>Principal</literal>
                                  object for the user authenticated by the <literal>log()</literal> step.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <literal>Group[] getRoleSets()</literal>: to return at least one
                                  <literal>Group</literal> named <literal>Roles</literal> that contains the roles assigned
                                  to the <literal>Principal</literal> authenticated during <literal>login()</literal>. A
                                  second common <literal>Group</literal> is named <literal>CallerPrincipal</literal> and
                                  provides the user's application identity rather than the security domain
                              identity.</para>
                          </listitem>
                      </itemizedlist>
                      <para>When subclassing the <literal>UsernamePasswordLoginModule</literal>, you need to override the
                          following:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <literal>void initialize(Subject, CallbackHandler, Map, Map)</literal>: if you have
                                  custom options to parse.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <literal>Group[] getRoleSets()</literal>: to return at least one
                                  <literal>Group</literal> named <literal>Roles</literal> that contains the roles assigned
                                  to the <literal>Principal</literal> authenticated during <literal>login()</literal>. A
                                  second common <literal>Group</literal> is named <literal>CallerPrincipal</literal> and
                                  provides the user's application identity rather than the security domain
                              identity.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <literal>String getUsersPassword()</literal>: to return the expected password for the
                                  current username available via the <literal>getUsername()</literal> method. The
                                      <literal>getUsersPassword()</literal> method is called from within
                                  <literal>login()</literal> after the <literal>callbackhandler</literal> returns the
                                  username and candidate password.</para>
                          </listitem>
                      </itemizedlist>
                  </section>
                  <section>
                      <title>A Custom LoginModule Example</title>
                      <para>In this section we will develop a custom login module example. It will extend the
                              <literal>UsernamePasswordLoginModule</literal> and obtains a user's password and role names
                          from a JNDI lookup. The idea is that there is a JNDI context that will return a user's password
                          if you perform a lookup on the context using a name of the form
                              <literal>password/&lt;username&gt;</literal> where
                          <literal>&lt;username&gt;</literal> is the current user being authenticated. Similarly,
                          a lookup of the form <literal>roles/&lt;username&gt;</literal> returns the requested
                          user's roles.</para>
                      <para>The source code for the example is located in the
                          <literal>src/main/org/jboss/chap8/ex2</literal> directory of the book examples. <xref
                              linkend="ch8.jndiuser.ex"/> shows the source code for the <literal>JndiUserAndPass</literal>
                          custom login module. Note that because this extends the JBoss
                              <literal>UsernamePasswordLoginModule</literal>, all the <literal>JndiUserAndPass</literal>
                          does is obtain the user's password and roles from the JNDI store. The
                          <literal>JndiUserAndPass</literal> does not concern itself with the JAAS
                          <literal>LoginModule</literal> operations.</para>
                      <example id="ch8.jndiuser.ex">
                          <title> A JndiUserAndPass custom login module</title>
                          <programlisting>package org.jboss.chap8.ex2;
                      
  import java.security.acl.Group;
  import java.util.Map;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  import javax.security.auth.Subject;
  import javax.security.auth.callback.CallbackHandler;
  import javax.security.auth.login.LoginException;
  
  import org.jboss.security.SimpleGroup;
  import org.jboss.security.SimplePrincipal;
  import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
  
  /** 
   *  An example custom login module that obtains passwords and roles
   *  for a user from a JNDI lookup.
   *     
   *  @author Scott.Stark at jboss.org
   *  @version $Revision: 1.1 $
  */
  public class JndiUserAndPass 
      extends UsernamePasswordLoginModule
  {
      /** The JNDI name to the context that handles the password/username lookup */
      private String userPathPrefix;
      /** The JNDI name to the context that handles the roles/ username lookup */
      private String rolesPathPrefix;
      
      /**
       * Override to obtain the userPathPrefix and rolesPathPrefix options.
       */
      public void initialize(Subject subject, CallbackHandler callbackHandler,
                             Map sharedState, Map options)
      {
          super.initialize(subject, callbackHandler, sharedState, options);
          userPathPrefix = (String) options.get("userPathPrefix");
          rolesPathPrefix = (String) options.get("rolesPathPrefix");
      }
      
      /**
       *  Get the roles the current user belongs to by querying the
       * rolesPathPrefix + '/' + super.getUsername() JNDI location.
       */
      protected Group[] getRoleSets() throws LoginException
      {
          try {
              InitialContext ctx = new InitialContext();
              String rolesPath = rolesPathPrefix + '/' + super.getUsername();
  
              String[] roles = (String[]) ctx.lookup(rolesPath);
              Group[] groups = {new SimpleGroup("Roles")};
              log.info("Getting roles for user="+super.getUsername());
              for(int r = 0; r &lt; roles.length; r ++) {
                  SimplePrincipal role = new SimplePrincipal(roles[r]);
                  log.info("Found role="+roles[r]);
                  groups[0].addMember(role);
              }
              return groups;
          } catch(NamingException e) {
              log.error("Failed to obtain groups for
                          user="+super.getUsername(), e);
              throw new LoginException(e.toString(true));
          }
      }
                      
      /** 
       * Get the password of the current user by querying the
       * userPathPrefix + '/' + super.getUsername() JNDI location.
       */
      protected String getUsersPassword() 
          throws LoginException
      {
          try {
              InitialContext ctx = new InitialContext();
              String userPath = userPathPrefix + '/' + super.getUsername();
              log.info("Getting password for user="+super.getUsername());
              String passwd = (String) ctx.lookup(userPath);
              log.info("Found password="+passwd);
              return passwd;
          } catch(NamingException e) {
              log.error("Failed to obtain password for
                          user="+super.getUsername(), e);
              throw new LoginException(e.toString(true));
          }
      }   
  }</programlisting>
                      </example>
                      <para>The details of the JNDI store are found in the
                          <literal>org.jboss.chap8.ex2.service.JndiStore</literal> MBean. This service binds an
                              <literal>ObjectFactory</literal> that returns a <literal>javax.naming.Context</literal>
                          proxy into JNDI. The proxy handles lookup operations done against it by checking the prefix of
                          the lookup name against <literal>password</literal> and <literal>roles</literal>. When the name
                          begins with <literal>password</literal>, a user's password is being requested. When the name
                          begins with <literal>roles</literal> the user's roles are being requested. The example
                          implementation always returns a password of <literal>theduke</literal> and an array of roles
                          names equal to <literal>{"TheDuke", "Echo"}</literal> regardless of what the username is. You
                          can experiment with other implementations as you wish.</para>
                      <para>The example code includes a simple session bean for testing the custom login module. To build,
                          deploy and run the example, execute the following command in the examples directory.</para>
                      <programlisting>[examples]$ ant -Dchap=chap8 -Dex=2 run-example
  ...
  run-example2:
       [copy] Copying 1 file to /tmp/jboss-4.0.1/server/default/deploy
       [echo] Waiting for 5 seconds for deploy...
       [java] [INFO,ExClient] Login with username=jduke, password=theduke
       [java] [INFO,ExClient] Looking up EchoBean2
       [java] [INFO,ExClient] Created Echo
       [java] [INFO,ExClient] Echo.echo('Hello') = Hello</programlisting>
                      <programlisting>19:06:13,266 INFO  [EjbModule] Deploying EchoBean2
  19:06:13,482 INFO  [JndiStore] Start, bound security/store
  19:06:13,486 INFO  [SecurityConfig] Using JAAS AuthConfig: jar:file:/private/tmp/jboss-4.0.1/
  server/default/tmp/deploy/tmp23012chap8-ex2.jar-contents/chap8-ex2.sar!/META-INF/login-config
  .xml
  19:06:13,654 INFO  [EJBDeployer] Deployed: file:/private/tmp/jboss-4.0.1/server/default/deplo
  y/chap8-ex2.jar</programlisting>
                      <para>The choice of using the <literal>JndiUserAndPass</literal> custom login module for the server
                          side authentication of the user is determined by the login configuration for the example
                          security domain. The EJB JAR <literal>META-INF/jboss.xml</literal> descriptor sets the security
                          domain </para>
                      <programlisting>&lt;?xml version="1.0"?&gt;
  &lt;jboss&gt;
      &lt;security-domain&gt;java:/jaas/chap8-ex2&lt;/security-domain&gt;
  &lt;/jboss&gt;</programlisting>
                      <para>The SAR <literal>META-INF/login-config.xml</literal> descriptor defines the login module
                          configuration.</para>
                      <programlisting>&lt;application-policy name = "chap8-ex2"&gt;
      &lt;authentication&gt;
          &lt;login-module code="org.jboss.chap8.ex2.JndiUserAndPass"
                        flag="required"&gt;
              &lt;module-option name = "userPathPrefix"&gt;/security/store/password&lt;/module-option&gt;
              &lt;module-option name = "rolesPathPrefix"&gt;/security/store/roles&lt;/module-option&gt;
          &lt;/login-module&gt;
      &lt;/authentication&gt;
  &lt;/application-policy&gt;</programlisting>
                  </section>
              </section>
          </section>
  
  
          <section id="ch8.srp.sect">
              <title>The Secure Remote Password (SRP) Protocol</title>
              <para>The SRP protocol is an implementation of a public key exchange handshake described in the Internet
                  standards working group request for comments 2945(RFC2945). The RFC2945 abstract states:</para>
              <para>This document describes a cryptographically strong network authentication mechanism known as the
                  Secure Remote Password (SRP) protocol. This mechanism is suitable for negotiating secure connections
                  using a user-supplied password, while eliminating the security problems traditionally associated with
                  reusable passwords. This system also performs a secure key exchange in the process of authentication,
                  allowing security layers (privacy and/or integrity protection) to be enabled during the session. Trusted
                  key servers and certificate infrastructures are not required, and clients are not required to store or
                  manage any long-term keys. SRP offers both security and deployment advantages over existing
                  challenge-response techniques, making it an ideal drop-in replacement where secure password
                  authentication is needed.</para>
              <para>Note: The complete RFC2945 specification can be obtained from <ulink
                      url="http://www.rfc-editor.org/rfc.html"/>. Additional information on the SRP algorithm and its
                  history can be found at <ulink url="http://www-cs-students.stanford.edu/~tjw/srp/"/>.</para>
              <para>SRP is similar in concept and security to other public key exchange algorithms, such as Diffie-Hellman
                  and RSA. SRP is based on simple string passwords in a way that does not require a clear text password to
                  exist on the server. This is in contrast to other public key-based algorithms that require client
                  certificates and the corresponding certificate management infrastructure.</para>
              <para>Algorithms like Diffie-Hellman and RSA are known as public key exchange algorithms. The concept of
                  public key algorithms is that you have two keys, one public that is available to everyone, and one that
                  is private and known only to you. When someone wants to send encrypted information to you, then encrpyt
                  the information using your public key. Only you are able to decrypt the information using your private
                  key. Contrast this with the more traditional shared password based encryption schemes that require the
                  sender and receiver to know the shared password. Public key algorithms eliminate the need to share
                  passwords. </para>
              <para>The JBossSX framework includes an implementation of SRP that consists of the following elements:</para>
              <itemizedlist>
                  <listitem>
                      <para>An implementation of the SRP handshake protocol that is independent of any particular
                          client/server protocol</para>
                  </listitem>
                  <listitem>
                      <para>An RMI implementation of the handshake protocol as the default client/server SRP
                          implementation</para>
                  </listitem>
                  <listitem>
                      <para>A client side JAAS <literal>LoginModule</literal> implementation that uses the RMI
                          implementation for use in authenticating clients in a secure fashion</para>
                  </listitem>
                  <listitem>
                      <para>A JMX MBean for managing the RMI server implementation. The MBean allows the RMI server
                          implementation to be plugged into a JMX framework and externalizes the configuration of the
                          verification information store. It also establishes an authentication cache that is bound into
                          the JBoss server JNDI namespace.</para>
                  </listitem>
                  <listitem>
                      <para>A server side JAAS <literal>LoginModule</literal> implementation that uses the authentication
                          cache managed by the SRP JMX MBean.</para>
                  </listitem>
              </itemizedlist>
              <para>
                  <xref linkend="ch8.srpcomp.fig"/> gives a diagram of the key components involved in the JBossSX
                  implementation of the SRP client/server framework.</para>
              <figure id="ch8.srpcomp.fig">
                  <title>The JBossSX components of the SRP client-server framework.</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/Chap8-13.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>On the client side, SRP shows up as a custom JAAS <literal>LoginModule</literal> implementation that
                  communicates to the authentication server through an
                  <literal>org.jboss.security.srp.SRPServerInterface</literal> proxy. A client enables authentication
                  using SRP by creating a login configuration entry that includes the
                      <literal>org.jboss.security.srp.jaas.SRPLoginModule</literal>. This module supports the following
                  configuration options:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">principalClassName</emphasis>: This option is no longer supported. The
                          principal class is now always
                      <literal>org.jboss.security.srp.jaas.SRPPrincipal</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">srpServerJndiName</emphasis>: The JNDI name of the
                              <literal>SRPServerInterface</literal> object to use for communicating with the SRP
                          authentication server. If both <literal>srpServerJndiName</literal> and
                          <literal>srpServerRmiUrl</literal> options are specified, the
                          <literal>srpServerJndiName</literal> is tried before <literal>srpServerRmiUrl</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">srpServerRmiUrl</emphasis>: The RMI protocol URL string for the location
                          of the <literal>SRPServerInterface</literal> proxy to use for communicating with the SRP
                          authentication server.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">externalRandomA</emphasis>: A true/false flag indicating if the random
                          component of the client public key A should come from the user callback. This can be used to
                          input a strong cryptographic random number coming from a hardware token for example.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">hasAuxChallenge</emphasis>: A true/false flag indicating that a string
                          will be sent to the server as an additional challenge for the server to validate. If the client
                          session supports an encryption cipher then a temporary cipher will be created using the session
                          private key and the challenge object sent as a
                      <literal>javax.crypto.SealedObject</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">multipleSessions</emphasis>: a true/false flag indicating if a given
                          client may have multiple SRP login sessions active simultaneously.</para>
                  </listitem>
              </itemizedlist>
              <para>Any other options passed in that do not match one of the previous named options is treated as a JNDI
                  property to use for the environment passed to the <literal>InitialContext</literal> constructor. This is
                  useful if the SRP server interface is not available from the default <literal>InitialContext</literal>.</para>
              <para>The <literal>SRPLoginModule</literal> needs to be configured along with the standard
                      <literal>ClientLoginModule</literal> to allow the SRP authentication credentials to be used for
                  validation of access to security J2EE components. An example login configuration entry that demonstrates
                  such a setup is:</para>
              <programlisting>srp {
      org.jboss.security.srp.jaas.SRPLoginModule required
      srpServerJndiName="SRPServerInterface"
      ;
              
      org.jboss.security.ClientLoginModule required
      password-stacking="useFirstPass"
      ;
  };  </programlisting>
              <para>On the JBoss server side, there are two MBeans that manage the objects that collectively make up the
                  SRP server. The primary service is the <literal>org.jboss.security.srp.SRPService</literal> MBean, and
                  it is responsible for exposing an RMI accessible version of the SRPServerInterface as well as updating
                  the SRP authentication session cache. The configurable SRPService MBean attributes include the
                  following:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">JndiName</emphasis>: The JNDI name from which the SRPServerInterface proxy
                          should be available. This is the location where the <literal>SRPService</literal> binds the
                          serializable dynamic proxy to the <literal>SRPServerInterface</literal>. If not specified it
                          defaults to <literal>srp/SRPServerInterface</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">VerifierSourceJndiName</emphasis>: The JNDI name of the
                              <literal>SRPVerifierSource</literal> implementation that should be used by the
                              <literal>SRPService</literal>. If not set it defaults to
                          <literal>srp/DefaultVerifierSource</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">AuthenticationCacheJndiName</emphasis>: The JNDI name under which the
                          authentication <literal>org.jboss.util.CachePolicy</literal> implementation to be used for
                          caching authentication information is bound. The SRP session cache is made available for use
                          through this binding. If not specified it defaults to
                          <literal>srp/AuthenticationCache</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">ServerPort</emphasis>: RMI port for the
                          <literal>SRPRemoteServerInterface</literal>. If not specified it defaults to 10099.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">ClientSocketFactory</emphasis>: An optional custom
                              <literal>java.rmi.server.RMIClientSocketFactory</literal> implementation class name used
                          during the export of the <literal>SRPServerInterface</literal>. If not specified the default
                              <literal>RMIClientSocketFactory</literal> is used.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">ServerSocketFactory</emphasis>: An optional custom
                              <literal>java.rmi.server.RMIServerSocketFactory</literal> implementation class name used
                          during the export of the <literal>SRPServerInterface</literal>. If not specified the default
                              <literal>RMIServerSocketFactory</literal> is used.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">AuthenticationCacheTimeout</emphasis>: Specifies the timed cache policy
                          timeout in seconds. If not specified this defaults to 1800 seconds(30 minutes).</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">AuthenticationCacheResolution</emphasis>: Specifies the timed cache policy
                          resolution in seconds. This controls the interval between checks for timeouts. If not specified
                          this defaults to 60 seconds(1 minute).</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">RequireAuxChallenge</emphasis>: Set if the client must supply an auxiliary
                          challenge as part of the verify phase. This gives control over whether the
                              <literal>SRPLoginModule</literal> configuration used by the client must have the
                              <literal>useAuxChallenge</literal> option enabled.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">OverwriteSessions</emphasis>: A flag indicating if a successful user auth
                          for an existing session should overwrite the current session. This controls the behavior of the
                          server SRP session cache when clients have not enabled the multiple session per user mode. The
                          default is false meaning that the second attempt by a user to authentication will succeed, but
                          the resulting SRP session will not overwrite the previous SRP session state.</para>
                  </listitem>
              </itemizedlist>
              <para>The one input setting is the <literal>VerifierSourceJndiName</literal> attribute. This is the location
                  of the SRP password information store implementation that must be provided and made available through
                  JNDI. The <literal>org.jboss.security.srp SRPVerifierStoreService</literal> is an example MBean service
                  that binds an implementation of the <literal>SRPVerifierStore</literal> interface that uses a file of
                  serialized objects as the persistent store. Although not realistic for a production environment, it does
                  allow for testing of the SRP protocol and provides an example of the requirements for an
                      <literal>SRPVerifierStore</literal> service. The configurable
                  <literal>SRPVerifierStoreService</literal> MBean attributes include the following:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">JndiName</emphasis>: The JNDI name from which the
                              <literal>SRPVerifierStore</literal> implementation should be available. If not specified it
                          defaults to <literal>srp/DefaultVerifierSource</literal>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">StoreFile</emphasis>: The location of the user password verifier
                          serialized object store file. This can be either a URL or a resource name to be found in the
                          classpath. If not specified it defaults to <literal>SRPVerifierStore.ser</literal>.</para>
                  </listitem>
              </itemizedlist>
              <para>The <literal>SRPVerifierStoreService</literal> MBean also supports <literal>addUser</literal> and
                      <literal>delUser</literal> operations for addition and deletion of users. The signatures are:</para>
              <programlisting>public void addUser(String username, String password) throws IOException;
  public void delUser(String username) throws IOException;</programlisting>
              <para>An example configuration of these services is presented in <xref linkend="ch8.srp.sect"/>.</para>
              <section>
                  <title>Providing Password Information for SRP</title>
                  <para>The default implementation of the <literal>SRPVerifierStore</literal> interface is not likely to
                      be suitable for you production security environment as it requires all password hash information to
                      be available as a file of serialized objects. You need to provide an MBean service that provides an
                      implementation of the <literal>SRPVerifierStore</literal> interface that integrates with your
                      existing security information stores. The <literal>SRPVerifierStore</literal> interface is shown in.</para>
                  <example>
                      <title>The SRPVerifierStore interface</title>
                      <programlisting>package org.jboss.security.srp;
  
  import java.io.IOException;
  import java.io.Serializable;
  import java.security.KeyException;
  
  public interface SRPVerifierStore
  {
      public static class VerifierInfo implements Serializable
      {
          /**
           * The username the information applies to. Perhaps redundant
           * but it makes the object self contained.
           */
          public String username;
  
          /** The SRP password verifier hash */
          public byte[] verifier;
          /** The random password salt originally used to verify the password */
          public byte[] salt;
          /** The SRP algorithm primitive generator */
          public byte[] g;
          /** The algorithm safe-prime modulus */
          public byte[] N;
      }
      
      /**
       *  Get the indicated user's password verifier information.
       */
      public VerifierInfo getUserVerifier(String username)
          throws KeyException, IOException;
      /** 
       *  Set the indicated users' password verifier information. This
       *  is equivalent to changing a user's password and should
       *  generally invalidate any existing SRP sessions and caches.
       */
      public void setUserVerifier(String username, VerifierInfo info)
          throws IOException;
  
      /** 
       * Verify an optional auxiliary challenge sent from the client to
       * the server.  The auxChallenge object will have been decrypted
       * if it was sent encrypted from the client. An example of a
       * auxiliary challenge would be the validation of a hardware token
       * (SafeWord, SecureID, iButton) that the server validates to
       * further strengthen the SRP password exchange.
       */
       public void verifyUserChallenge(String username, Object auxChallenge)
           throws SecurityException;
  } </programlisting>
                      <para>The primary function of a <literal>SRPVerifierStore</literal> implementation is to provide
                          access to the <literal>SRPVerifierStore.VerifierInfo</literal> object for a given username. The
                              <literal>getUserVerifier(String)</literal> method is called by the
                          <literal>SRPService</literal> at that start of a user SRP session to obtain the parameters
                          needed by the SRP algorithm. The elements of the <literal>VerifierInfo</literal> objects are:</para>
                      <itemizedlist>
                          <listitem>
                              <para>
                                  <emphasis role="bold">username</emphasis>: The user's name or id used to login.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">verifier</emphasis>: This is the one-way hash of the password or
                                  PIN the user enters as proof of their identity. The
                                  <literal>org.jboss.security.Util</literal> class has a
                                  <literal>calculateVerifier</literal> method that performs that password hashing
                                  algorithm. The output password <literal>H(salt | H(username | ':' | password))</literal>
                                  as defined by RFC2945. Here <literal>H</literal> is the SHA secure hash function. The
                                  username is converted from a string to a <literal>byte[]</literal> using the UTF-8
                                  encoding.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">salt</emphasis>: This is a random number used to increase the
                                  difficulty of a brute force dictionary attack on the verifier password database in the
                                  event that the database is compromised. It is a value that should be generated from a
                                  cryptographically strong random number algorithm when the user's existing clear-text
                                  password is hashed.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">g</emphasis>: The SRP algorithm primitive generator. In general
                                  this can be a well known fixed parameter rather than a per-user setting. The
                                      <literal>org.jboss.security.srp.SRPConf</literal> utility class provides several
                                  settings for g including a good default which can obtained via
                                      <literal>SRPConf.getDefaultParams().g()</literal>.</para>
                          </listitem>
                          <listitem>
                              <para>
                                  <emphasis role="bold">N</emphasis>: The SRP algorithm safe-prime modulus. In general
                                  this can be a well known fixed parameter rather than a per-user setting. The
                                      <literal>org.jboss.security.srp.SRPConf</literal> utility class provides several
                                  settings for <literal>N</literal> including a good default which can obtained via
                                      <literal>SRPConf.getDefaultParams().N()</literal>.</para>
                          </listitem>
                      </itemizedlist>
                      <para>So, step 1 of integrating your existing password store is the creation of a hashed version of
                          the password information. If your passwords are already store in an irreversible hashed form,
                          then this can only be done on a per-user basis as part of an upgrade procedure for example. Note
                          that the <literal>setUserVerifier(String, VerifierInfo)</literal> method is not used by the
                          current SRPSerivce and may be implemented as no-op method, or even one that throws an exception
                          stating that the store is read-only.</para>
                      <para>Step 2 is the creation of the custom <literal>SRPVerifierStore</literal> interface
                          implementation that knows how to obtain the <literal>VerifierInfo</literal> from the store you
                          created in step 1. The <literal>verifyUserChallenge(String, Object)</literal> method of the
                          interface is only called if the client <literal>SRPLoginModule</literal> configuration specifies
                          the <literal>hasAuxChallenge</literal> option. This can be used to integrate existing hardware
                          token based schemes like SafeWord or Radius into the SRP algorithm.</para>
                      <para>Step 3 is the creation of an MBean that makes the step 2 implementation of the
                              <literal>SRPVerifierStore</literal> interface available via JNDI, and exposes any
                          configurable parameters you need. In addition to the default
                              <literal>org.jboss.security.srp.SRPVerifierStoreService</literal> example, the SRP example
                          presented later in this chapter provides a Java properties file based
                          <literal>SRPVerifierStore</literal> implementation. Between the two examples you should have
                          enough to integrate your security store.</para>
                  </example>
              </section>
              <section>
                  <title>Inside of the SRP algorithm</title>
                  <para>The appeal of the SRP algorithm is that is allows for mutual authentication of client and server
                      using simple text passwords without a secure communication channel. You might be wondering how this
                      is done.
                      <!--
                  <xref linkend="ch8.srpseq.fig"/> presents a
                  sequence diagram of the authentication protocol as implemented
                  by JBossSX.</para>
              <figure id="ch8.srpseq.fig">
                  <title>The SRP client-server authentication algorithm sequence diagram.</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/XXX.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para>The highlights of what is taking place for the key message
                  exchanges presented in <xref linkend="ch8.srpseq.fig"/> are as
                  follows.
                  
  -->
                      If you want the complete details and theory behind the algorithm, refer to the SRP references
                      mentioned in a note earlier. There are six steps that are performed to complete authentication:</para>
                  <orderedlist>
                      <listitem>
                          <para>The client side <literal>SRPLoginModule</literal> retrieves the SRPServerInterface
                              instance for the remote authentication server from the naming service.</para>
                      </listitem>
                      <listitem>
                          <para>The client side <literal>SRPLoginModule</literal> next requests the SRP parameters
                              associated with the username attempting the login. There are a number of parameters involved
                              in the SRP algorithm that must be chosen when the user password is first transformed into
                              the verifier form used by the SRP algorithm. Rather than hard-coding the parameters (which
                              could be done with minimal security risk), the JBossSX implementation allows a user to
                              retrieve this information as part of the exchange protocol. The
                                  <literal>getSRPParameters(username)</literal> call retrieves the SRP parameters for the
                              given username.</para>
                      </listitem>
                      <listitem>
                          <para>The client side <literal>SRPLoginModule</literal> begins an SRP session by creating an
                                  <literal>SRPClientSession</literal> object using the login username, clear-text
                              password, and SRP parameters obtained from step 2. The client then creates a random number A
                              that will be used to build the private SRP session key. The client then initializes the
                              server side of the SRP session by invoking the <literal>SRPServerInterface.init</literal>
                              method and passes in the username and client generated random number <literal>A</literal>.
                              The server returns its own random number <literal>B</literal>. This step corresponds to the
                              exchange of public keys.</para>
                      </listitem>
                      <listitem>
                          <para>The client side <literal>SRPLoginModule</literal> obtains the private SRP session key that
                              has been generated as a result of the previous messages exchanges. This is saved as a
                              private credential in the login <literal>Subject</literal>. The server challenge response
                                  <literal>M2</literal> from step 4 is verified by invoking the
                                  <literal>SRPClientSession.verify</literal> method. If this succeeds, mutual
                              authentication of the client to server, and server to client have been completed. The client
                              side <literal>SRPLoginModule</literal> next creates a challenge <literal>M1</literal> to the
                              server by invoking <literal>SRPClientSession.response</literal> method passing the server
                              random number <literal>B</literal> as an argument. This challenge is sent to the server via
                              the <literal>SRPServerInterface.verify</literal> method and server's response is saved as
                                  <literal>M2</literal>. This step corresponds to an exchange of challenges. At this point
                              the server has verified that the user is who they say they are.</para>
                      </listitem>
                      <listitem>
                          <para>The client side <literal>SRPLoginModule</literal> saves the login username and
                              <literal>M1</literal> challenge into the <literal>LoginModule</literal> sharedState map.
                              This is used as the Principal name and credentials by the standard JBoss
                                  <literal>ClientLoginModule</literal>. The <literal>M1</literal> challenge is used in
                              place of the password as proof of identity on any method invocations on J2EE components. The
                                  <literal>M1</literal> challenge is a cryptographically strong hash associated with the
                              SRP session. Its interception via a third partly cannot be used to obtain the user's
                              password.</para>
                      </listitem>
                      <listitem>
                          <para>At the end of this authentication protocol, the SRPServerSession has been placed into the
                              SRPService authentication cache for subsequent use by the
                              <literal>SRPCacheLoginModule</literal>.</para>
                      </listitem>
                  </orderedlist>
                  <para>Although SRP has many interesting properties, it is still an evolving component in the JBossSX
                      framework and has some limitations of which you should be aware. Issues of note include the
                      following:</para>
                  <itemizedlist>
                      <listitem>
                          <para>Because of how JBoss detaches the method transport protocol from the component container
                              where authentication is performed, an unauthorized user could snoop the SRP
                              <literal>M1</literal> challenge and effectively use the challenge to make requests as the
                              associated username. Custom interceptors that encrypt the challenge using the SRP session
                              key can be used to prevent this issue.</para>
                      </listitem>
                      <listitem>
                          <para>The SRPService maintains a cache of SRP sessions that time out after a configurable
                              period. Once they time out, any subsequent J2EE component access will fail because there is
                              currently no mechanism for transparently renegotiating the SRP authentication credentials.
                              You must either set the authentication cache timeout very long (up to 2,147,483,647 seconds,
                              or approximately 68 years), or handle re-authentication in your code on failure.</para>
                      </listitem>
                      <listitem>
                          <para>By default there can only be one SRP session for a given username. Because the negotiated
                              SRP session produces a private session key that can be used for encryption/decryption
                              between the client and server, the session is effectively a stateful one. JBoss supports for
                              multiple SRP sessions per user, but you cannot encrypt data with one session key and then
                              decrypt it with another.</para>
                      </listitem>
                  </itemizedlist>
                  <para>To use end-to-end SRP authentication for J2EE component calls, you need to configure the security
                      domain under which the components are secured to use the
                          <literal>org.jboss.security.srp.jaas.SRPCacheLoginModule</literal>. The
                          <literal>SRPCacheLoginModule</literal> has a single configuration option named
                          <literal>cacheJndiName</literal> that sets the JNDI location of the SRP authentication
                          <literal>CachePolicy</literal> instance. This must correspond to the
                          <literal>AuthenticationCacheJndiName</literal> attribute value of the
                      <literal>SRPService</literal> MBean. The <literal>SRPCacheLoginModule</literal> authenticates user
                      credentials by obtaining the client challenge from the <literal>SRPServerSession</literal> object in
                      the authentication cache and comparing this to the challenge passed as the user credentials. <xref
                          linkend="ch8.srpseq2.fig"/> illustrates the operation of the SRPCacheLoginModule.login method
                      implementation.</para>
                  <figure id="ch8.srpseq2.fig">
                      <title>A sequence diagram illustrating the interaction of the SRPCacheLoginModule with the SRP
                          session cache.</title>
                      <mediaobject>
                          <imageobject>
                              <imagedata align="center" fileref="images/Chap8-14.jpg"/>
                          </imageobject>
                      </mediaobject>
                  </figure>
                  <section>
                      <title>An SRP example</title>
                      <para>We have covered quite a bit of material on SRP and now its time to demonstrate SRP in practice
                          with an example. The example demonstrates client side authentication of the user via SRP as well
                          as subsequent secured access to a simple EJB using the SRP session challenge as the user
                          credential. The test code deploys an EJB JAR that includes a SAR for the configuration of the
                          server side login module configuration and SRP services. As in the previous examples we will
                          dynamically install the server side login module configuration using the
                          <literal>SecurityConfig</literal> MBean. In this example we also use a custom implementation of
                          the <literal>SRPVerifierStore</literal> interface that uses an in memory store that is seeded
                          from a Java properties file rather than a serialized object store as used by the
                              <literal>SRPVerifierStoreService</literal>. This custom service is
                              <literal>org.jboss.chap8.ex3.service.PropertiesVerifierStore</literal>. The following shows
                          the contents of the JAR that contains the example EJB and SRP services.</para>
                      <programlisting>[examples]$ java -cp output/classes ListJar output/chap8/chap8-ex3.jar
  output/chap8/chap8-ex3.jar
  +- META-INF/MANIFEST.MF
  +- META-INF/ejb-jar.xml
  +- META-INF/jboss.xml
  +- org/jboss/chap8/ex3/Echo.class
  +- org/jboss/chap8/ex3/EchoBean.class
  +- org/jboss/chap8/ex3/EchoHome.class
  +- roles.properties
  +- users.properties
  +- chap8-ex3.sar (archive)
  | +- META-INF/MANIFEST.MF
  | +- META-INF/jboss-service.xml
  | +- META-INF/login-config.xml
  | +- org/jboss/chap8/ex3/service/PropertiesVerifierStore$1.class
  | +- org/jboss/chap8/ex3/service/PropertiesVerifierStore.class
  | +- org/jboss/chap8/ex3/service/PropertiesVerifierStoreMBean.class
  | +- org/jboss/chap8/service/SecurityConfig.class
  | +- org/jboss/chap8/service/SecurityConfigMBean.class</programlisting>
                      <para>The key SRP related items in this example are the SRP MBean services configuration, and the
                          SRP login module configurations. The <literal>jboss-service.xml</literal> descriptor of the
                              <literal>chap8-ex3.sar</literal> is given in <xref linkend="ch8.ex3servicexml.ex"/>, while
                              <xref linkend="ch8.srpclientconf.ex"/> and <xref linkend="ch8.srpserverconf.ex"/> give the
                          example client side and server side login module configurations.</para>
                      <example id="ch8.ex3servicexml.ex">
                          <title>The chap8-ex3.sar jboss-service.xml descriptor for the SRP services</title>
                          <programlisting>&lt;server&gt;
      &lt;!-- The custom JAAS login configuration that installs
           a Configuration capable of dynamically updating the
           config settings --&gt;
  
      &lt;mbean code="org.jboss.chap8.service.SecurityConfig" 
             name="jboss.docs.chap8:service=LoginConfig-EX3"&gt;
          &lt;attribute name="AuthConfig"&gt;META-INF/login-config.xml&lt;/attribute&gt;
          &lt;attribute name="SecurityConfigName"&gt;jboss.security:name=SecurityConfig&lt;/attribute&gt;
      &lt;/mbean&gt;
  
      &lt;!-- The SRP service that provides the SRP RMI server and server side
           authentication cache --&gt;
      &lt;mbean code="org.jboss.security.srp.SRPService" 
             name="jboss.docs.chap8:service=SRPService"&gt;
          &lt;attribute name="VerifierSourceJndiName"&gt;srp-test/chap8-ex3&lt;/attribute&gt;
          &lt;attribute name="JndiName"&gt;srp-test/SRPServerInterface&lt;/attribute&gt;
          &lt;attribute name="AuthenticationCacheJndiName"&gt;srp-test/AuthenticationCache&lt;/attribute&gt;
          &lt;attribute name="ServerPort"&gt;0&lt;/attribute&gt;
          &lt;depends&gt;jboss.docs.chap8:service=PropertiesVerifierStore&lt;/depends&gt;
      &lt;/mbean&gt;
  
      &lt;!-- The SRP store handler service that provides the user password verifier
           information --&gt;
      &lt;mbean code="org.jboss.chap8.ex3.service.PropertiesVerifierStore"
             name="jboss.docs.chap8:service=PropertiesVerifierStore"&gt;
          &lt;attribute name="JndiName"&gt;srp-test/chap8-ex3&lt;/attribute&gt;
      &lt;/mbean&gt;
  &lt;/server&gt;</programlisting>
                      </example>
                      <example id="ch8.srpclientconf.ex">
                          <title>The client side standard JAAS configuration</title>
                          <programlisting>srp {
      org.jboss.security.srp.jaas.SRPLoginModule required
      srpServerJndiName="srp-test/SRPServerInterface"
      ;
                      
      org.jboss.security.ClientLoginModule required
      password-stacking="useFirstPass"
      ;
  }; </programlisting>
                      </example>
                      <example id="ch8.srpserverconf.ex">
                          <title>The server side XMLLoginConfig configuration</title>
                          <programlisting>&lt;application-policy name="chap8-ex3"&gt;
      &lt;authentication&gt;
          &lt;login-module code="org.jboss.security.srp.jaas.SRPCacheLoginModule"
                        flag = "required"&gt;
              &lt;module-option name="cacheJndiName"&gt;srp-test/AuthenticationCache&lt;/module-option&gt;
          &lt;/login-module&gt;
          &lt;login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
                        flag = "required"&gt;
              &lt;module-option name="password-stacking"&gt;useFirstPass&lt;/module-option&gt;
          &lt;/login-module&gt;
      &lt;/authentication&gt;
  &lt;/application-policy&gt;           </programlisting>
                      </example>
                      <para>The example services are the <literal>ServiceConfig</literal> and the
                              <literal>PropertiesVerifierStore</literal> and <literal>SRPService</literal> MBeans. Note
                          that the <literal>JndiName</literal> attribute of the <literal>PropertiesVerifierStore</literal>
                          is equal to the <literal>VerifierSourceJndiName</literal> attribute of the
                          <literal>SRPService</literal>, and that the <literal>SRPService</literal> depends on the
                              <literal>PropertiesVerifierStore</literal>. This is required because the
                          <literal>SRPService</literal> needs an implementation of the <literal>SRPVerifierStore</literal>
                          interface for accessing user password verification information.</para>
                      <para>The client side login module configuration makes use of the <literal>SRPLoginModule</literal>
                          with a <literal>srpServerJndiName</literal> option value that corresponds to the JBoss server
                          component <literal>SRPService</literal> JndiName attribute
                              value(<literal>srp-test/SRPServerInterface</literal>). Also needed is the
                              <literal>ClientLoginModule</literal> configured with the
                              <literal>password-stacking="useFirstPass"</literal> value to propagate the user
                          authentication credentials generated by the <literal>SRPLoginModule</literal> to the EJB
                          invocation layer.</para>
                      <para>There are two issues to note about the server side login module configuration. First, note the
                              <literal>cacheJndiName=srp-test/AuthenticationCache</literal> configuration option tells the
                              <literal>SRPCacheLoginModule</literal> the location of the <literal>CachePolicy</literal>
                          that contains the <literal>SRPServerSession</literal> for users who have authenticated against
                          the <literal>SRPService</literal>. This value corresponds to the <literal>SRPService</literal>
                          <literal>AuthenticationCacheJndiName</literal> attribute value. Second, the configuration
                          includes a <literal>UsersRolesLoginModule</literal> with the
                              <literal>password-stacking=useFirstPass</literal> configuration option. It is required to
                          use a second login module with the <literal>SRPCacheLoginModule</literal> because SRP is only an
                          authentication technology. A second login module needs to be configured that accepts the
                          authentication credentials validated by the <literal>SRPCacheLoginModule</literal> to set the
                          principal's roles that determines the principal's permissions. The
                              <literal>UsersRolesLoginModule</literal> is augmenting the SRP authentication with
                          properties file based authorization. The user's roles are coming the
                          <literal>roles.properties</literal> file included in the EJB JAR.</para>
                      <para>Now, run the example 3 client by executing the following command from the book examples
                          directory:</para>
                      <programlisting>[examples]$ ant -Dchap=chap8 -Dex=3 run-example
  ...
  run-example3:
       [copy] Copying 1 file to /tmp/jboss-4.0.1/server/default/deploy
       [echo] Waiting for 5 seconds for deploy...
       [java] Logging in using the 'srp' configuration
       [java] Created Echo
       [java] Echo.echo()#1 = This is call 1
       [java] Echo.echo()#2 = This is call 2</programlisting>
                      <para>In the <literal>examples/logs</literal> directory you will find a file called
                              <literal>ex3-trace.log</literal>. This is a detailed trace of the client side of the SRP
                          algorithm. The traces show step-by-step the construction of the public keys, challenges, session
                          key and verification.</para>
                      <para>Note that the client has taken a long time to run relative to the other simple examples. The
                          reason for this is the construction of the client's public key. This involves the creation of a
                          cryptographically strong random number, and this process takes quite a bit of time the first
                          time it occurs. If you were to log out and log in again within the same VM, the process would be
                          much faster. Also note that <literal>Echo.echo()#2</literal> fails with an authentication
                          exception. The client code sleeps for 15 seconds after making the first call to demonstrate the
                          behavior of the <literal>SRPService</literal> cache expiration. The
                          <literal>SRPService</literal> cache policy timeout has been set to a mere 10 seconds to force
                          this issue. As stated earlier, you need to make the cache timeout very long, or handle
                          re-authentication on failure.</para>
                  </section>
              </section>
          </section>
          <section>
              <title>Running JBoss with a Java 2 security manager</title>
              <para>By default the JBoss server does not start with a Java 2 security manager. If you want to restrict
                  privileges of code using Java 2 permissions you need to configure the JBoss server to run under a
                  security manager. This is done by configuring the Java VM options in the <literal>run.bat</literal> or
                      <literal>run.sh</literal> scripts in the JBoss server distribution bin directory. The two required
                  VM options are as follows:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">java.security.manager</emphasis>: This is used without any value to
                          specify that the default security manager should be used. This is the preferred security
                          manager. You can also pass a value to the <literal>java.security.manager</literal> option to
                          specify a custom security manager implementation. The value must be the fully qualified class
                          name of a subclass of <literal>java.lang.SecurityManager</literal>. This form specifies that the
                          policy file should augment the default security policy as configured by the VM
                      installation.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">java.security.policy</emphasis>: This is used to specify the policy file
                          that will augment the default security policy information for the VM. This option takes two
                          forms: <literal>java.security.policy=policyFileURL</literal> and
                              <literal>java.security.policy==policyFileURL</literal>. The first form specifies that the
                          policy file should augment the default security policy as configured by the VM installation. The
                          second form specifies that only the indicated policy file should be used. The
                              <literal>policyFileURL</literal> value can be any URL for which a protocol handler exists,
                          or a file path specification. </para>
                  </listitem>
              </itemizedlist>
              <para> Both the <literal>run.bat</literal> and <literal>run.sh</literal> start scripts reference an
                  JAVA_OPTS variable which you can use to set the security manager properties. </para>
              <para>Enabling Java 2 security is the easy part. The difficult part of Java 2 security is establishing the
                  allowed permissions. If you look at the <literal>server.policy</literal> file that is contained in the
                  default configuration file set, you'll see that it contains the following permission grant statement:</para>
              <programlisting>grant {
      // Allow everything for now
      permission java.security.AllPermission;
  };</programlisting>
              <para>This effectively disables security permission checking for all code as it says any code can do
                  anything, which is not a reasonable default. What is a reasonable set of permissions is entirely up to
                  you.</para>
              <para>The current set of JBoss specific <literal>java.lang.RuntimePermissions</literal> that are required
                  include:</para>
              <informaltable>
                  <tgroup cols="3">
                      <thead>
                          <row>
                              <entry>TargetName</entry>
                              <entry>What the permission allows</entry>
                              <entry>Risks</entry>
                          </row>
                      </thead>
                      <tbody>
                          <row>
                              <entry> org.jboss.security.SecurityAssociation.getPrincipalInfo</entry>
                              <entry> Access to the org.jboss.security.SecurityAssociation getPrincipal() and
                                  getCredentials() methods.</entry>
                              <entry> The ability to see the current thread caller and credentials.</entry>
                          </row>
                          <row>
                              <entry> org.jboss.security.SecurityAssociation.setPrincipalInfo</entry>
                              <entry> Access to the org.jboss.security.SecurityAssociation setPrincipal() and
                                  setCredentials() methods.</entry>
                              <entry> The ability to set the current thread caller and credentials.</entry>
                          </row>
                          <row>
                              <entry> org.jboss.security.SecurityAssociation.setServer</entry>
                              <entry> Access to the org.jboss.security.SecurityAssociation setServer method.</entry>
                              <entry> The ability to enable or disable multithread storage of the caller principal and
                                  credential.</entry>
                          </row>
                          <row>
                              <entry> org.jboss.security.SecurityAssociation.setRunAsRole</entry>
                              <entry> Access to the org.jboss.security.SecurityAssociation pushRunAsRole and popRunAsRole
                                  methods.</entry>
                              <entry> The ability to change the current caller run-as role principal.</entry>
                          </row>
                      </tbody>
                  </tgroup>
              </informaltable>
              <para> To conclude this discussion, here is a little-known tidbit on debugging security policy settings.
                  There are various debugging flag that you can set to determine how the security manager is using your
                  security policy file as well as what policy files are contributing permissions. Running the VM as
                  follows shows the possible debugging flag settings:</para>
              <programlisting>[bin]$ java -Djava.security.debug=help
              
  all           turn on all debugging
  access        print all checkPermission results
  combiner      SubjectDomainCombiner debugging
  jar           jar verification
  logincontext  login context results
  policy        loading and granting
  provider      security provider debugging
  scl           permissions SecureClassLoader assigns
  
  The following can be used with access:
  
  stack     include stack trace
  domain    dumps all domains in context
  failure   before throwing exception, dump stack
            and domain that didn't have permission
  
  Note: Separate multiple options with a comma</programlisting>
              <para>Running with <literal>-Djava.security.debug=all</literal> provides the most output, but the output
                  volume is torrential. This might be a good place to start if you don't understand a given security
                  failure at all. A less verbose setting that helps debug permission failures is to use
                      <literal>-Djava.security.debug=access,failure</literal>. This is still relatively verbose, but not
                  nearly as bad as the all mode as the security domain information is only displayed on access
              failures.</para>
          </section>
          <section>
              <title>Using SSL with JBoss using JSSE</title>
              <para>JBoss uses JSEE, the Java Secure Socket Extension (JSSE), for SSL. JSSE is bundled with JDK 1.4. To
                  get started with JSSE you need a public key/private key pair in the form of an X509 certificate for use
                  by the SSL server sockets. For the purpose of this example we have created a self-signed certificate
                  using the JDK keytool and included the resulting keystore file in the chap8 source directory as
                      <literal>chap8.keystore</literal>. It was created using the following command and input:</para>
              <programlisting> keytool -genkey -keystore chap8.keystore -storepass rmi+ssl -keypass rmi+ssl -keyalg RSA -alias chapter8 -validity 3650 -dname "cn=chapter8 example,ou=admin book,dc=jboss,dc=org"</programlisting>
              <para>This produces a keystore file called <literal>chap8.keystore</literal>. A keystore is a database of
                  security keys. There are two different types of entries in a keystore:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">key entries</emphasis>: each entry holds very sensitive cryptographic key
                          information, which is stored in a protected format to prevent unauthorized access. Typically, a
                          key stored in this type of entry is a secret key, or a private key accompanied by the
                          certificate chain for the corresponding public key. The <literal>keytool</literal> and
                              <literal>jarsigner</literal> tools only handle the later type of entry, that is private keys
                          and their associated certificate chains.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">trusted certificate entries</emphasis>: each entry contains a single
                          public key certificate belonging to another party. It is called a trusted certificate because
                          the keystore owner trusts that the public key in the certificate indeed belongs to the identity
                          identified by the subject (owner) of the certificate. The issuer of the certificate vouches for
                          this, by signing the certificate.</para>
                  </listitem>
              </itemizedlist>
              <para>Listing the <literal>src/main/org/jboss/chap8/chap8.keystore</literal> examples file contents using
                  the keytool shows one self-signed certificate:</para>
              <programlisting>[examples]$ keytool -list -v -keystore src/main/org/jboss/chap8/chap8.keystore
  Enter keystore password:  rmi+ssl
  
  Keystore type: jks
  Keystore provider: SUN
  
  Your keystore contains 1 entry
  
  Alias name: chapter8
  Creation date: Dec 16, 2004
  Entry type: keyEntry
  Certificate chain length: 1
  Certificate[1]:
  Owner: CN=chapter8 example, OU=admin book, DC=jboss, DC=org
  Issuer: CN=chapter8 example, OU=admin book, DC=jboss, DC=org
  Serial number: 41c23d6c
  Valid from: Thu Dec 16 19:59:08 CST 2004 until: Sun Dec 14 19:59:08 CST 2014
  Certificate fingerprints:
           MD5:  36:29:FD:1C:78:44:14:5E:5A:C7:EB:E5:E8:ED:06:86
           SHA1: 37:FE:BB:8A:A5:CF:D9:3D:B9:61:8C:53:CE:19:1E:4D:BC:C9:18:F2
  
  
  *******************************************
  *******************************************</programlisting>
              <para>With JSSE working and a keystore with the certificate you will use for the JBoss server, your are
                  ready to configure JBoss to use SSL for EJB access. This is done by configuring the EJB invoker RMI
                  socket factories. The JBossSX framework includes implementations of the
                      <literal>java.rmi.server.RMIServerSocketFactory</literal> and
                      <literal>java.rmi.server.RMIClientSocketFactory</literal> interfaces that enable the use of RMI over
                  SSL encrypted sockets. The implementation classes are
                      <literal>org.jboss.security.ssl.RMISSLServerSocketFactory</literal> and
                      <literal>org.jboss.security.ssl.RMISSLClientSocketFactory</literal> respectively. There are two
                  steps to enable the use of SSL for RMI access to EJBs. The first is to enable the use of a keystore as
                  the database for the SSL server certificate, which is done by configuring an
                      <literal>org.jboss.security.plugins.JaasSecurityDomain</literal> MBean. The
                      <literal>jboss-service.xml</literal> descriptor in the <literal>chap8/ex4</literal> directory
                  includes the <literal>JaasSecurityDomain</literal> definition shown in <xref linkend="ch8.rmissl.ex"/>.</para>
              <example id="ch8.rmissl.ex">
                  <title>A sample JaasSecurityDomain config for RMI/SSL</title>
                  <programlisting>&lt;!-- The SSL domain setup --&gt;
  &lt;mbean code="org.jboss.security.plugins.JaasSecurityDomain"
         name="jboss.security:service=JaasSecurityDomain,domain=RMI+SSL"&gt;
      &lt;constructor&gt;
          &lt;arg type="java.lang.String" value="RMI+SSL"/&gt;
      &lt;/constructor&gt;
      &lt;attribute name="KeyStoreURL"&gt;chap8.keystore&lt;/attribute&gt;
      &lt;attribute name="KeyStorePass"&gt;rmi+ssl&lt;/attribute&gt;
  &lt;/mbean&gt; </programlisting>
              </example>
              <para>The <literal>JaasSecurityDomain</literal> is a subclass of the standard
                  <literal>JaasSecurityManager</literal> class that adds the notions of a keystore as well JSSE
                      <literal>KeyManagerFactory</literal> and <literal>TrustManagerFactory</literal> access. It extends
                  the basic security manager to allow support for SSL and other cryptographic operations that require
                  security keys. This configuration simply loads the chap8.keystore from the example 4 MBean SAR using the
                  indicated password.</para>
              <para>The second step is to define an EJB invoker configuration that uses the JBossSX RMI socket factories
                  that support SSL. To do this you need to define a custom configuration for the
                  <literal>JRMPInvoker</literal> we saw in <xref linkend="ch5.chapter"/> as well as an EJB setup that
                  makes use of this invoker. The top of the listing shows the <literal>jboss-service.xml</literal>
                  descriptor that defines the custom <literal>JRMPInovker</literal>
              </para>
              <programlisting>&lt;mbean code=&quot;org.jboss.invocation.jrmp.server.JRMPInvoker&quot;
         name=&quot;jboss:service=invoker,type=jrmp,socketType=SSL&quot;&gt;
      &lt;attribute name=&quot;RMIObjectPort&quot;&gt;14445&lt;/attribute&gt;
      &lt;attribute name=&quot;RMIClientSocketFactory&quot;&gt; 
          org.jboss.security.ssl.RMISSLClientSocketFactory
      &lt;/attribute&gt;
      &lt;attribute name=&quot;RMIServerSocketFactory&quot;&gt;
          org.jboss.security.ssl.RMISSLServerSocketFactory
      &lt;/attribute&gt;
      &lt;attribute name=&quot;SecurityDomain&quot;&gt;java:/jaas/RMI+SSL&lt;/attribute&gt;
      &lt;depends&gt;jboss.security:service=JaasSecurityDomain,domain=RMI+SSL&lt;/depends&gt;
  &lt;/mbean&gt;</programlisting>
              <para> To set up an SSL invoker, we will create an invoker binding named
                  <literal>stateless-ssl-invoker</literal> that uses our custom JRMPInvoker. We can declare the invoker
                  binding and connect it to <literal>EchoBean4</literal> as shown in the following
                  <literal>jboss.xml</literal> file. </para>
              <programlisting>&lt;?xml version=&quot;1.0&quot;?&gt;
  &lt;jboss&gt;
      &lt;enterprise-beans&gt;
          &lt;session&gt;
              &lt;ejb-name&gt;EchoBean4&lt;/ejb-name&gt;
              &lt;configuration-name&gt;Standard Stateless SessionBean&lt;/configuration-name&gt;
              &lt;invoker-bindings&gt;
                  &lt;invoker&gt;
                      &lt;invoker-proxy-binding-name&gt;
                          stateless-ssl-invoker
                      &lt;/invoker-proxy-binding-name&gt;
                  &lt;/invoker&gt;
              &lt;/invoker-bindings&gt;
          &lt;/session&gt;
      &lt;/enterprise-beans&gt;
      
      &lt;invoker-proxy-bindings&gt;
          &lt;invoker-proxy-binding&gt;
              &lt;name&gt;stateless-ssl-invoker&lt;/name&gt;
              &lt;invoker-mbean&gt;jboss:service=invoker,type=jrmp,socketType=SSL&lt;/invoker-mbean&gt;
              &lt;proxy-factory&gt;org.jboss.proxy.ejb.ProxyFactory&lt;/proxy-factory&gt;
              &lt;proxy-factory-config&gt;
              &lt;client-interceptors&gt;
                  &lt;home&gt;
                      &lt;interceptor&gt;org.jboss.proxy.ejb.HomeInterceptor&lt;/interceptor&gt;
                      &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                      &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
                      &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
                  &lt;/home&gt;
                  &lt;bean&gt;
                      &lt;interceptor&gt;org.jboss.proxy.ejb.StatelessSessionInterceptor&lt;/interceptor&gt;
                      &lt;interceptor&gt;org.jboss.proxy.SecurityInterceptor&lt;/interceptor&gt;
                      &lt;interceptor&gt;org.jboss.proxy.TransactionInterceptor&lt;/interceptor&gt;
                      &lt;interceptor&gt;org.jboss.invocation.InvokerInterceptor&lt;/interceptor&gt;
                  &lt;/bean&gt;
              &lt;/client-interceptors&gt;
              &lt;/proxy-factory-config&gt;
          &lt;/invoker-proxy-binding&gt;
      &lt;/invoker-proxy-bindings&gt;
  &lt;/jboss&gt;</programlisting>
              <para>The example 4 code is located under the <literal>src/main/org/jboss/chap8/ex4</literal> directory of
                  the book examples. This is another simple stateless session bean with an echo method that returns its
                  input argument. It is hard to tell when SSL is in use unless it fails, so we'll run the example 4 client
                  in two different ways to demonstrate that the EJB deployment is in fact using SSL. Start the JBoss
                  server using the default configuration and then run example 4b as follows:</para>
              <programlisting>[examples]$ ant -Dchap=chap8 -Dex=4b run-example
  ...
  run-example4b:
       [copy] Copying 1 file to /tmp/jboss-4.0.1/server/default/deploy
       [echo] Waiting for 15 seconds for deploy...
  ...
       [java] Exception in thread "main" java.rmi.ConnectIOException: error during JRMP connect
  ion establishment; nested exception is: 
       [java]     javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorExceptio
  n: No trusted certificate found
  ...            
  </programlisting>
              <para>The resulting exception is expected, and is the purpose of the 4b version of the example. Note that
                  the exception stack trace has been edited to fit into the book format, so expect some difference. The
                  key item to notice about the exception is it clearly shows you are using the Sun JSSE classes to
                  communicate with the JBoss EJB container. The exception is saying that the self-signed certificate you
                  are using as the JBoss server certificate cannot be validated as signed by any of the default
                  certificate authorities. This is expected because the default certificate authority keystore that ships
                  with the JSSE package only includes well known certificate authorities such as VeriSign, Thawte, and RSA
                  Data Security. To get the EJB client to accept your self-signed certificate as valid, you need to tell
                  the JSSE classes to use your <literal>chap8.keystore</literal> as its truststore. A truststore is just a
                  keystore that contains public key certificates used to sign other certificates. To do this, run example
                  4 using <literal>-Dex=4</literal> rather than <literal>-Dex=4b</literal> to pass the location of the
                  correct truststore using the <literal>javax.net.ssl.trustStore</literal> system property:</para>
              <programlisting>[examples]$ ant -Dchap=chap8 -Dex=4 run-example
  ...
  run-example4:
       [copy] Copying 1 file to /tmp/jboss-4.0.1/server/default/deploy
       [echo] Waiting for 5 seconds for deploy...
  ...
       [java] Created Echo
       [java] Echo.echo()#1 = This is call 1</programlisting>
              <para>This time the only indication that an SSL socket is involved is because of the <literal>SSL
                      handshakeCompleted</literal> message. This is coming from the
                  <literal>RMISSLClientSocketFactory</literal> class as a debug level log message. If you did not have the
                  client configured to print out log4j debug level messages, there would be no direct indication that SSL
                  was involved. If you note the run times and the load on your system CPU, there definitely is a
                  difference. SSL, like SRP, involves the use of cryptographically strong random numbers that take time to
                  seed the first time they are used. This shows up as high CPU utilization and start up times.</para>
              <para>One consequence of this is that if you are running on a system that is slower than the one used to run
                  the examples for the book, such as when running example 4b, you may seen an exception similar to the
                  following:</para>
              <programlisting>javax.naming.NameNotFoundException: EchoBean4 not bound
     at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer
  ...</programlisting>
              <para>The problem is that the JBoss server has not finished deploying the example EJB in the time the client
                  allowed. This is due to the initial setup time of the secure random number generator used by the SSL
                  server socket. If you see this issue, simply rerun the example again or increase the deployment wait
                  time in the chap8 <literal>build.xml</literal> Ant script.</para>
          </section>
          <section>
              <title>Configuring JBoss for use Behind a Firewall</title>
              <para>JBoss comes with many socket based services that open listening ports. In this section we list the
                  services that open ports that might need to be configured to work when accessing JBoss behind a
                  firewall. The following table shows the ports, socket type, associated service for the services in the
                  default configuration file set. <xref linkend="ch8.moreports.table"/> shows the same information for the
                  additional ports that exist in the all configuration file set.</para>
              <table id="ch8.ports.table">
                  <title>The ports found in the default configuration</title>
                  <tgroup cols="3">
                      <colspec colname="c1" colnum="1" colwidth=".25*"/>
                      <colspec colname="c2" colnum="2" colwidth=".25*"/>
                      <colspec colname="c3" colnum="3" colwidth="1*"/>
                      <thead>
                          <row>
                              <entry>Port</entry>
                              <entry>Type</entry>
                              <entry>Service</entry>
                          </row>
                      </thead>
                      <tbody>
                          <row>
                              <entry>1098</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.naming.NamingService</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>1099</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.naming.NamingService</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>4444</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.invocation.jrmp.server.JRMPInvoker</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>4445</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.invocation.pooled.server.PooledInvoker</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>8009</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.web.tomcat.tc4.EmbeddedTomcatService</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>8080</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.web.tomcat.tc4.EmbeddedTomcatService</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>8083</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.web.WebService</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>8093</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.mq.il.uil2.UILServerILService</literal>
                              </entry>
                          </row>
                      </tbody>
                  </tgroup>
              </table>
              <table id="ch8.moreports.table">
                  <title>Additional ports in the all configuration</title>
                  <tgroup cols="3">
                      <colspec colname="c1" colnum="1" colwidth=".25*"/>
                      <colspec colname="c2" colnum="2" colwidth=".25*"/>
                      <colspec colname="c3" colnum="3" colwidth="1*"/>
                      <thead>
                          <row>
                              <entry>Port</entry>
                              <entry>Type</entry>
                              <entry>Service</entry>
                          </row>
                      </thead>
                      <tbody>
                          <row>
                              <entry>1100</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.ha.jndi.HANamingService</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>1101</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.ha.jndi.HANamingService</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>1102</entry>
                              <entry>UDP</entry>
                              <entry>
                                  <literal>org.jboss.ha.jndi.HANamingService</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>1161</entry>
                              <entry>UDP</entry>
                              <entry>
                                  <literal>org.jboss.jmx.adaptor.snmp.agent.SnmpAgentService</literal>
                              </entry>
                          </row>
                          <row>
                              <entry> 1162</entry>
                              <entry> UDP</entry>
                              <entry>
                                  <literal>org.jboss.jmx.adaptor.snmp.trapd.TrapdService</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>3528</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.invocation.iiop.IIOPInvoker</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>4447</entry>
                              <entry>TCP</entry>
                              <entry>
                                  <literal>org.jboss.invocation.jrmp.server.JRMPInvokerHA</literal>
                              </entry>
                          </row>
                          <row>
                              <entry>45566<footnote>
                                      <para>Plus two additional anonymous UDP ports, one can be set using the
                                              <literal>rcv_port</literal>, and the other cannot be set.</para>
                                  </footnote>
                              </entry>
                              <entry>UDP</entry>
                              <entry>
                                  <literal>org.jboss.ha.framework.server.ClusterPartition</literal>
                              </entry>
                          </row>
                      </tbody>
                  </tgroup>
              </table>
          </section>
          <section>
              <title>How to Secure the JBoss Server</title>
              <para>JBoss comes with several admin access points that need to be secured or removed to prevent
                  unauthorized access to administrative functions in a deployment. This section describes the various
                  admin services and how to secure them.</para>
              <section>
                  <title>The JMX Console</title>
                  <para>The <literal>jmx-console.war</literal> found in the deploy directory provides an html view into
                      the JMX microkernel. As such, it provides access to arbitrary admin type access like shutting down
                      the server, stopping services, deploying new services, etc. It should either be secured like any
                      other web application, or removed.</para>
              </section>
              <section>
                  <title>The Web Console</title>
                  <para>The <literal>web-console.war</literal> found in the <literal>deploy/management</literal> directory
                      is another web application view into the JMX microkernel. This uses a combination of an applet and a
                      HTML view and provides the same level of access to admin functionality as the
                          <literal>jmx-console.war</literal>. As such, it should either be secured or removed. The
                          <literal>web-console.war</literal> contains commented out templates for basic security in its
                          <literal>WEB-INF/web.xml</literal> as well as commented out setup for a security domain in
                          <literal>WEB-INF/jboss-web.xml</literal>.</para>
              </section>
              <section>
                  <title>The HTTP Invokers</title>
                  <para>The <literal>http-invoker.sar</literal> found in the deploy directory is a service that provides
                      RMI/HTTP access for EJBs and the JNDI <literal>Naming</literal> service. This includes a servlet
                      that processes posts of marshalled <literal>org.jboss.invocation.Invocation</literal> objects that
                      represent invocations that should be dispatched onto the <literal>MBeanServer</literal>. Effectively
                      this allows access to MBeans that support the detached invoker operation via HTTP since one could
                      figure out how to format an appropriate HTTP post. To security this access point you would need to
                      secure the <literal>JMXInvokerServlet</literal> servlet found in the
                          <literal>http-invoker.sar/invoker.war/WEB-INF/web.xml</literal> descriptor. There is a secure
                      mapping defined for the <literal>/restricted/JMXInvokerServlet</literal> path by default, one would
                      simply have to remove the other paths and configure the <literal>http-invoker</literal> security
                      domain setup in the <literal>http-invoker.sar/invoker.war/WEB-INF/jboss-web.xml</literal>
                      descriptor.</para>
              </section>
              <section>
                  <title>The JMX Invoker</title>
                  <para>The <literal>jmx-invoker-adaptor-server.sar</literal> is a service that exposes the JMX
                      MBeanServer interface via an RMI compatible interface using the RMI/JRMP detached invoker service.
                      The only way for this service to be secured currently would be to switch the protocol to RMI/HTTP
                      and secure the <literal>http-invoker.sar</literal> as described in the previous section. In the
                      future this service will be deployed as an XMBean with a security interceptor that supports role
                      based access checks.</para>
              </section>
          </section>
      </chapter>
  
      <chapter>
          <title>Additional Services</title>
          <para>This chapter discusses useful MBean services that are not discussed elsewhere either because they are
              utility services not necessary for running JBoss, or they don't fit into a current section of the book.</para>
          <section id="ch10.threadmem">
              <title>Memory and Thread Monitoring</title>
  
              <para> The <literal>jboss.system:type=ServerInfo</literal> MBean provides several attributes that can be
                  used to monitor the thread and memory usage in a JBoss instance. These attributes can be monitored in
                  many ways: through the JMX Console, from a third-party JMX management tool, from shell scripts using the
                  twiddle command, etc... The most interesting attributes are shown below.</para>
  
              <variablelist>
                  <varlistentry>
                      <term>
                          <emphasis role="bold">FreeMemory</emphasis>
                      </term>
                      <listitem>
                          <para>This is the current free memory available in the JVM.</para>
                      </listitem>
                  </varlistentry>
                  <varlistentry>
                      <term>
                          <emphasis role="bold">ActiveThreadCount</emphasis>
                      </term>
                      <listitem>
                          <para>This is the number of active threads in the JVM.</para>
                      </listitem>
                  </varlistentry>
                  <varlistentry>
                      <term>
                          <emphasis role="bold">ActiveThreadGroupCount</emphasis>
                      </term>
                      <listitem>
                          <para>This is the number of active thread groups in the JVM.</para>
                      </listitem>
                  </varlistentry>
  
              </variablelist>
  
              <para>These are useful metrics for monitoring and alerting, but developers and administrators need a little
                  more insite than this. The Java 5 JVMs from Sun provide more detailed information about the current
                  state of the JVM. Some of these details are exposed by JBoss through operations on the SystemInfo MBean. </para>
  
              <variablelist>
                  <varlistentry>
                      <term>
                          <emphasis role="bold">listMemoryPools</emphasis>
                      </term>
                      <listitem>
                          <para>This operations shows the size and current usage of all JVM memory pools. This operation
                              is only available when using Java 5.</para>
                      </listitem>
                  </varlistentry>
  
                  <varlistentry>
                      <term>
                          <emphasis role="bold">listThreadDump</emphasis>
                      </term>
                      <listitem>
                          <para>This operations shows all threads currently running in the JVM. When using Java 5, JBoss
                              will display a complete stack trace for each thread, showing you exactly what code each
                              thread is executing. </para>
                      </listitem>
                  </varlistentry>
  
  
                  <varlistentry>
                      <term>
                          <emphasis role="bold">listThreadCpuUtilization</emphasis>
                      </term>
                      <listitem>
                          <para>This operations shows all threads currently running in the JVM along with the total CPU
                              time each thread has used. The operation is only available in Java 5. </para>
                      </listitem>
                  </varlistentry>
              </variablelist>
          </section>
          <section id="ch10.log4j">
              <title>The Log4j Service</title>
              <para>The <literal>Log4jService</literal> MBean configures the Apache log4j system. JBoss uses the log4j
                  framework as its internal logging API.</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">ConfigurationURL</emphasis>: The URL for the log4j configuration file.
                          This can refer to either a XML document parsed by the
                              <literal>org.apache.log4j.xml.DOMConfigurator</literal> or a Java properties file parsed by
                          the <literal>org.apache.log4j.PropertyConfigurator</literal>. The type of the file is determined
                          by the URL content type, or if this is null, the file extension. The default setting of
                              <literal>resource:log4j.xml</literal> refers to the <literal>conf/log4j.xml</literal> file
                          of the active server configuration file set.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">RefreshPeriod</emphasis>: The time in seconds between checks for changes
                          in the log4 configuration specified by the <literal>ConfigurationURL</literal> attribute. The
                          default value is 60 seconds.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">CatchSystemErr</emphasis>: This boolean flag if true, indicates if the
                              <literal>System.err</literal> stream should be redirected onto a log4j category called
                              <literal>STDERR</literal>. The default is true.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">CatchSystemOut</emphasis>: This boolean flag if true, indicates if the
                              <literal>System.out</literal> stream should be redirected onto a log4j category called
                              <literal>STDOUT</literal>. The default is true.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Log4jQuietMode</emphasis>: This boolean flag if true, sets the
                              <literal>org.apache.log4j.helpers.LogLog.setQuiteMode</literal>. As of log4j1.2.8 this needs
                          to be set to avoid a possible deadlock on exception at the appender level. See
                      bug#696819.</para>
                  </listitem>
              </itemizedlist>
          </section>
          <section id="ch10.props">
              <title>System Properties Management</title>
              <para>The management of system properties can be done using the system properties service. It supports
                  setting of the VM global property values just as <literal>java.lang.System.setProperty</literal> method
                  and the VM command line arguments do. </para>
              <para>Its configurable attributes include:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">Properties</emphasis>: a specification of multiple property
                              <literal>name=value</literal> pairs using the
                              <literal>java.util.Properites.load(java.io.InputStream)</literal> method format. Each
                              <literal>property=value</literal> statement is given on a separate line within the body of
                          the <literal>Properties</literal> attribute element.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">URLList</emphasis>: a comma separated list of URL strings from which to
                          load properties file formatted content. If a component in the list is a relative path rather
                          than a URL it will be treated as a file path relative to the
                              <literal>&lt;jboss-dist&gt;/server/&lt;config&gt;</literal> directory. For
                          example, a component of <literal>conf/local.properties</literal> would be treated as a file URL
                          that points to the
                          <literal>&lt;jboss-dist&gt;/server/default/conf/local.properties</literal> file when
                          running with the <literal>default</literal> configuration file set. </para>
                  </listitem>
              </itemizedlist>
              <para>The following illustrates the usage of the system properties service with an external properties file.</para>
              <programlisting>&lt;mbean code="org.jboss.varia.property.SystemPropertiesService"
          name="jboss.util:type=Service,name=SystemProperties"&gt;
              
      &lt;!-- Load properties from each of the given comma separated URLs --&gt;
      &lt;attribute name="URLList"&gt;
          http://somehost/some-location.properties,
          ./conf/somelocal.properties
      &lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
              <para>The following illustrates the usage of the system properties service with an embedded properties list.</para>
              <programlisting>&lt;mbean code="org.jboss.varia.property.SystemPropertiesService"
          name="jboss.util:type=Service,name=SystemProperties"&gt;
      &lt;!-- Set properties using the properties file style. --&gt;
      &lt;attribute name="Properties"&gt;
         property1=This is the value of my property
         property2=This is the value of my other property
      &lt;/attribute&gt;
              
  &lt;/mbean&gt;</programlisting>
          </section>
          <section id="ch10.propertyeditor">
              <title>Property Editor Management</title>
              <para>In JBoss, JavaBean property editors are used for reading data types from service files and for editing
                  values in the JMX console. The <literal>java.bean.PropertyEditorManager</literal> class controls the
                      <literal>java.bean.PropertyEditor</literal> instances in the system. The property editor manager can
                  be managed in JBoss using the <literal>org.jboss.varia.property.PropertyEditorManagerService</literal>
                  MBean. The property editor manager service is configured in
                  <literal>deploy/properties-service.xml</literal> and supports the following attributes: </para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">BootstrapEditors:</emphasis> This is a listing of
                              <literal>property_editor_class=editor_value_type_class</literal> pairs defining the property
                          editor to type mappings that should be preloaded into the property editor manager. The value
                          type of this attribute is a string so that it may be set from a string without requiring a
                          custom property editor.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Editors</emphasis>: This serves the same function as the
                              <literal>BootstrapEditors</literal> attribute, but its type is
                          <literal>java.util.Properties</literal>. Setting it from a string value in a service file
                          requires a custom property editor for properties objects already be loaded. JBoss provides a
                          suitable property editor.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">EditorSearchPath</emphasis>: This attribute allows one to set the editor
                          packages search path on the <literal>PropertyEditorManager</literal> editor packages search
                          path. Since there can be only one search path, setting this value overrides the default search
                          path established by JBoss. If you set this, make sure to add the JBoss search path,
                              <literal>org.jboss.util.propertyeditor</literal> and
                              <literal>org.jboss.mx.util.propertyeditor</literal>, to the front of the new search path.
                      </para>
                  </listitem>
              </itemizedlist>
          </section>
          <section id="ch10.bindingmanager">
              <title>Services Binding Management</title>
              <para>With all of the independently deployed services available in JBoss, running multiple instances on a
                  given machine can be a tedious exercise in configuration file editing to resolve port conflicts. The
                  binding service allows you centrally configure the ports for multiple JBoss instances. After the service
                  is normally loaded by JBoss, the <literal>ServiceConfigurator</literal> queries the service binding
                  manager to apply any overrides that may exist for the service. The service binding manager is configured
                  in <literal>conf/jboss-service.xml</literal>. The set of configurable attributes it supports include:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">ServerName</emphasis>: This is the name of the server configuration this
                          JBoss instance is associated with. The binding manager will apply the overrides defined for the
                          named configuration. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">StoreFactoryClassName</emphasis>: This is the name of the class that
                          implements the <literal>ServicesStoreFactory</literal> interface. You may provide your own
                          implementation, or use the default XML based store
                              <literal>org.jboss.services.binding.XMLServicesStoreFactory</literal>. The factory provides
                          a <literal>ServicesStore</literal> instance responsible for providing the names configuration
                          sets.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">StoreURL</emphasis>: This is the URL of the configuration store contents,
                          which is passed to the <literal>ServicesStore</literal> instance to load the server
                          configuration sets from. For the XML store, this is a simple service binding file. </para>
                  </listitem>
              </itemizedlist>
              <para> The following is a sample service binding manager configuration that uses the
                  <literal>ports-01</literal> configuration from the <literal>sample-bindings.xml</literal> file provided
                  in the JBoss examples directory. </para>
              <programlisting>&lt;mbean code=&quot;org.jboss.services.binding.ServiceBindingManager&quot; 
        name=&quot;jboss.system:service=ServiceBindingManager&quot;&gt;
      &lt;attribute name=&quot;ServerName&quot;&gt;ports-01&lt;/attribute&gt;
      &lt;attribute name=&quot;StoreURL&quot;&gt;
          ../docs/examples/binding-manager/sample-bindings.xml
      &lt;/attribute&gt;
      &lt;attribute name=&quot;StoreFactoryClassName&quot;&gt;
          org.jboss.services.binding.XMLServicesStoreFactory 
      &lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
              <para> The structure of the binding file is shown in <xref linkend="ch10.xmlstoredtd.fig"/>.</para>
              <figure id="ch10.xmlstoredtd.fig">
                  <title>The binding service file structure</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/Chap10-6.gif"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <para> The elements are:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">service-bindings</emphasis>: The root element of the configuration file.
                          It contains one or more server elements.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">server</emphasis>: This is the base of a JBoss server instance
                          configuration. It has a required <literal>name</literal> attribute that defines the JBoss
                          instance name to which it applies. This is the name that correlates with the
                              <literal>ServiceBindingManager</literal>
                          <literal>ServerName</literal> attribute value. The server element content consists of one or
                          more <literal>service-config</literal> elements.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">service-config</emphasis>: This element represents a configuration
                          override for an MBean service. It has a required name attribute that is the JMX
                              <literal>ObjectName</literal> string of the MBean service the configuration applies to. It
                          also has a required <literal>delegateClass</literal> name attribute that specifies the class
                          name of the <literal>ServicesConfigDelegate</literal> implementation that knows how to handle
                          bindings for the target service. Its contents consists of an optional
                          <literal>delegate-config</literal> element and one or more binding elements.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">binding</emphasis>: A <literal>binding</literal> element specifies a named
                          port and address pair. It has an optional <literal>name</literal> that can be used to provide
                          multiple binding for a service. An example would be multiple virtual hosts for a web container.
                          The port and address are specified via the optional <literal>port</literal> and
                          <literal>host</literal> attributes respectively. If the port is not specified it defaults to 0
                          meaning choose an anonymous port. If the host is not specified it defaults to null meaning any
                          address.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">delegate-config</emphasis>: The <literal>delegate-config</literal> element
                          is an arbitrary XML fragment for use by the <literal>ServicesConfigDelegate</literal>
                          implementation. The <literal>hostName</literal> and <literal>portName</literal> attributes only
                          apply to the <literal>AttributeMappingDelegate</literal> of the example and are there to prevent
                          DTD aware editors from complaining about their existence in the
                              <literal>AttributeMappingDelegate</literal> configurations. Generally both the attributes
                          and content of the <literal>delegate-config</literal> are arbitrary, but there is no way to
                          specify and a element can have any number of attributes with a DTD.</para>
                  </listitem>
              </itemizedlist>
              <para>The three <literal>ServicesConfigDelegate</literal> implementations are
                      <literal>AttributeMappingDelegate</literal>, <literal>XSLTConfigDelegate</literal>, and
                      <literal>XSLTFileDelegate</literal>. </para>
  
              <section>
                  <title>AttributeMappingDelegate</title>
  
                  <para>The <literal>AttributeMappingDelegate</literal> class is an implementation of the
                          <literal>ServicesConfigDelegate</literal> that expects a <literal>delegate-config</literal>
                      element of the form:</para>
                  <programlisting>&lt;delegate-config portName="portAttrName" hostName="hostAttrName"&gt;
      &lt;attribute name="someAttrName"&gt;someHostPortExpr&lt;/attribute&gt;
      &lt;!-- ... --&gt;
  &lt;/delegate-config&gt;</programlisting>
                  <para>The <literal>portAttrName</literal> is the attribute name of the MBean service to which the
                      binding port value should be applied, and the <literal>hostAttrName</literal> is the attribute name
                      of the MBean service to which the binding host value should be applied. If the
                      <literal>portName</literal> attribute is not specified then the binding port is not applied.
                      Likewise, if the <literal>hostName</literal> attribute is not specified then the binding host is not
                      applied. The optional attribute element(s) specify arbitrary MBean attribute names whose values are
                      a function of the host and/or port settings. Any reference to <literal>${host}</literal> in the
                      attribute content is replaced with the host binding and any <literal>${port}</literal> reference is
                      replaced with the port binding. The <literal>portName</literal>, <literal>hostName</literal>
                      attribute values and attribute element content may reference system properties using the
                          <literal>${x}</literal> syntax that is supported by the JBoss services descriptor.</para>
                  <para>The sample listing illustrates the usage of <literal>AttributeMappingDelegate</literal>.</para>
                  <programlisting>&lt;service-config name="jboss:service=Naming"
                   delegateClass="org.jboss.services.binding.AttributeMappingDelegate"&gt;
       &lt;delegate-config portName="Port"/&gt;
       &lt;binding port="1099" /&gt;
  &lt;/service-config&gt;</programlisting>
                  <para>Here the <literal>jboss:service=Naming</literal> MBean service has its <literal>Port</literal>
                      attribute value overridden to 1099. The corresponding setting from the jboss1 server configuration
                      overrides the port to 1199.</para>
  
              </section>
  
              <section>
                  <title>XSLTConfigDelegate</title>
  
                  <para>The <literal>XSLTConfigDelegate</literal> class is an implementation of the
                          <literal>ServicesConfigDelegate</literal> that expects a <literal>delegate-config</literal>
                      element of the form:</para>
                  <programlisting>&lt;delegate-config&gt;
      &lt;xslt-config configName="ConfigurationElement"&gt;&lt;![CDATA[
          Any XSL document contents...
          ]]&gt;
       &lt;/xslt-config&gt;
       &lt;xslt-param name="param-name"&gt;param-value&lt;/xslt-param&gt;
       &lt;!-- ... --&gt;
  &lt;/delegate-config&gt;</programlisting>
                  <para>The <literal>xslt-config</literal> child element content specifies an arbitrary XSL script
                      fragment that is to be applied to the MBean service attribute named by the
                      <literal>configName</literal> attribute. The named attribute must be of type
                          <literal>org.w3c.dom.Element</literal>. The optional <literal>xslt-param</literal> elements
                      specify XSL script parameter values for parameters used in the script. There are two XSL parameters
                      defined by default called <literal>host</literal> and <literal>port</literal>, and their values are
                      set to the configuration host and port bindings.</para>
                  <para>The <literal>XSLTConfigDelegate</literal> is used to transform services whose
                          <literal>port/interface</literal> configuration is specified using a nested XML fragment. The
                      following example maps the port number on hypersonic datasource:</para>
                  <programlisting>   
  &lt;service-config name=&quot;jboss.jca:service=ManagedConnectionFactory,name=DefaultDS&quot; 
                  delegateClass=&quot;org.jboss.services.binding.XSLTConfigDelegate&quot;&gt;
      &lt;delegate-config&gt;
          &lt;xslt-config configName=&quot;ManagedConnectionFactoryProperties&quot;&gt;&lt;![CDATA[
  &lt;xsl:stylesheet
        xmlns:xsl=&apos;http://www.w3.org/1999/XSL/Transform&apos; version=&apos;1.0&apos;&gt;
  
    &lt;xsl:output method=&quot;xml&quot; /&gt;
    &lt;xsl:param name=&quot;host&quot;/&gt;
    &lt;xsl:param name=&quot;port&quot;/&gt;
  
    &lt;xsl:template match=&quot;/&quot;&gt;
      &lt;xsl:apply-templates/&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match=&quot;config-property[@name=&apos;ConnectionURL&apos;]&quot;&gt;
      &lt;config-property type=&quot;java.lang.String&quot; name=&quot;ConnectionURL&quot;&gt;
         jdbc:hsqldb:hsql://&lt;xsl:value-of select=&apos;$host&apos;/&gt;:&lt;xsl:value-of select=&apos;$port&apos;/&gt;
      &lt;/config-property&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match=&quot;*|@*&quot;&gt;
      &lt;xsl:copy&gt;
        &lt;xsl:apply-templates select=&quot;@*|node()&quot;/&gt;
      &lt;/xsl:copy&gt;
    &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;
  ]]&gt;
          &lt;/xslt-config&gt;
       &lt;/delegate-config&gt;
       &lt;binding host=&quot;localhost&quot; port=&quot;1901&quot;/&gt;
  &lt;/service-config&gt;  </programlisting>
              </section>
              <section>
                  <title>XSLTFileDelegate</title>
                  <para>The <literal>XSLTFileDelegate</literal> class works similarly to the
                      <literal>XSLTConfigDelegate</literal> except that instead of transforming an embedded XML fragment,
                      the XSLT script transforms a file read in from the file system. The
                      <literal>delegate-config</literal> takes exactly the same form: </para>
                  <programlisting>&lt;delegate-config&gt;
      &lt;xslt-config configName="ConfigurationElement"&gt;&lt;![CDATA[
          Any XSL document contents...
          ]]&gt;
       &lt;/xslt-config&gt;
       &lt;xslt-param name="param-name"&gt;param-value&lt;/xslt-param&gt;
       &lt;!-- ... --&gt;
  &lt;/delegate-config&gt;</programlisting>
                  <para>The <literal>xslt-config</literal> child element content specifies an arbitrary XSL script
                      fragment that is to be applied to the MBean service attribute named by the
                      <literal>configName</literal> attribute. The named attribute must be a String value corresponding to
                      an XML file that will be transformed. The optional <literal>xslt-param</literal> elements specify
                      XSL script parameter values for parameters used in the script. There are two XSL parameters defined
                      by default called <literal>host</literal> and <literal>port</literal>, and their values are set to
                      the configuration <literal>host</literal> and <literal>port</literal> bindings.</para>
                  <para>The following example maps the host and port values for the Tomcat connectors:</para>
                  <programlisting>   
  &lt;service-config name=&quot;jboss.web:service=WebServer&quot;
                  delegateClass=&quot;org.jboss.services.binding.XSLTFileDelegate&quot;&gt;
      &lt;delegate-config&gt;
          &lt;xslt-config configName=&quot;ConfigFile&quot;&gt;&lt;![CDATA[
     &lt;xsl:stylesheet
           xmlns:xsl=&apos;http://www.w3.org/1999/XSL/Transform&apos; version=&apos;1.0&apos;&gt;
  
       &lt;xsl:output method=&quot;xml&quot; /&gt;
       &lt;xsl:param name=&quot;port&quot;/&gt;
  
       &lt;xsl:variable name=&quot;portAJP&quot; select=&quot;$port - 71&quot;/&gt;
       &lt;xsl:variable name=&quot;portHttps&quot; select=&quot;$port + 363&quot;/&gt;
  
       &lt;xsl:template match=&quot;/&quot;&gt;
         &lt;xsl:apply-templates/&gt;
       &lt;/xsl:template&gt;
  
        &lt;xsl:template match = &quot;Connector&quot;&gt;
           &lt;Connector&gt;
              &lt;xsl:for-each select=&quot;@*&quot;&gt;
              &lt;xsl:choose&gt;
                 &lt;xsl:when test=&quot;(name() = &apos;port&apos; and . = &apos;8080&apos;)&quot;&gt;
                    &lt;xsl:attribute name=&quot;port&quot;&gt;
                        &lt;xsl:value-of select=&quot;$port&quot; /&gt;
                    &lt;/xsl:attribute&gt;
                 &lt;/xsl:when&gt;
                 &lt;xsl:when test=&quot;(name() = &apos;port&apos; and . = &apos;8009&apos;)&quot;&gt;
                    &lt;xsl:attribute name=&quot;port&quot;&gt;
                        &lt;xsl:value-of select=&quot;$portAJP&quot; /&gt;
                    &lt;/xsl:attribute&gt;
                 &lt;/xsl:when&gt;
                 &lt;xsl:when test=&quot;(name() = &apos;redirectPort&apos;)&quot;&gt;
                    &lt;xsl:attribute name=&quot;redirectPort&quot;&gt;
                        &lt;xsl:value-of select=&quot;$portHttps&quot; /&gt;
                    &lt;/xsl:attribute&gt;
                 &lt;/xsl:when&gt;
                 &lt;xsl:when test=&quot;(name() = &apos;port&apos; and . = &apos;8443&apos;)&quot;&gt;
                    &lt;xsl:attribute name=&quot;port&quot;&gt;
                        &lt;xsl:value-of select=&quot;$portHttps&quot; /&gt;
                    &lt;/xsl:attribute&gt;
                 &lt;/xsl:when&gt;
                 &lt;xsl:otherwise&gt;
                    &lt;xsl:attribute name=&quot;{name()}&quot;&gt;&lt;xsl:value-of select=&quot;.&quot; /&gt;&lt;/xsl:attribute&gt;
                 &lt;/xsl:otherwise&gt;
              &lt;/xsl:choose&gt;
              &lt;/xsl:for-each&gt;
              &lt;xsl:apply-templates/&gt;
           &lt;/Connector&gt;
        &lt;/xsl:template&gt;
  
       &lt;xsl:template match=&quot;*|@*&quot;&gt;
         &lt;xsl:copy&gt;
           &lt;xsl:apply-templates select=&quot;@*|node()&quot;/&gt;
         &lt;/xsl:copy&gt;
       &lt;/xsl:template&gt;
     &lt;/xsl:stylesheet&gt;
     ]]&gt;
          &lt;/xslt-config&gt;
      &lt;/delegate-config&gt;
      &lt;binding port=&quot;8280&quot;/&gt;
  &lt;/service-config&gt; </programlisting>
              </section>
  
  
              <section>
                  <title>The Sample Bindings File</title>
                  <para>JBoss ships with service binding configuration file for starting up to three separate JBoss
                      instances on one host. Here we will walk through the steps to bring up the two instances and look at
                      the sample configuration. Start by making two server configuration file sets called
                      <literal>jboss0</literal> and <literal>jboss1</literal> by running the following command from the
                      book examples directory:</para>
                  <programlisting>[examples]$ ant -Dchap=chap10 -Dex=1 run-example</programlisting>
                  <para>This creates duplicates of the <literal>server/default</literal> configuration file sets as
                          <literal>server/jboss0</literal> and <literal>server/jboss1</literal>, and then replaces the
                          <literal>conf/jboss-service.xml</literal> descriptor with one that has the
                          <literal>ServiceBindingManager</literal> configuration enabled as follows:</para>
                  <programlisting>&lt;mbean code="org.jboss.services.binding.ServiceBindingManager"
         name="jboss.system:service=ServiceBindingManager"&gt;
      &lt;attribute name="ServerName"&gt;${jboss.server.name}&lt;/attribute&gt;
      &lt;attribute name="StoreURL"&gt;${jboss.server.base.dir}/chap10ex1-bindings.xml&lt;/attribute&gt;
      &lt;attribute name="StoreFactoryClassName"&gt;
          org.jboss.services.binding.XMLServicesStoreFactory
      &lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
                  <para>Here the configuration name is <literal>${jboss.server.name}</literal>. JBoss will replace that
                      with name of the actual JBoss server configuration that we pass to the run script with the
                          <literal>-c</literal> option. That will be either <literal>jboss0</literal> or
                      <literal>jboss1</literal>, depending on which configuration is being run. The binding manager will
                      find the corresponding server configuration section from the
                      <literal>chap10ex1-bindings.xml</literal> and apply the configured overrides. The
                      <literal>jboss0</literal> configuration uses the default settings for the ports, while the
                          <literal>jboss1</literal> configuration adds 100 to each port number.</para>
                  <para>To test the sample configuration, start two JBoss instances using the <literal>jboss0</literal>
                      and <literal>jboss1</literal> configuration file sets created previously. You can observe that the
                      port numbers in the console log are different for the <literal>jboss1</literal> server. To test out
                      that both instances work correctly, try accessing the web server of the first JBoss on port 8080 and
                      then try the second JBoss instance on port 8180. </para>
              </section>
          </section>
          <section id="ch10.classload">
              <title>RMI Dynamic Class Loading</title>
              <para>The <literal>WebService</literal> MBean provides dynamic class loading for RMI access to the server
                  EJBs. The configurable attributes for the service are as follows:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">Port</emphasis>: the <literal>WebService</literal> listening port number.
                          A port of 0 will use any available port.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Host</emphasis>: Set the name of the public interface to use for the host
                          portion of the RMI codebase URL.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">BindAddress</emphasis>: the specific address the
                          <literal>WebService</literal> listens on. This can be used on a multi-homed host for a
                              <literal>java.net.ServerSocket</literal> that will only accept connect requests to one of
                          its addresses.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">Backlog</emphasis>: The maximum queue length for incoming connection
                          indications (a request to connect) is set to the <literal>backlog</literal> parameter. If a
                          connection indication arrives when the queue is full, the connection is refused.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">DownloadServerClasses</emphasis>: A flag indicating if the server should
                          attempt to download classes from thread context class loader when a request arrives that does
                          not have a class loader key prefix.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">DownloadResources</emphasis>: A flag indicating whether the server should
                          attempt to download non-class file resources using the thread context class loader. Note that
                          allowing this is generally a security risk as it allows access to server configuration files
                          which may contain security settings. </para>
                  </listitem>
                  <listitem>
                      <para><emphasis role="bold">ThreadPool</emphasis>: The
                              <literal>org.jboss.util.threadpool.BasicThreadPoolMBean</literal> instance thread pool used
                          for the class loading. </para>
                  </listitem>
              </itemizedlist>
          </section>
          <section id="ch10.sched">
              <title>Scheduling Tasks</title>
              <para>Java includes a simple timer based capability through the <literal>java.util.Timer</literal> and
                      <literal>java.util.TimerTask</literal> utility classes. JMX also includes a mechanism for scheduling
                  JMX notifications at a given time with an optional repeat interval as the
                      <literal>javax.management.timer.TimerMBean</literal> agent service.</para>
              <para>JBoss includes two variations of the JMX timer service in the
                      <literal>org.jboss.varia.scheduler.Scheduler</literal> and
                      <literal>org.jboss.varia.scheduler.ScheduleManager</literal> MBeans. Both MBeans rely on the JMX
                  timer service for the basic scheduling. They extend the behavior of the timer service as described in
                  the following sections.</para>
              <section>
                  <title>org.jboss.varia.scheduler.Scheduler </title>
                  <para>The Scheduler differs from the <literal>TimerMBean</literal> in that the
                      <literal>Scheduler</literal> directly invokes a callback on an instance of a user defined class, or
                      an operation of a user specified MBean.</para>
                  <itemizedlist>
                      <listitem>
                          <para>
                              <emphasis role="bold">InitialStartDate</emphasis>: Date when the initial call is scheduled.
                              It can be either:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <literal>NOW</literal>: date will be the current time plus 1 seconds</para>
                              </listitem>
                              <listitem>
                                  <para>A number representing the milliseconds since 1/1/1970</para>
                              </listitem>
                              <listitem>
                                  <para>Date as String able to be parsed by <literal>SimpleDateFormat</literal> with
                                      default format pattern "<literal>M/d/yy h:mm a</literal>". If the date is in the
                                      past the <literal>Scheduler</literal> will search a start date in the future with
                                      respect to the initial repetitions and the period between calls. This means that
                                      when you restart the MBean (restarting JBoss etc.) it will start at the next
                                      scheduled time. When no start date is available in the future the
                                      <literal>Scheduler</literal> will not start.</para>
                              </listitem>
                          </itemizedlist>
                          <para>For example, if you start your <literal>Schedulable</literal> everyday at Noon and you
                              restart your JBoss server then it will start at the next Noon (the same if started before
                              Noon or the next day if start after Noon).</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">InitialRepetitions</emphasis>: The number of times the scheduler will
                              invoke the target's callback. If -1 then the callback will be repeated until the server is
                              stopped.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">StartAtStartup</emphasis>: A flag that determines if the
                                  <literal>Scheduler</literal> will start when it receives its startService life cycle
                              notification. If true the <literal>Scheduler</literal> starts on its startup. If false, an
                              explicit <literal>startSchedule</literal> operation must be invoked on the
                                  <literal>Scheduler</literal> to begin.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SchedulePeriod</emphasis>: The interval between scheduled calls in
                              milliseconds. This value must be bigger than 0.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SchedulableClass</emphasis>: The fully qualified class name of the
                                  <literal>org.jboss.varia.scheduler.Schedulable</literal> interface implementation that
                              is to be used by the <literal>Scheduler</literal> . The
                              <literal>SchedulableArguments</literal> and <literal>SchedulableArgumentTypes</literal> must
                              be populated to correspond to the constructor of the <literal>Schedulable</literal>
                              implementation.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SchedulableArguments</emphasis>: A comma separated list of arguments
                              for the <literal>Schedulable</literal> implementation class constructor. Only primitive data
                              types, <literal>String</literal> and classes with a constructor that accepts a
                                  <literal>String</literal> as its sole argument are supported.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SchedulableArgumentTypes</emphasis>: A comma separated list of
                              argument types for the <literal>Schedulable</literal> implementation class constructor. This
                              will be used to find the correct constructor via reflection. Only primitive data types,
                                  <literal>String</literal> and classes with a constructor that accepts a
                              <literal>String</literal> as its sole argument are supported.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SchedulableMBean</emphasis>: Specifies the fully qualified JMX
                                  <literal>ObjectName</literal> name of the schedulable MBean to be called. If the MBean
                              is not available it will not be called but the remaining repetitions will be decremented.
                              When using <literal>SchedulableMBean</literal> the <literal>SchedulableMBeanMethod</literal>
                              must also be specified.</para>
                      </listitem>
                      <listitem>
                          <para>
                              <emphasis role="bold">SchedulableMBeanMethod</emphasis>: Specifies the operation name to be
                              called on the schedulable MBean. It can optionally be followed by an opening bracket, a
                              comma separated list of parameter keywords, and a closing bracket. The supported parameter
                              keywords include:</para>
                          <itemizedlist>
                              <listitem>
                                  <para>
                                      <literal>NOTIFICATION</literal> which will be replaced by the timers notification
                                      instance (javax.management.Notification)</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <literal>DATE</literal> which will be replaced by the date of the notification call
                                      (java.util.Date)</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <literal>REPETITIONS</literal> which will be replaced by the number of remaining
                                      repetitions (long)</para>
                              </listitem>
                              <listitem>
                                  <para>
                                      <literal>SCHEDULER_NAME</literal> which will be replaced by the
                                      <literal>ObjectName</literal> of the <literal>Scheduler</literal>
                                  </para>
                              </listitem>
                              <listitem>
                                  <para>Any fully qualified class name which the <literal>Scheduler</literal> will set to
                                      null.</para>
                              </listitem>
                          </itemizedlist>
                      </listitem>
                  </itemizedlist>
                  <para>A given Scheduler instance only support a single schedulable instance. If you need to configure
                      multiple scheduled events you would use multiple <literal>Scheduler</literal> instances, each with a
                      unique <literal>ObjectName</literal>. The following is an example of configuring a
                          <literal>Scheduler</literal> to call a <literal>Schedulable</literal> implementation as well as
                      a configuration for calling a MBean.</para>
                  <programlisting>&lt;server&gt;
                   
      &lt;mbean code="org.jboss.varia.scheduler.Scheduler"
             name="jboss.docs.chap10:service=Scheduler"&gt;
          &lt;attribute name="StartAtStartup"&gt;true&lt;/attribute&gt;
          &lt;attribute name="SchedulableClass"&gt;org.jboss.chap10.ex2.ExSchedulable&lt;/attribute&gt;
          &lt;attribute name="SchedulableArguments"&gt;TheName,123456789&lt;/attribute&gt;
          &lt;attribute name="SchedulableArgumentTypes"&gt;java.lang.String,long&lt;/attribute&gt;
                   
          &lt;attribute name="InitialStartDate"&gt;NOW&lt;/attribute&gt;
          &lt;attribute name="SchedulePeriod"&gt;60000&lt;/attribute&gt;
          &lt;attribute name="InitialRepetitions"&gt;-1&lt;/attribute&gt;
      &lt;/mbean&gt;
                   
  &lt;/server&gt; </programlisting>
                  <para>The <literal>SchedulableClass</literal>
                      <literal>org.jboss.chap10.ex2.ExSchedulable</literal> example class is given below.</para>
                  <programlisting>package org.jboss.chap10.ex2;
  
  import java.util.Date;
  import org.jboss.varia.scheduler.Schedulable;
  
  import org.apache.log4j.Logger;
  
  /**
   * A simple Schedulable example.
   * @author Scott.Stark at jboss.org
   * @version $Revision: 1.1 $
   */
  public class ExSchedulable implements Schedulable
  {
      private static final Logger log = Logger.getLogger(ExSchedulable.class);
  
      private String name;
      private long value;
  
      public ExSchedulable(String name, long value)
      {
          this.name = name;
          this.value = value;
          log.info("ctor, name: " + name + ", value: " + value);
      }
  
      public void perform(Date now, long remainingRepetitions)
      {
          log.info("perform, now: " + now +
                   ", remainingRepetitions: " + remainingRepetitions +
                   ", name: " + name + ", value: " + value);
      }
  }</programlisting>
                  <para>Deploy the timer SAR by running:</para>
                  <programlisting>[examples]$ ant -Dchap=chap10 -Dex=2 run-example</programlisting>
                  <para>The server console shows the following which includes the first two timer invocations, separated
                      by 60 seconds:</para>
                  <programlisting>21:09:27,716 INFO  [ExSchedulable] ctor, name: TheName, value: 123456789
  21:09:28,925 INFO  [ExSchedulable] perform, now: Mon Dec 20 21:09:28 CST 2004, 
    remainingRepetitions: -1, name: TheName, value: 123456789
  21:10:28,899 INFO  [ExSchedulable] perform, now: Mon Dec 20 21:10:28 CST 2004, 
    remainingRepetitions: -1, name: TheName, value: 123456789
  21:11:28,897 INFO  [ExSchedulable] perform, now: Mon Dec 20 21:11:28 CST 2004, 
    remainingRepetitions: -1, name: TheName, value: 123456789</programlisting>
              </section>
          </section>
  
          <section id="ch10.timer">
              <title>The Timer Service</title>
              <para>The JMX standard defines a timer MBean (<literal>javax.management.timer.Timer</literal>) which can
                  send notifications at predetermined times. The a timer MBean can be instantiated within JBoss as any
                  other MBean. </para>
  
              <programlisting>&lt;mbean code=&quot;javax.management.timer.Timer&quot; name=&quot;jboss.monitor:name=Heartbeat,type=Timer&quot;/&gt;</programlisting>
  
  
              <para> A standard JMX timer doesn't produce any timer events unless it is asked to. To aid in the
                  configuration of the timer MBean, JBoss provides a complementary <literal>TimerService</literal> MBean.
                  It interacts with the timer MBean to configure timer events at regular intervals and to transform them
                  into JMX notifications more suitable for other services. The <literal>TimerService</literal> MBean takes
                  the following attributes: </para>
  
  
              <itemizedlist>
                  <listitem>
                      <para><emphasis role="bold">NotificationType</emphasis>: This is the type of the notification to be
                          generated. </para>
                  </listitem>
                  <listitem>
                      <para><emphasis role="bold">NotificationMessage</emphasis>: This is the message that should be
                          associated with the generated notification.</para>
                  </listitem>
  
                  <listitem>
                      <para><emphasis role="bold">TimerPeriod</emphasis>: This is the time period between notification.
                          The time period is in milliseconds, unless otherwise specified with a unit like "30min" or "4h".
                          Valid time suffixes are <literal>msec</literal>, <literal>sec</literal>, <literal>min</literal>
                          and <literal>h</literal>. </para>
                  </listitem>
                  <listitem>
                      <para><emphasis role="bold">Repeatitions</emphasis>: This is the number of times the alert should be
                          generated. A value of 0 indicates the alert should repeat indefinitely.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">TimerMbean</emphasis>: This is the <literal>ObjectName</literal> of the
                          time MBean that this <literal>TimerService</literal> instance should configure notifications
                          for. </para>
                  </listitem>
  
              </itemizedlist>
  
              <para>The following sample illustrates the the use of the <literal>TimerService</literal> MBean.</para>
  
  
              <programlisting>&lt;mbean code=&quot;org.jboss.monitor.services.TimerService&quot; 
         name=&quot;jboss.monitor:name=Heartbeat,type=TimerService&quot;&gt;
      &lt;attribute name=&quot;NotificationType&quot;&gt;jboss.monitor.heartbeat&lt;/attribute&gt;
      &lt;attribute name=&quot;NotificationMessage&quot;&gt;JBoss is alive!&lt;/attribute&gt;
      &lt;attribute name=&quot;TimerPeriod&quot;&gt;60sec&lt;/attribute&gt;
      &lt;depends optional-attribute-name=&quot;TimerMBean&quot;&gt;
          jboss.monitor:name=Heartbeat,type=Timer
      &lt;/depends&gt;
  &lt;/mbean&gt;</programlisting>
  
              <para>This MBean configuration configures the <literal>jboss.monitor:name=Heartbeat,type=Timer</literal>
                  timer to generate a <literal>jboss.monitor.heartbeat</literal> notification every 60 seconds. Any
                  service that that wants to receive this periodic notifications can subscribe to the notification. </para>
  
              <para>As an example, JBoss provides a simple <literal>NotificationListener</literal> MBean that can listen
                  for a particular notifcation and log a log message when an event is generated. This MBean is very useful
                  for debugging or manually observing notifications. The following MBean definition listens for any events
                  generated by the heartbeat timer used in the previous examples. </para>
  
  
              <programlisting>&lt;mbean code=&quot;org.jboss.monitor.services.NotificationListener&quot; 
         name=&quot;jboss.monitor:service=NotificationListener&quot;&gt;
      &lt;attribute name=&quot;SubscriptionList&quot;&gt;
          &lt;subscription-list&gt;
              &lt;mbean name=&quot;jboss.monitor:name=Heartbeat,type=Timer&quot; /&gt;
          &lt;/subscription-list&gt;
      &lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
  
              <para> The <literal>subscription-list</literal> element lists which MBeans the listener should listen to.
                  Notice that the MBean we are listening to is the name of the actual timer MBean and not the
                      <literal>TimerService</literal> MBean. Because the timer might generate multiple events, configured
                  by multiple <literal>TimerService</literal> instances, you may need to filter by notification type. The
                      <literal>filter</literal> element can be used to create notification filters that select only the
                  notification types desired. The following listing shows how we can limit notifications to only the
                      <literal>jboss.monitor.heartbeat</literal> type the timer service configured. </para>
  
  
              <programlisting>&lt;mbean code=&quot;org.jboss.monitor.services.NotificationListener&quot;
        name=&quot;jboss.monitor:service=NotificationListener&quot;&gt;
      &lt;attribute name=&quot;SubscriptionList&quot;&gt;
          &lt;subscription-list&gt;
              &lt;mbean name=&quot;jboss.monitor:name=Heartbeat,type=Timer&quot;&gt;
                  &lt;filter factory=&quot;NotificationFilterSupportFactory&quot;&gt;
                      &lt;enable type=&quot;jboss.monitor.heartbeat&quot;/&gt;                        
                  &lt;/filter&gt;
              &lt;/mbean&gt;
          &lt;/subscription-list&gt;
      &lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
  
              <para>As an example of a slightly more interesting listener, we'll look at the ScriptingListener. This
                  listener listens for particular events and then executes a specified script when events are received.
                  The script can be writen in any bean shell scripting language. The ScriptingListener accepts has the
                  following parameters.</para>
  
              <itemizedlist>
                  <listitem>
                      <para><emphasis role="bold">ScriptLanguage</emphasis>: This is the language the script is written
                          in. This should be <literal>beanshell</literal>, unless you have loaded libraries for another
                          beanshell compatible language.</para>
                  </listitem>
                  <listitem>
                      <para><emphasis role="bold">Script</emphasis>: This is the text of the script to evaluate. It is
                          good practice to enclose the script in a CDATA section to minimize conflicts between scripting
                          language syntax and XML syntax.</para>
                  </listitem>
                  <listitem>
                      <para><emphasis role="bold">SubscriptionList</emphasis>: This is the list of MBeans that this MBean
                          will listen to for events that will trigger the script.</para>
                  </listitem>
              </itemizedlist>
  
              <para>The following example illustrates the use of the <literal>ScriptingListener</literal>. When the
                  previously configured timer generates a heartbeat notification, the beanshell script will execute,
                  printing the current memory values to STDOUT. (This output will be redirected to the log files) Notice
                  that the beanshell script has a reference to the MBean server and can execute operations against other
                  MBeans. </para>
  
              <programlisting>&lt;mbean code=&quot;org.jboss.monitor.services.ScriptingListener&quot; 
         name=&quot;jboss.monitor:service=ScriptingListener&quot;&gt; 
      &lt;attribute name=&quot;SubscriptionList&quot;&gt;
          &lt;subscription-list&gt;
              &lt;mbean name=&quot;jboss.monitor:name=Heartbeat,type=Timer&quot;/&gt;
          &lt;/subscription-list&gt;
      &lt;/attribute&gt;
      &lt;attribute name=&quot;ScriptLanguage&quot;&gt;beanshell&lt;/attribute&gt;
      &lt;attribute name=&quot;Script&quot;&gt;
                  &lt;![CDATA[
     import javax.management.ObjectName;
  
     /* poll free memory and thread count */   
     ObjectName target = new ObjectName(&quot;jboss.system:type=ServerInfo&quot;);
  
     long freeMemory = server.getAttribute(target, &quot;FreeMemory&quot;);
     long threadCount = server.getAttribute(target, &quot;ActiveThreadCount&quot;);
  
     log.info(&quot;freeMemory&quot; + freeMemory + &quot;, threadCount&quot; + threadCount);
  ]]&gt;
      &lt;/attribute&gt;
  &lt;/mbean&gt;</programlisting>
  
  
              <para>Of course, you are not limited to these JBoss-provided notification listeners. Other services such as
                  the barrier service (see <xref linkend="ch10.barrier"/>) receive and act on notifications that could be
                  generated from a timer. Additionally, any MBean can be coded to listen for timer-generated
                  notifications. </para>
          </section>
  
  
  
          <section id="ch10.barrier">
              <title>The BarrierController Service</title>
              <para> Expressing dependencies between services using the &lt;depends&gt; tag is a convenient way to
                  make the lifecycle of one service depend on the lifecycle of another. For example, when
                      <literal>serviceA</literal> depends on <literal>serviceB</literal> JBoss will ensure the
                      <literal>serviceB.create()</literal> is called before <literal>serviceA.create()</literal> and
                      <literal>serviceB.start()</literal> is called before <literal>serviceA.start()</literal>.</para>
              <para>However, there are cases where services do not conform to the JBoss lifecycle model, i.e. they don't
                  expose create/start/stop/destroy lifesycle methods). This is the case for
                      <literal>jboss.system:type=Server MBean</literal>, which represents the JBoss server itself. No
                  lifecycle operations are exposed so you cannot simply express a dependcy like: if JBoss is fully started
                  then start my own service.</para>
              <para>Or, even if they do conform to the JBoss lifecycle model, the completion of a lifecycle method (e.g.
                  the <literal>start</literal> method) may not be sufficient to describe a dependency. For example the
                      <literal>jboss.web:service=WebServer</literal> MBean that wraps the embedded Tomcat server in JBoss
                  does not start the Tomcat connectors until after the server is fully started. So putting a dependency on
                  this MBean, if we want to hit a webpage through Tomcat, will do no good.</para>
              <para>Resolving such non-trivial dependencies is currently performed using JMX notifications. For example
                  the <literal>jboss.system:type=Server</literal> MBean emits a notification of type
                      <literal>org.jboss.system.server.started</literal> when it has completed startup, and a notification
                  of type <literal>org.jboss.system.server.stopped</literal> when it shuts down. Similarly,
                      <literal>jboss.web:service=WebServer</literal> emits a notification of type
                      <literal>jboss.tomcat.connectors.started</literal> when it starts up. Services can subscribe to
                  those notifications in order to implement more complex dependencies. This technique has been generalized
                  with the barrier controller service. </para>
              <para> The barrier controller is a relatively simple MBean service that extends
                      <literal>ListenerServiceMBeanSupport</literal> and thus can subscribe to any notification in the
                  system. It uses the received notifications to control the lifecycle of a dynamically created MBean
                  called the barrier. </para>
              <para> The barrier is instantiated, registered and brought to the create state when the barrier controller
                  is deployed. After that, the barrier is started and stopped when matching notifications are received.
                  Thus, other services need only depend on the barrier MBean using the usual
                      <literal>&lt;depends&gt;</literal> tag, without having to worry about complex lifecycle
                  issues. They will be started and stopped in tandem with the Barrier. When the barrier controller is
                  undeployed the barrier is destroyed. </para>
              <para> The notifications of interest are configured in the barrier controller using the
                      <literal>SubscriptionList</literal> attribute. In order to identify the starting and stopping
                  notifications we associate with each subscription a handback string object. Handback objects, if
                  specified, are passed back along with the delivered notifications at reception time (i.e. when
                      <literal>handleNotification()</literal> is called) to qualify the received notifications, so that
                  you can identify quickly from which subscription a notification is originating (because your listener
                  can have many active subscriptions).</para>
              <para> So we tag the subscriptions that produce the starting/stopping notifications of interest using any
                  handback strings, and we configure this same string to the <literal>StartBarrierHandback</literal> (and
                      <literal>StopBarrierHandback</literal> correspondingly) attribute of the barrier controller. Thus we
                  can have more than one notifications triggering the starting or stopping of the barrier. </para>
              <para>The following example shows a service that depends on the Tomcat connectors. In fact, this is a very
                  common pattern for services that want to hit a servlet inside tomcat. The service that depends on the
                  Barrier in the example, is a simple memory monitor that creates a background thread and monitors the
                  memory usage, emitting notifications when thresholds get crossed, but it could be anything. We've used
                  this because it prints out to the console starting and stopping messages, so we know when the service
                  gets activated/deactivated.</para>
              <programlisting>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  &lt;!-- $Id: master.xml,v 1.1 2006/09/18 16:48:19 nrichards Exp $ --&gt;
  
  &lt;server&gt;
    &lt;!--
      In this example we have the BarrierController controlling a Barrier
      that is started when we receive the &quot;jboss.tomcat.connectors.started&quot;
      notification from the Tomcat mbean, and stopped when we receive the
      &quot;org.jboss.system.server.stopped&quot; notification from the server mbean.
      
      The dependent services need only define a dependency on the Barrier mbean!
    --&gt;
    &lt;mbean code=&quot;org.jboss.system.BarrierController&quot;
           name=&quot;jboss:service=BarrierController&quot;&gt;
      
      &lt;!-- Whether to have the Barrier initially started or not --&gt;
      &lt;attribute name=&quot;BarrierEnabledOnStartup&quot;&gt;false&lt;/attribute&gt;
      
      &lt;!-- Whether to subscribe for notifications after startup --&gt;
      &lt;attribute name=&quot;DynamicSubscriptions&quot;&gt;true&lt;/attribute&gt;
      
      &lt;!-- Dependent services will depend on this mbean --&gt;
      &lt;attribute name=&quot;BarrierObjectName&quot;&gt;jboss:name=TomcatConnector,type=Barrier&lt;/attribute&gt;
      
      &lt;!-- The notification subscription handback that starts the barrier --&gt;
      &lt;attribute name=&quot;StartBarrierHandback&quot;&gt;start&lt;/attribute&gt;
      
      &lt;!-- The notification subscription handback that stops the barrier --&gt;
      &lt;attribute name=&quot;StopBarrierHandback&quot;&gt;stop&lt;/attribute&gt;
      
      &lt;!-- The notifications to subscribe for, along with their handbacks --&gt;
      &lt;attribute name=&quot;SubscriptionList&quot;&gt;
        &lt;subscription-list&gt;
          &lt;mbean name=&quot;jboss.web:service=WebServer&quot; handback=&quot;start&quot;&gt;
            &lt;filter factory=&quot;NotificationFilterSupportFactory&quot;&gt;
              &lt;enable type=&quot;jboss.tomcat.connectors.started&quot;/&gt;
            &lt;/filter&gt;
          &lt;/mbean&gt;
          &lt;mbean name=&quot;jboss.system:type=Server&quot; handback=&quot;stop&quot;&gt;
            &lt;filter factory=&quot;NotificationFilterSupportFactory&quot;&gt;
              &lt;enable type=&quot;org.jboss.system.server.stopped&quot;/&gt;
            &lt;/filter&gt;
          &lt;/mbean&gt;        
        &lt;/subscription-list&gt;
      &lt;/attribute&gt;
    &lt;/mbean&gt;
  
    &lt;!--
      An example service that depends on the Barrier we declared above.
      This services creates a background thread and monitors the memory
      usage. When it exceeds the defined thresholds it emits notifications
    --&gt;
    &lt;mbean code=&quot;org.jboss.monitor.services.MemoryMonitor&quot;
           name=&quot;jboss.monitor:service=MemoryMonitor&quot;&gt;
  
      &lt;attribute name=&quot;FreeMemoryWarningThreshold&quot;&gt;20m&lt;/attribute&gt;
      &lt;attribute name=&quot;FreeMemoryCriticalThreshold&quot;&gt;15m&lt;/attribute&gt;
      
      &lt;!-- The BarrierObjectName configured in the BarrierController --&gt;
      &lt;depends&gt;jboss:name=TomcatConnector,type=Barrier&lt;/depends&gt;
    &lt;/mbean&gt;
    
  &lt;/server&gt;</programlisting>
              <para>If you hot-deploy this on a running server the Barrier will be stopped because by the time the barrier
                  controller is deployed the starting notification is already seen. (There are ways to overcome this.)
                  However, if you re-start the server, the barrier will be started just after the Tomcat connectors get
                  activated. You can also manually start or stop the barrier by using the
                  <literal>startBarrier()</literal> and <literal>stopBarrier()</literal> operations on the barrier
                  controller. The attribute <literal>BarrierStateString</literal> indicates the status of the barrier.
              </para>
          </section>
  
  
  
          <section id="ch10.snmp">
              <title> Exposing MBean Events via SNMP</title>
              <para>JBoss has an SNMP adaptor service that can be used to intercept JMX notifications emitted by MBeans,
                  convert them to traps and send them to SNMP managers. In this respect the snmp-adaptor acts as a SNMP
                  agent. Future versions may offer support for full agent get/set functionality that maps onto MBean
                  attributes or operations.</para>
              <para>This service can be used to integrate JBoss with higher order system/network management platforms (HP
                  OpenView, for example), making the MBeans visible to those systems. The MBean developer can instrument
                  the MBeans by producing notifications for any significant event (e.g. server coldstart), and adaptor can
                  then be configured to intercept the notification and map it onto an SNMP traps. The adaptor uses the
                  JoeSNMP package from OpenNMS as the SNMP engine.</para>
              <para>The SNMP service is configured in <literal>snmp-adaptor.sar</literal>. This service is only available
                  in the <literal>all</literal> configuration, so you'll need to copy it to your configuration if you want
                  to use it. Inside the snmp-adaptor.sar directory, there are two configuration files that control the
                  SNMP service.</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">managers.xml</emphasis>: configures where to send traps. The content model
                          for this file is shown in <xref linkend="ch2.snmp.fig"/>.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">notifications.xml</emphasis>: specifies the exact mapping of each
                          notification type to a corresponding SNMP trap. The content model for this file is shown in
                              <xref linkend="ch2.trap.fig"/>.</para>
                  </listitem>
              </itemizedlist>
              <para>The <literal>SNMPAgentService</literal> MBean is configured in
                      <literal>snmp-adaptor.sar/META-INF/jboss-service.xml</literal>. The configurable parameters are:</para>
              <itemizedlist>
                  <listitem>
                      <para>
                          <emphasis role="bold">HeartBeatPeriod</emphasis>: The period in seconds at which heartbeat
                          notifications are generated.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">ManagersResName</emphasis>: Specifies the resource name of the
                              <literal>managers.xml</literal> file.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">NotificationMapResName</emphasis>: Specifies the resource name of the
                              <literal>notications.xml</literal> file. </para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">TrapFactoryClassName</emphasis>: The
                              <literal>org.jboss.jmx.adaptor.snmp.agent.TrapFactory</literal> implementation class that
                          takes care of translation of JMX Notifications into SNMP V1 and V2 traps.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">TimerName</emphasis>: Specifies the JMX ObjectName of the JMX timer
                          service to use for heartbeat notifications.</para>
                  </listitem>
                  <listitem>
                      <para>
                          <emphasis role="bold">SubscriptionList</emphasis>: Specifies which MBeans and notifications to
                          listen for.</para>
                  </listitem>
              </itemizedlist>
              <figure id="ch2.snmp.fig">
                  <title>The schema for the SNMP managers file</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/snmp-manager-list.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
              <figure id="ch2.trap.fig">
                  <title>The schema for the notification to trap mapping file</title>
                  <mediaobject>
                      <imageobject>
                          <imagedata align="center" fileref="images/snmp-notification-map-list.jpg"/>
                      </imageobject>
                  </mediaobject>
              </figure>
  
              <para><literal>TrapdService</literal> is a simple MBean that acts as an SNMP Manager. It listens to a
                  configurable port for incoming traps and logs them as DEBUG messages using the system logger. You can
                  modify the log4j configuration to redirect the log output to a file. <literal>SnmpAgentService</literal>
                  and <literal>TrapdService</literal> are not dependent on each other.</para>
  
          </section>
      </chapter>
  
  
      <appendix id="appendix-install">
          <title>Book Example Installation</title>
          <para>The book comes with the source code for the examples discussed in the book. The examples are included with
              the book archive. Unzipping the example code archive creates a JBoss <literal>jboss4guide</literal>
              directory that contains an <literal>examples</literal> subdirectory. This is the <literal>examples</literal>
              directory referred to by the book.</para>
          <para>The only customization needed before the examples may be used is to set the location of the JBoss server
              distribution. This may be done by editing the <literal>examples/build.xml</literal> file and changing the
                  <literal>jboss.dist</literal> property value. This is shown in bold below:</para>
          <programlisting>&lt;project name=&quot;JBoss book examples&quot; default=&quot;build-all&quot; basedir=&quot;.&quot;&gt;
      &lt;!-- Allow override from local properties file --&gt;
      &lt;property file=&quot;ant.properties&quot;/&gt;
  
      &lt;!-- Override with your JBoss server bundle dist location --&gt;
      &lt;property name=&quot;jboss.dist&quot;        value=&quot;<emphasis role="bold">/tmp/jboss-4.0.3</emphasis>&quot;/&gt;
      &lt;property name=&quot;jboss.deploy.conf&quot; value=&quot;default&quot;/&gt;
      ...</programlisting>
          <para>or by creating an <literal>.ant.properties</literal> file in the examples directory that contains a
              definition for the <literal>jboss.dist</literal> property. For example:</para>
          <programlisting>jboss.dist=/usr/local/jboss/jboss-4.0.1</programlisting>
          <para>Part of the verification process validates that the version you are running the examples against matches
              what the book examples were tested against. If you have a problem running the examples first look for the
              output of the validate target such as the following:</para>
          <programlisting>validate:
       [java] ImplementationTitle: JBoss [Zion]
       [java] ImplementationVendor: JBoss Inc.
       [java] ImplementationVersion: 4.0.1 (build: CVSTag=JBoss_4_0_1 date=200412230944)
       [java] SpecificationTitle: JBoss
       [java] SpecificationVendor: JBoss (http://www.jboss.org/)
       [java] SpecificationVersion: 4.0.1
       [java] JBoss version is: 4.0.1</programlisting>
      </appendix>
  
  
  
  </book>
  
  
  



More information about the jboss-cvs-commits mailing list