[jboss-cvs] JBossRemoting/docs/guide/en ...

Ron Sigal ron_sigal at yahoo.com
Sun Jul 30 02:56:36 EDT 2006


  User: rsigal  
  Date: 06/07/30 02:56:36

  Added:       docs/guide/en                 chap15.xml chap4.xml chap5.xml
                        chap2.xml chap1.xml chap13.xml chap8.xml chap3.xml
                        chap10.xml chap7.xml chap6.xml chap12.xml
                        chap11.xml chap14.xml chap9.xml chap16.xml
  Log:
  JBREM-558:  Broke master.xml into 16 chapters, which are imported by a new master.xml.
  
  Revision  Changes    Path
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap15.xml
  
  Index: chap15.xml
  ===================================================================
    <chapter>
      <title>Future plans</title>
  
      <para>Full road map for JBossRemoting can be found at <!--<link linkend="???">
                  http://jira.jboss.com/jira/browse/JBREM?report=com.atlassian.jira.plugin.system.project:roadmap-panel
               </link>--> <ulink
      url="http://jira.jboss.com/jira/browse/JBREM?report=com.atlassian.jira.plugin.system.project:roadmap-panel">
      http://jira.jboss.com/jira/browse/JBREM?report=com.atlassian.jira.plugin.system.project:roadmap-panel
      </ulink>.</para>
  
      <para>If you have questions, comments, bugs, fixes, contributions, or
      flames, please post them to the JBoss Remoting users forum <!--<link linkend="???">http://www.jboss.com/index.html?module=bb&amp;op=viewforum&amp;f=222</link>-->
      (<ulink
      url="http://www.jboss.com/index.html?module=bb&amp;op=viewforum&amp;f=222">
      http://www.jboss.com/index.html?module=bb&amp;op=viewforum&amp;f=222
      </ulink>). You can also find more information about JBoss Remoting on our
      <!--<link linkend="???">http://www.jboss.org/wiki/Wiki.jsp?page=Remoting</link>-->
      wiki (<ulink url="http://www.jboss.org/wiki/Wiki.jsp?page=Remoting">
      http://www.jboss.org/wiki/Wiki.jsp?page=Remoting </ulink> ). The wiki will
      usually contain the latest updates to doc and features that did not make
      into previous release.</para>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap4.xml
  
  Index: chap4.xml
  ===================================================================
    <chapter>
      <title>Remoting libraries and thirdparty dependancies</title>
  
      <para>The remoting distribution comes several different version of the
      remoting libraries. This is mainly done so the size of the footprint for
      can be controlled based on the features of remoting that will be used.
      Remoting distribution will include the following remoting binaries (found
      in the lib directory of the distribution)</para>
  
      <para><emphasis role="bold">jboss-remoting.jar</emphasis> - this binary
      contains all the remoting classes. This is the only remoting jar that is
      needed to perform any remoting funtion within JBoss Remoting.</para>
  
      <para>Since some may want to better control size of the binary footprint
      needed to use remoting, the remoting classes have been broken out into
      multiple remoting binaries based on their function. There are four
      categories of these binaries; core, detection, transport, and
      other.</para>
  
      <bridgehead>core</bridgehead>
  
      <para><emphasis role="bold">jboss-remoting-core.jar</emphasis> - contains
      all the core remoting classes needed for remoting to function. If not
      using jboss-remoting.jar, then jboss-remoting.core.jar will be
      required.</para>
  
      <bridgehead>detection</bridgehead>
  
      <para><emphasis role="bold">jboss-remoting-detection</emphasis> - contains
      all the remoting classes needed to perform automatic discovery of remoting
      servers. It includes both the jndi and multicast detector classes as well
      as the network registry classes.</para>
  
      <bridgehead>transport</bridgehead>
  
      <para><emphasis role="bold">jboss-remoting-socket.jar</emphasis> -
      contains all the classes needed for the socket and sslsocket transports to
      function as both a client and a server.</para>
  
      <para><emphasis><emphasis
      role="bold">jboss-remoting-socket-client.jar</emphasis></emphasis> -
      contains all the classes needed for the socket and sslsocket transports to
      function as a client only. This means will not be able to perform any push
      callbacks or sending of streams using this jar.</para>
  
      <para><emphasis role="bold">jboss-remoting-http.jar</emphasis> - contains
      all the classes needed for the http and https transports to function as a
      client and a server.</para>
  
      <para><emphasis role="bold">jboss-remoting-http-client.jar</emphasis> -
      contains all the classes needed for the http, https, servlet, and
      sslservlet transports to function as a client only. This means will not be
      able to perform any push callbacks or sending of streams using this
      jar.</para>
  
      <para><emphasis role="bold">jboss-remoting-servlet.jar</emphasis> -
      contains all the classes needed for the servlet or sslservlet transports
      to function as a server only (also requires servlet-invoker.war be
      deployed within web container as well)</para>
  
      <para><emphasis role="bold">jboss-remoting-rmi.jar</emphasis> - contains
      all the classes needed for the rmi and sslrmi transports to function as a
      client and a server.</para>
  
      <para><emphasis role="bold">jboss-remoting-multiplex.jar</emphasis> -
      contains all the classes needed for the multiplex and sslmultiplex
      transports to function as a client and a server. Use of this jar also
      requires jboss-remoting-socket.jar be on classpath as well.</para>
  
      <bridgehead>other</bridgehead>
  
      <para><emphasis role="bold">jboss-remoting-serialization.jar</emphasis> -
      contains just the remoting serialization classes (and serialization
      manager implementations for java and jboss).</para>
  
      <para><emphasis role="bold"><emphasis
      role="bold">jboss-remoting-samples.jar</emphasis> </emphasis>- all the
      remoting samples showing example code for different remotng
      functions.</para>
  
      <section>
        <title>Thirdparty libraries</title>
  
        <para>This section covers which thirdparty jars are required based on
        the feature or transport to be used. Remember, whenever see
        jboss-remoting-XXX.jar mentioned, they can all be replaced with just the
        jboss-remoting.jar.</para>
  
        <para><emphasis role="bold">All remoting servers:</emphasis>
        jboss-remoting-core.jar, jboss-common.jar, jboss-jmx.jar,
        log4j.jar</para>
  
        <para><emphasis role="bold">All remoting clients:
        </emphasis>jboss-remoting-core.jar, jboss-common.jar, jboss-jmx.jar,
        log4j.jar, concurrent.jar</para>
  
        <para>Note: concurrent.jar needed because of org.jboss.util.id.GUID used
        to create session id within Client
        (http://jira.jboss.com/jira/browse/JBREM-549)</para>
  
        <para>Remoting requires the use of JMX classes. It does not require the
        JBoss implementation (jboss-jmx.jar) of JMX in order to function
        correctly, so can replace jboss-jmx.jar with another JMX implementation
        library (or exclude it if using jdk 1.5 or higher, which has JMX
        implementation built in).</para>
  
        <para><emphasis role="bold">Multicast detection:
        </emphasis>jboss-remoting-detection.jar, concurrent.jar,
        dom4j.jar</para>
  
        <para><emphasis role="bold">JNDI detection:</emphasis>
        jboss-remoting-detection.jar, concurrent.jar, dom4j.jar, jnpserver.jar
        (for jndi api classes)</para>
  
        <para>The dom4j.jar for use of detection is required because using
        jboss-jmx.jar.</para>
  
        <para><emphasis role="bold">Socket server:</emphasis>
        jboss-remoting-socket.jar</para>
  
        <para><emphasis role="bold">Socket client:</emphasis>
        jboss-remoting-socket-client.jar</para>
  
        <para><emphasis role="bold">HTTP server:</emphasis>
        jboss-remoting-http.jar, tomcat-coyote.jar, tomcat-util.jar,
        commons-logging-api.jar, tomcat-http.jar</para>
  
        <para>Note: need tomcat-apr.jar and tcnative-1.dll/tcnative-1.so on
        system path if want to use APR based tomcat connector</para>
  
        <para><emphasis role="bold">HTTP client:</emphasis>
        jboss-remoting-http-client.jar</para>
  
        <para><emphasis role="bold">Servlet server:</emphasis>
        servlet-invoker.war (deployed in web container),
        jboss-remoting-servlet.jar</para>
  
        <para><emphasis role="bold">Servlet client:</emphasis>
        jboss-remoting-http-client.jar</para>
  
        <para><emphasis role="bold">RMI server and client:</emphasis>
        jboss-remoting-rmi.jar</para>
  
        <para><emphasis role="bold">Multiplex server and client:</emphasis>
        jboss-remoting-socket.jar, jboss-remoting-multiplex.jar</para>
  
        <para><emphasis role="bold">JBoss serialization:</emphasis>
        jboss-serialization.jar, trove.jar</para>
      </section>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap5.xml
  
  Index: chap5.xml
  ===================================================================
    <chapter>
      <title>Configuration</title>
  
      <para>This covers the configuration for JBoss Remoting discovery,
      connectors, marshallers, and transports. All the configuration properties
      specified can be set either via calls to the object itself, including via
      JMX (so can be done via the JMX or Web console), or via a JBoss AS service
      xml file. Examples of service xml configurations can be seen with each of
      the sections below. There is also an example-service.xml file included in
      the remoting distribution that shows full examples of all the remoting
      configurations.</para>
  
      <section>
        <title>General Connector and Invoker configuration</title>
  
        <para>The server invoker and invocation handlers are configured via the
        Connector. Only one invoker can be declared per connector (multiple
        InvokerLocator attributes or invoker elements within the Configuration
        attribute is not permitted). Although declaring an invocation handler is
        not required, it should only be omitted in the case of declaring a
        callback server that will not receive direct invocations, but only
        callback messages. Otherwise client invocations can not be processed.
        The invocation handler is the only interface that is required by the
        remoting framework for a user to implement and will be what the remoting
        framework calls upon when receiving invocations.</para>
  
        <para>There are two ways in which to specify the server invoker
        configuration via a service xml file. The first is to specify just the
        InvokerLocator attribute as a sub-element of the Connector MBean. For
        example, a possible configuration for a Connector using a socket invoker
        that is listening on port 8084 on the test.somedomain.com address would
        be:</para>
  
        <programlisting>
           &lt;mbean code="org.jboss.remoting.transport.Connector"
                 xmbean-dd="org/jboss/remoting/transport/Connector.xml"
                 name="jboss.remoting:service=Connector,transport=Socket"
                 display-name="Socket transport Connector"&gt;
              &lt;attribute name="<emphasis role="bold">InvokerLocator</emphasis>"&gt;
                 &lt;![CDATA[<emphasis role="bold">socket://test.somedomain.com:8084</emphasis>]]&gt;
              &lt;/attribute&gt;
              &lt;attribute name="Configuration"&gt;
                 &lt;config&gt;
                    &lt;handlers&gt;
                       &lt;handler <emphasis role="bold">subsystem</emphasis>="mock"&gt;
                          <emphasis role="bold">org.jboss.remoting.transport.mock.MockServerInvocationHandler</emphasis>
                       &lt;/handler&gt;
                    &lt;/handlers&gt;
                 &lt;/config&gt;
              &lt;/attribute&gt;
           &lt;/mbean&gt;
        </programlisting>
  
        <para>Note that all the server side socket invoker configurations will
        be set to their default values in this case. Also, it is important to
        add CDATA to any locator uri that contains more than one
        parameter.</para>
  
        <para>The other way to configure the Connector and its server invoker in
        greater detail is to provide an <code>invoker</code> sub-element within
        the config element of the Configuration attribute. The only attribute of
        invoker element is transport, which will specify which transport type to
        use (e.g.. socket, rmi, http, or multiplex). All the sub-elements of the
        invoker element will be attribute elements with a name attribute
        specifying the configuration property name and then the value. An
        <code>isParam</code> attribute can also be added to indicate that the
        attribute should be added to the locator uri, in the case the attribute
        needs to be used by the client. An example using this form of
        configuration is as follows:</para>
  
        <programlisting> 
           &lt;mbean code="org.jboss.remoting.transport.Connector"
                 xmbean-dd="org/jboss/remoting/transport/Connector.xml"
                 name="jboss.remoting:service=Connector,transport=Socket"
                 display-name="Socket transport Connector"&gt;
  
              &lt;attribute name="Configuration"&gt;
                 &lt;config&gt;
                 <emphasis role="bold"> 
                    &lt;invoker transport="socket"&gt;
                       &lt;attribute name="numAcceptThreads"&gt;1&lt;/attribute&gt;
                       &lt;attribute name="maxPoolSize"&gt;303&lt;/attribute&gt;
                       &lt;attribute name="clientMaxPoolSize" isParam="true"&gt;304&lt;/attribute&gt;
                       &lt;attribute name="socketTimeout"&gt;60000&lt;/attribute&gt;
                       &lt;attribute name="serverBindAddress"&gt;192.168.0.82&lt;/attribute&gt;
                       &lt;attribute name="serverBindPort"&gt;6666&lt;/attribute&gt;
                       &lt;attribute name="clientConnectAddress"&gt;216.23.33.2&lt;/attribute&gt;
                       &lt;attribute name="clientConnectPort"&gt;7777&lt;/attribute&gt;
                       &lt;attribute name="enableTcpNoDelay" isParam="true"&gt;false&lt;/attribute&gt;
                       &lt;attribute name="backlog"&gt;200&lt;/attribute&gt;
                    &lt;/invoker&gt;
                 </emphasis>
                    &lt;handlers&gt;
                       &lt;handler subsystem="mock"&gt;
                          org.jboss.remoting.transport.mock.MockServerInvocationHandler
                       &lt;/handler&gt;
                    &lt;/handlers&gt;
                 &lt;/config&gt;
              &lt;/attribute&gt;
  
           &lt;/mbean&gt;
        </programlisting>
  
        <para>Also note that <code>${jboss.bind.address}</code> can be used for
        any of the bind address properties, which will be replaced with the bind
        address specified to JBoss when starting (i.e. via the -b
        option).</para>
  
        <para>All the attributes set in this configuration could be set directly
        in the locator uri of the InvokerLocator attribute value, but would be
        much more difficult to decipher visually and is more prone to editing
        mistakes.</para>
  
        <para>One of the components of a locator uri that can be expressed
        within the InvokerLocator attribute is the path. For example, can
        express a locator uri path of 'foo/bar' via the InvokerLocator attribute
        as:</para>
  
        <programlisting>            &lt;attribute name="InvokerLocator"&gt;&lt;![CDATA[socket://test.somedomain.com:8084/<emphasis
            role="bold">foo/bar</emphasis>]]&gt;&lt;/attribute&gt;
  </programlisting>
  
        <para>To include the path using the Configuration attribute, can include
        a specific 'path' attribute. So the same InvokerLocator can be expressed
        as follows with the Configuration attribute:</para>
  
        <programlisting>
              &lt;attribute name="Configuration"&gt;
                 &lt;config&gt;
                   &lt;invoker transport="socket"&gt;
                     &lt;attribute name="serverBindAddress"&gt;test.somedomain.com&lt;/attribute&gt;
                     &lt;attribute name="serverBindPort"&gt;8084&lt;/attribute&gt;
                     <emphasis role="bold">&lt;attribute name="path"&gt;foo/bar&lt;/attribute&gt;</emphasis>
                   &lt;/invoker&gt;
                   ...
  </programlisting>
  
        <para>Note: The value for the 'path' attribute should NOT start or end
        with a / (slash).</para>
      </section>
  
      <section>
        <title>Handlers</title>
  
        <para>Handlers are classes that the invocation is given to on the server
        side (the final target for remoting invocations). To implement a
        handler, all that is needed is to implement the
        <code>org.jboss.remoting.ServerInvocationHandler</code> interface. There
        are a two ways in which to register a handler with a Connector. The
        first is to do it programmatically. The second is via service
        configuration. For registering programmatically, can either pass the
        ServerInvocationHandler reference itself or an ObjectName for the
        ServerInvocationHandler (in the case that it is an MBean). To pass the
        handler reference directly, call
        <code>Connector::addInvocationHandler(String subsystem,
        ServerInvocationHandler handler)</code>. For example (from
        <code>org.jboss.remoting.samples.simple.SimpleServer</code>):</para>
  
        <programlisting>
              InvokerLocator locator = new InvokerLocator(locatorURI);
              Connector connector = new Connector();
              connector.setInvokerLocator(locator.getLocatorURI());
              connector.create();
  
              SampleInvocationHandler invocationHandler = new SampleInvocationHandler();
              // first parameter is sub-system name. can be any String value.
              connector.addInvocationHandler("sample", invocationHandler);
  
              connector.start();
           </programlisting>
  
        <para>To pass the handler by ObjectName, call
        <code>Connector::addInvocationHandler(String subsystem, ObjectName
        handlerObjectName)</code> . For example (from
        <code>org.jboss.test.remoting.handler.mbean.ServerTest</code>):</para>
  
        <programlisting>
              MBeanServer server = MBeanServerFactory.createMBeanServer();
              InvokerLocator locator = new InvokerLocator(locatorURI);
              Connector connector = new Connector();
              connector.setInvokerLocator(locator.getLocatorURI());
              connector.start();
  
              server.registerMBean(connector, new ObjectName("test:type=connector,transport=socket"));
  
              // now create Mbean handler and register with mbean server
              MBeanHandler handler = new MBeanHandler();
              ObjectName objName = new ObjectName("test:type=handler");
              server.registerMBean(handler, objName);
  
              connector.addInvocationHandler("test", objName);
           </programlisting>
  
        <para>Is important to note that if not starting the Connector via the
        service configuration, will need to explicitly register it with the
        MBeanServer (will throw exception otherwise).</para>
  
        <para>If using a service configuration for starting the Connector and
        registering handlers, can either specify the fully qualified class name
        for the handler, which will instantiate the handler instance upon
        startup (which requires there be a void parameter constructor), such
        as:</para>
  
        <programlisting>           
              &lt;handlers&gt;
                &lt;handler subsystem="mock"&gt;
                  org.jboss.remoting.transport.mock.MockServerInvocationHandler
                &lt;/handler&gt;
              &lt;/handlers&gt;
           </programlisting>
  
        <para>where MockServerInvocationHandler will be constructed upon startup
        and registered with the Connector as a handler.</para>
  
        <para>Can also use an ObjectName to specify the handler. The
        configuration is the same, but instead of specifying a fully qualified
        class name, you specify the ObjectName for the handler, such as (can see
        <code>mbeanhandler-service.xml</code> under remoting tests for full
        example):</para>
  
        <programlisting>          
              &lt;handlers&gt;
                &lt;handler subsystem="mock"&gt;test:type=handler&lt;/handler&gt;
              &lt;/handlers&gt;
           </programlisting>
  
        <para>The only requirement for this configuration is that the handler
        MBean must already be created and registered with the MBeanServer at the
        point the Connector is started.</para>
  
        <bridgehead>Handler implementations</bridgehead>
  
        <para>The Connectors will maintain a reference to the handler instances
        provided (either indirectly via the MBean proxy or directly via the
        instance object reference). For each request to the server invoker, the
        handler will be called upon. Since the server invokers can be
        multi-threaded (and in most cases would be), this means that the handler
        may receive concurrent calls to handle invocations. Therefore, handler
        implementations should take care to be thread safe in their
        implementations.</para>
  
        <bridgehead>Stream handler</bridgehead>
  
        <para>There is also an invocation handler interface that extends the
        ServerInvocationHandler interface specifically for handling of input
        streams as well as normal invocations. See the section on sending
        streams for further details. As for Connector configuration, it is the
        same.</para>
  
        <bridgehead>HTTP handlers</bridgehead>
  
        <para>Since there is extra information needed when dealing with the http
        transport, such as headers and response codes, special consideration is
        needed by handlers. The handlers receiving http invocations can get and
        set this extra information via the InvocationRequest that is passed to
        the handler.</para>
  
        <para>Server invoker for the http transport will add the following to
        the InvocationRequest's request payload map:</para>
  
        <para><emphasis role="bold">MethodType</emphasis> - the http request
        type (i.e., GET, POST, PUT, HEADER, OPTIONS). Can use the contant value
        HTTPMetadataConstants.METHODTYPE, if don't want to use the actual string
        'MethodType' as the key to the request payload map.</para>
  
        <para><emphasis role="bold">Path</emphasis> - the url path. Can use the
        contant value HTTPMetadataConstants.PATH, if don't want to use the
        actual string 'Path' as the key to the request payload map.</para>
  
        <para><emphasis role="bold">HttpVersion</emphasis> - the client's http
        version. Can use the contant value HTTPMetadataConstants.HTTPVERSION, if
        don't want to use the actual string 'HttpVersion' as the key to the
        request payload map.</para>
  
        <para>Other properties from the original http request will also be
        included in the request payload map, such as request headers. Can
        reference
        org.jboss.test.remoting.transport.http.method.MethodInvocationHandler as
        an example for pulling request properties from the
        InvocationRequest.</para>
  
        <para>The only time this will not be added is a POST request where an
        InvocationRequest is passed and is not binary content type
        (application/octet-stream).</para>
  
        <para>The handlers receiving http invocations can also set the response
        code, response message, and response headers. To do this, will need to
        get the return payload map from the InvocationRequest passed (via its
        getReturnPayload() method). Then populate this map with whatever
        properties needed. For response code and message, will need to use the
        following keys for the map:</para>
  
        <para><emphasis role="bold">ResponseCode</emphasis> - Can use the
        constant value HTTPMetaDataConstants.RESPONSE_CODE, if don't want to use
        the actual string 'ResponseCode' as they key. <emphasis
        role="bold">IMPORTANT</emphasis> - The value put into map for this key
        MUST be of type java.lang.Integer.</para>
  
        <para><emphasis role="bold">ResponseCodeMessage</emphasis> - Can use the
        constant value HTTPMetadataConstants.RESPONSE_CODE_MESSAGE, if don't
        want to use the actual string 'ResponseCodeMessage' as the key. The
        value put into map for this key should be of type
        java.lang.String.</para>
  
        <para>Is also important to note that ALL http requests will be passed to
        the handler. So even OPTIONS, HEAD, and PUT method requests will need to
        be handled. So, for example, if want to accept OPTIONS method requests,
        would need to populate response map with key of 'Allow' and value of
        'OPTIONS, POST, GET, HEAD, PUT', in order to tell calling client that
        all these method types are allowed. Can see an example of how to do this
        within
        org.jboss.test.remoting.transport.http.method.MethodInvocationHandler.</para>
  
        <para>The PUT request will be handled the same as a POST method request
        and the PUT request payload will be included within the
        InvocationRequest passed to the server handler. It is up to the server
        handler to set the proper resonse code (or throw proper exception) for
        the processing of the PUT request. See <ulink
        url="http://www.ietf.org/rfc/rfc2616.txt?number=2616">
        http://www.ietf.org/rfc/rfc2616.txt?number=2616 </ulink>, section 9.6
        for details on response codes and error responses).</para>
  
        <bridgehead>HTTP Client</bridgehead>
  
        <para>The HttpClientInvoker will now put the return from
        HTTPURLConnection's getHeaderFields() method into the metadata map
        passed to the Client's invoke() method (if not null). This means that if
        the caller passes a non-null Map, it can then get the response headers.
        It is important to note that each response header field key in the
        metadata map is associated with a list of response header values, so to
        get a value, would need code similar to:</para>
  
        <programlisting>Object response = remotingClient.invoke((Object) null, metadata); 
  String allowValue = (String) ((List) metadata.get("Allow").get(0);
  </programlisting>
  
        <para>Can reference
        org.jboss.test.remoting.transport.http.method.HTTPInvokerTestClient for
        an example of this.</para>
  
        <para>Note that when making a http request using the OPTIONS method
        type, the return from the Client's invoke() method will ALWAYS be
        null.</para>
  
        <para>Also, if the response code is 400, the response returned will be
        that of the error stream and not the standard input stream. So is
        important to check for the response code.</para>
  
        <para>Two values that will always be set within the metadata map passed
        to the Client's invoke() method (when not null), is the response code
        and response message from the server. These can be found using the
        keys:</para>
  
        <para><emphasis role="bold">ResponseCode</emphasis> - Can use the
        constant value HTTPMetaDataConstants.RESPONSE_CODE, if don't want to use
        the actual string 'ResponseCode' as the key. <emphasis
        role="bold">IMPORTANT</emphasis> - The value returned for this key will
        be of type java.lang.Integer.</para>
  
        <para><emphasis role="bold">ResponseCodeMessage</emphasis> - Can use the
        constant value from HTTPMetadataConstants.RESPONSE_CODE_MESSAGE, if
        don't want to use the actual string 'ResponseCodeMessage' as the key.
        The value returned for this key will be of type java.lang.String.</para>
  
        <para>An example of getting the response code can be found within
        org.jboss.test.remoting.transport.http.method.HTTPInvokerTestClient.</para>
      </section>
  
      <section>
        <title>Discovery (Detectors)</title>
  
        <bridgehead>Domains</bridgehead>
  
        <para>Detectors have the ability to accept multiple domains. What
        domains that the detector will accept as viewable can either be set
        programmatically via the method:</para>
  
        <para><code>public void setConfiguration(org.w3c.dom.Element xml)
        </code></para>
  
        <para>or by adding to jboss-service.xml configuration for the detector.
        The domains that the detector is currently accepting can be retrieved
        from the method:</para>
  
        <para><code>public org.w3c.dom.Element getConfiguration()</code></para>
  
        <para>The configuration xml is a MBean attribute of the detector, so can
        be set or retrieved via JMX.</para>
  
        <para>There are three possible options for setting up the domains that a
        detector will accept. The first is to not call the
        <code>setConfiguration()</code> method (or just not add the
        configuration attribute to the service xml). This will cause the
        detector to use only its domain and is the default behavior. This
        enables it to be backwards compatible with earlier versions of JBoss
        Remoting (JBoss 4, DR2 and before).</para>
  
        <para>The second is to call the <code>setConfiguration()</code> method
        (or add the configuration attribute to the service xml) with the
        following xml element:</para>
  
        <programlisting>    
            &lt;domains&gt;
              &lt;domain&gt;domain1&lt;/domain&gt;
              &lt;domain&gt;domain2&lt;/domain&gt;
            &lt;/domains&gt;
           </programlisting>
  
        <para>where <code>domain1</code> and <code>domain2</code> are the two
        domains you would like the detector to accept. This will cause the
        detector to accept detections only from the domains specified, and no
        others.</para>
  
        <para>The third and final option is to call the setConfiguration()
        method (or add the configuration attribute to the service xml) with the
        following xml element:</para>
  
        <programlisting>
            &lt;domains&gt;
            &lt;/domains&gt;
        </programlisting>
  
        <para>This will cause the detector to accept all detections from any
        domain.</para>
  
        <para>By default, remoting detection will ignore any detection message
        the it receives from a server invoker running within its own jvm. To
        disable this, add an element called 'local' to the detector
        configuration (alongside the domain element) to indicate should accept
        detection messages from local server invokers. This will be false by
        default, so maintains the same behavior as previous releases. For
        example:</para>
  
        <programlisting>        &lt;domains&gt;
              &lt;domain&gt;domain1&lt;/domain&gt;
              &lt;domain&gt;domain2&lt;/domain&gt;
          &lt;/domains&gt;
          &lt;local/&gt; </programlisting>
  
        <para>An example entry of a Multicast detector in the jboss-service.xml
        that accepts detections only from the roxanne and sparky domains using
        port 5555, including servers in the same jvm, is as follows:</para>
  
        <programlisting>
           &lt;mbean code="org.jboss.remoting.detection.multicast.MulticastDetector"
                 name="jboss.remoting:service=Detector,transport=multicast"&gt;
              &lt;attribute name="Port"&gt;5555&lt;/attribute&gt;
              &lt;attribute name="Configuration"&gt;
                &lt;domains&gt;
                  &lt;domain&gt;roxanne&lt;/domain&gt;
                  &lt;domain&gt;sparky&lt;/domain&gt;
                &lt;/domains&gt;
                &lt;local/&gt;
              &lt;/attribute&gt;
           &lt;/mbean&gt;
        </programlisting>
  
        <bridgehead>Global Detector Configuration</bridgehead>
  
        <para>The following are configuration attributes for all the remoting
        detectors.</para>
  
        <para><emphasis role="bold">DefaultTimeDelay</emphasis> - amount of
        time, in milliseconds, which can elapse without receiving a detection
        event before suspecting that a server is dead and performing an explicit
        invocation on it to verify it is alive. If this invocation, or ping,
        fails, the server will be removed from the network registry. The default
        is 5000 milliseconds.</para>
  
        <para><emphasis role="bold">HeartbeatTimeDelay</emphasis> - amount of
        time to wait between sending (and sometimes receiving) detection
        messages. The default is 1000 milliseconds.</para>
  
        <bridgehead>JNDIDetector</bridgehead>
  
        <para><emphasis role="bold">Port</emphasis> - port to which detector
        will connect for the JNDI server.</para>
  
        <para><emphasis role="bold">Host</emphasis> - host to which the detector
        will connect for the JNDI server.</para>
  
        <para><emphasis role="bold">ContextFactory</emphasis> - context factory
        string used when connecting to the JNDI server. The default is
        <code>org.jnp.interfaces.NamingContextFactory</code> .</para>
  
        <para><emphasis role="bold">URLPackage</emphasis> - url package string
        to use when connecting to the JNDI server. The default is
        <code>org.jboss.naming:org.jnp.interfaces</code> .</para>
  
        <para><emphasis role="bold">CleanDetectionNumber</emphasis> - Sets the
        number of detection iterations before manually pinging remote server to
        make sure still alive. This is needed since remote server could crash
        and yet still have an entry in the JNDI server, thus making it appear
        that it is still there. The default value is 5.</para>
  
        <para>Can either set these programmatically using setter method or as
        attribute within the remoting-service.xml (or anywhere else the service
        is defined). For example:</para>
  
        <programlisting>
           &lt;mbean code="org.jboss.remoting.detection.jndi.JNDIDetector"
                 name="jboss.remoting:service=Detector,transport=jndi"&gt;
              &lt;attribute name="Host"&gt;localhost&lt;/attribute&gt;
              &lt;attribute name="Port"&gt;5555&lt;/attribute&gt;
           &lt;/mbean&gt;
        </programlisting>
  
        <para>If the JNDIDetector is started without the Host attribute being
        set, it will try to start a local JNP instance (the JBoss JNDI server
        implementation) on port 1088.</para>
  
        <bridgehead>MulticastDetector</bridgehead>
  
        <para><emphasis role="bold">DefaultIP</emphasis> - The IP that is used
        to broadcast detection messages on via multicast. To be more specific,
        will be the ip of the multicast group the detector will join. This
        attribute is ignored if the Address has already been set when started.
        Default is 224.1.9.1.</para>
  
        <para><emphasis role="bold">Port</emphasis> - The port that is used to
        broadcast detection messages on via multicast. Default is 2410.</para>
  
        <para><emphasis role="bold">BindAddress</emphasis> - The address to bind
        to for the network interface.</para>
  
        <para><emphasis role="bold">Address</emphasis> - The IP of the multicast
        group that the detector will join. The default will be that of the
        DefaultIP if not explicitly set.</para>
      </section>
  
      <section>
        <title>Transports (Invokers)</title>
  
        <section>
          <title>Server Invokers</title>
  
          <para>The following configuration properties are common to all the
          current server invokers.</para>
  
          <para><emphasis role="bold">serverBindAddress</emphasis> - The address
          on which the server binds to listen for requests. The default is an
          empty value which indicates the server should be bound to the host
          provided by the locator url, or if this value is null, the local host
          as provided by <code>InetAddress.getLocalHost()</code> .</para>
  
          <para><emphasis role="bold">serverBindPort</emphasis> - The port to
          listen for requests on. A value of 0 or less indicates that a free
          anonymous port should be chosen.</para>
  
          <para><emphasis role="bold">maxNumThreadsOneway</emphasis> - specifies
          the maximum number of threads to be used within the thread pool for
          accepting one way invocations on the server side. This property will
          only be used in the case that the default thread pool is used. If a
          custom thread pool is set, this property will have no meaning. This
          property can also be retrieved or set programmatically via the
          <code>MaxNumberOfOnewayThreads</code> property.</para>
  
          <para><emphasis role="bold">onewayThreadPool</emphasis> - specifies
          either the fully qualified class name for a class that implements the
          <code>org.jboss.util.threadpool.ThreadPool</code> interface or the JMX
          ObjectName for an MBean that implements the
          <code>org.jboss.util.threadpool.ThreadPool</code> interface. This will
          replace the default
          <code>org.jboss.util.threadpool.BasicThreadPool</code> used by the
          server invoker.</para>
  
          <para>Note that this value will NOT be retrieved until the first
          one-way (server side) invocation is made. So if the configuration is
          invalid, will not be detected until this first call is made. The
          thread pool can also be accessed or set via the
          <code>OnewayThreadPool</code> property programmatically.</para>
  
          <para>Important to note that the default thread pool used for the
          one-way invocations on the server side will block the calling thread
          if all the threads in the pool are in use until one is
          released.</para>
                  
        </section>
  
        <section>
          <title>Configurations affecting the invoker client</title>
  
          <para>There are some configurations which will impact the invoker
          client. These will be communicated to the client invoker via
          parameters in the Locator URI. These configurations can not be changed
          during runtime, so can only be set up upon initial configuration of
          the server invoker on the server side. The following is a list of
          these and their effects.</para>
  
          <para><emphasis role="bold">clientConnectPort</emphasis> - the port
          the client will use to connect to the remoting server. This would be
          needed in the case that the client will be going through a router that
          forwards requests made externally to a different port
          internally.</para>
  
          <para><emphasis role="bold">clientConnectAddress</emphasis> - the ip
          or hostname the client will use to connect to the remoting server.
          This would be needed in the case that the client will be going through
          a router that forwards requests made externally to a different ip or
          host internally.</para>
  
          <para>If no client connect address or server bind address specified,
          will use the local host's address (via
          <code>InetAddress.getLocalHost().getHostAddress()</code> ).</para>
        </section>
  
        <section>
          <title>How the server bind address and port is ultimately
          determined</title>
  
          <para>If the serverBindAddress property is set, it will be used for
          binding. If the serverBindAddress is not set, but the
          clientConnectAddress property is set, the server invoker will bind to
          local host address. If neither the serverBindAddress nor the
          clientConnectAddress properties are set, then will try to bind to the
          host specified within the InvokerLocator. If the host value of the
          InvokerLocator is also not set, will bind to local host.</para>
  
          <para>If there is a system property called 'remoting.bind_by_host' and
          if is false, will bind by IP address instead of host. Otherwise will
          use host name. This only applies when configured address is 0.0.0.0.
          To facilitate setting this property, the following static variable is
          defined in <classname>InvokerLocator</classname>:</para>
  
          <programlisting>
             public static final String BIND_BY_HOST = "remoting.bind_by_host";
          </programlisting>
  
          <para>If the serverBindPort property is set, it will be used. If this
          value is 0 or a negative number, then the next available port will be
          found and used. If the serverBindPort property is not set, but the
          clientConnectPort property is set, then the next available port will
          be found and used. If neither the serverBindPort nor the
          clientConnectPort is set, then the port specified in the original
          InvokerLocator will be used. If this is 0 or a negative number, then
          the next available port will be found and used. In the case that the
          next available port is used because either the serverBindPort or the
          original InvokerLocator port value was either 0 or negative, the
          InvokerLocator will be updated to reflect the new port value.</para>
        </section>
  
        <section>
          <title>Socket Invoker</title>
  
          <para>The following configuration properties can be set at any time,
          but will not take effect until the socket invoker, on the server side,
          is stopped and restarted.</para>
  
          <para><emphasis role="bold">timeout</emphasis> - The socket timeout
          value passed to the Socket.setSoTimeout() method. The default on the
          server side is 60000 (one minute). If the timeout parameter is set,
          its value will also be passed to the client side (see below).</para>
  
          <para><emphasis role="bold">backlog</emphasis> - The preferred number
          of unaccepted incoming connections allowed at a given time. The actual
          number may be greater than the specified backlog. When the queue is
          full, further connection requests are rejected. Must be a positive
          value greater than 0. If the value passed if equal or less than 0,
          then the default value will be assumed. The default value is
          200.</para>
  
          <para><emphasis role="bold">numAcceptThreads</emphasis> - The number
          of threads that exist for accepting client connections. The default is
          1.</para>
  
          <para><emphasis role="bold">maxPoolSize</emphasis> - The number of
          server threads for processing client. The default is 300.</para>
  
          <para><emphasis role="bold">serverSocketClass</emphasis> - specifies
          the fully qualified class name for the custom SocketWrapper
          implementation to use on the server.</para>
  
          <bridgehead>Configurations affecting the Socket invoker
          client</bridgehead>
  
          <para>There are some configurations which will impact the socket
          invoker client. These will be communicated to the client invoker via
          parameters in the Locator URI. These configurations can not be changed
          during runtime, so can only be set up upon initial configuration of
          the socket invoker on the server side. The following is a list of
          these and their effects.</para>
  
          <para><emphasis role="bold">enableTcpNoDelay</emphasis> - can be
          either true or false and will indicate if client socket should have
          TCP_NODELAY turned on or off. TCP_NODELAY is for a specific purpose;
          to disable the Nagle buffering algorithm. It should only be set for
          applications that send frequent small bursts of information without
          getting an immediate response; where timely delivery of data is
          required (the canonical example is mouse movements). The default is
          false.</para>
  
          <para><emphasis role="bold">timeout</emphasis> - The socket timeout
          value passed to the Socket.setSoTimeout() method. The default on the
          client side is 1800000 (or 30 minutes).</para>
  
          <para><emphasis role="bold">clientMaxPoolSize</emphasis> - the client
          side maximum number of threads. The default is 10.</para>
  
          <para><emphasis role="bold">clientSocketClass</emphasis> - specifies
          the fully qualified class name for the custom SocketWrapper
          implementation to use on the client. Note, will need to make sure this
          is marked as a client parameter (using the 'isParam' attribute).
          Making this change will not affect the marshaller/unmarshaller that is
          used, which may also be a requirement.</para>
  
          <para>An example of locator uri for a socket invoker that has
          TCP_NODELAY set to false and the client's max pool size of 30 would
          be:</para>
  
          <para><code>
          socket://test.somedomain.com:8084/?enableTcpNoDelay=false&amp;maxPoolSize=30
          </code></para>
  
          <para>To reiterate, these client configurations can only be set within
          the server side configuration and will not change during
          runtime.</para>
        </section>
  
        <section>
          <title>SSL Socket Invoker</title>
  
          <para>Supports all the configuration attributes as the Socket Invoker,
          plus the following:</para>
  
          <para><emphasis role="bold">serverSocketFactory</emphasis> - Sets the
          server socket factory. If want ssl support use a server socket factory
          that supports ssl. The only requirement is that the server socket
          factory value must be an ObjectName, meaning the server socket factory
          implementation must be an MBean and also MUST implement the
          <code>org.jboss.remoting.security.ServerSocketFactoryMBean</code>
          interface.</para>
        </section>
  
        <section>
          <title>RMI Invoker</title>
  
          <para><emphasis role="bold">registryPort</emphasis> - the port on
          which to create the RMI registry. The default is 3455. This also needs
          to have the isParam attribute set to true.</para>
        </section>
  
        <section>
          <title>SSL RMI Invoker</title>
  
          <para>This is essentially identical to the RMI invoker, except that it
          creates SSL socket and server socket factories by default.</para>
  
          <para><emphasis role="bold">Note.</emphasis> Both the RMI and SSL RMI
          server invokers create a socket factory and pass it to a client
          invoker along with the RMI stub. Therefore, the socket factory must be
          serializable. If the SSL RMI server invoker is allowed to create an
          <classname>SSLSocketFactory</classname> from SSL parameters, it will
          take care to create a serializable socket factory. However, if a
          socket factory is passed in to the server invoker by one of the
          methods discussed earlier, then the user is responsible for supplying
          a serializable socket factory.</para>
  
          <para>The rules discussed above for configuring socket and server
          socket factories apply to the SSL RMI transport, but there is a twist,
          since the server invoker creates the (client) socket factory and
          packages it with its own stub. The server invoker creates a copy of
          <classname>org.jboss.remoting.transport.rmi.ssl.SerializableSSLClientSocketFactory</classname>,
          which is essentially just a holder for the configuration map passed to
          the server invoker, with any parameters removed which concern trust
          store and key store configuration. On the client side, when a client
          SSL RMI invoker is created, it stores its own configuration map in a
          static variable which the transferred
          <classname>SerializableSSLClientSocketFactory</classname> can retrieve
          and merge with the configuration information it brought with it from
          the server. In particular, if a socket factory is explicitly passed to
          the client invoker, then
          <classname>SerializableSSLClientSocketFactory</classname> will use it.
          If not, then <classname>SerializableSSLClientSocketFactory</classname>
          will use any key store and trust store information passed to the
          client to create and configure a socket factory.</para>
        </section>
  
        <section>
          <title>HTTP Invoker</title>
  
          <para>The HTTP server invoker implementation is based on the Apache
          Tomcat connector components which support GET, POST, HEAD, OPTIONS,
          and HEAD method types and keep-alive. Therefore, most any
          configuration allowed for Tomcat can be configured for the remoting
          HTTP server invoker. For more information on the configuration
          attributes available for the Tomcat connectors, please refer to <ulink
          url="http://tomcat.apache.org/tomcat-5.5-doc/config/http.htm">http://tomcat.apache.org/tomcat-5.5-doc/config/http.htm</ulink>.
          <!--<link linkend="???">http://tomcat.apache.org/tomcat-5.5-doc/config/http.html</link>-->
          So for example, if wanted to set the maximum number of threads to be
          used to accept incoming http requests, would use the 'maxThreads'
          attribute. The only exception when should use remoting configuration
          over the Tomcat configuration is for attribute 'address' (use
          serverBindAddress instead) and attribute 'port' (use serverBindPort
          instead).</para>
  
          <para>Note: The http invoker no longer has the configuration
          attributes 'maxNumThreadsHTTP' or 'HTTPThreadPool' as thread pooling
          is now handled within the Tomcat connectors, which does not expose
          external API for setting these.</para>
  
          <para>Since the remoting HTTP server invoker implementation is using
          Tomcat connectors, is possible to swap out the Tomcat protocol
          implementations being used. By default, the protocol being used is
          <code>org.apache.coyote.http11.Http11Protocol</code>. However, it is
          possible to switch to use the
          <code>org.apache.coyote.http11.Http11AprProtocol</code> protocol,
          which is based on the Apache Portable Runtime (see <ulink
          url="http://tomcat.apache.org/tomcat-5.5-doc/apr.html">http://tomcat.apache.org/tomcat-5.5-doc/apr.html</ulink>
          <!--<link linkend="???">http://tomcat.apache.org/tomcat-5.5-doc/apr.html</link>-->
          and <ulink url="http://apr.apache.org/">http://apr.apache.org/</ulink>
          <!--<link linkend="???">http://apr.apache.org/</link>--> for more
          details). If want to use the APR implementation, simply put the
          tcnative-1.dll (or tcnative-1.so) on the system path so can be loaded.
          The APR native binaries can be found at <ulink
          url="http://tomcat.heanet.ie">http://tomcat.heanet.ie</ulink>.<!--<link linkend="???">http://tomcat.heanet.ie</link>--></para>
  
          <para>Note: There is a bug with release 1.1.1 of APR where get an
          error upon shutting down (see JBREM-277 for more information). This
          does not impact anything while running, but is still an issue when
          shutting down (as upon starting up again, can get major problems).
          This should be fixed in a later release of APR and since can just
          replace the 1.1.1 version of tcnative-1.dll with the new one.</para>
  
          <bridgehead>Client request headers</bridgehead>
  
          <para>The HTTP Invoker allows for some of the properties to be passed
          as request headers from client caller. The following are possible http
          headers and what they mean:</para>
  
          <para><emphasis role="bold">sessionId</emphasis> - is the remoting
          session id to identify the client caller. If this is not passed, the
          HTTP server invoker will try to create a session id based on
          information that is passed. Note, this means if the sessionId is not
          passed as part of the header, there is no gurantee that the sessionId
          supplied to the invocation handler will always indicate the request
          from the same client.</para>
  
          <para><emphasis role="bold">subsystem</emphasis> - the subsystem to
          call upon (which invoker handler to call upon). If there is more than
          one handler per Connector, this will need to be set (otherwise will
          just use the only one available).</para>
  
          <para>These request headers are set automatically when using a
          remoting client, but if using another client to send request to the
          HTTP server invoker, may want to add these headers.</para>
  
          <bridgehead>Exception Handling</bridgehead>
  
          <para>When using remoting on the client side to connect to a remoting
          server (or any web server for that matter) via the http transport, if
          the server returns a response code greater than 400, the remoting
          client will read the error stream and return that as the response.
          Thus, the response returned will be of type java.lang.Exception. NOTE:
          this does NOT mean that the call to the Client's invoke() method will
          throw the exception, but instead will return the actual Exception
          object instance as a normally returned response. Therefore, is
          important that if want to check if response is an error instead of
          normal response, will need to look at the response code put in the
          metadata Map passed to the invoke() method on the Client instance. See
          the HTTP Handler section above for more details.</para>
        </section>
  
        <section>
          <title>HTTPS Invoker</title>
  
          <para>Supports all the configuration attributes as the HTTP Invoker,
          plus the following:</para>
  
          <para><emphasis role="bold">serverSocketFactory</emphasis> - Sets the
          server socket factory. If want ssl support, use a server socket
          factory that supports ssl. The only requirement is that the server
          socket factory value must be an ObjectName, meaning the server socket
          factory implementation must be an MBean and also MUST implement the
          <code>org.jboss.remoting.security.ServerSocketFactoryMBean</code>
          interface.</para>
  
          <para><emphasis role="bold">SSLImplementation</emphasis> - Sets the
          Tomcat SSLImplementation to use. This should always be
          <code>org.jboss.remoting.transport.coyote.ssl.RemotingSSLImplementation</code>.</para>
        </section>
  
        <section>
          <title>HTTP(S) Client Invoker - proxy and basic authentication</title>
  
          <para>This section covers configuration specific to the HTTP Client
          Invoker only and is NOT related to HTTP(S) invoker configuration on
          the server side (via service xml).</para>
  
          <bridgehead>proxy</bridgehead>
  
          <para>There are a few ways in which to enable http proxy using the
          HTTP client invoker. The first is simply to add the following
          properties to the metadata Map passed on the Client's invoke() method:
          <code>http.proxyHost</code> and <code>http.proxyPort</code></para>
  
          <para>An example would be:</para>
  
          <programlisting>
                 Map metadata = new HashMap();
                 ...
  
                 // proxy info
                 metadata.put("http.proxyHost", "ginger");
                 metadata.put("http.proxyPort", "80");
  
                 ...
  
                 response = client.invoke(payload, metadata);
              </programlisting>
  
          <para>The http.proxyPort property is not required and if not present,
          will use default of 80.</para>
  
          <para>The other way to enable use of an http proxy server from the
          HTTP client invoker is to set the following system properties (either
          via <code>System.setProperty()</code> method call or via JVM
          arguments): <code>http.proxyHost</code>, <code>http.proxyPort</code>,
          and <code>proxySet</code></para>
  
          <para>An example would be setting the following JVM arguments:</para>
  
          <programlisting>-Dhttp.proxyHost=ginger -Dhttp.proxyPort=80 -DproxySet=true</programlisting>
  
          <para>Note: when testing with Apache 2.0.48 (mod_proxy and
          mod_proxy_http), all of the properties above were required.</para>
  
          <para>Setting the system properties will take precedence over setting
          the metadata Map.</para>
  
          <bridgehead>Basic authentication - direct and via proxy</bridgehead>
  
          <para>The HTTP client invoker also has support for BASIC
          authentication for both proxied and non-proxied invocations. For
          proxied invocations, the following properties need to be set:
          <code>http.proxy.username</code> and
          <code>http.proxy.password</code>.</para>
  
          <para>For non-proxied invocations, the following properties need to be
          set: <code>http.basic.username</code> and
          <code>http.basic.password</code>.</para>
  
          <para>For setting either proxied or non-proxied properties, can be
          done via the metadata map or system properties (see setting proxy
          properties above for how to). However, for authentication properties,
          values set in the metadata Map will take precedence over those set
          within the system properties.</para>
  
          <para>Note: Only the proxy authentication has been tested using Apache
          2.0.48; non-proxied authentication has not.</para>
  
          <para>Since there are many different ways to do proxies and
          authentication in this great world of web, not all possible
          configurations have been tested (or even supported). If you find a
          particular problem or see that a particular implementation is not
          supported, please enter an issue in Jira ( <!--<link linkend="???">http://jira.jboss.com</link>-->
          <ulink url="http://jira.jboss.com">http://jira.jboss.com</ulink> )
          under the JBossRemoting project, as this is where bugs and feature
          requests belong. If after reading the documentation have unanswered
          questions about how to use these features, please post them to the
          remoting forum ( <!--<link linkend="???">http://www.jboss.org/index.html?module=bb&amp;op=viewforum&amp;f=176</link> -->
          <ulink
          url="http://www.jboss.org/index.html?module=bb&amp;op=viewforum&amp;f=176">
          http://www.jboss.org/index.html?module=bb&amp;op=viewforum&amp;f=176
          </ulink> ).</para>
  
          <bridgehead>Host name verification</bridgehead>
  
          <para>During the SSL handshake when making client calls using https
          transport, if the URL's hostname and the server's identification
          hostname mismatch, a javax.net.ssl.HostnameVerifier implementation
          will be called to determine if this connection should be allowed. The
          default implementation will not allow this. To override this behavior
          to allow this by changing the HostnameVerifier implementation, can use
          the 'org.jboss.security.ignoreHttpsHost' property'. This property can
          either be set using a system property or within the metadata Map
          passed to the Client's invoke() method (which will override both the
          default value and the setting from the system property).</para>
        </section>
  
        <section>
          <title>Servlet Invoker</title>
  
          <para>The servlet invoker is a server invoker implementation that uses
          a servlet running within a web container to accept initial client
          invocation requests. The servlet request is then passed on to the
          servlet invoker for processing.</para>
  
          <para>The deployment for this particular server invoker is a little
          different than the other server invokers since a web deployment is
          also required. To start, the servlet invoker will need to be
          configured and deployed. This can be done by adding the Connector
          MBean service to an existing service xml or creating a new one. The
          following is an example of how to declare a Connector that uses the
          servlet invoker:</para>
  
          <programlisting>
             &lt;mbean code="org.jboss.remoting.transport.Connector"
                    xmbean-dd="org/jboss/remoting/transport/Connector.xml"
                    name="jboss.remoting:service=Connector,transport=Servlet"
                    display-name="Servlet transport Connector"&gt;
  
                &lt;attribute name="InvokerLocator"&gt;
                   servlet://localhost:8080/servlet-invoker/ServerInvokerServlet
                &lt;/attribute&gt;
  
                &lt;attribute name="Configuration"&gt;
                   &lt;config&gt;
                      &lt;handlers&gt;
                         &lt;handler subsystem="test"&gt;
                            org.jboss.test.remoting.transport.web.WebInvocationHandler
                         &lt;/handler&gt;
                      &lt;/handlers&gt;
                   &lt;/config&gt;
                &lt;/attribute&gt;
             &lt;/mbean&gt;
          </programlisting>
  
          <para>An important point of configuration to note is that the value
          for the InvokerLocator attribute is the exact url used to access the
          servlet for the servlet invoker (more on how to define this below),
          with the exception of the protocol being servlet instead of http. This
          is important because if using automatic discovery, this is the locator
          url that will be discovered and used by clients to connect to this
          server invoker.</para>
  
          <para>The next step is to configure and deploy the servlet that fronts
          the servlet invoker. The pre-built deployment file for this servlet is
          the servlet-invoker.war file (which can be found in the release
          distribution or under the output/lib/ directory if doing a source
          build). By default, it is actually an exploded war, so the
          servlet-invoker.war is actually a directory so that can be more easily
          configured (feel free to zip up into an actual war file if prefer). In
          the WEB-INF directory is located the web.xml file. This is a standard
          web configuration file and should look like:</para>
  
          <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;!--The the JBossRemoting server invoker servlet web.xml descriptor--&gt;
             &lt;web-app&gt;
                &lt;servlet&gt;
                   &lt;servlet-name&gt;ServerInvokerServlet&lt;/servlet-name&gt;
                   &lt;description&gt;The ServerInvokerServlet receives requests via HTTP protocol
                      from within a web container and passes it onto the ServletServerInvoker for processing.
                   &lt;/description&gt;
                   &lt;servlet-class&gt;
                      org.jboss.remoting.transport.servlet.web.ServerInvokerServlet
                   &lt;/servlet-class&gt;
                   &lt;init-param&gt;
                      &lt;param-name&gt;invokerName&lt;/param-name&gt;
                      &lt;param-value&gt;
                         jboss.remoting:service=invoker,transport=servlet
                      &lt;/param-value&gt;
                      &lt;description&gt;The servlet server invoker&lt;/description&gt;
                   &lt;/init-param&gt;
                   &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
                &lt;/servlet&gt;
                &lt;servlet-mapping&gt;
                   &lt;servlet-name&gt;ServerInvokerServlet&lt;/servlet-name&gt;
                   &lt;url-pattern&gt;/ServerInvokerServlet/*&lt;/url-pattern&gt;
                &lt;/servlet-mapping&gt;
             &lt;/web-app&gt;
          </programlisting>
  
          <para>This file can be changed to meet any web requirements you might
          have, such as adding security or changing the actual url context that
          the servlet maps to. If the url that the servlet maps to is changed,
          will need to change the value for the InvokerLocator in the Connector
          configuration mentioned above. Also note that there is a parameter,
          invokerName, that has the value of the object name of the servlet
          server invoker. This is what the ServerInvokerServlet uses to look up
          the server invoker which it will pass the requests on to.</para>
  
          <para>Due to the way the servlet invoker is currently configured and
          deployed, it must run within the JBoss application server and is not
          portable to other web servers.</para>
  
          <bridgehead>Exception handling</bridgehead>
  
          <para>If the ServletServerInvoker catches any exception thrown from
          the invocation handler invoke() call, it will send an error to the
          client with a status of 500 and include the original exception message
          as its error message. From the client side, the client invoker will
          actually throw a CannotConnectException, which will have root
          exception as its cause. The cause should be an IOException with the
          server's message. For example, the stack trace from the exception
          thrown within the test case
          org.jboss.remoting.transport.servlet.test.ServletInvokerTestClient
          is:</para>
  
          <programlisting>
                 org.jboss.remoting.CannotConnectException: Can not connect http client invoker.
                 at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:154)
                 at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:68)
                 at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:113)
                 at org.jboss.remoting.Client.invoke(Client.java:221)
                 at org.jboss.remoting.Client.invoke(Client.java:184)
                 at
                 org.jboss.remoting.transport.servlet.test.ServletInvokerTestClient.testInvocation(ServletInvokerTestClient.java:65)
                 at
                 org.jboss.remoting.transport.servlet.test.ServletInvokerTestClient.main(ServletInvokerTestClient.java:98)
                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                 at java.lang.reflect.Method.invoke(Method.java:324)
                 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:78)
                 Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL:
                 http://localhost:8080/servlet-invoker/ServerInvokerServlet
                 at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:791)
                 at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:139)
                 ... 11 more
              </programlisting>
  
          <bridgehead>Issues</bridgehead>
  
          <para>One of the issues of using Servlet invoker is that the
          invocation handlers (those that implement ServerInvocationHandler) can
          not return very much detail in regards to a web context. For example,
          the content type used for the response is the same as that of the
          request.</para>
        </section>
  
        <section>
          <title id="section-multiplex" xreflabel="Multiplex Invoker">Multiplex
          Invoker</title>
  
          <para>The multiplex invoker is intended to replicate the functionality
          of the socket invoker with the added feature that it supports multiple
          streams of communication over a single pair of sockets. Multiplexing
          may be motivated by, for example, a desire to conserve socket
          resources or by firewall restrictions on port availability. This
          additional service is made possible by the Multiplex subproject, which
          provides "virtual" sockets and "virtual" server sockets. Please refer
          to the Multiplex documentation at</para>
  
          <blockquote>
            <para><ulink
            url="http://labs.jboss.com/portal/jbossremoting/docs/index.html">
            http://labs.jboss.com/portal/jbossremoting/docs/index.html</ulink></para>
          </blockquote>
  
          <para>for further details.</para>
  
          <para>In a typical multiplexed scenario a
          <classname>Client</classname> on a client host, through a
          <classname>MultiplexClientInvoker</classname> <emphasis>C</emphasis>,
          could make synchronous method invocations to a
          <classname>MultiplexServerInvoker</classname> on a server host, and at
          the same time (and over the same TCP connection) asynchronous push
          callbacks could be made to a
          <classname>MultiplexServerInvoker</classname> <emphasis>S</emphasis>
          on the client host. In this, the <emphasis role="bold">Prime
          Scenario</emphasis>, which motivated the creation of the multiplex
          invoker, <emphasis>C</emphasis> and <emphasis>S</emphasis> use two
          different virtual sockets but share the same port and same actual
          socket. We say that <emphasis>C</emphasis> and <emphasis>S</emphasis>
          belong to the same <emphasis role="bold">invoker
          group</emphasis>.</para>
  
          <para>One of the primary design goals of the Multiplex subsystem is
          for virtual sockets and virtual server sockets to demonstrate behavior
          as close as possible to their real counterparts, and, indeed, they
          implement complete socket and server socket APIs. However, they are
          necessarily different in some respects, and it follows that the
          multiplex invoker is somewhat different than the socket invoker. In
          particular, there are three areas specific to the multiplex invoker
          that must be understood in order to use it effectively:</para>
  
          <orderedlist>
            <listitem>
              <para>Establishing on the server an environment prerequisite for
              creating multiplex connections</para>
            </listitem>
  
            <listitem>
              <para>Configuring the client for multiplexed method invocations
              and callbacks</para>
            </listitem>
  
            <listitem>
              <para>Shutting down invoker groups.</para>
            </listitem>
          </orderedlist>
  
          <section>
            <title>Setting up the server</title>
  
            <para>There are two kinds of
            <classname>MultiplexServerInvoker</classname>s, <emphasis
            role="bold">master</emphasis> and <emphasis
            role="bold">virtual</emphasis>, corresponding to the two kinds of
            virtual server sockets: <classname>MasterServerSocket</classname>
            and <classname>VirtualServerSocket</classname>. Briefly, the
            difference between the two virtual server socket classes is that a
            <classname>MasterServerSocket</classname> is derived from
            <classname>java.net.ServerSocket</classname> and its
            <methodname>accept()</methodname> method is implemented by way of
            the inherited method <methodname>super.accept()</methodname>. A
            <classname>MasterServerSocket</classname> can accept connect
            requests from multiple machines. A
            <classname>VirtualServerSocket</classname>, on the other hand, is
            based on an actual socket connected to another actual socket on some
            host <emphasis>H</emphasis>, and consequently a
            <classname>VirtualServerSocket</classname> can accept connect
            requests only from <emphasis>H</emphasis>.</para>
  
            <para>Each multiplex connection depends on a pair of connected real
            sockets, one on the client host and one on the server host, and this
            connection is created when an actual socket contacts an actual
            server socket. It follows that a multiplex connection begins with a
            connection request to a <classname>MasterServerSocket</classname>.
            Once the connection is established, it is possible to build up
            <emphasis role="bold">virtual socket groups</emphasis>, consisting
            of virtual sockets (and at most one
            <classname>VirtualServerSocket</classname>) revolving around the
            actual socket at each end of the connection. Each virtual socket in
            a socket group at one end is connected to a virtual socket in the
            socket group at the other end.</para>
  
            <para>Master and virtual
            <classname>MultiplexServerInvoker</classname>s assume the
            characteristics of their server sockets:
            <classname>MasterServerSocket</classname> and
            <classname>VirtualServerSocket</classname>, respectively. That is, a
            master <classname>MultiplexServerInvoker</classname> can accept
            requests from any host, while a virtual
            <classname>MultiplexServerInvoker</classname> can accept requests
            only from the particular host to which it has a multiplex
            connection. Since a multiplex connection begins with a connection
            request to a <classname>MasterServerSocket</classname>, it follows
            that the use of the multiplex invoker must begin with a connection
            request from the client (made by either a
            <classname>MultiplexClientInvoker</classname> or a virtual
            <classname>MultiplexServerInvoker</classname>: see below) to a
            master <classname>MultiplexServerInvoker</classname> on the server.
            The master <classname>MultiplexServerInvoker</classname> responds by
            "cloning" itself (metaphorically, not necessarily through the use of
            <methodname>clone()</methodname>) into a virtual
            <classname>MultiplexServerInvoker</classname> with the same
            parameters and same set of invocation handlers but with a
            <classname>VirtualServerSocket</classname> belonging to a new socket
            group. In so doing the master
            <classname>MultiplexServerInvoker</classname> builds up a <emphasis
            role="bold">server invoker farm</emphasis> of virtual
            <classname>MultiplexServerInvoker</classname>s, each in contact with
            a different <classname>MultiplexClientInvoker</classname> over a
            distinct multiplex connection. The virtual
            <classname>MultiplexServerInvoker</classname>s do the actual work of
            responding to method invocation requests, sent by their
            corresponding <classname>MultiplexClientInvoker</classname>s through
            virtual sockets in a socket group at the client end of a multiplex
            connection to virtual sockets created by the
            <classname>VirtualServerSocket</classname> in the socket group at
            the server end of the connection. Note that virtual
            <classname>MultiplexServerInvoker</classname>s share data structures
            with the master, so that registering invocation handlers with the
            master makes them available to the members of the farm. The members
            of a master <classname>MultiplexServerInvoker</classname>'s invoker
            farm are accessible by way of the methods</para>
  
            <blockquote>
              <orderedlist>
                <listitem>
                  <para><methodname>MultiplexServerInvoker.getServerInvokers()</methodname>
                  and</para>
                </listitem>
  
                <listitem>
                  <para><methodname>MultiplexServerInvoker.getServerInvoker(InetSocketAddress)</methodname></para>
                </listitem>
              </orderedlist>
            </blockquote>
  
            <para>the latter of which returns a virtual
            <classname>MultiplexServerInvoker</classname> keyed on the address
            to which its <classname>VirtualServerSocket</classname> is
            connected. When the master
            <classname>MultiplexServerInvoker</classname> shuts down, its farm
            of virtual invokers shuts down as well</para>
  
            <para>There are two ways of constructing a virtual
            <classname>MultiplexServerInvoker</classname>, one being the cloning
            method just discussed. It is also possible to construct one
            directly. Once a multiplex connection is established, a virtual
            <classname>MultiplexServerInvoker</classname> can be created with a
            <classname>VirtualServerSocket</classname> belonging to a socket
            group at one end of the connection. The
            <classname>MultiplexServerInvoker</classname> constructor determines
            whether to create a virtual or master invoker according to the
            presence or absence of certain parameters, discussed below, that may
            be added to its <classname>InvokerLocator</classname>. Server rules
            1 through 3 described below result in the construction of a virtual
            <classname>MultiplexServerInvoker</classname>, and server rule 4
            (the absence of these parameters) results in the construction of a
            master <classname>MultiplexServerInvoker</classname>.</para>
  
            <para>Setting up the server, then, is simply a matter of starting a
            master <classname>MultiplexServerInvoker</classname> with a simple
            <classname>InvokerLocator</classname>, unadorned with any parameters
            specific to the multiplex invoker. As always, the server invoker is
            not created directly but by way of a
            <classname>Connector</classname>, as in the following:</para>
  
            <blockquote>
              <programlisting>
              Connector connector = new Connector();
              Connector.setInvokerLocator("multiplex://demo.jboss.com:8080");
              Connector.create()
              Connector.start()
              </programlisting>
            </blockquote>
          </section>
  
          <section>
            <title>Setting up the client</title>
  
            <para>Before multiplex connections can be established, a master
            <classname>MultiplexServerInvoker</classname> must be created as
            described in the previous section. For example, the Prime Scenario
            would begin with starting a master
            <classname>MultiplexServerInvoker</classname> on the server host,
            followed by starting, on the client host, a
            <classname>MultiplexClientInvoker</classname> <emphasis>C</emphasis>
            and a virtual <classname>MultiplexServerInvoker</classname>
            <emphasis>S</emphasis> (in either order). The first to start
            initiates a multiplex connection to the master
            <classname>MultiplexServerInvoker</classname> and requests the
            creation of a virtual <classname>MultiplexServerInvoker</classname>.
            Note that it is crucial for <emphasis>C</emphasis> and
            <emphasis>S</emphasis> to know that they are meant to share a
            multiplex connection, i.e., that they are meant to belong to the
            same invoker group. Consider the following attempt to set up a
            shared connection between hosts bluemonkey.acme.com and
            demo.jboss.com. First, <emphasis>C</emphasis> is initialized on host
            bluemonkey.acme.com with the <classname>InvokerLocator</classname>
            multiplex://demo.jboss.com:8080, and, assuming the absence of an
            existing multiplex connection to demo.jboss.com:8080, a new virtual
            socket group based on a real socket bound to an arbitrary port, say
            32000, is created. Then <emphasis>S</emphasis> is initialized with
            <classname>InvokerLocator</classname>
            multiplex://bluemonkey.acme.com:4444, but since it needs to bind to
            port 4444, it is unable to share the existing connection. [Actually,
            the example is slightly deceptive, since
            multiplex://bluemonkey.acme.com:4040 would result in the creation of
            a master <classname>MultiplexServerInvoker</classname>. But if it
            were suitably extended with the parameters discussed below so that a
            virtual <classname>MultiplexServerInvoker</classname> were created,
            the virtual invoker would be unable to share the existing
            connection.]</para>
  
            <para>So <emphasis>C</emphasis> and <emphasis>S</emphasis> need to
            agree on the address and port of the real socket underlying the
            virtual socket group they are intended to share on the client host
            and the address and port of the real socket underlying the peer
            virtual socket group on the server host. Or, more succintly, they
            must know that they are meant to belong to the same invoker group.
            Note the relationship between an invoker group and the virtual
            socket group which supports it: a
            <classname>MultiplexClientInvoker</classname> uses virtual sockets
            in its underlying virtual socket group, and a
            <classname>MultiplexServerInvoker</classname> in an invoker group
            has a <classname>VirtualServerSocket</classname> that creates
            virtual sockets in the underlying virtual socket group.</para>
  
            <para><emphasis>C</emphasis> and <emphasis>S</emphasis> each get
            half of the information necessary to identify their invoker group
            directly from their respective
            <classname>InvokerLocator</classname>s. In particular,
            <emphasis>C</emphasis> gets the remote address and port, and
            <emphasis>S</emphasis> gets the binding address and port. The
            additional information may be provided through the use of <emphasis
            role="bold">invoker group parameters</emphasis>, which may be
            communicated to <emphasis>C</emphasis> and <emphasis>S</emphasis> in
            one of two ways:</para>
  
            <orderedlist>
              <listitem>
                <para>they may be appended to the
                <classname>InvokerLocator</classname> passed to the
                <classname>Client</classname> which creates
                <emphasis>C</emphasis> and/or to the
                <classname>InvokerLocator</classname> passed to the
                <classname>Connector</classname> which creates
                <emphasis>S</emphasis></para>
              </listitem>
  
              <listitem>
                <para>they may be stored in a configuration
                <classname>Map</classname> which is passed to the
                <classname>Client</classname> and/or
                <classname>Connector</classname>.</para>
              </listitem>
            </orderedlist>
  
            <para>In either case, there are two ways in which the missing
            information can be supplied to <emphasis>C</emphasis> and
            <emphasis>S</emphasis>:</para>
  
            <orderedlist>
              <listitem>
                <para>The information can be provided explicitly by way of
                invoker group parameters:</para>
  
                <orderedlist>
                  <listitem>
                    <para><emphasis>multiplexBindHost</emphasis> and
                    <emphasis>multiplexBindPort</emphasis> parameters can be
                    passed to <emphasis>C</emphasis>, and</para>
                  </listitem>
  
                  <listitem>
                    <para><emphasis>multiplexConnectHost</emphasis> and
                    <emphasis>multiplexConnectPort</emphasis> parameters can be
                    passed to <emphasis>S</emphasis>.</para>
                  </listitem>
                </orderedlist>
              </listitem>
  
              <listitem>
                <para><emphasis>C</emphasis> and <emphasis>S</emphasis> can be
                tied together by giving them the same <emphasis
                role="bold">multiplexId</emphasis>, supplied by invoker group
                parameters:</para>
  
                <orderedlist>
                  <listitem>
                    <para><emphasis>clientMultiplexId</emphasis>, for the
                    <classname>MultiplexClientInvoker</classname>, and</para>
                  </listitem>
  
                  <listitem>
                    <para><emphasis>serverMultiplexId</emphasis>, for the
                    <classname>MultiplexServerInvoker</classname>.</para>
                  </listitem>
                </orderedlist>
  
                <para>Giving them matching multiplexIds tells them that they are
                meant to belong to the same invoker group and that they should
                provide the missing information to each other.</para>
              </listitem>
            </orderedlist>
  
            <para>The behavior of a starting
            <classname>MultiplexClientInvoker</classname> <emphasis>C</emphasis>
            is governed by the following four <emphasis role="bold">client
            rules</emphasis>:</para>
  
            <orderedlist>
              <listitem>
                <para>If <emphasis>C</emphasis> has a
                <emphasis>clientMultiplexId</emphasis> parameter, it will use it
                to attempt to find a
                <classname>MultiplexServerInvoker</classname>
                <emphasis>S</emphasis> with a
                <emphasis>serverMultiplexId</emphasis> parameter with the same
                value. If it succeeds, it will retrieve binding host and port
                values, create or reuse a suitable multiplex connection to the
                server, and start. Moreover, if <emphasis>S</emphasis> was
                unable to start because of insufficient information (server rule
                3), then <emphasis>C</emphasis> will supply the missing
                information and <emphasis>S</emphasis> will start. Note that in
                this situation <emphasis>C</emphasis> will ignore any
                <emphasis>multiplexBindHost</emphasis> and
                <emphasis>multiplexBindPort</emphasis> parameters passed to
                it.</para>
              </listitem>
  
              <listitem>
                <para>If <emphasis>C</emphasis> does not find a
                <classname>MultiplexServerInvoker</classname> through a
                multiplexId (either because it did not get a
                <emphasis>clientMultiplexId</emphasis> parameter or because
                there is no <classname>MultiplexServerInvoker</classname> with a
                matching multiplexId), but it does have
                <emphasis>multiplexBindHost</emphasis> and
                <emphasis>multiplexBindPort</emphasis> parameters, then it will
                create or reuse a suitable multiplex connection to the server,
                and start. Also, if it has a multiplexId, it will advertise
                itself for the benefit of a
                <classname>MultiplexServerInvoker</classname> that may come
                along later (see server rule 1).</para>
              </listitem>
  
              <listitem>
                <para>If <emphasis>C</emphasis> has a multiplexId and neither
                finds a <classname>MultiplexServerInvoker</classname> with a
                matching multiplexId nor has
                <emphasis>multiplexBindHost</emphasis> and
                <emphasis>multiplexBindPort</emphasis> parameters, then it will
                not start, but it will advertise itself so that it may be found
                later by a <classname>MultiplexServerInvoker</classname> (see
                server rule 1).</para>
              </listitem>
  
              <listitem>
                <para>If <emphasis>C</emphasis> has neither
                <emphasis>clientMultiplexId</emphasis> nor
                <emphasis>multiplexBindHost</emphasis> and
                <emphasis>multiplexBindPort</emphasis> parameters, it will
                create or reuse a multiplex connection from an arbitrary local
                port to the host and port given in its
                <classname>InvokerLocator</classname>, and start.</para>
              </listitem>
            </orderedlist>
  
            <para>Similarly, the behavior of a starting
            <classname>MultiplexServerInvoker</classname> <emphasis>S</emphasis>
            is governed by the following four <emphasis role="bold">server
            rules</emphasis>:</para>
  
            <orderedlist>
              <listitem>
                <para>If <emphasis>S</emphasis> has a
                <emphasis>serverMultiplexId</emphasis> parameter, it will use it
                to attempt to find a
                <classname>MultiplexClientInvoker</classname>
                <emphasis>C</emphasis> with a matching
                <emphasis>clientMultiplexId</emphasis>. If it succeeds, it will
                retrieve server host and port values, create a
                <classname>VirtualServerSocket</classname>, create or reuse a
                suitable multiplex connection to the server, and start.
                Moreover, if <emphasis>C</emphasis> was unable to start due to
                insufficient information (client rule 3), then
                <emphasis>S</emphasis> will supply the missing information and
                <emphasis>C</emphasis> will start. Note that in this situation
                <emphasis>S</emphasis> will ignore
                <emphasis>multiplexConnectHost</emphasis> and
                <emphasis>multiplexConnectPort</emphasis> parameters, if any, in
                its <classname>InvokerLocator</classname>.</para>
              </listitem>
  
              <listitem>
                <para>If <emphasis>S</emphasis> does not find a
                <classname>MultiplexClientInvoker</classname> through a
                multiplexId (either because it did not get a
                <emphasis>serverMultiplexId</emphasis> parameter or because
                there is no <classname>MultiplexClientInvoker</classname> with a
                matching multiplexId), but it does have
                <emphasis>multiplexConnectHost</emphasis> and
                <emphasis>multiplexConnectPort</emphasis> parameters, then it
                will create a <classname>VirtualServerSocket</classname>, create
                or reuse a suitable multiplex connection to the server, and
                start. Also, if it has a multiplexId, it will advertise itself
                for the benefit of a
                <classname>MultiplexClientInvoker</classname> that may come
                along later (see client rule 1).</para>
              </listitem>
  
              <listitem>
                <para>If <emphasis>S</emphasis> has a multiplexId and neither
                finds a <classname>MultiplexClientInvoker</classname> with a
                matching multiplexId nor has
                <emphasis>multiplexConnectHost</emphasis> and
                <emphasis>multiplexConnectPort</emphasis> parameters, then it
                will not start, but it will advertise itself so that it may be
                found later by a <classname>MultiplexClientInvoker</classname>
                (see client rule 1).</para>
              </listitem>
  
              <listitem>
                <para>If <emphasis>S</emphasis> has neither
                <emphasis>serverMultiplexId</emphasis> nor
                <emphasis>multiplexConnectHost</emphasis> and
                <emphasis>multiplexConnectPort</emphasis> parameters, it will
                create a <classname>MasterServerSocket</classname> bound to the
                host and port in its <classname>InvokerLocator</classname> and
                start.</para>
              </listitem>
            </orderedlist>
  
            <section>
              <title>Notes</title>
  
              <orderedlist>
                <listitem>
                  <para>Like server invokers, client invokers are not started
                  directly but are started indirectly through calls to
                  <methodname>Client(InvokerLocator locator)</methodname>, such
                  as:</para>
  
                  <programlisting>
              Client client = new Client("multiplex://demo.jboss.com:8080/?clientMultiplexId=id0");
              client.connect();
                    </programlisting>
  
                  <para><emphasis role="bold">N.B.</emphasis> For the multiplex
                  invoker, it is important to call
                  <methodname>Client.connect()</methodname>. Otherwise, the last
                  <classname>MultiplexClientInvoker</classname> that leaves an
                  invoker group will not get a chance to shut the group
                  down.</para>
                </listitem>
  
                <listitem>
                  <para>It should not be inferred that
                  <classname>MultiplexClientInvoker</classname>s and
                  <classname>MultiplexServerInvoker</classname>s belong to the
                  same invoker group <emphasis>only if </emphasis> they are
                  required to do so by invoker group parameters. In fact, if two
                  <classname>Client</classname>s are created with the
                  <classname>InvokerLocator</classname>
                  multiplex://demo.jboss.com, the second one, lacking any
                  constraints on its binding address and port, is certainly not
                  prevented from sharing a connection with the first. Rather,
                  the function of the invoker group parameters is to
                  <emphasis>force</emphasis>
                  <classname>MultiplexClientInvoker</classname>s and
                  <classname>MultiplexServerInvoker</classname>s to share a
                  connection.</para>
                </listitem>
  
                <listitem>
                  <para>There are situations in which the method of passing
                  parameters by way of the configuration map is preferable to
                  appending them to an <classname>InvokerLocator</classname>.
                  One of the functions of an
                  <classname>InvokerLocator</classname> is to identify a server,
                  and modifying the content of its
                  <classname>InvokerLocator</classname> may interfere with the
                  ability to locate the server. For example, one of the features
                  of JBoss Remoting is the substitution of method calls for
                  remote invocations when it discovers that a server runs in the
                  same JVM as the client. However, appending multiplex
                  parameters to the <classname>InvokerLocator</classname> by
                  which the server is identified will prevent the Remoting
                  runtime from recognizing the local presence of the server, and
                  the optimization will not occur.</para>
                </listitem>
  
                <listitem>
                  <para>It is possible, and convenient, to set up a multiplexing
                  scenario using no parameters other than
                  <emphasis>clientMultiplexId</emphasis> and
                  <emphasis>serverMultiplexId</emphasis>. Note, however, that in
                  this case neither the <classname>Clients</classname> nor the
                  <classname>Connector</classname> will be fully initialized
                  until after both have been started. If the
                  <classname>Clients</classname> and the
                  <classname>Connector</classname> are to be started
                  independently, then the other parameters must be used.
                  <emphasis role="bold">N.B.</emphasis> If a
                  <classname>Client</classname> depends on
                  <classname>Connector</classname> in the same invoker group to
                  supply binding information, it is an error to call methods
                  such as <methodname>Client.connect()</methodname> and
                  <methodname>Client.invoke()</methodname> until the
                  <classname>Connector</classname> has been started.</para>
                </listitem>
  
                <listitem>
                  <para><classname>Clients</classname> and the optional
                  <classname>Connector</classname> may be created (and the
                  <classname>Connector</classname> started) in any order.</para>
                </listitem>
              </orderedlist>
            </section>
          </section>
  
          <section>
            <title>Shutting down invoker groups.</title>
  
            <para>A virtual socket group will shut down, releasing a real socket
            and a number of threads, when (1) its last member has closed and (2)
            the socket group at the remote end of the multiplex connection
            agrees to the proposed shut down. The second condition prevents a
            situation in which a new virtual socket tries to join what it thinks
            is a viable socket group at the same time that the peer socket group
            is shutting down. So for a virtual socket group to shut down, all
            members at both ends of the connection must be closed.</para>
  
            <para>The implication of this negotiated shutdown mechanism is that
            as long as the <classname>VirtualServerSocket</classname> used by a
            virtual <classname>MultiplexServerInvoker</classname> remains open,
            resources at the client end of the connection cannot be freed, and
            for this reason it is important to understand how to close virtual
            <classname>MultiplexServerInvoker</classname>s.</para>
  
            <para>There are three ways in which a virtual
            <classname>MultiplexServerInvoker</classname> that belongs to a
            master <classname>MultiplexServerInvoker</classname>'s invoker farm
            can shut down. <itemizedlist>
                <listitem>
                  <para>When a master
                  <classname>MultiplexServerInvoker</classname> is closed, it
                  closes all of the virtual
                  <classname>MultiplexServerInvoker</classname>s it
                  created.</para>
                </listitem>
  
                <listitem>
                  <para>A virtual <classname>MultiplexServerInvoker</classname>
                  can be retrieved by calling either
                  <methodname>MultiplexServerInvoker.getServerInvokers()</methodname>
                  or
                  <methodname>MultiplexServerInvoker.getServerInvoker(InetSocketAddress)</methodname>
                  on its master <classname>MultiplexServerInvoker</classname>
                  and then closed directly.</para>
                </listitem>
  
                <listitem>
                  <para>When the <methodname>accept()</methodname> method of its
                  <classname>VirtualServerSocket</classname> times out, and when
                  it detects that all multiplex invokers in the invoker group at
                  the client end of the connection have shut down, a virtual
                  <classname>MultiplexServerInvoker</classname> will shut itself
                  down. Note that when all members leave an invoker group, it is
                  guaranteed not to be revived, i.e., no new members may
                  join.</para>
                </listitem>
              </itemizedlist> The third method insures that without any explicit
            intervention, closing all multiplex invokers on the client (by way
            of calling <methodname>Client.disconnect()</methodname> and
            <methodname>Connector.stop()</methodname>) is guaranteed to result
            in the eventual release of resources. The timeout period may be
            adjusted by setting the <emphasis>timeout</emphasis> parameter (see
            below). Alternatively, the second method, in conjunction with the
            use of
            <methodname>MultiplexServerInvoker.isSafeToShutdown()</methodname>,
            which returns <code>true</code> on
            <classname>MultiplexServerInvoker</classname> <code>M</code> if and
            only if (1) <code>M</code> is not virtual, or (2) all of the
            multiplex invokers in the invoker group at the client end of
            <code>M</code>'s connection have shut down. For example, a thread
            could be dedicated to looking for useless
            <classname>MultiplexServerInvoker</classname>s and terminating them
            before their natural expiration through timing out.</para>
          </section>
  
          <section>
            <title>Examples</title>
  
            <para>The following are examples of setting up a client for
            multiplexed synchronous and asynchronous communication. They each
            assume the existence of a master
            <classname>MultiplexServerInvoker</classname> running on
            demo.jboss.com:8080.</para>
  
            <para>For complete examples see the section <xref
            linkend="section-multiplex-invokers" />.</para>
  
            <orderedlist>
              <listitem>
                <para>A <classname>MultiplexClientInvoker</classname>
                <emphasis>C</emphasis> starts first:</para>
  
                <programlisting>
              String parameters = "multiplexBindHost=localhost&amp;multiplexBindPort=7070&amp;clientMultiplexId=demoId1";
              String locatorURI = "multiplex://demo.jboss.com:8080/?" + parameters;
              InvokerLocator locator = new InvokerLocator(locatorURI);
              Client client = new Client(locator);
              client.connect();
                 </programlisting>
  
                <para>and then it is found by a
                <classname>MultiplexServerInvoker</classname> with a matching
                multiplexId, which joins <emphasis>C</emphasis>'s invoker group
                and starts:</para>
  
                <programlisting>
              Connector connector = new Connector();
              String parameters = "serverMultiplexId=demoId1";
              String locatorURI = "multiplex://localhost:7070/?" + parameters;
              InvokerLocator locator = new InvokerLocator(locatorURI);
              connector.setInvokerLocator(locator.getLocatorURI());
              connector.create();
              connector.start();
                 </programlisting>
              </listitem>
  
              <listitem>
                <para>A <classname>MultiplexClientInvoker</classname>
                <emphasis>C</emphasis> starts:</para>
  
                <programlisting>
              String parameters = "multiplexBindHost=localhost&amp;multiplexBindPort=7070";
              String locatorURI = "multiplex://demo.jboss.com:8080/?" + parameters;
              InvokerLocator locator = new InvokerLocator(locatorURI);
              Client client = new Client(locator);
              client.connect();
                    </programlisting>
  
                <para>and a <classname>MultiplexServerInvoker</classname>
                <emphasis>S</emphasis> starts independently, joining
                <emphasis>C</emphasis>'s invoker group by virtue of having
                matching local and remote addresses and ports:</para>
  
                <programlisting>
              Connector connector = new Connector();
              String parameters = "multiplexConnectHost=demo.jboss.com&amp;multiplexConnectPort=8080";
              String locatorURI = "multiplex://localhost:7070/?" + parameters;
              InvokerLocator locator = new InvokerLocator(locatorURI);
              connector.setInvokerLocator(locator.getLocatorURI());
              connector.create();
              connector.start();
                 </programlisting>
              </listitem>
  
              <listitem>
                <para>A <classname>MultiplexClientInvoker</classname>
                <emphasis>C</emphasis> is created but does not start:</para>
  
                <programlisting>
              String parameters = "clientMultiplexId=demoId2";
              String locatorURI = "multiplex://demo.jboss.com:8080/?" + parameters;
              InvokerLocator locator = new InvokerLocator(locatorURI);
              Client client = new Client(locator);
                 </programlisting>
  
                <para>and then a <classname>MultiplexServerInvoker</classname>
                <emphasis>S</emphasis> is created with a matching multiplexId,
                allowing both <emphasis>C</emphasis> and <emphasis>S</emphasis>
                to start:</para>
  
                <programlisting>
              Connector connector = new Connector();
              String parameters = "serverMultiplexId=demoId2";
              String locatorURI = "multiplex://localhost:7070/?" + parameters;
              InvokerLocator locator = new InvokerLocator(locatorURI);
              connector.setInvokerLocator(locator.getLocatorURI());
              connector.create();
              connector.start();
              client.connect();
                 </programlisting>
  
                <para>Note the call to <methodname>Client.connect()</methodname>
                after the call to
                <methodname>Connector.start()</methodname>.</para>
              </listitem>
  
              <listitem>
                <para>A <classname>MultiplexClientInvoker</classname>
                <emphasis>C</emphasis> starts in an invoker group based on a
                real socket bound to an arbitrary local port:</para>
  
                <programlisting>
              String locatorURI = "multiplex://demo.jboss.com:8080";
              InvokerLocator locator = new InvokerLocator(locatorURI);
              Client client = new Client(locator);
              client.connect();
                 </programlisting>
  
                <para>and then a <classname>MultiplexServerInvoker</classname>
                <emphasis>S</emphasis> starts independently:</para>
  
                <programlisting>
              Connector connector = new Connector();
              String locatorURI = "multiplex://localhost:7070";
              InvokerLocator locator = new InvokerLocator(locatorURI);
              connector.setInvokerLocator(locator.getLocatorURI());
              connector.create();
              connector.start();
                 </programlisting>
  
                <para>Note that <emphasis>S</emphasis> creates a
                <classname>MasterServerSocket</classname> rather than a
                <classname>VirtualServerSocket</classname> in this case and so
                does not share a multiplex connection and does not belong to an
                invoker group.</para>
              </listitem>
  
              <listitem>
                <para>This is example 1, rewritten so that the invoker group
                parameters are passed by way of a configuration
                <classname>Map</classname> instead of
                <classname>InvokerLocator</classname>s. A
                <classname>MultiplexClientInvoker</classname>
                <emphasis>C</emphasis> starts first:</para>
  
                <programlisting>
              String locatorURI = "multiplex://demo.jboss.com:8080";
              InvokerLocator locator = new InvokerLocator(locatorURI);
              Map configuration = new HashMap();
              configuration.put(MultiplexInvokerConstants.MULTIPLEX_BIND_HOST_KEY, "localhost");
              configuration.put(MultiplexInvokerConstants.MULTIPLEX_BIND_PORT_KEY, "7070");
              configuration.put(MultiplexInvokerConstants.CLIENT_MULTIPLEX_ID_KEY, "demoId1");
              Client client = new Client(locator, configuration);
              client.connect();
                 </programlisting>
  
                <para>and then it is found by a
                <classname>MultiplexServerInvoker</classname> with a matching
                multiplexId, which joins <emphasis>C</emphasis>'s invoker group
                and starts:</para>
  
                <programlisting>
              String locatorURI = "multiplex://localhost:7070";
              InvokerLocator locator = new InvokerLocator(locatorURI);
              Map configuration = new HashMap();
              configuration.put(MultiplexInvokerConstants.SERVER_MULTIPLEX_ID_KEY, "demoId1");
              Connector connector = new Connector(locator.getLocatorURI(), configuration);
              connector.create();
              connector.start();
                 </programlisting>
              </listitem>
            </orderedlist>
          </section>
  
          <section>
            <title>Configuration properties</title>
  
            <para>There are four categories of configuration properties
            supported by the multiplex invoker, the last three of which are
            specific to the multiplex invoker. Properties in categories 2 and 3
            may be configured by appending them to the server's locator URI.
            Properties in categories 2, 3, and 4 may be configured by putting
            their values in a configuration <classname>HashMap</classname> and
            passing the map to a <classname>MultiplexServerInvoker</classname>
            and/or <classname>MultiplexClientInvoker</classname> constructor,
            according to the category. Constants for the property names in
            categories 2, 3, and 4 are found in
            <classname>org.jboss.remoting.transport.multiplex.Multiplex</classname>.
            Note that some of them are also found in the older
            <classname>org.jboss.remoting.transport.multiplex.MultiplexInvokerConstants</classname>,
            but the use of that class is now deprecated.</para>
  
            <orderedlist numeration="arabic">
              <listitem>
                <para>The following properties are managed by ancestor classes
                of <classname>MultiplexServerInvoker</classname>.  See the discussion
                under <classname>SocketServerInvoker</classname> for more
                information.</para>
                <para><emphasis role="bold">socketTimeout</emphasis> - The
                socket timeout value passed to the
                <methodname>Socket.setSoTimeout()</methodname> method and the
                <methodname>ServerSocket.setSoTimeout()</methodname> method. The
                default is 60000 (or 1 minute).</para>
  
                <para><emphasis role="bold">numAcceptThreads</emphasis> - The
                number of threads that exist for accepting client connections.
                The default is 1.</para>
              </listitem>
  
              <listitem>
                <para>The following properties are intended to be passed to a
                virtual <classname>MultiplexServerInvoker</classname> to
                configure its multiplex connection. These properties are
                specific to the multiplex invoker.</para>
  
                <para><emphasis role="bold">multiplexConnectHost</emphasis> -
                the name or address of the host to which the multiplex
                connection should be made.</para>
  
                <para><emphasis role="bold">multiplexConnectPort</emphasis> -
                the port to which the multiplex connection should be
                made.</para>
  
                <para><emphasis role="bold">serverMultiplexId</emphasis> - a
                string that associates a
                <classname>MultiplexServerInvoker</classname> with a
                <classname>MultiplexClientInvoker</classname> with which it
                should share a multiplex connection.</para>
  
                <para><emphasis role="bold">multiplex.maxAcceptErrors</emphasis>
                - Master and virtual
                <classname>MultiplexServerInvoker</classname>s keep a counter of
                errors experienced by their server socket, and they terminate
                when this maximum is exceeded. Note that
                <classname>SSLHandshakeException</classname>s are excluded from
                the count, since they could indicate a client rather than server
                error.</para>
              </listitem>
  
              <listitem>
                <para>The following properties are intended to be passed to a
                virtual <classname>MultiplexClientInvoker</classname> to
                configure its multiplex connection. These properties are
                specific to the multiplex invoker.</para>
  
                <para><emphasis role="bold">multiplexBindHost</emphasis> - the
                host name or address to which the local end of the multiplex
                connection should be bound.</para>
  
                <para><emphasis role="bold">multiplexBindPort</emphasis> - the
                port to which the local end of the multiplex connection should
                be bound</para>
  
                <para><emphasis role="bold">clientMultiplexId</emphasis> - a
                string that associates a
                <classname>MultiplexClientInvoker</classname> with a
                <classname>MultiplexServerInvoker</classname> with which it
                should share a multiplex connection.</para>
              </listitem>
  
              <listitem>
                <para>There is also a set of properties which are specific to
                the Multiplex subsystem internal classes. See the Multiplex
                documentation at</para>
  
                <blockquote>
                  <para><ulink
                  url="http://labs.jboss.com/portal/jbossremoting/docs/index.html">
                  http://labs.jboss.com/portal/jbossremoting/docs/index.html</ulink></para>
                </blockquote>
  
                <para>for more information.</para>
              </listitem>
            </orderedlist>
          </section>
        </section>
  
        <section>
          <title>SSL Multiplex Invoker</title>
  
          <para>This transport is essentially identical to the Multiplex
          transport, except that it will create SSL socket factories and server
          socket factories by default.</para>
  
          <para>The twist to be found with the multiplex transport is that
          virtual <classname>MultiplexServerInvoker</classname>s use a
          <classname>VirtualServerSocket</classname>, which is based on a client
          rather than a server socket, and consequently they act like a client
          in some ways. In particular, a virtual
          <classname>MultiplexServerInvoker</classname> will, in some cases,
          attempt to connect to a remote master
          <classname>MultiplexServerInvoker</classname>, for which it will need
          an actual client socket. All of the rules for configuring socket
          factories apply to the <classname>MultiplexServerInvoker</classname>,
          which calls the same method that client invokers use to get a socket
          factory. Moreover, if necessary, it will look for a
          <classname>ServerSocketFactoryMBean</classname> to get SSL information
          when configuring a socket factory.</para>
        </section>
      </section>
  
      <section>
        <title>Marshalling</title>
  
        <para>Marshalling of data can range from extremely simple to somewhat
        complex, depending on how much customization is needed. The following
        explains how marshallers/unmarshallers can be configured. Note that this
        applies for all the different transports, but will use the socket
        transport for examples.</para>
  
        <para>The easiest way to configure marshalling is to specify nothing at
        all. This will prompt the remoting invokers to use their default
        marshaller/unmarshallers. For example, the socket invoker will use the
        SerializableMarshaller/SerializableUnMarshaller and the http invoker
        will use the HTTPMarshaller/HTTPUnMarshaller, on both the client and
        server side.</para>
  
        <para>The next easiest way is to specify the data type of the
        marshaller/unmarshaller as a parameter to the locator url. This can be
        done by simply adding the key word 'datatype' to the url, such
        as:</para>
  
        <programlisting>socket://myhost:5400/?datatype=serializable</programlisting>
  
        <para>This can be done for types that are statically bound within the
        <code>MarshalFactory</code> , serializable and http, without requiring
        any extra coding, since they will be available to any user of remoting.
        However, is more likely this will be used for custom marshallers (since
        could just use the default data type from the invokers if using the
        statically defined types). If using custom marshaller/unmarshaller, will
        need to make sure both are added programmatically to the
        <code>MarshalFactory</code> during runtime (on both the client and
        server side). This can be done by the following method call within the
        MarshalFactory:</para>
  
        <programlisting>public static void addMarshaller(String dataType, Marshaller marshaller, UnMarshaller unMarshaller)
        </programlisting>
  
        <para>The dataType passed can be any String value desired. For example,
        could add custom InvocationMarshaller and InvocationUnMarshaller with
        the data type of 'invocation'. An example using this data type would
        then be:</para>
  
        <programlisting>socket://myhost:5400/?datatype=invocation</programlisting>
  
        <para>One of the problems with using a data type for a custom
        Marshaller/UnMarshaller is having to explicitly code the addition of
        these within the MarshalFactory on both the client and the server. So
        another approach that is a little more flexible is to specify the fully
        qualified class name for both the Marshaller and UnMarshaller on the
        locator url. For example:</para>
  
        <programlisting>socket://myhost:5400/?datatype=invocation&amp;
              marshaller=org.jboss.invocation.unified.marshall.InvocationMarshaller&amp;
              unmarshaller=org.jboss.invocation.unified.marshall.InvocationUnMarshaller
           </programlisting>
  
        <para>This will prompt remoting to try to load and instantiate the
        Marshaller and UnMarshaller classes. If both are found and loaded, they
        will automatically be added to the MarshalFactory by data type, so will
        remain in memory. Now the only requirement is that the custom Marshaller
        and UnMarshaller classes be available on both the client and server's
        classpath.</para>
  
        <para>Another requirement of the actual Marshaller and UnMarshaller
        classes is that they have a void constructor. Otherwise loading of these
        will fail.</para>
  
        <para>This configuration can also be applied using the service xml. If
        using declaration of invoker using the InvokerLocator attribute, can
        simply add the datatype, marshaller, and unmarshaller parameters to the
        defined InvokerLocator attribute value. For example:</para>
  
        <programlisting>      
           &lt;attribute name="InvokerLocator"&gt;
              &lt;![CDATA[socket://${jboss.bind.address}:8084/?datatype=invocation&amp;
              marshaller=org.jboss.invocation.unified.marshall.InvocationMarshaller&amp;
              unmarshaller=org.jboss.invocation.unified.marshall.InvocationUnMarshaller]]&gt;
           &lt;/attribute&gt;
        </programlisting>
  
        <para>If were using config element to declare the invoker, will need to
        add an attribute for each and include the isParam attribute set to true.
        For example:</para>
  
        <programlisting>
           &lt;invoker transport="socket"&gt;
              &lt;attribute name="dataType" isParam="true"&gt;invocation&lt;/attribute&gt;
              &lt;attribute name="marshaller" isParam="true"&gt;
                 org.jboss.invocation.unified.marshall.InvocationMarshaller
              &lt;/attribute&gt;
              &lt;attribute name="unmarshaller" isParam="true"&gt;
                    org.jboss.invocation.unified.marshall.InvocationUnMarshaller
              &lt;/attribute&gt;
           &lt;/invoker&gt;
        </programlisting>
  
        <para>This configuration is fine if the classes are present within the
        client's classpath. If they are not, can provide configuration for
        allowing clients to dynamically load the classes from the server. To do
        this, can use the parameter 'loaderport' with the value of the port you
        would like your marshal loader to run on. For example:</para>
  
        <programlisting>
           &lt;invoker transport="socket"&gt;
              &lt;attribute name="dataType" isParam="true"&gt;invocation&lt;/attribute&gt;
              &lt;attribute name="marshaller" isParam="true"&gt;
                 org.jboss.invocation.unified.marshall.InvocationMarshaller
              &lt;/attribute&gt;
              &lt;attribute name="unmarshaller" isParam="true"&gt;
                 org.jboss.invocation.unified.marshall.InvocationUnMarshaller
              &lt;/attribute&gt;
              &lt;attribute name="loaderport" isParam="true"&gt;5401&lt;/attribute&gt;
           &lt;/invoker&gt;
        </programlisting>
  
        <para>When this parameter is supplied, the Connector will recognize this
        at startup and create a marshal loader connector automatically, which
        will run on the port specified. The locator url will be exactly the same
        as the original invoker locator, except will be using the socket
        transport protocol and will have all marshalling parameters removed
        (except the dataType). When the remoting client can not load the
        marshaller/unmarshaller for the specified data type, it will try to load
        them from the marshal loader service running on the loader port,
        including any classes they depend on. This will happen automatically and
        no coding is required (only the ability for the client to access the
        server on the specified loader port, so must provide access if running
        through firewall).</para>
  
        <bridgehead>Compression marshalling</bridgehead>
  
        <para>A compression marshaller/unmarshaller is available as well which
        uses gzip to compress and uncompress large payloads for wire transfer.
        The implementation classes are
        <classname>org.jboss.remoting.marshal.compress.CompressingMarshaller</classname>
        and
        <classname>org.jboss.remoting.marshal.compress.CompressingUnMarshaller</classname>.
        They extend the
        <code>org.jboss.remoting.marshal.serializable.SerializableMarshaller</code>
        and
        <code>org.jboss.remoting.marshal.serializable.SerializableUnMarshaller</code>
        interfaces and maintain the same behavior with the addition of
        compression.</para>
      </section>
  
      <section>
        <title>Callbacks</title>
  
        <section>
          <title>Callback overview</title>
  
          <para>Although this section covers callback configuration, will need
          to first cover a little general information about callbacks within
          remoting. There are two models for callbacks, push and pull. In the
          push model, the client will register a callback server via an
          InvokerLocator with the target server. When the target server has a
          callback to deliver, it will call on the callback server directly and
          send the callback message.</para>
  
          <para>The other model, pull callbacks, allows the client to call on
          the target server to collect the callback messages waiting for it. The
          target server then has to manage these callback messages on the server
          until the client calls to collect them. Since the server has no
          control of when the client will call to get the callbacks, it has to
          be aware of memory constraints as it manages a growing number of
          callbacks. The way the callback server does this is through use of a
          persistence policy. This policy indicates at what point the server has
          too little free memory available and therefore the callback message
          should be put into a persistent store. This policy can be configured
          via the <code>memPercentCeiling</code> attribute (see more on
          configuring this below).</para>
  
          <para>By default, the persistent store used by the invokers is the
          <code>org.jboss.remoting.NullCallbackStore</code> . The
          NullCallbackStore will simply throw away the callback to help avoid
          running out of memory. When the persistence policy is triggered and
          the NullCallbackStore is called upon to store the callback, the
          invocation handler making the call will be thrown an IOException with
          the message:</para>
  
          <para><literal>Callback has been lost because not enough free memory
          to hold object.</literal></para>
  
          <para>and there will be an error in the log stating which object was
          lost. In this same scenario, the client will get an instance of the
          <code>org.jboss.remoting.NullCallbackStore</code> .
          <code>FailedCallback</code> class when they call to get their
          callbacks. This class will throw a RuntimeException with the following
          message when <code>getCallbackObject()</code> is called:</para>
  
          <para><literal>This is an invalid callback. The server ran out of
          memory, so callbacks were lost.</literal></para>
  
          <para>Also, the payload of the callback will be the same string. The
          client will also get any valid callbacks that were kept in memory
          before the persistence policy was triggered.</para>
  
          <para>An example case when using the NullCallbackStore might be when
          callback objects A, B, and C are stored in memory because there is
          enough free memory. Then when callback D comes, the persistence policy
          is triggered and the NullCallbackStore is asked to persist callback D.
          The NullCallbackStore will throw away callback D and create a
          FailedCallback object to take its place. Then callback E comes, and
          there is still too little free memory, so that is thrown away by the
          NullCallbackStore.</para>
  
          <para>Then the client calls to get its callbacks. It will receive a
          List containing callbacks A, B, C and the FailedCallback. When the
          client asks the FailedCallback for its callback payload, it will throw
          the aforementioned exception.</para>
  
          <para>Besides the default NullCallbackStore, there is a truly
          persistent CallbackStore, which will persist callback messages to disk
          so they will not be lost. The description of the CallbackStore is as
          follows:</para>
  
          <para><literal>Acts as a persistent list which writes Serializable
          objects to disk and will retrieve them in same order in which they
          were added (FIFO). Each file will be named according to the current
          time (using System.currentTimeMillis() with the file suffix specified
          (see below). When the object is read and returned by calling the
          getNext() method, the file on disk for that object will be deleted. If
          for some reason the store VM crashes, the objects will still be
          available upon next startup. The attributes to make sure to configure
          are:</literal></para>
  
          <para><literal>file path - this determines which directory to write
          the objects. The default value is the property value of
          'jboss.server.data.dir' and if this is not set, then will be 'data'.
          For example, might be /jboss/server/default/data.</literal></para>
  
          <para><literal>file suffix - the file suffix to use for the file
          written for each object stored.</literal></para>
  
          <para><literal>This is also a service mbean, so can be run as a
          service within JBoss AS or stand alone.</literal></para>
  
          <para>Custom callback stores can also be implemented and defined
          within configuration. The only requirement is that it implements the
          org.jboss.remoting.SerializableStore interface and has a void
          constructor (only in the case of using a fully qualified classname in
          configuration).</para>
  
          <para>Once a callback client has been removed as a listener, all
          persisted callbacks will be removed from disk.</para>
        </section>
  
        <section>
          <title>Callback Configuration</title>
  
          <para>All callback configuration will need to be defined within the
          invoker configuration, since the invoker is the parent that creates
          the callback servers as needed (when client registers for pull
          callbacks). Example service xml are included below.</para>
  
          <para><emphasis role="bold">callbackMemCeiling</emphasis> - the
          percentage of free memory available before callbacks will be
          persisted. If the memory heap allocated has reached its maximum value
          and the percent of free memory available is less than the
          callbackMemCeiling, this will trigger persisting of the callback
          message. The default value is 20.</para>
  
          <para>Note: The calculations for this is not always accurate. The
          reason is that total memory used is usually less than the max allowed.
          Thus, the amount of free memory is relative to the total amount
          allocated at that point in time. It is not until the total amount of
          memory allocated is equal to the max it will be allowed to allocate.
          At this point, the amount of free memory becomes relevant. Therefore,
          if the memory percentage ceiling is high, it might not trigger until
          after free memory percentage is well below the ceiling.</para>
  
          <para><emphasis role="bold">callbackStore</emphasis> - specifies the
          callback store to be used. The value can be either an MBean ObjectName
          or a fully qualified class name. If using class name, the callback
          store implementation must have a void constructor. The default is to
          use the NullCallbackStore.</para>
  
          <bridgehead>CallbackStore configuration</bridgehead>
  
          <para>The CallbackStore can be configured via the invoker
          configuration as well.</para>
  
          <para><emphasis role="bold">StoreFilePath</emphasis> - indicates to
          which directory to write the callback objects. The default value is
          the property value of 'jboss.server.data.dir' and if this is not set,
          then will be 'data'. Will then append 'remoting' and the callback
          client's session id. An example would be
          'data\remoting\5c4o05l-9jijyx-e5b6xyph-1-e5b6xyph-2'.</para>
  
          <para><emphasis role="bold">StoreFileSuffix</emphasis> - indicates the
          file suffix to use for the callback objects written to disk. The
          default value is 'ser'.</para>
  
          <bridgehead>Sample service configuration</bridgehead>
  
          <para>Socket transport with callback store specified by class name and
          memory ceiling set to 30%:</para>
  
          <programlisting>
             &lt;mbean code="org.jboss.remoting.transport.Connector"
                   xmbean-dd="org/jboss/remoting/transport/Connector.xml"
                   name="jboss.remoting:service=Connector,transport=Socket"
                   display-name="Socket transport Connector"&gt;
  
                &lt;attribute name="Configuration"&gt;
                   &lt;config&gt;
                      &lt;invoker transport="socket"&gt;
                         &lt;attribute name="callbackStore"&gt;org.jboss.remoting.CallbackStore&lt;/attribute&gt;
                         &lt;attribute name="callbackMemCeiling"&gt;30&lt;/attribute&gt;
                      &lt;/invoker&gt;
                      &lt;handlers&gt;
                         &lt;handler subsystem="test"&gt;
                            org.jboss.remoting.callback.pull.memory.CallbackInvocationHandler
                         &lt;/handler&gt;
                      &lt;/handlers&gt;
                   &lt;/config&gt;
                &lt;/attribute&gt;
             &lt;/mbean&gt;
          </programlisting>
  
          <para>Socket transport with callback store specified by MBean
          ObjectName and declaration of CallbackStore as service:</para>
  
          <programlisting>
             &lt;mbean code="org.jboss.remoting.CallbackStore"
                   name="jboss.remoting:service=CallbackStore,type=Serializable"
                   display-name="Persisted Callback Store"&gt;
  
                &lt;!-- the directory to store the persisted callbacks into --&gt;
                &lt;attribute name="StoreFilePath"&gt;callback_store&lt;/attribute&gt;
                &lt;!-- the file suffix to use for each callback persisted to disk --&gt;
                &lt;attribute name="StoreFileSuffix"&gt;cbk&lt;/attribute&gt;
             &lt;/mbean&gt;
  
             &lt;mbean code="org.jboss.remoting.transport.Connector"
                   xmbean-dd="org/jboss/remoting/transport/Connector.xml"
                   name="jboss.remoting:service=Connector,transport=Socket"
                   display-name="Socket transport Connector"&gt;
  
                &lt;attribute name="Configuration"&gt;
                   &lt;config&gt;
                      &lt;invoker transport="socket"&gt;
                         &lt;attribute name="callbackStore"&gt;
                            jboss.remoting:service=CallbackStore,type=Serializable
                         &lt;/attribute&gt;
                      &lt;/invoker&gt;
                      &lt;handlers&gt;
                         &lt;handler subsystem="test"&gt;
                            org.jboss.remoting.callback.pull.memory.CallbackInvocationHandler
                         &lt;/handler&gt;
                      &lt;/handlers&gt;
                   &lt;/config&gt;
                &lt;/attribute&gt;
             &lt;/mbean&gt;
          </programlisting>
  
          <para>Socket transport with callback store specified by class name and
          the callback store's file path and file suffix defined:</para>
  
          <programlisting>
             &lt;mbean code="org.jboss.remoting.transport.Connector"
                   xmbean-dd="org/jboss/remoting/transport/Connector.xml"
                   name="jboss.remoting:service=Connector,transport=Socket"
                   display-name="Socket transport Connector"&gt;
  
                &lt;attribute name="Configuration"&gt;
                   &lt;config&gt;
                      &lt;invoker transport="socket"&gt;
                         &lt;attribute name="callbackStore"&gt;org.jboss.remoting.CallbackStore&lt;/attribute&gt;
                         &lt;attribute name="StoreFilePath"&gt;callback&lt;/attribute&gt;
                         &lt;attribute name="StoreFileSuffix"&gt;cst&lt;/attribute&gt;
                      &lt;/invoker&gt;
                      &lt;handlers&gt;
                         &lt;handler subsystem="test"&gt;
                            org.jboss.remoting.callback.pull.memory.CallbackInvocationHandler
                         &lt;/handler&gt;
                      &lt;/handlers&gt;
                   &lt;/config&gt;
                &lt;/attribute&gt;
             &lt;/mbean&gt;
          </programlisting>
        </section>
  
        <section>
          <title>Callback Exception Handling</title>
  
          <para>Since performing callbacks can sometimes fail, due to network
          errors or errors produced by the client callback handler, there needs
          to be a mechanism for managing exceptions when delivering callbacks.
          This is handled via use of the
          <code>org.jboss.remoting.callback.CallbackErrorHandler</code>
          interface. Implementations of this interface can be registered with
          the Connector to control the behavior when callback exceptions
          occur.</para>
  
          <para>The implementation of the CallbackErrorHandler interface can be
          specified by setting the 'callbackErrorHandler' attribute to either
          the ObjectName of an MBean instance of the CallbackErrorHandler which
          is already running and registered with the MBeanServer, or can just
          specify the fully qualified class name of the CallbackErrorHandler
          implementation (which will be constructed on the fly and must have a
          void parameter constructor). The full server invoker configuration
          will be passed along to the CallbackErrorHandler, so if want to add
          extra configuration information in the invoker's configuration for the
          callback error handler, it will be available. If no callback error
          handler is specified via configuration,
          <code>org.jboss.remoting.callback.DefaultCallbackErrorHandler</code>
          will be used by default. This implementation will allow up to 5
          exceptions to occur when trying to deliver a callback message from the
          server to the registered callback listener client (regardless of what
          the cause of the exception is, so could be because could not connect
          or could be because the client actually threw a valid exception).
          After the DefaultCallbackErrorHandler receives its fifth exception, it
          will remove the callback listener from the server invoker handler and
          shut down the callback listener proxy on the server side. The number
          of exceptions the DefaultCallbackErrorHandler will allow before
          removing the listener can by configured by the 'callbackErrorsAllowed'
          attribute.</para>
        </section>
      </section>
  
      <section>
        <title>Programmatic configuration</title>
  
        <para>It is possible to configure all this programmatically, if running
        outside the JBoss Application server for example, but is a little more
        tedious. Since the remoting components are all bound together by the
        <code>org.jboss.remoting.transport.Connector</code> class, will need to
        call its <code>setConfiguration(org.w3c.dom.Element xml)</code> method
        with same xml as in the mbean service configuration, before calling its
        <code>start()</code> method.</para>
  
        <para>The xml passed to the Connector should have
        <code>&lt;config&gt;</code> element as the root element and continue
        from there with <code>&lt;invoker&gt;</code> sub-element and so on. An
        example of this can be found in
        org.jboss.test.remoting.configuration.SocketClientConfigurationTestCase.</para>
      </section>
  
      <section>
        <title>Socket factories and server socket factories</title>
        
        <para>All current transports depend on sockets and server sockets, and the
        ability to specify their implementation classes provides considerable
        power in configuring Remoting.  Notably, SSL sockets
        and server sockets are the basis of secure communications in Remoting.
        This section covers the configuration of socket factories and server
        socket factories on both the server side and the client side, and then
        focuses on SSL configuration.
        </para>
        
        <section>
           <title>Server side programmatic configuration</title>
           <para>
           All server invokers use server sockets, and it makes sense,
           therefore, to be able to configure server invokers with
           server socket factories.  It is also true, though less obvious.
           that server invokers create sockets (other than by way of
           server sockets).  When a server invoker makes a push
           callback to a client, it creates a client invoker, which creates a
           socket.  Moreover, some server invokers, e.g., the RMI server invoker,
           have their own idiosyncratic uses for socket factories.  Remoting offers a
           number of ways of configuring socket factories and server socket
           factories, and these apply to all transports.
           </para>
           
           <section>
              <title id="section-ssf-serverside" xreflabel="Server socket factories">
                 Server socket factories.
              </title>
              <para>For <classname>ServerSocketFactory</classname>s, there are
              ten options for programmatic configuration:</para>
              
              <orderedlist>
                 
                 <listitem>
                    <para>Get the <classname>ServerInvoker</classname> by calling
                    <methodname>Connector.getServerInvoker()</methodname> and call
                    <methodname>ServerInvoker.setServerSocketFactory()</methodname>.</para>
                 </listitem>
  
                 <listitem>
                    <para>Call <methodname>Connector.setServerSocketFactory()</methodname>.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                    Put a constructed <classname>ServerSocketFactory</classname> in a
                    configuration map, using key
                    <constant>Remoting.CUSTOM_SERVER_SOCKET_FACTORY</constant>,
                    and pass the map to one of the <classname>Connector</classname>
                    constructors.
                    </para>
                 </listitem>
                         
                 <listitem>
                    <para>
                       Create an xml document with root element <code>&lt;config&gt;</code>,
                       setting the <code>&lt;serverSocketFactory&gt;</code> attribute to
                       the name of a <classname>ServerSocketFactoryMBean</classname> and pass
                       the document to <methodname>Connector.setConfiguration()</methodname>.  For
                       example:
                       
                       <programlisting>
                          StringBuffer buf = new StringBuffer();
                          buf.append("&lt;?xml version=\"1.0\"?&gt;\n");
                          buf.append("&lt;config&gt;");
                          buf.append("   &lt;invoker transport=\"sslsocket\"&gt;");
                          buf.append("      &lt;attribute name=\"serverBindAddress\"&gt;" + getHostName() + "&lt;/attribute&gt;");
                          buf.append("      &lt;attribute name=\"serverBindPort\"&gt;" + freeport + "&lt;/attribute&gt;");
                          buf.append("      &lt;attribute name=\"serverSocketFactory\"&gt;" + socketFactoryObjName + "&lt;/attribute&gt;");
                          buf.append("   &lt;/invoker&gt;");
                          buf.append("&lt;/config&gt;");
                          ByteArrayInputStream bais = new ByteArrayInputStream(buf.toString().getBytes());
                          Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bais);
                          connector.setConfiguration(xml.getDocumentElement());
                       </programlisting>
                    </para>
                 </listitem>
                     
                 <listitem>
                    <para>
                       Create an xml document with root element <code>&lt;config&gt;</code>,
                       setting the <code>&lt;serverSocketFactory&gt;</code> attribute to
                       the class name of a <classname>ServerSocketFactory</classname> and pass
                       the document to <methodname>Connector.setConfiguration()</methodname>.  
                       The <code>&lt;serverSocketFactory&gt;</code> class must have a default
                       constructor, which will be used to create a 
                    <classname>ServerSocketFactory</classname>.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Put the <classname>ObjectName</classname> of a
                       <classname>ServerSocketFactoryMBean</classname> in a configuration map,
                       using key <constant>ServerInvoker.SERVER_SOCKET_FACTORY</constant>,
                       and pass the map to one of the <classname>Connector</classname>
                       constructors.
                    </para>
                 </listitem>
                             
                 <listitem>
                    <para>
                    Put the class name of a <classname>ServerSocketFactory</classname>
                    in a configuration map, using key
                    <constant>ServerInvoker.SERVER_SOCKET_FACTORY</constant>,
                    and pass the map to one of the <classname>Connector</classname> constructors.
                    The <code>&lt;serverSocketFactory&gt;</code> class must have a
                    default constructor, which will be used to create a 
                    <classname>ServerSocketFactory</classname>.
                    </para>
                 </listitem>
                             
                 <listitem>
                    <para>
                    Put a set of SSL parameters, using the keys in
                    <classname>org.jboss.remoting.security.SSLSocketBuilder</classname>, in a
                    configuration map and pass the map to one of the
                    <classname>Connector</classname> constructors. These will be used by
                    <classname>SSLSocketBuilder</classname> (see below) to create a
                    <classname>CustomSSLServerSocketFactory</classname>.
                    </para>
                 </listitem>
                             
                 <listitem>
                    <para>
                    Configure an appropriate set of SSL system properties
                    and use one of the SSL transports (https, sslmultiplex,
                    sslrmi, or sslsocket). The properties will be used to
                    create some kind of <classname>SSLServerSocketFactory</classname>,
                    as determined by the transport.
                    </para>
                 </listitem>
                             
                 <listitem>
                    <para>
                    Use one of the non-SSL transports and do nothing. A default
                    <classname>ServerSocketFactory</classname> will be constructed.
                    </para>
                 </listitem>
              </orderedlist>
              
              <para>
                 These options are essentially in descending order of precedence.
                 If options 3 and 6, for example, are both
                 used, the factory passed in option 3 will prevail.
                 Options 4 and 5 are mutually exclusive, as are options 6 and 7.
                 Options 1, 2, 3, 5, and 7 are illustrated in
                 <classname>FactoryConfigSample</classname>
                 and options 4, 6, 8, and 9 are illustrated in
                 <classname>FactoryConfigSSLSample</classname>,
                 both of which are in package
                 <classname>org.jboss.remoting.samples.config.factories</classname>.
              </para>
              
              <para>
              <emphasis role="bold">Timing considerations.</emphasis> The 
              <classname>ServerInvoker</classname>, for any transport, is created
              during the call to <methodname>Connector.create()</methodname>, before which 
              option 1 is unavailable. Option 2, on the other hand,
              is only available before the call to
              <methodname>Connector.create()</methodname>.
              Once the <classname>ServerInvoker</classname> has been created, it
              selects a <classname>ServerSocketFactory</classname>, according to
              the rules enumerated above, during the <methodname>create()</methodname>
              phase.  For all current transports, the actual
              <classname>ServerSocket</classname> is created during the call to
              <methodname>Connector.start()</methodname>, so that a call to
              <methodname>ServerInvoker.setServerSocketFactory()</methodname> 
              (option 1) can override the selected <classname>ServerSocketFactory</classname>
              until <methodname>Connector.start()</methodname> is called.
              </para>
           </section>
           
           <section>
              <title>Socket factories</title>
              <para>
              For <classname>SocketFactory</classname>s, there are also ten options
              for programmatic configuration, and they are essentially the same as
              the previous ten.  Note, however, that options 5 and 6 are reversed.
              This is because an <classname>ServerSocketFactoryMBean</classname>,
              if it exists, is given precedence over class names:</para>
              
              <orderedlist>
                 <listitem>
                    <para>
                       Call <methodname>Connector.setSocketFactory()</methodname>.
                    </para>
                 </listitem>
        
                 <listitem>
                    <para>
                       Get the <classname>ServerInvoker</classname> by calling
                       <methodname>Connector.getServerInvoker()</methodname> and call
                       <methodname>ServerInvoker.setSocketFactory()</methodname>.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Put a constructed <classname>SocketFactory</classname> in a
                       configuration map, using key
                       <constant>Remoting.CUSTOM_SOCKET_FACTORY</constant>, and pass
                       the map to one of the <classname>Connector</classname> constructors.
                    
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Create an xml document with root element <code>&lt;config&gt;</code>,
                       setting the <code>&lt;serverSocketFactory&gt;</code> attribute to
                       the name of a <classname>ServerSocketFactoryMBean</classname> and pass
                       the document to <methodname>Connector.setConfiguration()</methodname>.
                       If the MBean has type
                       <classname>SSLServerSocketFactoryServiceMBean</classname>, its
                       configuration information will be gathered and used to construct a
                       <classname>CustomSSLSocketFactory</classname>.
                       <emphasis role="bold">Note.</emphasis>  This method is guaranteed to
                       work only for callback client invokers.  For other, transport
                       specific, socket factory uses, the transport may or may not
                       use this information.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Put the <classname>ObjectName</classname> of a
                       <classname>ServerSocketFactoryMBean</classname> in a configuration
                       map, using key <constant>ServerInvoker.SERVER_SOCKET_FACTORY</constant>,
                       and pass the map to one of the <classname>Connector</classname>
                       constructors. If the MBean has type
                       <classname>SSLServerSocketFactoryServiceMBean</classname>, its
                       configuration information will be gathered and used to construct a
                       <classname>CustomSSLSocketFactory</classname>.
                       <emphasis role="bold">Note.</emphasis>  This method is guaranteed to
                       work only for callback client invokers.  For other, transport
                       specific, socket factory uses, the transport may or may not
                       use this information.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Create an xml document with root element <code>&lt;config&gt;</code>,
                       setting the <code>&lt;socketFactory&gt;</code> attribute to
                       the class name of a <classname>SocketFactory</classname> and pass
                       the document to <methodname>Connector.setConfiguration()</methodname>.
                       For example:
                       
                       <programlisting>
                          StringBuffer buf = new StringBuffer();
                          buf.append("&lt;?xml version=\"1.0\"?&gt;\n");
                          buf.append("&lt;config&gt;");
                          buf.append("   &lt;invoker transport=\"sslsocket\"&gt;");
                          buf.append("      &lt;attribute name=\"serverBindAddress\"&gt;" + getHostName() + "&lt;/attribute&gt;");
                          buf.append("      &lt;attribute name=\"serverBindPort\"&gt;" + freeport + "&lt;/attribute&gt;");
                          buf.append("      &lt;attribute name=\"socketFactory\"&gt;" + socketFactoryClassname + "&lt;/attribute&gt;");
                          buf.append("   &lt;/invoker&gt;");
                          buf.append("&lt;/config&gt;");
                          ByteArrayInputStream bais = new ByteArrayInputStream(buf.toString().getBytes());
                          Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bais);
                          connector.setConfiguration(xml.getDocumentElement());
                       </programlisting>
                       
                       The <classname>SocketFactory</classname> class must have a
                       default constructor, which will be used to create a 
                    <classname>SocketFactory</classname>.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Put the class name of a <classname>SocketFactory</classname>
                       in a configuration map, using key
                       <constant>Remoting.SOCKET_FACTORY_NAME</constant>, and pass the map
                       to one of the <classname>Connector</classname> constructors. The 
                       <classname>SocketFactory</classname> class
                       must have a default constructor.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Put a set of SSL parameters, using the keys in
                       <classname>org.jboss.remoting.security.SSLSocketBuilder</classname>,
                       in a configuration map and pass the map to one of the
                       <classname>Connector</classname> constructors. These will be used by
                       <classname>SSLSocketBuilder</classname> (see below) to create a
                       <classname>CustomSSLSocketFactory</classname>.
                    
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Configure an appropriate set of SSL system properties and use one of
                       the SSL transports (https, sslmultiplex, sslrmi, or sslsocket). The
                       properties will be used to create some kind of
                       <classname>SSLSocketFactory</classname>, as determined by the
                       transport.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Use one of the non-SSL transports and do nothing. Ordinary
                       <classname>Socket</classname>s will be used.
                    </para>
                 </listitem>
             </orderedlist>
               
             <para>Again, these are essentially in descending order of precedence.        
                Options 1, 2, 3, 6, and 7 are illustrated in
                <classname>FactoryConfigSample</classname>
                and options 4, 5, 8, and 9 are illustrated in
                <classname>FactoryConfigSSLSample</classname>,
                both of which are in package
                <classname>org.jboss.remoting.samples.config.factories</classname>.
             </para>
             
              <para>
              <emphasis role="bold">Timing considerations.</emphasis> A new
              <classname>Client</classname>, with a client invoker, is created
              on the server side whenever a callback listener is registered by a
              call to <methodname>Client.addListener()</methodname>.  If a 
              <classname>SocketFactory</classname> is supplied by any of options 1 to 5,
              it will be passed to the <classname>Client</classname>.  Otherwise, any
              information from options 6 to 9 will be passed to the client invoker,
              which will create a <classname>SocketFactory</classname> according
              to the rules given below in the section on client side socket factory
              configuration.  Once <methodname>Connector.create()</methodname>
              has been called,
              <methodname>ServerInvoker.setSocketFactory()</methodname>, may be
              called at any time to determine the 
              <classname>SocketFactory</classname> used by the next callback
              client invoker.
              </para>
           </section>
        </section>
  
        <section>
           <title>Client side programmatic configuration</title>
           <para>
           On the client side it is possible to configure socket factories for client
           invokers and to configure server socket factories for callback server invokers.
           Configuration on the client side is largely the same as configuration
           on the server side, with the exception that no
           <classname>MBeanServer</classname> is assumed to be present, and the
           <classname>Client</classname> has no facilities for parsing xml
           documents.
           </para>
           
           <section>
              <title>Server socket factories.</title>
              <para>For <classname>ServerSocketFactory</classname>s in callback
              server invokers, there are
              eight options for programmatic configuration, which are identical to
              options 1-3, 5 and 7-10 on the server side (we don't assume the
              existence of an <classname>MBeanServer</classname> on the client
              side:</para>
              
              <orderedlist>
                 <listitem>
                    <para>Get the <classname>ServerInvoker</classname> by calling
                    <methodname>Connector.getServerInvoker()</methodname> and call
                    <methodname>ServerInvoker.setServerSocketFactory()</methodname>.</para>
                 </listitem>
              
                 <listitem>
                    <para>Call <methodname>Connector.setServerSocketFactory()</methodname>.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                    Put a constructed <classname>ServerSocketFactory</classname> in a
                    configuration map, using key
                    <constant>Remoting.CUSTOM_SERVER_SOCKET_FACTORY</constant>,
                    and pass the map to one of the <classname>Connector</classname>
                    constructors.
                    </para>
                 </listitem>
                         
                 <listitem>
                    <para>
                       Create an xml document with root element <code>&lt;config&gt;</code>,
                       setting the <code>&lt;serverSocketFactory&gt;</code> attribute to
                       the class name of a <classname>ServerSocketFactory</classname> and pass
                       the document to <methodname>Connector.setConfiguration()</methodname>.
                       For example:
                       
                       <programlisting>
                          StringBuffer buf = new StringBuffer();
                          buf.append("&lt;?xml version=\"1.0\"?&gt;\n");
                          buf.append("&lt;config&gt;");
                          buf.append("   &lt;invoker transport=\"sslsocket\"&gt;");
                          buf.append("      &lt;attribute name=\"serverBindAddress\"&gt;" + getHostName() + "&lt;/attribute&gt;");
                          buf.append("      &lt;attribute name=\"serverBindPort\"&gt;" + freeport + "&lt;/attribute&gt;");
                          buf.append("      &lt;attribute name=\"serverSocketFactory\"&gt;" + serverSocketFactoryClassname + "&lt;/attribute&gt;");
                          buf.append("   &lt;/invoker&gt;");
                          buf.append("&lt;/config&gt;");
                          ByteArrayInputStream bais = new ByteArrayInputStream(buf.toString().getBytes());
                          Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bais);
                          connector.setConfiguration(xml.getDocumentElement());
                       </programlisting>
                       
                       The <classname>ServerSocketFactory</classname> class must
                       have a default constructor, which will be used to create a
                       <classname>ServerSocketFactory</classname>.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                    Put the class name of a <classname>ServerSocketFactory</classname>
                    in a configuration map, using key
                    <constant>ServerInvoker.SERVER_SOCKET_FACTORY</constant>,
                    and pass the map to one of the <classname>Connector</classname> constructors.
                    The <classname>ServerSocketFactory</classname> class must
                    have a default constructor, which will be used to create a
                    <classname>ServerSocketFactory</classname>.</para>
                 </listitem>
                             
                 <listitem>
                    <para>
                    Put a set of SSL parameters, using the keys in
                    <classname>org.jboss.remoting.security.SSLSocketBuilder</classname>, in a
                    configuration map and pass the map to one of the
                    <classname>Connector</classname> constructors. These will be used by
                    <classname>SSLSocketBuilder</classname> (see below) to create a
                    <classname>CustomSSLServerSocketFactory</classname>.
                    </para>
                 </listitem>
                             
                 <listitem>
                    <para>
                    Configure an appropriate set of SSL system properties
                    and use one of the SSL transports (https, sslmultiplex,
                    sslrmi, or sslsocket). The properties will be used to
                    create some kind of <classname>SSLServerSocketFactory</classname>,
                    as determined by the transport.
                    </para>
                 </listitem>
                             
                 <listitem>
                    <para>
                    Use one of the non-SSL transports and do nothing. A default
                    <classname>ServerSocketFactory</classname> will be constructed.
                    </para>
                 </listitem>
              </orderedlist>
              
              <para>
                 These options are essentially in descending order of precedence.
                 For example, if options 3 and 5, for example, are both
                 used, the factory passed in options 3 will prevail.
                 Options 1, 2, 3, 4, and 5 are illustrated in
                 <classname>FactoryConfigSample</classname>
                 and options 6 and 7 are illustrated in
                 <classname>FactoryConfigSSLSample</classname>,
                 both of which are in package
                 <classname>org.jboss.remoting.samples.config.factories</classname>.
              </para>
              
              <para>
              <emphasis role="bold">Timing considerations.</emphasis>  See the
              discussion in the section on the creation of server socket factories
              on the server side.
              </para>
           </section>
     
           <section>
              <title>Socket factories.</title>
              <para>
              For <classname>SocketFactory</classname>s in client invokers,
              there are seven options
              for programmatic configuration, and they are essentially the same as 
              1-3 and 5-8 in the previous section (<classname>Client</classname>
              has no facility for parsing xml documents:</para>
              
              <orderedlist>
        
                 <listitem>
                    <para>
                       Get the <classname>ClientInvoker</classname> by calling
                       <methodname>Client.getInvoker()</methodname> and call
                       <methodname>ClientInvoker.setSocketFactory()</methodname>.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Call <methodname>Client.setSocketFactory()</methodname>.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Put a constructed <classname>SocketFactory</classname> in a
                       configuration map, using key
                       <constant>Remoting.CUSTOM_SOCKET_FACTORY</constant>, and pass
                       the map to one of the <classname>Client</classname> constructors.
                    
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Put the class name of a <classname>SocketFactory</classname>
                       in a configuration map, using key
                       <constant>Remoting.SOCKET_FACTORY_NAME</constant>, and pass the map
                       to one of the <classname>Client</classname> constructors.
                       The <classname>SocketFactory</classname> class must
                       have a default constructor, which will be used to create a
                       <classname>SocketFactory</classname>.
                    
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Put a set of SSL parameters, using the keys in
                       <classname>org.jboss.remoting.security.SSLSocketBuilder</classname>,
                       in a configuration map and pass the map to one of the
                       <classname>Client</classname> constructors. These will be used by
                       <classname>SSLSocketBuilder</classname> (see below) to create a
                       <classname>CustomSSLSocketFactory</classname>.
                    
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Configure an appropriate set of SSL system properties and use one of
                       the SSL transports (https, sslmultiplex, sslrmi, or sslsocket). The
                       properties will be used to create some kind of
                       <classname>SSLSocketFactory</classname>, as determined by the
                       transport.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       Use one of the non-SSL transports and do nothing. Ordinary
                       <classname>Socket</classname>s will be used.
                    </para>
                 </listitem>
             </orderedlist>
               
             <para>Again, these are essentially in descending order of precedence.
                 Options 1, 2, 3, and 4 are illustrated in
                 <classname>FactoryConfigSample</classname>
                 and options 5 and 6 are illustrated in
                 <classname>FactoryConfigSSLSample</classname>,
                 both of which are in package
                 <classname>org.jboss.remoting.samples.config.factories</classname>.
             </para>
             
             <para>
              <emphasis role="bold">Timing considerations.</emphasis> A 
              <classname>SocketFactory</classname> is created in the constructor
              for <classname>RemoteClientInvoker</classname>, the ancestor of
              all current remote client invokers (that is, all client invokers except
              <classname>LocalClientInvoker</classname>, which can make a call
              by reference on a server invoker in the same JVM), but it is
              currently used only by SSL transports, for which the timing 
              considerations vary.</para>
              
              <orderedlist>
              
                 <listitem>
                    <para>
                       <emphasis role="bold">https: </emphasis> 
                       <classname>HTTPSClientInvoker</classname> sets the
                       socket factory on its
                       <classname>HttpsURLConnection</classname> each time
                       <methodname>Client.invoke()</methodname> is called.  Option
                       1 may be used to reset the <classname>SocketFactory</classname>
                       for future invocations at any time.
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       <emphasis role="bold">sslmultiplex: </emphasis> Whichever
                       of <classname>SSLMultiplexClientInvoker</classname> or
                       <classname>SSLMultiplexServerInvoker</classname> first
                       gets sufficient bind and connect information to create a
                       priming socket (see the section on the multiplex invoker for
                       a discussion of priming sockets) passes the
                       current <classname>SocketFactory</classname> to be
                       used to create the actual
                       socket that supports the multiplexed connection.  This
                       happens during the call to either
                       <methodname>Client.connect()</methodname> or
                       <methodname>Connector.create()</methodname>.  Once the
                       actual socket is created, no further configuration is
                       possible
                    </para>
                 </listitem>
                 
                 <listitem>
                    <para>
                       <emphasis role="bold">sslrmi: </emphasis> A 
                       <classname>SocketFactory</classname>
                       is either created or configured for future creation during
                       <methodname>Client.create()</methodname>.  No further
                       configuration is possible.
                    </para>
                 </listitem>
                    
                 <listitem>
                    <para>
                       <emphasis role="bold">sslsocket: </emphasis> 
                       <classname>SSLSocketClientInvoker</classname> uses the current
                       <classname>SocketFactory</classname> to create a new socket
                       whenever it runs out of available pooled connections. Option
                       1 may be used to reset the <classname>SocketFactory</classname>
                       for future connections at any time.
                    </para>
                 </listitem>
              </orderedlist>
           </section>
        </section>
        
        <section>
           <title>Server side configuration in the JBoss Application Server</title>
           
           <para>
           Everything in the previous two sections applies to configuring socket
           and server socket factories in any environment, including inside the
           JBoss Application Server (JBossAS), but JBossAS adds some new options. 
           In particular, the <classname>SARDeployer</classname> (see
           <emphasis>The JBoss 4 Application Server Guide</emphasis>
           on the labs.jboss.org web site) can read information 
           from a <code>*-service.xml</code> file, as discussed above in the
           section "General Connector and Invoker configuration," and use it to
           configure MBeans such as <classname>Connector</classname>s.</para>
           
           <para>
           An example of a service xml that covers all the different
           transport and service configurations can be found within the
           example-service.xml file under the etc directory of the JBoss Remoting
           distribution.</para>
  
           <para>The server socket factory to be used by a server invoker can be
           set via configuration within the service xml. To do this, the
           serverSocketFactory attribute will need to be set as a sub-element of
           the invoker element (this cannot be done if just specifying the invoker
           configuration using the InvokerLocator attribute). The attribute value
           must be either</para>
           
           <orderedlist>
              <listitem>
                 <para>the JMX ObjectName of an MBean that implements the
                 <code>org.jboss.remoting.security.ServerSocketFactoryMBean</code>
                 interface, or</para>
              </listitem>
              
              <listitem>
                 <para>
                 the class name of a <classname>ServerSocketFactory</classname>
                 with a default constructor.
                 </para>
              </listitem>
           </orderedlist>
           
           
           <para>An example of the first case would be:</para>
     
           <programlisting>
              &lt;mbean code="org.jboss.remoting.transport.Connector"
                    xmbean-dd="org/jboss/remoting/transport/Connector.xml"
                    name="jboss.remoting:service=Connector,transport=Socket"
                    display-name="Socket transport Connector"&gt;
     
                 &lt;attribute name="Configuration"&gt;
                    &lt;config&gt;
                       &lt;invoker transport="sslsocket"&gt;
                          &lt;attribute name="serverSocketFactory"&gt;
                             jboss.remoting:service=ServerSocketFactory,type=SSL
                          &lt;/attribute&gt;
                          &lt;attribute name="numAcceptThreads"&gt;1&lt;/attribute&gt;
           </programlisting>
           
           <para>The <code>serverSocketFactory</code> attribute is processed
           as follows:</para>
           
           <orderedlist>
              <listitem>
                 <para>Take its String value, create an <classname>ObjectName</classname>
                 from it, and look up an MBean with that name from the <classname>MBeanServer</classname>
                 that the invoker has been registered with (by
                 way of the <classname>Connector</classname>).  If an MBean with that
                 name is found, create a proxy to it of type
                 <code>org.jboss.remoting.security.ServerSocketFactoryMBean</code>.
                 (Technically, a user could set the
                 <code>serverSocketFactory</code> property with the locator url, but the
                 preferred method is to use the explicit configuration via the invoker
                 element's attribute, as discussed above.)</para>
              </listitem>
              
              <listitem>
                 <para>If no MBean is found with a matching
                 <classname>ObjectName</classname>,
                 treat the <code>serverSocketFactory</code> attribute as a class name
                 and try to create an instance using the default constructor.</para>
              </listitem>
           </orderedlist>
           
           <para>The JBossRemoting project provides an implementation of the
           ServerSocketFactoryMBean that can be used and should provide most of the
           customization features that would be needed. More on this implementation
           later.</para>
           
           <para>Note that these two options correspond exactly to options 4 and 5
           in section <xref linkend="section-ssf-serverside"/> (on the server side),
           which is how these two new options are implemented.</para>
           
           <para><emphasis role="bold">Timing considerations.</emphasis>  If a
           <classname>Connector</classname> is accessed by way of the 
           <classname>MBeanServer</classname>, then most of the options for
           configuring the server socket factory discussed in 
           <xref linkend="section-ssf-serverside"/> are irrelevant since 
           <classname>ConnectorMBean</classname> does not expose methods for using
           them.  However, when a <classname>Connector</classname> that is registered
           with an <classname>MBeanServer</classname> creates a
           server invoker during a call to
           <methodname>Connector.create()</methodname>, it also registers the
           server invoker with the same <classname>MBeanServer</classname>, which
           means that the server invoker is accessible by way of its
           <classname>ObjectName</classname>, which has the form</para>
           
           <programlisting>
              jboss.remoting:service=invoker,transport=socket,host=www.jboss.com,port=8765
           </programlisting>
  
           <para>for example, followed by additional parameter=value pairs.  (See
           the jmx-console for a running instance of JBossAS at
           http://localhost:8080/jmx-console/ to see examples of server invoker
           <classname>ObjectName</classname>s.)  Now, if another
           MBean is configured in a <code>*-service.xml</code> file to be
           dependent on the server invoker MBean, e.g.</para>
           
           <programlisting>
              &lt;mbean code="org.jboss.Blah" name="jboss.remoting:whatever,name=blah"&gt;
                 &lt;depends optional-attribute-name="serverInvoker"&gt;
                     jboss.remoting:service=invoker,transport=socket,host=www.jboss.com,port=8765
                 &lt;/depends&gt;
              &lt;/mbean&gt;
           </programlisting>
           
           <para>then <methodname>org.jboss.Blah.create()</methodname> will have
           access to the designated server invoker after the invoker has been
           created but before it has been started, which means that
           <methodname>ServerInvoker.setServerSocketFactory()</methodname> will be
           effective.  (See the <emphasis>The JBoss 4 Application Server
           Guide</emphasis>, Chapter 2, for more information about the life cycle
           of JBoss MBeans.)</para>
           </section>
         
        <section>
           <title>SSL transports</title>
  
           <para>There are now four transports that support SSL: https,
           sslmultiplex, sslrmi, and sslsocket.  All of preceding discussion
           applies to each of these, and, moreover, they are all extensions of their
           non-ssl counterparts, so only some ssl specific information will be
           added here.</para>
           
           <bridgehead>https</bridgehead>
     
           <para>The https transport is a bit different from the sslsocket in
           configuration since the implementation is based off the Tomcat
           connectors. The first major difference is the transport protocol keyword
           to identify it, which is 'https'.</para>
     
           <para>Next is defining the SSL implementation and server socket factory
           to be used. The SSL implementation to be used can be set via the
           'SSLImplementation' attribute and should always have a value of
           <code>org.jboss.remoting.transport.coyote.ssl.RemotingSSLImplementation</code>.
           The server socket factory to be used should be set via the
           'serverSocketFactory' attribute and should always be the
           javax.management.ObjectName value for an implementation of the
           <code>org.jboss.remoting.security.ServerSocketFactoryMBean</code>
           interface, which should already be registered with the MBeanServer and
           running (more details on this in a minute).</para>
     
           <para>An example of setting up https via service.xml configuration would
           be:</para>
     
           <programlisting>     &lt;mbean code="org.jboss.remoting.transport.Connector"
           xmbean-dd="org/jboss/remoting/transport/Connector.xml"
           name="jboss.remoting:service=Connector,transport=HTTPS"
           display-name="HTTPS transport Connector"&gt;
     
           &lt;attribute name="Configuration"&gt;
              &lt;config&gt;
                 &lt;invoker transport="https"&gt;
                    &lt;!-- The following is for setting the server socket factory.  If want ssl support --&gt;
                    &lt;!-- use a server socket factory that supports ssl.  The only requirement is that --&gt;
                    &lt;!-- the server socket factory value must be an ObjectName, meaning the --&gt;
                    &lt;!-- server socket factory implementation must be a MBean and also --&gt;
                    &lt;!-- MUST implement the org.jboss.remoting.security.ServerSocketFactoryMBean interface. --&gt;
                    &lt;attribute name="serverSocketFactory"&gt;jboss.remoting:service=ServerSocketFactory,type=SSL&lt;/attribute&gt;
                    &lt;attribute name="SSLImplementation"&gt;org.jboss.remoting.transport.coyote.ssl.RemotingSSLImplementation&lt;/attribute&gt;
                    &lt;attribute name="serverBindAddress"&gt;${jboss.bind.address}&lt;/attribute&gt;
                    &lt;attribute name="serverBindPort"&gt;6669&lt;/attribute&gt;
                 &lt;/invoker&gt;
                 &lt;handlers&gt;
                    &lt;handler subsystem="mock"&gt;org.jboss.test.remoting.transport.mock.MockServerInvocationHandler&lt;/handler&gt;
                 &lt;/handlers&gt;
              &lt;/config&gt;
           &lt;/attribute&gt;
           &lt;!-- This depends is included because need to make sure this mbean is running before configure invoker. --&gt;
           &lt;depends&gt;jboss.remoting:service=ServerSocketFactory,type=SSL&lt;/depends&gt;
        &lt;/mbean&gt;
     </programlisting>
     
           <para>Notice that the 'serverSocketFactory' attribute has a value of
           'jboss.remoting:service=ServerSocketFactory,type=SSL', which is not
           defined in the configuration snippet. More on how to define this in the
           next section.</para>
     
           <para>One of the major changes related to using the Tomcat connectors
           with regards to SSL is that everything within Tomcat is defined via
           properties configuration and there is no external API for making changes
           during runtime. This means that there is no way to set server socket
           factory implementation programatically, other than via configuration (so
           cannot call setServerSocketFactory() method on the server invoker as
           could with the ssl socket invoker). This also means that if not running
           within the JBoss Application Server container, but running stand alone,
           will need to setup an MBeanServer and register the server socket factory
           with it programatically. For an example of how to do this
           programatically, can refer to
           org.jboss.test.remoting.transport.http.ssl.basic.HTTPSInvokerTestServer.</para>
     
           <para>The configuration for SSL support only works when using the java
           based http processor and not with the APR based transport. See section
           4.7 for more information on using the APR based transport.</para>
                    
           <bridgehead>sslmultiplex</bridgehead>
           
           <para>The sslmultiplex server invoker inherits from the socket server
           invoker a method with signature</para>
           
           <programlisting>
              public void setNewServerSocketFactory(ServerSocketFactory serverSocketFactory)
           </programlisting>
           
           <para>which supports dynamic replacement of server socket factories.  The
           principal motivation for this facility is to be able to swap in a
           new <classname>SSLServerSocketFactory</classname> configured with an
           updated keystore.</para>
           
           <bridgehead>sslsocket</bridgehead>
           <para>In addition to the various configuration options discussed above,
           the sslsocket transport exposes the</para>
     
           <programlisting>public void setServerSocketFactory(ServerSocketFactory serverSocketFactory)</programlisting>
           
           <para>method as a JMX operation.</para>
           
           <para>Also, the sslsocket server invoker inherits from the socket server
           invoker a method with signature</para>
           
           <programlisting>
              public void setNewServerSocketFactory(ServerSocketFactory serverSocketFactory)
           </programlisting>
           
           <para>which supports dynamic replacement of server socket factories.  The
           principal motivation for this facility is to be able to swap in a
           new <classname>SSLServerSocketFactory</classname> configured with an
           updated keystore.</para>
           
        </section>
           
        <section>
           <title>SSLSocketBuilder</title>
     
           <para>Throughout this section reference has been made to SSL
           socket factory and server socket factory configuration parameters.
           This subsection will introduce these parameters in the context of
           configuring
           <classname>org.jboss.remoting.security.SSLSocketBuilder</classname>,
           Remoting's flexible, highly customizable master factory for creating
           socket and server socket factories.  It can be used programmatically on
           both the client and server side, and it is also a service MBean, so it 
           can be configured and started from within a service xml in a JBossAS 
           environment.</para>
           
           <para>Once a <classname>SSLSocketBuilder</classname> has been
           constructed and configured, a call to its method
           <methodname>createSSLServerSocketFactory()</methodname> will return a custom
           instance of a <classname>SSLServerSocketFactory</classname>, and a 
           call to <methodname>createSSLSocketFactory()</methodname> will
           return a custom instance of <classname>SSLSocketFactory</classname>.</para>
                    
           <para>
           There are two modes in which the <classname>SSLSocketBuilder</classname>
           can be run. The first is the default mode where all that is needed is to
           declare the <classname>SSLSocketBuilder</classname> and set the system properties
           <code>javax.net.ssl.keyStore</code> and
           <code>javax.net.ssl.keyStorePassword</code>. This will use the JVM
           vendor's default configuration for creating the SSL server socket
           factory.</para>
     
           <para>In order to customize any of the SSL properties, the
           first requirement is that the default mode is turned off. This is
           <emphasis role="bold">IMPORTANT</emphasis> because otherwise, if the
           default mode is not explicitly turned off, all other settings will be
           IGNORED, even if they are explicitly set. To turn off the default mode
           via service xml configuration, set the
           <code>UseSSLServerSocketFactory</code> attribute to false. This can also
           be done programmatically by calling the
           <code>setUseSSLServerSocketFactory()</code> and passing false as the
           parameter value.</para>
           
           <para>There are two ways to configure a
           <classname>SSLSocketBuilder</classname></para>
           
           <orderedlist>
              <listitem>
                 <para>set its bean attributes, either programmatically or by xml
                 configuration, or</para>
              </listitem>
              
              <listitem>
                 <para>pass to a <classname>SSLSocketBuilder</classname> constructor
                 a configuration map with keys defined in the
                 <classname>SSLSocketBuilder</classname> class.</para>
              </listitem>
           </orderedlist>
           
     
           <para>The configuration properties for
           <classname>SSLSocketBuilder</classname>are as follows:</para>
           
           <table frame="all" id="SSLSocketBuilderTable" xreflabel="Table 1">
              <title><classname>SSLSocketBuilder</classname> configuration 
              parameters.</title>
  
              <tgroup cols="5">
        
                 <colspec colname="c1" colnum="1"/>
                 <colspec colname="c2" colnum="2"/>
                 <colspec colname="c3" colnum="3" align="center"/>
                 <colspec colname="c4" colnum="4" align="center"/>
                 <colspec colname="c5" colnum="5"/>
                             
                 <thead>
                    <row>
                       <entry>
                          <para>attribute</para>
                       </entry>
                       <entry>
                          <para>key name</para>
                       </entry>
                       <entry>
                          <para>type</para>
                       </entry>
                       <entry>
                          <para>default</para>
                       </entry>
                       <entry>
                          <para>description</para>
                       </entry>
                    </row>
                 </thead>
        
                 <tbody>
                    <row>
                       <entry><para>ClientAuthMode</para></entry>
                       <entry><para>REMOTING_CLIENT_AUTH_MODE</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para>need</para></entry>
                       <entry>
                          <para>Determines if sockets need or want
                          client authentication. This configuration option is only
                          useful for sockets in the server mode.  Value may be
                          "none", "want", or "need".</para></entry>
                    </row>
                    
                    <row>
                       <entry><para>KeyAlias</para></entry>
                       <entry><para>REMOTING_KEY_ALIAS</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para></para></entry>
                       <entry>
                          <para>The preferred identity in key store to be used by
                          key managers</para></entry>
                    </row>
                    
                    <row>
                       <entry><para>KeyPassword</para></entry>
                       <entry><para>REMOTING_KEY_PASSWORD</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para></para></entry>
                       <entry>
                          <para>Sets the password to use for the keys within the key store.
                          This only needs to be set if
                          <methodname>setUseSSLServerSocketFactory()</methodname> is set to false
                          (otherwise will be ignored). If this value is not set, but
                          the key store password is, it will use that value for the
                          key password.</para></entry>
                    </row>
                    
                    <row>
                       <entry><para>KeyStoreAlgorithm</para></entry>
                       <entry><para>REMOTING_KEY_STORE_ALGORITHM</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para>SunX509</para></entry>
                       <entry>
                          <para>The algorithm for the key manager factory.</para></entry>
                    </row>
                    
                    <row>
                       <entry><para>KeyStorePassword</para></entry>
                       <entry><para>REMOTING_KEY_STORE_PASSWORD</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para></para></entry>
                       <entry>
                          <para>The password
                          to use for the key store. This only needs to be set if
                          <methodname>setUseSSLServerSocketFactory()</methodname>
                          is set to false (otherwise will be
                          ignored). The value passed will also be used for the
                          key password if the latter attribute is not explicitly
                          set.</para></entry>
                    </row>
                    
                    <row>
                       <entry><para>KeyStoreType</para></entry>
                       <entry><para>REMOTING_KEY_STORE_TYPE</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para>JKS</para></entry>
                       <entry>
                          <para>The type to be
                          used for the key store. Some
                          acceptable values are JKS (Java Keystore - Sun's keystore
                          format), JCEKS (Java Cryptography Extension keystore -
                          More secure version of JKS), and PKCS12 (Public-Key
                          Cryptography Standards #12 keystore - RSA's Personal
                          Information Exchange Syntax Standard). These are not case
                          sensitive.</para></entry>
                    </row>               
                    
                    <row>
                       <entry><para>KeyStoreURL</para></entry>
                       <entry><para>REMOTING_KEY_STORE_FILE_PATH</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para></para></entry>
                       <entry>
                          <para>Property used to define where
                          <classname>SSLSocketBuilder</classname> will
                          look for the keystore file. This can be relative to the thread's
                          classloader or can be an absolute path on the file system or
                          can be a URL.</para></entry>
                    </row>      
                    
                    <row>
                       <entry><para>Provider</para></entry>
                       <entry><para>none</para></entry>
                       <entry><para>java.security.Provider</para></entry>
                       <entry><para></para></entry>
                       <entry>
                          <para>Java Security API implementation to use.</para></entry>
                    </row>  
                    
                    <row>
                       <entry><para>ProviderName</para></entry>
                       <entry><para>REMOTING_SSL_PROVIDER_NAME</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para></para></entry>
                       <entry>
                          <para>Name of Java Security API implementation to use.
                          </para></entry>
                    </row>  
                                   
                    <row>
                       <entry><para>SecureRandom</para></entry>
                       <entry><para>none</para></entry>
                       <entry><para>java.security.SecureRandom</para></entry>
                       <entry><para><code>new SecureRandom()</code></para></entry>
                       <entry>
                          <para>Random number generator to use.</para></entry>
                    </row>  
                    
                    <row>
                       <entry><para>SecureSocketProtocol</para></entry>
                       <entry><para>REMOTING_SSL_PROTOCOL</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para>TLS</para></entry>
                       <entry>
                          <para> The protocol for the <classname>SSLContext</classname>.
                          Some acceptable values are TLS, SSL, and SSLv3</para></entry>
                    </row>  
                    
                    <row>
                       <entry><para>ServerAuthMode</para></entry>
                       <entry><para>REMOTING_SERVER_AUTH_MODE</para></entry>
                       <entry><para>boolean/String</para></entry>
                       <entry><para>true</para></entry>
                       <entry>
                          <para>Determines if a client should attempt to
                          authenticate a server certificate as one it trusts.</para></entry>
                    </row>               
                    
                    <row>
                       <entry><para>ServerSocketUseClientMode</para></entry>
                       <entry><para>REMOTING_SERVER_SOCKET_USE_CLIENT_MODE</para></entry>
                       <entry><para>boolean/String</para></entry>
                       <entry><para>false</para></entry>
                       <entry>
                          <para>Determines if the server sockets will be in
                          client or server mode.</para></entry>
                    </row>  
                                   
                    <row>
                       <entry><para>SocketUseClientMode</para></entry>
                       <entry><para>REMOTING_SOCKET_USE_CLIENT_MODE</para></entry>
                       <entry><para>boolean/String</para></entry>
                       <entry><para>true</para></entry>
                       <entry>
                          <para>Determines if the sockets will be in
                          client or server mode.</para></entry>
                    </row>  
                    
                    <row>
                       <entry><para>TrustStoreAlgorithm</para></entry>
                       <entry><para>REMOTING_TRUST_STORE_ALGORITHM</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para>value of <code>KeyStoreAlgorithm</code>, or
                              SunX509 if <code>KeyStoreAlgorithm</code>
                              is not set</para></entry>
                       <entry>
                          <para>trust store key management algorithm</para></entry>
                    </row>  
                    
                    <row>
                       <entry><para>TrustStorePassword</para></entry>
                       <entry><para>REMOTING_TRUST_STORE_PASSWORD</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para></para></entry>
                       <entry>
                          <para>trust store password</para></entry>
                    </row> 
                    
                    <row>
                       <entry><para>TrustStoreType</para></entry>
                       <entry><para>REMOTING_TRUST_STORE_TYPE</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para>value of <code>KeyStoreType</code>, or
                              JKS if <code>KeyStoreType</code>
                              is not set</para></entry>
                       <entry>
                          <para>type of trust store</para></entry>
                    </row>                 
                    
                    <row>
                       <entry><para>TrustStoreURL</para></entry>
                       <entry><para>REMOTING_TRUST_STORE_FILE_PATH</para></entry>
                       <entry><para>String</para></entry>
                       <entry><para></para></entry>
                       <entry>
                          <para>location of trust store</para></entry>
                    </row> 
                    
                    <row>
                       <entry><para>UseSSLServerSocketFactory</para></entry>
                       <entry><para>none</para></entry>
                       <entry><para>boolean</para></entry>
                       <entry><para>true</para></entry>
                       <entry>
                          <para>Determines if default
                          <classname>SSLServerSocketFactory</classname> should be
                          created.</para></entry>
                    </row> 
                    
                    <row>
                       <entry><para>UseSSLSocketFactory</para></entry>
                       <entry><para>none</para></entry>
                       <entry><para>boolean</para></entry>
                       <entry><para>true</para></entry>
                       <entry>
                          <para>Determines if default
                          <classname>SSLSocketFactory</classname> should be
                          created.</para></entry>
                    </row> 
                 </tbody>
              </tgroup>
           </table>
  
           <para><emphasis role="bold">Note.</emphasis>
              If any of the attributes <code>KeyStoreURL</code>,
              <code>KeyStorePassword</code>, <code>KeyStoreType</code>,
              <code>TrustStoreURL</code>, <code>TrustStorePassword</code>, or
              <code>TrustStoreType</code> are left unconfigured, 
              <classname>SSLSocketBuilder</classname> will also examine the
              corresponding standard SSL system properties "javax.net.ssl.keyStore",
              "javax.net.ssl.keyStorePassword", "javax.net.ssl.keyStoreType",
              "javax.net.ssl.trustStore", "javax.net.ssl.trustStorePassword",
              "javax.net.ssl.trustStoreType". In the cases of 
              <code>KeyStoreType</code> and <code>TrustStoreType</code>, 
              <classname>SSLSocketBuilder</classname> will then
              go on to use default values after checking the system
              properties.</para>
           
           <para>The following is an example of configuring a
           <classname>SSLSocketBuilder</classname> and using it to create a custom
           <classname>SSLSocketFactory</classname>:</para>
           
           <programlisting>
           protected SSLSocketFactory getSocketFactory() throws Exception
           {
              HashMap config = new HashMap();
              config.put(SSLSocketBuilder.REMOTING_KEY_STORE_TYPE, "JKS");
              String keyStoreFilePath = getKeystoreFilePath();
              config.put(SSLSocketBuilder.REMOTING_KEY_STORE_FILE_PATH, keyStoreFilePath);
              config.put(SSLSocketBuilder.REMOTING_KEY_STORE_PASSWORD, "unit-tests-server");
              config.put(SSLSocketBuilder.REMOTING_SSL_PROTOCOL, "SSL");
              SSLSocketBuilder builder = new SSLSocketBuilder(config);
              builder.setUseSSLSocketFactory(false);
              return builder.createSSLSocketFactory();
           }
           </programlisting>
           
           <para>More examples of configuring <classname>SSLSocketBuilder</classname> can
           be found in the class <classname>FactoryConfigSSLSample</classname> in the
           package <code>org.jboss.remoting.samples.config.factories</code>.</para>
           
           <para>The following is an example of configuring
           <classname>SSLSocketBuilder</classname> in a *-service.xml file:</para>
           
           <programlisting>
              &lt;!-- This service is used to build the SSL Server socket factory --&gt;
              &lt;!-- This will be where all the store/trust information will be set. --&gt;
              &lt;!-- If do not need to make any custom configurations, no extra attributes --&gt;
              &lt;!-- need to be set for the SSLSocketBuilder and just need to set the --&gt;
              &lt;!-- javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword system properties. --&gt;
              &lt;!-- This can be done by just adding something like the following to the run --&gt;
              &lt;!-- script for JBoss --&gt;
              &lt;!-- (this one is for run.bat): --&gt;
              &lt;!-- set JAVA_OPTS=-Djavax.net.ssl.keyStore=.keystore --&gt;
              &lt;!-- -Djavax.net.ssl.keyStorePassword=opensource %JAVA_OPTS% --&gt;
              &lt;!-- Otherwise, if want to customize the attributes for SSLSocketBuilder, --&gt;
              &lt;!-- will need to uncomment them below. --&gt;
              &lt;mbean code="org.jboss.remoting.security.SSLSocketBuilder"
                    name="jboss.remoting:service=SocketBuilder,type=SSL"
                    display-name="SSL Server Socket Factory Builder"&gt;
                 &lt;!-- IMPORTANT - If making ANY customizations, this MUST be set to false. --&gt;
                 &lt;!-- Otherwise, will used default settings and the following attributes will be ignored. --&gt;
                 &lt;attribute name="UseSSLServerSocketFactory"&gt;false&lt;/attribute&gt;
                 &lt;!-- This is the url string to the key store to use --&gt;
                 &lt;attribute name="KeyStoreURL"&gt;.keystore&lt;/attribute&gt;
                 &lt;!-- The password for the key store --&gt;
                 &lt;attribute name="KeyStorePassword"&gt;opensource&lt;/attribute&gt;
                 &lt;!-- The password for the keys (will use KeystorePassword if this is not set explicitly. --&gt;
                 &lt;attribute name="KeyPassword"&gt;opensource&lt;/attribute&gt;
                 &lt;!-- The protocol for the SSLContext. Default is TLS. --&gt;
                 &lt;attribute name="SecureSocketProtocol"&gt;TLS&lt;/attribute&gt;
                 &lt;!-- The algorithm for the key manager factory. Default is SunX509. --&gt;
                 &lt;attribute name="KeyManagementAlgorithm"&gt;SunX509&lt;/attribute&gt;
                 &lt;!-- The type to be used for the key store. --&gt;
                 &lt;!-- Defaults to JKS. Some acceptable values are JKS (Java Keystore - Sun's keystore format), --&gt;
                 &lt;!-- JCEKS (Java Cryptography Extension keystore - More secure version of JKS), and --&gt;
                 &lt;!-- PKCS12 (Public-Key Cryptography Standards #12 keystore - RSA's Personal Information Exchange Syntax Standard). --&gt;
                 &lt;!-- These are not case sensitive. --&gt;
                 &lt;attribute name="KeyStoreType"&gt;JKS&lt;/attribute&gt;
              &lt;/mbean&gt;
           </programlisting>
        </section>
     
        <section>
           <title>SSLServerSocketFactoryService</title>
    
           <para>Although any server socket factory can be set for the various
           transports, there is a customizable server socket factory service
           provided within JBossRemoting that supports SSL. This is the
           <code>org.jboss.remoting.security.SSLServerSocketFactoryService</code>
           class. The <code>SSLServerSocketFactoryService</code> class extends the
           <code>javax.net.ServerSocketFactory</code> class and also implements the
           <code>SSLServerSocketFactoryServiceMBean</code> interface (so that it
           can be set using the <code>socketServerFactory</code> attribute
           described previously). Other than providing the proper interfaces, this
           class is a simple wrapper around the
           <code>org.jboss.remoting.security.SSLSocketBuilder</code> class.</para>
  
           <para>The following is an example of configuring
           <classname>SSLServerSocketFactoryService</classname> in a *-service.xml
           file.  Note that it depends on the <classname>SSLSocketBuilder</classname>
           MBean defined in the xml fragment above:</para>
        
        <programlisting>
           &lt;!-- This service provides the exact same API as the ServerSocketFactory, so --&gt;
           &lt;!-- can be set as an attribute of that type on any MBean requiring an ServerSocketFactory. --&gt;
           &lt;mbean code="org.jboss.remoting.security.SSLServerSocketFactoryService"
                 name="jboss.remoting:service=ServerSocketFactory,type=SSL"
                 display-name="SSL Server Socket Factory"&gt;
              &lt;depends optional-attribute-name="SSLSocketBuilder"
                 proxy-type="attribute"&gt;jboss.remoting:service=SocketBuilder,type=SSL&lt;/depends&gt;
           &lt;/mbean&gt;
        </programlisting>
        
        </section>
     
        <section>
           <title>General Security How To</title>
     
           <para>Since we are talking about keystores and truststores, this section
           will quickly go over how to quickly generate a test keystore and
           truststore for testing. This is not intended to be a full security
           overview, just an example of how I originally created mine for
           testing.</para>
     
           <para>To get started, will need to create key store and trust
           store.</para>
     
           <para>Generating key entry into keystore:</para>
     
           <programlisting>
                 C:\tmp\ssl&gt;keytool -genkey -alias remoting -keyalg RSA
                 Enter keystore password: opensource
                 What is your first and last name?
                 [Unknown]: Tom Elrod
                 What is the name of your organizational unit?
                 [Unknown]: Development
                 What is the name of your organization?
                 [Unknown]: JBoss Inc
                 What is the name of your City or Locality?
                 [Unknown]: Atlanta
                 What is the name of your State or Province?
                 [Unknown]: GA
                 What is the two-letter country code for this unit?
                 [Unknown]: US
                 Is CN=Tom Elrod, OU=Development, O=JBoss Inc, L=Atlanta, ST=GA, C=US correct?
                 [no]: yes
     
                 Enter key password for &lt;remoting&gt;
                 (RETURN if same as keystore password):
              </programlisting>
     
           <para>Since did not specify the -keystore filename parameter, created
           the keystore in $HOME/.keystore (or C:\Documents and
           Settings\Tom\.keystore).</para>
     
           <para>Export the RSA certificate (without the private key)</para>
     
           <programlisting>
                 C:\tmp\ssl&gt;keytool -export -alias remoting -file remoting.cer
                 Enter keystore password: opensource
                 Certificate stored in file &lt;remoting.cer&gt;
              </programlisting>
     
           <para>Import the RSE certificate into a new truststore file.</para>
     
           <programlisting>
                 C:\tmp\ssl&gt;keytool -import -alias remoting -keystore .truststore -file remoting.cer
                 Enter keystore password: opensource
                 Owner: CN=Tom Elrod, OU=Development, O=JBoss Inc, L=Atlanta, ST=GA, C=US
                 Issuer: CN=Tom Elrod, OU=Development, O=JBoss Inc, L=Atlanta, ST=GA, C=US
                 Serial number: 426f1ee3
                 Valid from: Wed Apr 27 01:10:59 EDT 2005 until: Tue Jul 26 01:10:59 EDT 2005
                 Certificate fingerprints:
                 MD5: CF:D0:A8:7D:20:49:30:67:44:03:98:5F:8E:01:4A:6A
                 SHA1: C6:76:3B:6C:79:3B:8D:FD:FB:4F:33:3B:25:C9:01:9D:50:BF:9F:8A
                 Trust this certificate? [no]: yes
                 Certificate was added to keystore
              </programlisting>
     
           <para>Now have two files, .keystore for the server and .truststore for
           the client.</para>
        </section>
        
        <section>
           <title>Troubleshooting Tips</title>
     
           <para>Common errors when using server socket factory:</para>
     
           <programlisting>javax.net.ssl.SSLException: No available certificate corresponds to the SSL cipher suites which are enabled.</programlisting>
     
           <para>The 'javax.net.ssl.keyStore' system property has not been set and
           are using the default SSLServerSocketFactory.</para>
     
           <programlisting>java.net.SocketException: Default SSL context init failed: Cannot recover key</programlisting>
     
           <para>The 'javax.net.ssl.keyStorePassword' system property has not been
           set and are using the default SSLServerSocketFactory.</para>
     
           <programlisting>java.io.IOException: Can not create SSL Server Socket Factory due to the url to the key store not being set.</programlisting>
     
           <para>The default SSLServerSocketFactory is NOT being used (so custom
           configuration for the server socket factory) and the key store url has
           not been set.</para>
     
           <programlisting>java.lang.IllegalArgumentException: password can't be null</programlisting>
     
           <para>The default SSLServerSocketFactory is NOT being used (so custom
           configuration for the server socket factory) and the key store password
           has not been set.</para>
        </section>
      </section>
  
      <section>
        <title>Configuration by properties</title>
  
        <para>This section covers configuration properties by constant values
        and bean properties for individual classes. This will duplicate some of
        the configuration properties already covered and is just another view to
        some of the same information.</para>
  
        <bridgehead>org.jboss.remoting.InvokerLocator</bridgehead>
  
        <para><emphasis role="bold">SERVER_BIND_ADDRESS</emphasis> (actual value
        is 'jboss.bind.address') - indicates the system property key for bind
        address that should be used.</para>
  
        <para><emphasis role="bold">BIND_BY_HOST</emphasis> (actual value is
        'remoting.bind_by_host') - indicates the system property key for if the
        local bind address should be by host name (e.g.
        InetAddress.getLocalHost().getHostName()) or if should be by IP (e.g.
        InetAddress.getLocalHost().getHostAddress()). The default is 'True',
        meaning will will use local host name. This configuration only applies
        when the initial bind address is 0.0.0.0 (or InvokerLocator.ANY).</para>
  
        <para><emphasis role="bold">DATATYPE</emphasis> (actual value is
        'datatype') - indicates the marshalling datatype that should be used for
        a particular invoker. Each invoker has its own default marshaller and
        unmarshaller based on default datatype. For examle, the socket transport
        has a default datatype of 'serializable', which is has a default
        registry within the MarshalFactory to use
        org.jboss.remoting.marshal.serializable.SerializableMarshaller and
        org.jboss.remoting.marshal.serializable.SerializableUnMarshaller. The
        marshaller and unmarshaller used by an invoker can be overriden by
        setting the 'datatype' parameter within the LocatorInvoker. For example,
        could use a locator url of:</para>
  
        <programlisting>socket://myhost:6500/?datatype=test</programlisting>
  
        <para>which would cause the socket invoker to use the marshaller and
        unmarshaller registered with the MarshalFactory under the datatype
        'test'. Of course, this require that the marshaller and unmarshaller
        implementations to be used have already been registered with the
        MarshalFactory (otherwise will get an exception).</para>
  
        <para><emphasis role="bold">SERIALIZATIONTYPE</emphasis> (actual value
        is 'serializationtype') - indicates the serialization implementation to
        use. Currently, the only possible values are 'java' and 'jboss'. Java
        serialization is the default. Setting to 'jboss' will cause JBoss
        Serialization to be used. In implementation, this equates to the
        parameter that will be passed to the
        SerializationStreamFactory.getManagerInstance() method. This
        configuration can be set as an invoker locator url parameter (e.g.
        socket://myhost:5400/?serializationtype=jboss) or as an entry to the
        configuration Map passed when constructing a remoting client or
        server.</para>
  
        <para><emphasis role="bold">MARSHALLER</emphasis> (actual value is
        'marshaller') - used to indicate which marshaller implementation should
        be used by the invoker. This is an override for whatever the invoker's
        default implementation is. This can be set as a parameter of the invoker
        locator url (e.g.
        socket://myhost:6500/?marshaller=org.jboss.test.remoting.marshall.dynamic.remote.http.TestMarshaller).
        Using this configuration requires that the value be the fully qualified
        classname of the marshaller implementation to use (which must be on the
        classpath, have a void constructor, and implement the
        org.jboss.remoting.marshal.Marshaller interface).</para>
  
        <para><emphasis role="bold">UNMARSHALLER</emphasis> (actual value is
        'unmarshaller') - used to indicate which unmarshaller implementation
        should be used by the invoker. This is an override for whatever the
        invoker's default implementation is. This can be set as a parameter of
        the invoker locator url (e.g.
        socket://myhost:6500/?unmarshaller=org.jboss.test.remoting.marshall.dynamic.remote.http.TestUnMarshaller).
        Using this configuration requires that the value be the fully qualified
        classname of the unmarshaller implementation to use (which must be on
        the classpath, ahve a void constructor, and implement the
        org.jboss.remotng.marshal.UnMarshaller interface).</para>
  
        <para><emphasis role="bold">LOADER_PORT</emphasis> (actual value is
        'loaderport') - indicates the port number where the class loader server
        resides. This can be used when is possible that a client may not have
        particular classes locally and would want to load them from ther
        dynamically. This property can be set as a parameter to the invoker
        locator url. A clasic example of when this might be used would be in
        conjunction with using custom marshalling. For example, if have
        configured a server to use custom marshaller and unmarshaller that the
        client will not have access to, could create a invoker locator such
        as:</para>
  
        <programlisting>socket://myhost:6500/?datatype=test&amp;loaderport=6501&amp;
  marshaller=org.jboss.test.remoting.marshall.dynamic.remote.http.TestMarshaller&amp;
  unmarshaller=org.jboss.test.remoting.marshall.dynamic.remote.http.TestUnMarshaller</programlisting>
  
        <para>When the client invoker begins to make an invocation, will try to
        look up marshaller and unmarshaller based on type ('test' in this case)
        and when can not find a registry entry for it, will try to load the
        TestMarshaller and TestUnMarshaller from the classpath. When the classes
        can not be found locally, will make a call to the loader server (on port
        6501) to load the classes locally. Once they are retreived from the
        server, will be registered locally, so is a one time only event (as next
        time will be found in the registry).</para>
  
        <para>This can work for loading any remote server classes, but requires
        the loaderport be included in the invoker locator url.</para>
  
        <para><emphasis role="bold">BYVALUE</emphasis> (actual value is
        'byvalue') - indicates if when making local invocations (meaning client
        and server invoker exists within same jvm), the marshalling will be done
        by value, instead of the default, by reference. Using this
        configuration, the marshalling will actually perform a clone of the
        object instance (see
        org.jboss.remoting.serialization.SerializationManager.createMarshalledValueForClone()).
        Value for this property should be of type String and be either 'true' or
        'false'.</para>
  
        <para><emphasis role="bold">FORCE_REMOTE</emphasis> (actual value is
        'force_remote') - indicates if when making local invocations (meaning
        client and server invoker exists within same jvm), the remote invokers
        should be used instead of local invoker. Is equivalent to making
        invocations as though client and server were in different jvms). Value
        for this property should be of type String and be either 'true' or
        'false'.</para>
  
        <para><emphasis role="bold">CLIENT_LEASE</emphasis> (actual value is
        'leasing') - indicates if client should try to automatically establish a
        lease with the server. Is false by default. Value for this property
        should be of type String and be either 'true' or 'false'.</para>
  
        <para><emphasis role="bold">CLIENT_LEASE_PERIOD</emphasis> (actual value
        is 'lease_period') - defines what the client lease period should be in
        the case that server side leasing is turned on. Value for this parameter
        key should be the number of milliseconds to wait before each client
        lease renewal and must be greater than zero in order to be recognized.
        If this property is not set (and CLIENT_LEASE is), will use the lease
        period as specified by the server.</para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.Client</bridgehead>
  
        <para><emphasis role="bold">RAW</emphasis> (actual value is
        'rawPayload') - key to use for the metadata Map passed when making a
        invoke() call and wish for the invocation payload to be sent as is and
        not wrapped within a remoting invocation request object. This should be
        used when want to make direct calls on systems outside of remoting (e.g.
        making a http POST request to a web service).</para>
  
        <para><emphasis role="bold">ENABLE_LEASE</emphasis> (actual value is
        'enableLease') - key for the configuration map passed to the Client
        constructor to indicate that client should make initial request to
        establish lease with server. The value for this should be either a
        String that java.lang.Boolean can evaluate or a java.lang.Boolean. By
        default, leasing is turned off, so this property would be used to turn
        on leasing for the client.</para>
  
        <para><emphasis role="bold">HANDSHAKE_COMPLETED_LISTENER</emphasis>
        (actual value is 'handshakeCompletedListener') - key for the
        configuration map passed to the Client constructor providing a ssl
        javax.net.ssl.HandshakeCompletedListener implementation, which will be
        called on when ssl handshake completed with server.</para>
  
        <para></para>
  
        <para>The following three configuration properties are only useful when
        using one of the following Client methods:</para>
  
        <programlisting>public void addListener(InvokerCallbackHandler callbackhandler, Map metadata, Object callbackHandlerObject) throws Throwable
  public void addListener(InvokerCallbackHandler callbackhandler, Map metadata, Object callbackHandlerObject, boolean serverToClient) throws Throwable</programlisting>
  
        <para> <emphasis role="bold">CALLBACK_SERVER_PROTOCOL</emphasis> (actual
        value is 'callbackServerProtocol') - key for the configuration when
        adding a callback handler and internal callback server connector is
        created. The value should be the transport protocol to be used. By
        default will use the same protocol as being used by this client (e.g.
        http, socket, rmi, multiplex, etc.).</para>
  
        <para><emphasis role="bold">CALLBACK_SERVER_HOST</emphasis> (actual
        value is 'callbackServerHost') - key for the configuration when adding a
        callback handler and internal callback server connector is created. The
        value should be the host name to be used. By default will use the result
        of calling InetAddress.getLocalHost().getHostAddress().</para>
  
        <para><emphasis role="bold">CALLBACK_SERVER_PORT</emphasis> (actual
        value is 'callbackServerPort') - key for the configuration when adding a
        callback handler and internal callback server connector is created. The
        value should be the port to be used. By default will find a random
        unused port. </para>
  
        <para></para>
  
        <para><emphasis role="bold">Bean properties (meaning have
        getter/setter):</emphasis> <emphasis role="bold">SessionId</emphasis> -
        session id used when making invocations on server invokers. There is a
        default unique id automatically generated for each Client instance, so
        unless you have a good reason to set this, do not set this.</para>
  
        <para><emphasis role="bold">Subsystem</emphasis> - the subsystem being
        used when routing invocation requests on the server side. Specifing a
        subsystem is only needed when server has multiple handlers registered
        (which will each have their own associated subsystem). Best if specified
        using Client constructor.</para>
  
        <para><emphasis role="bold">MaxNumberOfThreads</emphasis> - the maximum
        number of threads to use within client pool for one way invocations on
        the client side (meaning oneway invocation is handled by thread in this
        pool and user's call returns immediately) Default value is
        MAX_NUM_ONEWAY_THREADS (whose value is 10).</para>
  
        <para><emphasis role="bold">OnewayThreadPool</emphasis> - the thread
        pool being used for making one way invocations on the client side. If
        one has not be specifically set via configuration or call to set it,
        will always return instance of
        org.jboss.util.threadpool.BasicThreadPool.</para>
  
        <para><emphasis role="bold">SocketFactory</emphasis> - instance of
        javax.net.SocketFactory, which can only be set on the Client before the
        connect() method has been called. Otherwise, a runtime exception will be
        thrown.</para>
  
        <para><emphasis role="bold">Marshaller</emphasis> - the marshaller
        implementation that should be used by the client invoker (transport).
        This overrides the client's default marshaller (or any set within
        configuration).</para>
  
        <para><emphasis role="bold">UnMarshaller</emphasis> - the unmarshaller
        implementation that should be used by the client invoker (transport).
        This overrides the client's default unmarshaller (or any set within
        configuration). </para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.Remoting</bridgehead>
  
        <para><emphasis role="bold">CUSTOM_SERVER_SOCKET_FACTORY</emphasis>
        (actual value is 'customServerSocketFactory') - key for the
        configuration map passed to a Connector to indicate the server socket
        factory to be used. This will override the creation of any other socket
        factory. Value must be an instance of
        javax.net.ServerSocketFactory.</para>
  
        <para><emphasis role="bold">CUSTOM_SOCKET_FACTORY</emphasis> (actual
        value is 'customSocketFactory') - key for the configuration map passed
        to a Client to indicate the socket factory to be used. This will
        override the creation of any other socket factory. Value must be
        instance of javax.net.SocketFactory.</para>
  
        <para><emphasis role="bold">SOCKET_FACTORY_NAME</emphasis> (actual value
        is 'customSocketFactoryName') - key for the configuration map passed to
        a Client to indicate the classname of the socket factory to be used.
        Value should be fully qualified classname of class that is an instance
        of javax.net.SocketFactory and has a void constructor. This property
        will not be used if CUSTOM_SOCKET_FACTORY is also set. </para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.ServerInvoker</bridgehead>
  
        <para><emphasis role="bold">MAX_NUM_ONEWAY_THREADS_KEY</emphasis>
        (actual value is 'maxNumThreadsOneway') - key for the maximum number of
        thread to be used in the thread pool for one way invocations (server
        side). This property is only used when the default oneway thread pool is
        used.</para>
  
        <para><emphasis role="bold">ONEWAY_THREAD_POOL_CLASS_KEY</emphasis>
        (actual value is 'onewayThreadPool') - key for setting the setting the
        oneway thread pool to use. The value used with this key will first be
        checked to see if is a JMX ObjectName and if so, try to look up
        associated mbean for the ObjectName given and cast to type
        org.jboss.util.threadpool.ThreadPoolMBean (via
        MBeanServerInvocationHandler.newProxyInstance()). If the value is not a
        JMX ObjectName, will assume is a fully qualified classname and load the
        coresponding class and create a new instance of it (which will require
        it to have a void constructor). The newly created instance will then be
        cast to type of org.jboss.util.threadpool.ThreadPool.</para>
  
        <para><emphasis role="bold">SERVER_BIND_ADDRESS_KEY</emphasis> (actual
        value is 'serverBindAddress') - key for setting the address the server
        invoker should bind to. The value can be either host name or IP.</para>
  
        <para><emphasis role="bold">CLIENT_CONNECT_ADDRESS_KEY</emphasis>
        (actual value is 'clientConnectAddress') - key for setting the addres
        the client invoker should connecto to. This should be used when client
        will be connecting to server from outside the server's network and the
        external address is different from that of the internal address the
        server invoker will bind to (e.g. using NAT to expose different external
        address). This will mostly be useful when client uses remoting detection
        to discover remoting servers. The value can be either host name or
        IP.</para>
  
        <para><emphasis role="bold">SERVER_BIND_PORT_KEY</emphasis> (actual
        value is 'serverBindPort') - key for setting the port the server invoker
        should bind to. If the value supplied is less than or equal to zero, the
        server invoker will randomly choose a free port to use.</para>
  
        <para><emphasis role="bold">CLIENT_CONNECT_PORT_KEY</emphasis> (actual
        value is 'clientConnectPort') - key for setting the port the client
        invoker should connect to. This should be used when client will be
        connecting to server from outside the server's network and the external
        port is different from that of the internal port the server invoker will
        bind to (e.g. using NAT to expose different port routing). This will be
        mostly useful when client uses remoting detection to discover remoting
        servers.</para>
  
        <para><emphasis role="bold">CLIENT_LEASE_PERIOD</emphasis> (actual value
        is 'clientLeasePeriod') - key used for setting the amount of time (in
        milliseconds) that a client should renew its lease. If this value is not
        set, the default of five seconds (see DEFAULT_CLIENT_LEASE_PERIOD), will
        be used. This value will also be what is given to the client when it
        initially querys server for leasing information.</para>
  
        <para><emphasis role="bold">TIMEOUT</emphasis> (actual value is
        'timeout') - key for setting the timeout value (in milliseconds) for
        socket connections.</para>
  
        <para><emphasis role="bold">SERVER_SOCKET_FACTORY</emphasis> (actual
        value is 'serverSocketFactory') - key for setting the value for the
        server socket factory to be used by the server invoker. The value can be
        either a JMX Object name, in which case will lookup the mbean and create
        a proxy to it with type of
        org.jboss.remoting.security.ServerSocketFactoryMBean (via
        MBeanServerInvocationHandler.newProxyInstance()). If not a JMX
        ObjectName, will assume is the fully qualified classname to the
        implementation to be used and will load the class, create a new instance
        of it (which requires it to have a void constructor). The instance will
        then be cast to type javax.net.ServerSocketFactory.</para>
  
        <para></para>
  
        <para><emphasis role="bold">Bean properties (meaning have
        getter/setter):</emphasis></para>
  
        <para><emphasis role="bold">ServerSocketFactory</emphasis> -
        implementation of javax.net.ServerSocketFactory to be used by the server
        invoker. This takes precedence over any other configuration for the
        server socket factory.</para>
  
        <para><emphasis role="bold">Timeout</emphasis> - timeout (in
        milliseconds) for socket connection. If set after create() method
        called, this value will override value set by TIMEOUT key.</para>
  
        <para><emphasis role="bold">LeasePeriod</emphasis> - the amount of time
        (in milliseconds) that a client should renew its lease. If this value is
        not set, the default of five seconds (see DEFAULT_CLIENT_LEASE_PERIOD),
        will be used. This value will also be what is given to the client when
        it initially querys server for leasing information. If set after
        create() method called, this value will override value set by
        CLIENT_LEASE_PERIOD key.</para>
  
        <para><emphasis role="bold">MaxNumberOfOnewayThreads</emphasis> - the
        maximum number of thread to be used in the thread pool for one way
        invocations (server side). This property is only used when the default
        oneway thread pool is used. If set after create() method called, this
        value will override value set by MAX_NUM_ONEWAY_THREADS_KEY key.</para>
  
        <para><emphasis role="bold">OnewayThreadPool</emphasis> - the oneway
        thread pool to use.</para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.callback.CallbackPoller</bridgehead>
  
        <para><emphasis role="bold">CALLBACK_POLL_PERIOD</emphasis> (actual
        value is 'callbackPollPeriod') - key for setting the frequency (in
        milliseconds) in which Client's internal callback poller should poll
        server for waiting callbacks. This configuration is only necessary when
        using one of the following Client methods:</para>
  
        <programlisting>public void addListener(InvokerCallbackHandler callbackhandler, Map metadata, Object callbackHandlerObject) throws Throwable
  public void addListener(InvokerCallbackHandler callbackhandler, Map metadata, Object callbackHandlerObject, boolean serverToClient) throws Throwable</programlisting>
  
        <para>and should be one of the entries in the metadata Map passed. This
        will also only apply when the underlying transport is uni-directional
        (e.g. socket, http, rmi). Bi-directional transports will not need to
        poll. If this property is not set, the default (see
        CallbackPoller.DEFAULT_POLL_PERIOD) value is five seconds. </para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.callback.CallbackStore </bridgehead>
  
        <para><emphasis role="bold">FILE_PATH_KEY</emphasis> (actual value is
        'StoreFilePath') - key for setting which directory to write the callback
        objects. The default value is the property value of
        'jboss.server.data.dir' and if this is not set, then will be 'data'.
        Will then append 'remoting' and the callback client's session id. An
        example would be
        'data\remoting\5c4o05l-9jijyx-e5b6xyph-1-e5b6xyph-2'.</para>
  
        <para><emphasis role="bold">FILE_SUFFIX_KEY</emphasis> (actual value is
        'StoreFileSuffix') - key for setting the file suffix to use for the
        callback objects written to disk. The default value is 'ser'. </para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.callback.DefaultCallbackErrorHandler
        </bridgehead>
  
        <para><emphasis role="bold">CALLBACK_ERRORS_ALLOWED</emphasis> (actual
        value is 'callbackErrorsAllowed') - key for setting the number of
        callback exceptions will be allowed when calling on
        org.jboss.remoting.callback.InvokerCallbackHandler.handleCallback(Callback
        callback) before cleaning up the callback listener. This only applies to
        push callback. The default if this property is not set is five. </para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.callback.ServerInvokerCallbackHandler</bridgehead>
  
        <para><emphasis role="bold">CALLBACK_STORE_KEY</emphasis> (actual value
        is 'callbackStore') - key for specifing the callback store to be used.
        The value can be either a JMX ObjectName or a fully qualified class
        name, either way, must implement org.jboss.remoting.SerializableStore.
        If using class name, the callback store implementation must have a void
        constructor. The default is to use the
        org.jboss.remoting.callback.NullCallbackStore.</para>
  
        <para><emphasis role="bold">CALLBACK_ERROR_HANDLER_KEY</emphasis>
        (actual value is 'callbackErrorHandler') - key for specifing the
        callback exception handler to be used. The value can be either a JMX
        ObjectName or a fully qualified class name, either way, must implement
        org.jboss.remoting.callback.CallbackErrorHandler. If using class name,
        the callback exception handler implementation must have a void
        constructor. The default is to use
        org.jboss.remoting.callback.DefaultCallbackErrorHandler.</para>
  
        <para><emphasis role="bold">CALLBACK_MEM_CEILING</emphasis> (actual
        value is 'callbackMemCeiling') - key for specifing the percentage of
        free memory available before callbacks will be persisted. If the memory
        heap allocated has reached its maximum value and the percent of free
        memory available is less than the callbackMemCeiling, this will trigger
        persisting of the callback message. The default value is 20. </para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.detection.jndi.JNDIDetector</bridgehead>
  
        <para><emphasis role="bold">Bean properties (meaning have
        getter/setter):</emphasis> <emphasis
        role="bold">SubContextName</emphasis> - sub context name under which
        detection messages will be bound and looked up. </para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.transport.http.HTTPMetadataConstants</bridgehead>
  
        <para>The following are keys to use to get corresponding values from the
        Map returned from call to
        org.jboss.remoting.InvocationRequest.getRequestPayload() within a
        org.jboss.remoting.ServerInvocationHandler implementation. For
        example:</para>
  
        <programlisting>   public Object invoke(InvocationRequest invocation) throws Throwable
     {
        Map headers = invocation.getRequestPayload();
  </programlisting>
  
        <para>Where variable 'headers' will contain entries for the following
        keys.</para>
  
        <para><emphasis role="bold">METHODTYPE</emphasis> (actual value is
        'MethodType') - key for getting the method type used by client in http
        request. This will be populated within the Map returned from call to
        org.jboss.remoting.InvocationRequest.getRequestPayload() within a
        org.jboss.remoting.ServerInvocationHandler implementation. For example:
        </para>
  
        <programlisting>   public Object invoke(InvocationRequest invocation) throws Throwable
     {
        Map headers = invocation.getRequestPayload();
        String methodType = (String) headers.get(HTTPMetadataConstants.METHODTYPE);
        if(methodType != null)
        {
           if(methodType.equals("GET"))
           ...
  </programlisting>
  
        <para> <emphasis role="bold">PATH</emphasis> (actual value is 'Path') - 
        key for getting the path from the url request from the calling client.
        This will be populated within the Map returned from call to
        org.jboss.remoting.InvocationRequest.getRequestPayload() within a
        org.jboss.remoting.ServerInvocationHandler implementation. For example:
        </para>
  
        <programlisting>   public Object invoke(InvocationRequest invocation) throws Throwable
     {
        Map headers = invocation.getRequestPayload();
        String path = (String) headers.get(HTTPMetadataConstants.PATH);
        ...
  </programlisting>
  
        <para> <emphasis role="bold">HTTPVERSION</emphasis> (actual value is
        'HttpVersion') - key for getting the HTTP version from the calling
        client request (e.g. HTTP/1.1). </para>
  
        <para></para>
  
        <para></para>
  
        <para><emphasis role="bold">RESPONSE_CODE</emphasis> (actual value is
        'ResponseCode') - key for getting and setting the HTTP response code.
        Will be used as key to get the response code from metadata Map passed to
        the Client's invoke() method after the invocation has been made. For
        example:</para>
  
        <programlisting>Map metadata = new HashMap();
  Object response = remotingClient.invoke(myPayloadObject, metadata);
  Integer responseCode = (Integer) metadata.get(HTTPMetadataConstants.RESPONSE_CODE);
  </programlisting>
  
        <para>Will be used as key to put the response code in the return payload
        map from invocation handler. For example:</para>
  
        <programlisting>   public Object invoke(InvocationRequest invocation) throws Throwable
     {
        Map responseHeaders = invocation.getReturnPayload();
        responseHeaders.put(HTTPMetadataConstants.RESPONSE_CODE,  new Integer(202));
  </programlisting>
  
        <para> <emphasis role="bold">RESPONSE_CODE_MESSAGE</emphasis> (actual
        value is 'ResponseCodeMessage') - key for getting and setting the HTTP
        response code message. Will be used as the key to get the response code
        message from metadata Map passed to the Client's invoke() method after
        the invocation has been made. For example:</para>
  
        <programlisting>Map metadata = new HashMap();
  Object response = remotingClient.invoke(myPayloadObject, metadata);
  String responseCodeMessage = (String) metadata.get(HTTPMetadataConstants.RESPONSE_CODE_MESSAGE);
  </programlisting>
  
        <para>Will be used as key to put the response code message in the return
        payload map from invocation handler. For example:</para>
  
        <programlisting>   public Object invoke(InvocationRequest invocation) throws Throwable
     {
        Map responseHeaders = invocation.getReturnPayload();
        responseHeaders.put(HTTPMetadataConstants.RESPONSE_CODE_MESSAGE, "Custom response code and message from remoting server");
  </programlisting>
  
        <para> <emphasis role="bold">NO_THROW_ON_ERROR</emphasis> (actual value
        is 'NoThrowOnError') - key indicating if http client invoker (for
        transports http, https, servlet, and sslservlet) should throw an
        exception if the server response code is equal to or greater than 400.
        Unless set to true, the client invoker will by default throw either the
        exception that originated on the server (if using remoting server) or
        throw a org.jboss.remoting.transport.http.WebServerError, whose message
        will be the error html returned from the web server.</para>
  
        <para></para>
  
        <para>For every http client request made from remoting client, a
        remoting version and remoting specific user agent will be set as a
        request property. The request property key for the remoting version will
        be 'JBoss-Remoting-Version' and the value will be set based on return
        from call to Version.getDefaultVersion(). The 'User-Agent' request
        property value will be set to the evaluation of '"JBossRemoting - " +
        Version.VERSION'.</para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker</bridgehead>
  
        <para><emphasis role="bold">IGNORE_HTTPS_HOST</emphasis> (actual value
        is 'org.jboss.security.ignoreHttpsHost') - key indicating if the http
        client invoker (for transports https and sslservlet) should ignore host
        name verification (meaning will not check for URL's hostname and
        server's identification hostname mismatch during handshaking). By
        default, if this not set to true, standard hostname verification will be
        performed.</para>
  
        <para><emphasis role="bold">HOSTNAME_VERIFIER</emphasis> (actual value
        is 'hostnameVerifier') - key indicating the hostname verifier that
        should be used by the http client invoker. The value should be the fully
        qualified classname of class that implements
        javax.net.ssl.HostnameVerifier and has a void constructor.</para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.transport.rmi.RMIServerInvoker</bridgehead>
  
        <para><emphasis role="bold">REGISTRY_PORT_KEY</emphasis> (actual value
        is 'registryPort') - the port on which to create the RMI registry. The
        default is 3455. This also needs to have the isParam attribute set to
        true. </para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.transport.socket.MicroSocketClientInvoker
        </bridgehead>
  
        <para><emphasis role="bold">TCP_NODELAY_FLAG</emphasis> (actual value is
        'enableTcpNoDelay') - can be either true or false and will indicate if
        client socket should have TCP_NODELAY turned on or off. TCP_NODELAY is
        for a specific purpose; to disable the Nagle buffering algorithm. It
        should only be set for applications that send frequent small bursts of
        information without getting an immediate response; where timely delivery
        of data is required (the canonical example is mouse movements). The
        default is false.</para>
  
        <para><emphasis role="bold">MAX_POOL_SIZE_FLAG</emphasis> (actual value
        is 'clientMaxPoolSize') - the client side maximum number of threads. The
        default is 50.</para>
  
        <para><emphasis role="bold">CLIENT_SOCKET_CLASS_FLAG</emphasis> (actual
        value is 'clientSocketClass') - specifies the fully qualified class name
        for the custom SocketWrapper implementation to use on the client. Note,
        will need to make sure this is marked as a client parameter (using the
        'isParam' attribute). Making this change will not affect the
        marshaller/unmarshaller that is used, which may also be a requirement.
        </para>
  
        <para></para>
  
        <bridgehead>org.jboss.remoting.transport.socket.SocketServerInvoker
        </bridgehead>
  
        <para><emphasis role="bold">CHECK_CONNECTION_KEY</emphasis> (actual
        value is 'socket.check_connection') - key for indicating if socket
        invoker should continue to keep socket connection between client and
        server open after invocations by sending a ping on the connection before
        being re-used. The default for this is false.</para>
  
        <para><emphasis role="bold">SERVER_SOCKET_CLASS_FLAG</emphasis> (actual
        value is 'serverSocketClass') - specifies the fully qualified class name
        for the custom SocketWrapper implementation to use on the server.
        </para>
      </section>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap2.xml
  
  Index: chap2.xml
  ===================================================================
    <chapter>
      <title>Architecture</title>
  
      <para>The most critical component of the JBoss Remoting architecture is
      how servers are identified. This is done via an InvokerLocator, which can
      be represented by a simple String with a URL based format (e.g.,
      socket://myhost:5400). This is all that is required to either create a
      remoting server or to make a call on a remoting server. The remoting
      framework will then take the information embedded within the
      InvokerLocator and construct the underlying remoting components needed and
      build the full stack required for either making or receiving remote
      invocations.</para>
  
      <para>There are several layers to this framework that mirror each other on
      the client and server side. The outermost layer is the one which the user
      interacts with. On the client side, this is the Client class upon which
      the user will make its calls. On the server side, this is the
      InvocationHandler, which is implemented by the user and is the ultimate
      receiver of invocation requests. Next is the transport, which is
      controlled by the invoker layer. Finally, at the lowest layer is the
      marshalling, which converts data type to wire format.</para>
  
      <graphic fileref="images/design.jpg" />
  
      <para>When a user calls on the Client to make an invocation, it will pass
      this invocation request to the appropriate client invoker, based on the
      transport specified by the locator url. The client invoker will then use
      the marshaller to convert the invocation request object to the proper data
      format to send over the network. On the server side, an unmarshaller will
      receive this data from the network and convert it back into a standard
      invocation request object and send it on to the server invoker. The server
      invoker will then pass this invocation request on to the user’s
      implementation of the invocation handler. The response from the invocation
      handler will pass back through the server invoker and on to the
      marshaller, which will then convert the invocation response object to the
      proper data format and send back to the client. The unmarshaller on the
      client will convert the invocation response from wire data format into
      standard invocation response object, which will be passed back up through
      the client invoker and Client to the original caller.</para>
  
      <bridgehead>Client</bridgehead>
  
      <para>On the client side, there are a few utility class that help in
      figuring out which client invoker and marshal instances should be
      used.</para>
  
      <graphic fileref="images/design_client.jpg" />
  
      <para>For determining which client invoker to use, the Client will pass
      the InvokerRegistry the locator for the target server it wishes to make
      invocations on. The InvokerRegistry will return the appropriate client
      invoker instance based on information contained within the locator, such
      as transport type. The client invoker will then call upon the
      MarshalFactory to get the appropriate Marshaller and UnMarshaller for
      converting the invocation objects to the proper data format for wire
      transfer. All invokers have a default data type that can be used to get
      the proper marshal instances, but can be overridden within the locator
      specified.</para>
  
      <bridgehead>Server</bridgehead>
  
      <para>On the server side, there are also a few utility classes for
      determining the appropriate server invoker and marshal instances that
      should be used. There is also a server specific class for tying the
      invocation handler to the server invoker.</para>
  
      <graphic fileref="images/design_server.jpg" />
  
      <para>On the server side, it is the Connector class that is used as the
      external point for configuration and control of the remoting server. The
      Connector class will call on the InvokerRegistry with its locator to
      create a server invoker. Once the server invoker is returned, the
      Connector will then register the invocation handlers on it. The server
      invoker will use the MarshalFactory to obtain the proper marshal instances
      as is done on the client side.</para>
  
      <bridgehead>Detection</bridgehead>
  
      <para>To add automatic detection, a remoting Detector will need to be
      added on both the client and the server side as well as a NetworkRegistry
      to the client side.</para>
  
      <graphic fileref="images/design_detection.jpg" />
  
      <para>When a Detector on the server side is created and started, it will
      periodically pull from the InvokerRegistry all the server invokers that it
      has created. The detector will then use the information to publish a
      detection message containing the locator and subsystems supported by each
      server invoker. The publishing of this detection message will be either
      via a multicast broadcast or a binding into a JNDI server. On the client
      side, the Detector will either receive the multicast broadcast message or
      poll the JNDI server for detection messages. If the Detector determines a
      detection message is for a remoting server that just came online it will
      register it in the NetworkRegistry. The NetworkRegistry houses the
      detection information for all the discovered remoting servers. The
      NetworkRegistry will also emit a JMX notification upon any change to this
      registry of remoting servers. The change to the NetworkRegistry can also
      be for when a Detector has discovered that a remoting server is no longer
      available and removes it from the registry.</para>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap1.xml
  
  Index: chap1.xml
  ===================================================================
    <chapter>
      <title>Overview</title>
  
      <section>
        <title>What is JBoss Remoting</title>
  
        <para>The purpose of JBoss Remoting is to provide a single API for most
        network based invocations and related service that uses pluggable
        transports and data marshallers. The JBossRemoting API provides the
        ability for making synchronous and asynchronous remote calls, push and
        pull callbacks, and automatic discovery of remoting servers. The
        intention is to allow for the use of different transports to fit
        different needs, yet still maintain the same API for making the remote
        invocations and only requiring configuration changes, not code
        changes.</para>
  
        <para>JBossRemoting is a standalone project, separate from the JBoss
        Application Server project, but will be the framework used for many of
        the JBoss projects and components when making remote calls.
        JBossRemoting is included in the recent releases of the JBoss
        Application Server and can be run as a service within the container as
        well. Service configurations are included in the configuration section
        below.</para>
      </section>
  
      <section>
        <title>Features</title>
  
        <para>The features available with JBoss Remoting are:</para>
  
        <itemizedlist>
          <listitem>
            <para><emphasis role="bold">Server identification</emphasis> – a
            simple url based identifier which allows for remoting servers to be
            identified and called upon.</para>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Pluggable transports</emphasis> – can
            use different protocol transports the same remoting API.</para>
  
            <para>Provided transports:</para>
  
            <itemizedlist>
              <listitem>
                <para>Socket (SSL Socket)</para>
              </listitem>
  
              <listitem>
                <para>RMI (SSL RMI)</para>
              </listitem>
  
              <listitem>
                <para>HTTP(S)</para>
              </listitem>
  
              <listitem>
                <para>Multiplex (SSL Multiplex)</para>
              </listitem>
  
              <listitem>
                <para>Servlet</para>
              </listitem>
            </itemizedlist>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Pluggable data marshallers</emphasis> –
            can use different data marshallers and unmarshallers to convert the
            invocation payloads into desired data format for wire
            transfer.</para>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Pluggable serialization</emphasis> - can
            use different serialization implementations for data streams.</para>
  
            <para>Provided serialization implementations:</para>
  
            <itemizedlist>
              <listitem>
                <para>Java serialization</para>
              </listitem>
  
              <listitem>
                <para>JBoss serialization</para>
              </listitem>
            </itemizedlist>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Automatic discovery</emphasis> – can
            detect remoting servers as they come on and off line.</para>
  
            <para>Provided detection implementations:</para>
  
            <itemizedlist>
              <listitem>
                <para>Multicast</para>
              </listitem>
  
              <listitem>
                <para>JNDI</para>
              </listitem>
            </itemizedlist>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Server grouping</emphasis> – ability to
            group servers by logical domains, so only communicate with servers
            within specified domains.</para>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Callbacks</emphasis> – can receive
            server callbacks via push and pull models. Pull model allows for
            persistent stores and memory management.</para>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Asynchronous calls</emphasis> – can make
            asynchronous, or one way, calls to server.</para>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Local invocation</emphasis> – if making
            an invocation on a remoting server that is within the same process
            space, remoting will automatically make this call by reference, to
            improve performance.</para>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Remote classloading</emphasis> – allows
            for classes, such as custom marshallers, that do not exist within
            client to be loaded from server.</para>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Sending of streams</emphasis> – allows
            for clients to send input streams to server, which can be read on
            demand on the server.</para>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Clustering</emphasis> - seamless client
            failover for remote invocations.</para>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Connection failure
            notification</emphasis> - notification if client or server has
            failed</para>
          </listitem>
  
          <listitem>
            <para><emphasis role="bold">Data Compression</emphasis> - can use
            compression marshaller and unmarshaller for compresssion of large
            payloads.</para>
          </listitem>
        </itemizedlist>
  
        <para>All the features within JBoss Remoting were created with ease of
        use and extensibility in mind. If you have a suggestion for a new
        feature or an improvement to a current feature, please log in our issue
        tracking system at <!--<link linkend="???">http://jira.jboss.com</link>-->
        <ulink url="http://jira.jboss.com">http://jira.jboss.com</ulink></para>
      </section>
  
      <section>
        <title>How to get JBoss Remoting</title>
  
        <para>The JBossRemoting distribution can be downloaded from <ulink
        url="http://www.jboss.org/products/remoting">
        http://www.jboss.org/products/remoting </ulink> . This distribution
        contains everything needed to run JBossRemoting stand alone. The
        distribution includes binaries, source, documentation, javadoc, and
        sample code.</para>
      </section>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap13.xml
  
  Index: chap13.xml
  ===================================================================
    <chapter>
      <title>Getting the JBossRemoting source and building</title>
  
      <para>The JBossRemoting source code resides in the JBoss CVS repository
      under the CVS module JBossRemoting. To check out the source using the
      anonymous account, use the following command:</para>
  
      <programlisting>cvs -d:pserver:anonymous at anoncvs.forge.jboss.com:/cvsroot/jboss checkout JBossRemoting</programlisting>
  
      <para>To check out the source using a committer user id, use the
      following:</para>
  
      <programlisting>cvs -d:ext:username at cvs.forge.jboss.com:/cvsroot/jboss checkout JBossRemoting</programlisting>
  
      <para>This should checkout the entire remoting project, including doc,
      tests, libs, etc.</para>
  
      <para>See <!--<link linkend="???">http://www.jboss.org/wiki/Wiki.jsp?page=CVSRepository</link>-->
      <ulink url="http://www.jboss.org/wiki/Wiki.jsp?page=CVSRepository">
      http://www.jboss.org/wiki/Wiki.jsp?page=CVSRepository </ulink> for more
      information on how to access the JBoss CVS repository.</para>
  
      <para>The build process for JBossRemoting is based on a standard ant build
      file (build.xml). The version of ant that is supported is ant 1.6.2, but
      should work with earlier versions as there are no special ant features
      being used.</para>
  
      <para>The main ant build targets are as follows:</para>
  
      <para><emphasis role="bold">compile</emphasis> - compiles all the core
      JBossRemoting classes.</para>
  
      <para><emphasis role="bold">jars</emphasis> - creates the
      jboss-remoting.jar file from the compiled classes</para>
  
      <para><emphasis role="bold">javadoc</emphasis> - creates the javadoc html
      files for JBossRemoting</para>
  
      <para><emphasis role="bold">tests.compile</emphasis> - compiles the
      JBossRemoting test files</para>
  
      <para><emphasis role="bold">tests.jars</emphasis> - creates the
      jboss-remoting-tests.jar and jboss-remoting-loading-tests.jar
      files.</para>
  
      <para><emphasis role="bold">tests.quick</emphasis> - runs the functional
      unit tests for JBossRemoting.</para>
  
      <para><emphasis role="bold">tests</emphasis> - runs all the tests for
      JBossRemoting, including functional and performance tests for all the
      different transports.</para>
  
      <para><emphasis role="bold">clean</emphasis> - removes all the build
      artifacts and directories.</para>
  
      <para><emphasis role="bold">most</emphasis> - calls clean then jars
      targets.</para>
  
      <para><emphasis role="bold">dist</emphasis> - builds the full
      JBossRemoting distribution including running the full test suite.</para>
  
      <para><emphasis role="bold">dist.quick</emphasis> - builds the full
      JBossRemoting distribution, but does not run the test suite.</para>
  
      <para>The root directory for all build output is the output directory.
      Under this directory will be:</para>
  
      <para><literal>classes</literal> - compiled core classes
      <literal></literal></para>
  
      <para><literal>etc</literal> - deployment and JMX XMBean xml files
      <literal></literal></para>
  
      <para><literal>lib</literal> - all the jars and war file produced by the
      build <literal></literal></para>
  
      <para><literal>tests</literal> - contains the compiled test classes and
      test results</para>
  
      <para>For most development, the most target can be used. Please run the
      tests.quick target before checking anything in to ensure that code changes
      did not break any previously functioning test.</para>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap8.xml
  
  Index: chap8.xml
  ===================================================================
    <chapter>
      <title>Connection Exception Listeners</title>
  
      <bridgehead>Client side</bridgehead>
  
      <para>It is possible to register a listener with the remoting client to
      receive callbacks when a connection failure to a remoting server is
      detected, even when the client is idle.</para>
  
      <para>The only requirement is to implement the
      <code>org.jboss.remoting.ConnectionListener</code> interface, which has
      only one method:</para>
  
      <programlisting>public void handleConnectionException(Throwable throwable, Client client)</programlisting>
  
      <para>Then call the <code>addConnectionListener(ConnectionListener
      listener)</code> method on the Client class and pass your listener
      instance. Can also call <code>addConnectionListener(ConnectionListener
      listener, int pingPeriod)</code> if want to specify how frequently wish to
      ping server.</para>
  
      <para>Currently, the Client will use the
      <code>org.jboss.remoting.ConnectionValidator</code> class to handle the
      detection of connection failures. This is done by pinging the server
      periodically (defaults to every 2 seconds). If there is a failure during
      this ping, the exception and the Client will be passed to the
      listener.</para>
  
      <bridgehead>Server side</bridgehead>
  
      <para>A remoting server also has the capability to detect when a client is
      no longer available. This is done by estabilishing a lease with the
      remoting clients that connect to a server.</para>
  
      <para>To turn on server side connection failure detection of remoting
      clients, will need to satisfy two criteria. The first is that the client
      lease period is set and is a value greater than 0. The value is
      represented in milliseconds. The client lease period can be set by either
      the 'clientLeasePeriod' attribute within the Connector configuration or by
      calling the:<programlisting>public void setLeasePeriod(long leasePeriodValue)</programlisting>method
      within Connector. The second criterion is that an implementation of the
      <code>org.jboss.remoting.ConnectionListener</code> interface is added as a
      connection listener to the Connector, via the method:<programlisting>public void addConnectionListener(ConnectionListener listener)</programlisting>Note,
      there is no way to set the connection listener via xml based configuration
      for the Connector. Once both criteria are met, the remoting server will
      turn on client leasing.</para>
  
      <para>The ConnectionListener will be notified of both client failures and
      client disconnects via the handleConnectionException() method. If the
      client failed, meaning its lease was not renewed within configured time
      period, the first parameter to the handleConnectionException() method will
      be null. If the client disconnected in a regular manner, the first
      parameter to the handleConnectionException() method will be of type
      ClientDisconnectedException (which indicates a normal termination). Note,
      the client's lease will be renewed on the server with any and every
      invocation made on the server from the client, whether it be a normal
      invocation or a ping from the client internally.</para>
  
      <para>One the client side, there is no API or configuration changes
      needed. When the client initially connects to the server, it will check to
      see if client leasing is turned on by the server. If it is, it will
      internally start pinging periodically to the server to maintain the lease.
      When the client disconnects, it will internally send message to the server
      to stop monitoring lease for this client. Therefore, it is <emphasis
      role="bold">IMPORTANT</emphasis> that disconnect is called on the client
      when done using it. Otherwise, the client will continue to make its ping
      call on the server to keep its lease current.</para>
  
      <para>The client can also provide extra metadata the will be communicated
      to the connection listener in case of failure by supplying a metadata Map
      to the Client constructor. This map will be included in the Client
      instance passed to the connection listener (via the
      handleConnectionException() method) via the Client's getConfiguration()
      method.</para>
  
      <para>For examples of how to use server side connection listeners,
      reference org.jboss.test.remoting.lease.LeaseTestServer and
      org.jboss.test.remoting.lease.LeaseTestClient.</para>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap3.xml
  
  Index: chap3.xml
  ===================================================================
    <chapter>
      <title>JBoss Remoting Components</title>
  
      <para>This section covers a few of the main components exposed within the
      Remoting API with a brief overview.</para>
  
      <para><emphasis role="bold">org.jboss.remoting.Client</emphasis> – is the
      class the user will create and call on from the client side. This is the
      main entry point for making all invocations and adding a callback
      listener. The Client class requires only the InvokerLocator for the server
      you wish to call upon and that you call connect before use and disconnect
      after use (which is technically only required for stateful transports and
      when client leasing is turned on, but good to call in either case).</para>
  
      <para><emphasis role="bold">org.jboss.remoting.InvokerLocator</emphasis> –
      is a class, which can be described as a string URI, for identifying a
      particular JBossRemoting server JVM and transport protocol. For example,
      the InvokerLocator string socket://192.168.10.1:8080 describes a TCP/IP
      Socket-based transport, which is listening on port 8080 of the IP address,
      192.168.10.1. Using the string URI, or the InvokerLocator object,
      JBossRemoting can make a client connection to the remote JBoss server. The
      format of the locator string is the same as the URI type:
      <code>[transport]://[host]:&lt;port&gt;/path/?&lt;parameter=value&gt;&amp;&lt;parameter=value&gt;</code>
      A few important points to note about the InvokerLocator. The string
      representation used to construct the InvokerLocator may be modified after
      creation. This can occur if the host supplied is 0.0.0.0, in which case
      the InvokerLocator will attempt to replace it with the value of the local
      host name. This can also occur if the port specified is less than zero or
      not specified at all (in which case remoting will select a random port to
      use).</para>
  
      <para><emphasis
      role="bold">org.jboss.remoting.transport.Connector</emphasis> - is an
      MBean that loads a particular ServerInvoker implementation for a given
      transport subsystem and one or more ServerInvocationHandler
      implementations that handle Subsystem invocations on the remote server
      JVM. The Connector is the main user touch point for configuring and
      managing a remoting server.</para>
  
      <para><emphasis
      role="bold">org.jboss.remoting.ServerInvocationHandler</emphasis> – is the
      interface that the remote server will call on with an invocation received
      from the client. This interface must be implemented by the user. This
      implementation will also be required to keep track of callback listeners
      that have been registered by the client as well.</para>
  
      <para><emphasis role="bold">org.jboss.remoting.InvocationRequest
      </emphasis> – is the actual remoting payload of an invocation. This class
      wraps the caller’s request and provides extra information about the
      invocation, such as the caller’s session id and its callback locator (if
      one exists). This will be object passed to the
      ServerInvocationHandler.</para>
  
      <para><emphasis
      role="bold">org.jboss.remoting.stream.StreamInvocationHandler</emphasis> –
      extends the ServerInvocationHandler interface and should be implemented if
      expecting to receive invocations containing an input stream.</para>
  
      <para><emphasis
      role="bold">org.jboss.remoting.callback.InvokerCallbackHandler</emphasis>
      – the interface for any callback listener to implement. Upon receiving
      callbacks, the remoting client will call on this interface if registered
      as a listener.</para>
  
      <para><emphasis
      role="bold">org.jboss.remoting.callback.Callback</emphasis> – the callback
      object passed to the InvokerCallbackHandler. It contains the callback
      payload supplied by the invocation handler, any handle object specified
      when callback listener was registered, and the locator from which the
      callback came.</para>
  
      <para><emphasis
      role="bold">org.jboss.remoting.network.NetworkRegistry</emphasis> – this
      is a singleton class that will keep track of remoting servers as new ones
      are detected and dead ones are detected. Upon a change in the registry,
      the NetworkRegistry fires a NetworkNotification.</para>
  
      <para><emphasis role="bold">org.jboss.remoting.network.NetworkNotification
      </emphasis> – a JMX Notification containing information about a remoting
      server change on the network. The notification contains information in
      regards to the server’s identity and all its locators.</para>
  
      <para><emphasis
      role="bold">org.jboss.remoting.detection.Detection</emphasis> – is the
      detection message fired by the Detectors. Contains the locator and
      subsystems for the server invokers of a remoting server as well as the
      remoting server’s identity.</para>
  
      <para><emphasis role="bold">org.jboss.remoting.ident.Identity</emphasis> –
      is one of the main components remoting uses during discovery to identify
      remoting server instances (is actually the way it guarantees uniqueness).
      If have two remoting servers running on the same server, they can be
      uniquely identified. The reason the identity is persisted (currently only
      able to do this to the file system) is so if a server crashes and then
      restarts, can identify it when it restarts as the one that crashed
      (instead of being a completely new instance that is being started). This
      may be important from a monitoring point as would want to know that the
      crashed server is back online.</para>
  
      <para>When creating the identity to be presisted, remoting will first look
      to see if a system property for 'jboss.identity' has been set already. If
      it has, will use that one. If not, will get the value for the
      'ServerDataDir' attribute of the 'jboss.system:type=ServerConfig' mbean.
      If can retrieve this value, will just this as the directory to write out
      the 'jboss.identity' file. If not, will look to see if a system property
      has been set for 'jboss.identity.dir'. If it has, will use this as the
      directory to write the 'jboss.identity' file to, otherwise, will default
      to '.'. If for some reason the file can not be written to, will throw a
      RuntimeException, which will cause the detector to error during startup.
      For more details on how and where the identity is persisted, can refer to
      org.jboss.remoting.ident.Identity.createId().</para>
  
      <para><emphasis
      role="bold">org.jboss.remoting.detection.multicast.MulticastDetector</emphasis>
      – is the detector implementation that broadcasts its Detection message to
      other detectors using multicast.</para>
  
      <para><emphasis role="bold">org.jboss.remoting.detection.jndi.JNDIDetector
      </emphasis> – is the detector implementation that registers its Detection
      message to other detectors in a specified JNDI server.</para>
  
      <para>There are a few other components that are not represented as a
      class, but important to understand.</para>
  
      <para><emphasis role="bold">Subsystem</emphasis> – a sub-system is an
      identifier for what higher level system an invocation handler is
      associated with. The sub-system is declared as any String value. The
      reason for identifying sub-systems is that a remoting Connector’s server
      invoker may handle invocations for multiple invocation handlers, which
      need to be routed based on sub-system. For example, a particular socket
      based server invoker may handle invocations for both customer processing
      and order processing. The client making the invocation would then need to
      identify the intended sub-system to handle the invocation based on this
      identifier. If only one handler is added to a Connector, the client does
      not need to specify a sub-system when making an invocation.</para>
  
      <para><emphasis role="bold">Domain</emphasis> – a logical name for a group
      to which a remoting server can belong. The detectors can discriminate as
      to which detection messages they are interested based on their specified
      domain. The domain to which a remoting server belongs is stored within the
      Identity of that remoting server, which is included within the detection
      messages. Detectors can be configured to accept detection messages from
      one, many or all domains.</para>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap10.xml
  
  Index: chap10.xml
  ===================================================================
  
    <chapter>
      <title>How to use it - sample code</title>
  
      <para>Sample code demonstrating different remoting features can be found
      in the examples directory. They can be compiled and run manually via your
      IDE or via an ant build file found in the examples directory. There are
      many sets of sample code, each with their own package. Within most of
      these packages, there will be a server and a client class that will need
      to be executed</para>
  
      <section>
        <title>Simple invocation</title>
  
        <para>The simple invocation sample (found in the
        org.jboss.remoting.samples.simple package), has two classes;
        SimpleClient and SimpleServer. It demonstrates making a simple
        invocation from a remoting client to a remoting server. The SimpleClient
        class will create an InvokerLocator object from a simple url-like string
        that identifies the remoting server to call upon (which will be
        socket://localhost:5400 by default). Then the SimpleClient will create a
        remoting Client class, passing the newly created InvokerLocator. Next
        the Client will be called to make an invocation on the remoting server,
        passing the request payload object (which is a String with the value of
        "Do something"). The server will return a response from this call which
        is printed to standard output.</para>
  
        <para>Within the SimpleServer, a remoting server is created and started.
        This is done by first creating an InvokerLocator, just like was done in
        the SimpleClient. Then constructing a Connector, passing the
        InvokerLocator. Next, need to call create() on the Connector to
        initialize all the resources, such as the remoting server invoker. Once
        created, need to create the invocation handler. The invocation handler
        is the class that the remoting server will pass client requests on to.
        The invocation handler in this sample simply returns the simple String
        "This is the return to SampleInvocationHandler invocation". Once
        created, the handler is added to the Connector. Finally, the Connector
        is started and will start listening for incoming client requests.</para>
  
        <para>To run this example, can compile both the SimpleClient and
        SimpleServer class, then first run the SimpleServer and then the
        SimpleClient. Or can go to the examples directory and run the ant target
        'run-simple-server' and then in another console window run the ant
        target 'run-simple-client'. For example:</para>
  
        <para><programlisting>ant run-simple-server</programlisting>ant
        then:</para>
  
        <para><programlisting>ant run-simple-client</programlisting>The output
        when running the SimpleClient should look like:</para>
  
        <programlisting>Calling remoting server with locator uri of: socket://localhost:5400
  Invoking server with request of 'Do something'
  Invocation response: This is the return to SampleInvocationHandler invocation</programlisting>
  
        <para>The output when running the SimpleServer should look like:</para>
  
        <programlisting>Starting remoting server with locator uri of: socket://localhost:5400
  Invocation request is: Do something
  Returning response of: This is the return to SampleInvocationHandler invocation</programlisting>
  
        <para>Note: will have to manually shut down the SimpleServer once
        started.</para>
      </section>
  
      <section>
        <title>HTTP invocation</title>
  
        <para>This http invocation sample (found in the
        org.jboss.remoting.samples.http package), demonstrates how the http
        invoker can be used for a variety of http based invocations. This time,
        will start with the server side. The SimpleServer class is much like the
        one from the previous simple invocation example, except that instead of
        using the 'socket' transport, will be using the 'http' transport. Also,
        instead of using the SampleInvocationHandler class as the handler, will
        be using the WebInvocationHandler (code shown below).</para>
  
        <programlisting>public class <emphasis role="bold">WebInvocationHandler</emphasis> implements <emphasis
            role="bold">ServerInvocationHandler</emphasis>
  {
     // Pre-defined returns to be sent back to client based on type of request.
     public static final String RESPONSE_VALUE = "This is the return to simple text based http invocation.";
     public static final ComplexObject OBJECT_RESPONSE_VALUE = new ComplexObject(5, "dub", false);
     public static final String HTML_PAGE_RESPONSE = "&lt;html&gt;&lt;head&gt;&lt;title&gt;Test HTML page&lt;/title&gt;&lt;/head&gt;&lt;body&gt;" +
                                                     "&lt;h1&gt;HTTP/Servlet Test HTML page&lt;/h1&gt;&lt;p&gt;This is a simple page served for test." +
                                                     "&lt;p&gt;Should show up in browser or via invoker client&lt;/body&gt;&lt;/html&gt;";
  
     // Different request types that client may make
     public static final String NULL_RETURN_PARAM = "return_null";
     public static final String OBJECT_RETURN_PARAM = "return_object";
     public static final String STRING_RETURN_PARAM = "return_string";
  
  
     /**
      * called to handle a specific invocation
      *
      * @param invocation
      * @return
      * @throws Throwable
      */
     <emphasis role="bold">public Object invoke(InvocationRequest invocation) throws Throwable
     {
        // Print out the invocation request
        System.out.println("Invocation request from client is: " + invocation.getParameter());
        if(NULL_RETURN_PARAM.equals(invocation.getParameter()))
        {
           return null;
        }
        else if(invocation.getParameter() instanceof ComplexObject)
        {
              return OBJECT_RESPONSE_VALUE;
        }
        else if(STRING_RETURN_PARAM.equals(invocation.getParameter()))
        {
           Map responseMetadata = invocation.getReturnPayload();
           responseMetadata.put(HTTPMetadataConstants.RESPONSE_CODE,  new Integer(207));
           responseMetadata.put(HTTPMetadataConstants.RESPONSE_CODE_MESSAGE, "Custom response code and message from remoting server");
           // Just going to return static string as this is just simple example code.
           return RESPONSE_VALUE;
        }
        else
        {
           return HTML_PAGE_RESPONSE;
        }</emphasis>
     }
  </programlisting>
  
        <para>The most interesting part of the WebInvocationHandler is its
        invoke() method implementation. First it will check to see what the
        request parameter was from the InvocationRequest and based on what the
        value is, will return different responses. The first check is to see if
        the client passed a request to return a null value. The second will
        check to see if the request parameter from the client was of type
        ComplexObject. If so, return the pre-built ComplexObject that was
        created as a static variable.</para>
  
        <para>After that, will check to see if the request parameter was for
        returning a simple String. Notice in this block, will set the desired
        response code and message to be returned to the client. In this case,
        are setting the response code to be returned to 207 and the response
        message to "Custom response code and message from remoting server".
        These are non-standard code and message, but can be anything
        desired.</para>
  
        <para>Last, if have not found a matching invocation request parameter,
        will just return some simple html.</para>
  
        <para>Now onto the client side for making the calls to this handler,
        which can be found in SimpleClient (code shown below).</para>
  
        <programlisting>public class <emphasis role="bold">SimpleClient</emphasis>
  {
     // Default locator values
     private static String transport = "<emphasis role="bold">http</emphasis>";
     private static String host = "localhost";
     private static int port = 5400;
  
     public void makeInvocation(String locatorURI) throws Throwable
     {
        // create InvokerLocator with the url type string
        // indicating the target remoting server to call upon.
        InvokerLocator locator = new InvokerLocator(locatorURI);
        System.out.println("Calling remoting server with locator uri of: " + locatorURI);
  
        Client remotingClient = new Client(locator);
  
        // make invocation on remoting server and send complex data object
        // by default, the remoting http client invoker will use method type of POST,
        // which is needed when ever sending objects to the server.  So no metadata map needs
        // to be passed to the invoke() method.
        <emphasis role="bold">Object response = remotingClient.invoke(new ComplexObject(2, "foo", true), null);</emphasis>
  
        System.out.println("\nResponse from remoting http server when making http POST request and sending a complex data object:\n" + response);
  
  
        <emphasis role="bold">Map metadata = new HashMap();</emphasis>
        // set the metadata so remoting client knows to use http GET method type
        <emphasis role="bold">metadata.put("TYPE", "GET");</emphasis>
        // not actually sending any data to the remoting server, just want to get its response
        <emphasis role="bold">response = remotingClient.invoke((Object) null, metadata);</emphasis>
  
        System.out.println("\nResponse from remoting http server when making GET request:\n" + response);
  
        // now set type back to POST and send a plain text based request
        <emphasis role="bold">metadata.put("TYPE", "POST");</emphasis>
        <emphasis role="bold">response = remotingClient.invoke(WebInvocationHandler.STRING_RETURN_PARAM, metadata);</emphasis>
  
        System.out.println("\nResponse from remoting http server when making http POST request and sending a text based request:\n" + response);
  
        // notice are getting custom response code and message set by web invocation handler
        <emphasis role="bold">Integer responseCode = (Integer) metadata.get(HTTPMetadataConstants.RESPONSE_CODE);
        String responseMessage = (String) metadata.get(HTTPMetadataConstants.RESPONSE_CODE_MESSAGE);</emphasis>
        System.out.println("Response code from server: " + responseCode);
        System.out.println("Response message from server: " + responseMessage);
  
     }
  </programlisting>
  
        <para>This SimpleClient, like the one before in the simple invocation
        example, starts off by creating an InvokerLocator and remoting Client
        instance, except is using http transport instead of socket. The first
        invocation made is to send a newly constructed ComplexObject. If
        remember from the WebInvocationHandler above, will expect this
        invocation to return a different ComplexObject, which can be seen in the
        following system output line.</para>
  
        <para>The next invocation to be made is a simple http GET request. To do
        this, must first let the remoting client know that the method type needs
        to be changed from the default, which is POST, to be GET. Then make the
        invocation with a null payload (since not wanting to send any data, just
        get data in response) and the metadata map just populated with the GET
        type. This invocation request will return a response of html.</para>
  
        <para>Then, will change back to being a POST type request and will pass
        a simple String as the payload to the invocation request. This will
        return a simple String as the response from the WebInvocationHandler.
        Afterward, will see the specific response code and message printed to
        standard output, as well as the exception itself.</para>
  
        <para>To run this example, can compile all the classes in the package,
        then first run the SimpleServer and then the SimpleClient. Or can go to
        the examples directory and run the ant target 'run-http-server' and then
        in another console window run the ant target 'run-http-client'. For
        example:</para>
  
        <programlisting>ant run-http-server</programlisting>
  
        <para>and then:</para>
  
        <programlisting>ant run-http-client</programlisting>
  
        <para>The output when running the SimpleClient should look like:</para>
  
        <programlisting>Response from remoting http server when making http POST request and sending a complex data object:
  ComplexObject (i = 5, s = dub, b = false, bytes.length = 0)
  
  Response from remoting http server when making GET request:
  &lt;html&gt;&lt;head&gt;&lt;title&gt;Test HTML page&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;h1&gt;HTTP/Servlet Test HTML page&lt;/h1&gt;&lt;p&gt;This is a simple page served for test.&lt;p&gt;Should show up in browser or via invoker client&lt;/body&gt;&lt;/html&gt;
  
  Response from remoting http server when making http POST request and sending a text based request:
  This is the return to simple text based http invocation.
  Response code from server: 207
  Response message from server: Custom response code and message from remoting server</programlisting>
  
        <para>Notice that the first response is the ComplexObject from the
        static variable returned within WebInvocationHandler. The next response
        is html and then simple text from the WebInvocationHandler. Can see the
        specific response code and message set in the
        WebInvocationHandler.</para>
  
        <para>The output from the SimpleServer should look like:</para>
  
        <programlisting>Starting remoting server with locator uri of: http://localhost:5400
  Jan 26, 2006 11:39:53 PM org.apache.coyote.http11.Http11BaseProtocol init
  INFO: Initializing Coyote HTTP/1.1 on http-127.0.0.1-5400
  Jan 26, 2006 11:39:53 PM org.apache.coyote.http11.Http11BaseProtocol start
  INFO: Starting Coyote HTTP/1.1 on http-127.0.0.1-5400
  Invocation request from client is: ComplexObject (i = 2, s = foo, b = true, bytes.length = 0)
  Invocation request from client is: null
  Invocation request from client is: return_string</programlisting>
  
        <para>First the information for the http server invoker is written,
        which includes the locator uri used to start the server and the output
        from starting the Tomcat connector. Then will see the invocation
        parameter passed for each client request.</para>
  
        <para>Since the SimpleServer should still be running, can open a web
        browser and enter the locator uri, http://localhost:5400. This should
        cause the browser to render the html returned from the
        WebInvocationHandler.</para>
      </section>
  
      <section>
        <title>Oneway invocation</title>
  
        <para>The oneway invocation sample (found in the
        org.jboss.remoting.samples.oneway package) is very similar to the simple
        invocation example, except in this sample, the client will make
        asynchronous invocations on the server.</para>
  
        <para>The OnewayClient class sets up the remoting client as in the
        simple invocation sample, but instead of using the invoke() method, it
        uses the invokeOneway() method on the Client class. There are two basic
        modes when making a oneway invocation in remoting. The first is to have
        the calling thread to be the one that makes the actual call to the
        server. This allows the caller to ensure that the invocation request at
        least made it to the server. Once the server receives the invocation
        request, the call will return (and the request will be processed by a
        separate worker thread on the server). The other mode, which is
        demonstrated in the second call to invokeOneway, allows for the calling
        thread to return immediately and a worker thread on the client side will
        make the actual invocation on the server. This is faster of the two
        modes, but if there is a problem making the request on the server, the
        original caller will be unaware.</para>
  
        <para>The OnewayServer is exactly the same as the SimpleServer from the
        previous example, with the exception that invocation handler returns
        null (since even if did return a response, would not be delivered to the
        original caller).</para>
  
        <para>To run this example, can compile both the OnewayClient and
        OnewayServer class, then run the OnewayServer and then the OnewayClient.
        Or can go to the examples directory and run the ant target
        'run-oneway-server' and then in another console window run the ant
        target 'run-oneway-client'. For example:</para>
  
        <programlisting>ant run-oneway-server</programlisting>
  
        <para>and then:</para>
  
        <programlisting>ant run-oneway-client</programlisting>
  
        <para>The output when running the OnewayClient should look like:</para>
  
        <programlisting>Calling remoting server with locator uri of: socket://localhost:5400
  Making oneway invocation with payload of 'Oneway call 1.'
  Making oneway invocation with payload of 'Oneway call 2.'</programlisting>
  
        <para>The output when running the OnewayServer should look like:</para>
  
        <programlisting>Starting remoting server with locator uri of: socket://localhost:5400
  Invocation request is: Oneway call 1.
  Invocation request is: Oneway call 2.</programlisting>
  
        <para>Note: will have to manually shut down the OnewayServer once
        started.</para>
  
        <para>Although this example only demonstrates making one way
        invocations, could include this with callbacks (see further down) to
        have asynchronous invocations with callbacks to verify was
        processed.</para>
      </section>
  
      <section>
        <title>Discovery and invocation</title>
  
        <para>The discovery sample (found in the
        org.jboss.remoting.samples.detection package) is similar to the simple
        invocation example in that it makes a simple invocation from the client
        to the server. However, in this example, instead of explicitly
        specifying the invoker locator to use for the target remoting server, it
        is discovered dynamically during runtime. This example is composed of
        two classes; SimpleDetectorClient and SimpleDetectorServer.</para>
  
        <para>The SimpleDetectorClient starts off by setting up the remoting
        detector. Detection on the client side requires a few components; a JMX
        MBeanServer, one or more Detectors, and a NetworkRegistry. The Detectors
        will listen for detection messages from remoting servers and then add
        the information for the detected servers to the NetworkRegistry. They
        use JMX to lookup and call on the NetworkRegistry. The NetworkRegistry
        uses JMX Notifications to emit changes in network topology (remoting
        servers being added or removed).</para>
  
        <para>In this particular example, the SimpleDetectorClient is registered
        with the NetworkRegistry as a notification listener. When it receives
        notifications from the NetworkRegistry (via the handleNotification()
        method), it will check to see if the notification is for adding or
        removing a remoting server. If it is for adding a remoting server, the
        SimpleDetectorClient will get the array of InvokerLocators from the
        NetworkNotification and make a remote call for each. If the notification
        is for removing a remoting server, the SimpleDetectorClient will simply
        print out a message saying which server has been removed.</para>
  
        <para>The biggest change between the SimpleDetectorServer and the
        SimpleServer from the first sample is that have added a method,
        setupDetector(), to create and start a remoting Detector. On the server
        side, only two components are needed for detection; the Detector and a
        JMX MBeanServer. As for the setup of the Connector, it is exactly the
        same as before. Notice that even though we have added a Detector on the
        server side, the Connector is not directly aware of either Detector or
        the MBeanServer, so no code changes for the Connector setup is
        required.</para>
  
        <para>To run this example, can compile both the SimpleDetectorClient and
        SimpleDetectorServer class, then run the SimpleDetectorServer and then
        the SimpleDetectorClient. Or can go to the examples directory and run
        the ant target 'run-detector-server' and then in another window run the
        ant target 'run-detector-client'. For example:</para>
  
        <programlisting>ant run-detector-server</programlisting>
  
        <para>and then:</para>
  
        <programlisting>ant run-detector-client</programlisting>
  
        <para>The initial output when running the SimpleDetectorClient should
        look like:</para>
  
        <programlisting>ri Jan 13 09:36:50 EST 2006: [CLIENT]: Starting JBoss/Remoting client... to stop this client, kill it manually via Control-C
  Fri Jan 13 09:36:50 EST 2006: [CLIENT]: NetworkRegistry has been created
  Fri Jan 13 09:36:50 EST 2006: [CLIENT]: NetworkRegistry has added the client as a listener
  Fri Jan 13 09:36:50 EST 2006: [CLIENT]: MulticastDetector has been created and is listening for new NetworkRegistries to come online
  Fri Jan 13 09:36:50 EST 2006: [CLIENT]: GOT A NETWORK-REGISTRY NOTIFICATION: jboss.network.server.added
  Fri Jan 13 09:36:50 EST 2006: [CLIENT]: New server(s) have been detected - getting locators and sending welcome messages
  Fri Jan 13 09:36:50 EST 2006: [CLIENT]: Sending welcome message to remoting server with locator uri of: socket://127.0.0.1:5400/
  Fri Jan 13 09:36:50 EST 2006: [CLIENT]: The newly discovered server sent this response to our welcome message: Received your welcome message.  Thank you!</programlisting>
  
        <para>The output when running the SimpleDetectorServer should look
        like:</para>
  
        <programlisting>Fri Jan 13 09:36:46 EST 2006: [SERVER]: Starting JBoss/Remoting server... to stop this server, kill it manually via Control-C
  Fri Jan 13 09:36:46 EST 2006: [SERVER]: This server's endpoint will be: socket://localhost:5400
  Fri Jan 13 09:36:46 EST 2006: [SERVER]: MulticastDetector has been created and is listening for new NetworkRegistries to come online
  Fri Jan 13 09:36:46 EST 2006: [SERVER]: Starting remoting server with locator uri of: socket://localhost:5400
  Fri Jan 13 09:36:46 EST 2006: [SERVER]: Added our invocation handler; we are now ready to begin accepting messages from clients
  Fri Jan 13 09:36:50 EST 2006: [SERVER]: RECEIVED A CLIENT MESSAGE: Welcome Aboard!
  Fri Jan 13 09:36:50 EST 2006: [SERVER]: Returning the following message back to the client: Received your welcome message.  Thank you!</programlisting>
  
        <para>At this point, try stopping the SimpleDetectorServer (notice that
        the SimpleDetectorClient should still be running). After a few seconds,
        the client detector should detect that the server is no longer available
        and will see something like the following appended in the
        SimpleDetectorClient console window:</para>
  
        <programlisting>Fri Jan 13 09:37:04 EST 2006: [CLIENT]: GOT A NETWORK-REGISTRY NOTIFICATION: jboss.network.server.removed
  Fri Jan 13 09:37:04 EST 2006: [CLIENT]: It has been detected that a server has gone down with a locator of: InvokerLocator [socket://127.0.0.1:5400/]</programlisting>
      </section>
  
      <section>
        <title>Callbacks</title>
  
        <para>The callback sample (found in the
        org.jboss.remoting.samples.callback package) illustrates how to perform
        callbacks from a remoting server to a remoting client. This example is
        composed of two classes; CallbackClient and CallbackServer.</para>
  
        <para>Within remoting, there are two approaches in which a callback can
        be received. The first is to actively ask for callback messages from the
        remoting server, which is called a pull callback (since are pulling the
        callbacks from the server). The second is to have the server send the
        callbacks to the client as they are generated, which is called a push
        callback. This sample demonstrates how to do both pull and push
        callbacks.</para>
  
        <para>Looking at the CallbackClient class, will see that the first thing
        done is to create a remoting Client, which is done in the same manner as
        previous examples. Next, we'll perform a pull callback, which requires
        the creation of a CallbackHandler. The CallbackHandler, which implements
        the InvokerCallbackHandler interface, is what is called upon with a
        Callback object when a callback is received. The Callback object
        contains information such as the callback message (in Object form), the
        server locator from where the callback originally came from, and a
        handle object which can help to identify callback context (similar to
        the handle object within a JMX Notification). Once created, the
        CallbackHandler is then registered as a listener within the Client. This
        will cause the client to make a call to the server to notify the server
        it has a callback listener (more on this below in the server section).
        Although the CallbackHandler is not called upon directly when doing pull
        callbacks, it is needed as an identifier for the callbacks.</para>
  
        <para>Then the client will wait a few seconds, make a simple invocation
        on the server, and then call on the remoting Client instance to get any
        callbacks that may be available for our CallbackHandler. This will
        return a list of callbacks, if any exist. The list will be iterated and
        each callback will be printed to standard output. Finally, the callback
        handler will be removed as a listener from the remoting Client (which in
        turns removes it from the remoting server).</para>
  
        <para>After performing a pull callback, will perform a push callback.
        This is a little more involved as requires creating a callback server to
        which the remoting target server can callback on when it generates a
        callback message. To do this, will need to create a remoting Connector,
        just as have seen in previous examples. For this particular example, we
        use the same locator url as our target remoting server, but increment
        the port to listen on by one. Will also notice that use the
        SampleInvocationHandler hander from the CallbackServer (more in this in
        a minute). After creating our callback server, a CallbackHandler and
        callback handle object is created. Next, remoting Client is called to
        add our callback listener. Here we pass not only the CallbackHandler,
        but the InvokerLocator for the callback server (so the target server
        will know where to deliver callback messages to), and the callback
        handle object (which will be included in all the callback messages
        delivered for this particular callback listener).</para>
  
        <para>Then the client will wait a few seconds, to allow the target
        server time to generate and deliver callback messages. After that, we
        remove the callback listener and clean up our callback server.</para>
  
        <para>The CallbackServer is pretty much the same as the previous samples
        in setting up the remoting server, via the Connector. The biggest change
        resides in the ServerInvocationHandler implementation,
        SampleInvocationHandler (which is an inner class to CallbackServer). The
        first thing to notice is now have a variable called listeners, which is
        a List to hold any callback listeners that get registered. Also, in the
        constructor of the SampleInvocationHandler, we set up a new thread to
        run in the background. This thread, executing the run() method in
        SampleInvocationHandler, will continually loop looking to see if the
        shouldGenerateCallbacks has been set. If it has been, will create a
        Callback object and loop through its list of listeners and tell each
        listener to handle the newly created callback. Have also added
        implementation to the addListener() and removeListener() methods where
        will either add or remove specified callback listener from the internal
        callback listener list and set the shouldGenerateCallbacks flag
        accordingly. The invoke() method remains the same as in previous
        samples.</para>
  
        <para>To run this example, can compile both the CallbackClient and
        CallbackServer class, then run the CallbackServer and then the
        CallbackClient. Or can go to the examples directory and run the ant
        target 'run-callback-server' and then in another window run the ant
        target 'run-callback-client. For example:</para>
  
        <programlisting>ant run-callback-server</programlisting>
  
        <para>and then:</para>
  
        <programlisting>ant run-callback-client</programlisting>
  
        <para>The output in the CallbackClient console window should look
        like:</para>
  
        <programlisting>Calling remoting server with locator uri of: socket://localhost:5400
  Invocation response: This is the return to SampleInvocationHandler invocation
  Pull Callback value = Callback 1: This is the payload of callback invocation.
  Pull Callback value = Callback 2: This is the payload of callback invocation.
  Starting remoting server with locator uri of: InvokerLocator [socket://127.0.0.1:5401/]
  Received push callback.
  Received callback value of: Callback 3: This is the payload of callback invocation.
  Received callback handle object of: myCallbackHandleObject
  Received callback server invoker of: InvokerLocator [socket://127.0.0.1:5400/]
  Received push callback.
  Received callback value of: Callback 4: This is the payload of callback invocation.
  Received callback handle object of: myCallbackHandleObject
  Received callback server invoker of: InvokerLocator [socket://127.0.0.1:5400/]</programlisting>
  
        <para>This output shows that client first pulled two callbacks generated
        from the server. Then, after creating and registering our second
        callback handler and a callback server, two callbacks were received from
        the target server.</para>
  
        <para>The output in the CallbackServer console window should look
        like:</para>
  
        <programlisting>Starting remoting server with locator uri of: socket://localhost:5400
  Adding callback listener.
  Invocation request is: Do something
  Removing callback listener.
  Adding callback listener.
  Removing callback listener. </programlisting>
  
        <para>This output shows two distinct callback handlers being added and
        removed (with an invocation request being received after the first was
        added).</para>
  
        <para>There are a few important points to mention about this example.
        First, notice that in the client, the same callback handle object in the
        push callbacks was received as was registered with the callback
        listener. However, there was no special code required to facilitate this
        within the SampleInvocationHandler. This is handled within remoting
        automatically. Also notice when the callback server was created within
        the client, no special coding was required to register the callback
        handler with it, both were simply passed to the remoting Client instance
        when registering the callback listener and was handled
        internally.</para>
      </section>
  
      <section>
        <title>Streaming</title>
  
        <para>The streaning sample (found in the
        org.jboss.remoting.samples.stream package) illustrates how a
        java.io.InputStream can be sent from a client and read on demand from a
        server. This example is composed of two classes: StreamingClient and
        StreamingServer.</para>
  
        <para>Unlike the previous examples that sent plain old java objects as
        the payload, this example will be sending a java.io.FileInputStream as
        the payload to the server. This is a special case because streams can
        not be serialized. One approach to this might be to write out the
        contents of a stream to a byte buffer and send the whole data content to
        the server. However, this approach can be dangerous because if the data
        content of the stream is large, such as an 800MB file, would run the
        risk of causing an out of memory error (since are loading all 800MB into
        memory). Another approach, which is used by JBossRemoting, is to create
        a proxy to the original stream. This proxy can then be called upon for
        reading, same as the original stream. When this happens, the proxy will
        call back the original stream for the requested data.</para>
  
        <para>Looking at the StreamingClient, the remoting Client is created as
        in previous samples. Next, will create a java.io.FileInputStream to the
        sample.txt file on disk (which is in the same directory as the test
        classes). Finally, will call the remoting Client to do its invocation,
        passing the new FileInputStream and the name of the file. The second
        parameter could be of any Object type and is meant to supply some
        meaningful context to the server in regards to the stream being passed,
        such as the file name to use when writing to disk on the server side.
        The response from the server, in this example, is the size of the file
        it wrote to disk.</para>
  
        <para>The StreamingServer sets up the remoting server as was done in
        previous examples. However, instead of using an implementation of the
        ServerInvocationHandler class as the server handler, an implementation
        of the StreamInvocationHandler (which extends the
        ServerInvocationHandler) is used. The StreamInvocationHandler includes
        an extra method called handleStream() especially for processing requests
        with a stream as the payload. In this example, the class implementing
        the StreamInvocationHandler is the TestStreamInvocationHandler class,
        which is an inner class to the StreamingServer. The handleStream()
        method within the TestStreamInvocationHandler will use the stream passed
        to it to write out its contents to a file on disk, as specified by the
        second parameter passed to the handleStream() method. Upon writing out
        the file to disk, the handleStream() method will return to the client
        caller the size of the file.</para>
  
        <para>To run this example, can compile both the StreamingClient and
        StreamingServer class, then run the StreamingServer and then the
        StreamingClient. Or can go to the examples directory and run the ant
        target 'run-stream-server' and then in another window run the ant target
        'run-stream-client'. For example:</para>
  
        <programlisting>ant run-stream-server</programlisting>
  
        <para>and then:</para>
  
        <programlisting>ant run-stream-client</programlisting>
  
        <para>The output in the StreamingClient console window should look
        like:</para>
  
        <programlisting>Calling on remoting server with locator uri of: socket://localhost:5400
  Sending input stream for file sample.txt to server.
  Size of file sample.txt is 987
  Server returned 987 as the size of the file read.</programlisting>
  
        <para>The output in the StreamingServer console window should look
        like:</para>
  
        <programlisting>Starting remoting server with locator uri of: socket://localhost:5400
  Received input stream from client to write out to file server_sample.txt
  Read stream of size 987.  Now writing to server_sample.txt
  New file server_sample.txt has been written out to C:\tmp\JBossRemoting_1_4_0_final\examples\server_sample.txt</programlisting>
  
        <para>After running this example, there should be a newly created
        server_sample.txt file in the root examples directory. The contents of
        the file should look exactly like the contents of the sample.txt file
        located in the examples\org\jboss\remoting\samples\stream
        directory.</para>
      </section>
  
      <section>
        <title>JBoss Serialization</title>
  
        <para>The serialization sample (found in the
        org.jboss.remoting.samples.serialization package) illustrates how JBoss
        Serialization can be used in place of the standard java serialization to
        allow for sending of invocation payload objects that do not implement
        the java.io.Serializable interface. This example is composed of three
        classes: SerializationClient, SerializationServer, and
        NonSerializablePayload.</para>
  
        <para>This example is exactly like the one from the simple example with
        two differences. The first difference is the use of JBoss Serialization
        to convert object instances to binary data format for wire transfer.
        This is accomplished by adding an extra parameter (serializationtype) to
        the locator url with a value of 'jboss'. Is important to note that use
        of JBoss Serialization requires JDK 1.5, so this example will need to be
        run using JDK 1.5. The second difference is instead of sending and
        receiving a simple String type for the remote invocation payload, will
        be sending and receiving an instance of the NonSerializablePayload
        class.</para>
  
        <para>There are a few important points to notice with the
        NonSerializablePayload class. The first is that it does NOT implement
        the java.io.Serializable interface. The second is that it has a void
        parameter constructor. This is a requirement of JBoss Serialization for
        object instances that do not implement the Serializable interface.
        However, this void parameter constructor can be private, as in the case
        of NonSerializablePayload, as to not change the external API of the
        class.</para>
  
        <para>To run this example, can compile both the SerializationClient and
        SerializationServer class, then run the SerializationServer and then the
        SerializationClient. Or can go to the examples directory and run the ant
        target 'run-serialization-server' and then in another window run the ant
        target 'run-serialization-client'. For example:</para>
  
        <programlisting>ant run-serialization-server</programlisting>
  
        <para>and then:</para>
  
        <programlisting>ant run-serialization-client</programlisting>
  
        <para>The output in the SerializationClient console window should look
        like:</para>
  
        <programlisting>Calling remoting server with locator uri of: socket://localhost:5400/?serializationtype=jboss
  Invoking server with request of 'NonSerializablePayload - name: foo, id: 1'
  Invocation response: NonSerializablePayload - name: bar, id: 2</programlisting>
  
        <para>The output in the SerializationServer console window should look
        like:</para>
  
        <programlisting>Starting remoting server with locator uri of: socket://localhost:5400/?serializationtype=jboss
  Invocation request is: NonSerializablePayload - name: foo, id: 1
  Returning response of: NonSerializablePayload - name: bar, id: 2</programlisting>
  
        <para>Note: will have to manually shut down the SerializationServer once
        started.</para>
      </section>
  
      <section>
        <title>Transporters</title>
  
        <para>The transporter sample spans several examples showing different
        ways to use the transporter. Each specific example is within its own
        package under the org.jboss.remoting.samples.transporter package. Since
        each of the transporter examples includes common objects, as well as
        client and server classes, the common objects will be found under the
        main transporter sub-package and the client and server classes in their
        respective sub-packages (named client and server).</para>
  
        <section>
          <title>Transporter sample - basic</title>
  
          <para>The basic transporter example (found in
          org.jboss.remoting.samples.transporter.basic package) illustrates how
          to build a simple transporter for making remote invocations on plain
          old java objects.</para>
  
          <para>In this first, basic transporter example, will be using a few
          domain objects; <code>Customer</code> and Address, which are just data
          objects.</para>
  
          <programlisting>public class <emphasis role="bold">Customer</emphasis> implements Serializable
  {
     private String firstName = null;
     private String lastName = null;
     private Address addr = null;
     private int customerId = -1;
  
     public String getFirstName()
     {
        return firstName;
     }
  
     public void setFirstName(String firstName)
     {
        this.firstName = firstName;
     }
  
     public String getLastName()
     {
        return lastName;
     }
  
     public void setLastName(String lastName)
     {
        this.lastName = lastName;
     }
  
     public Address getAddr()
     {
        return addr;
     }
  
     public void setAddr(Address addr)
     {
        this.addr = addr;
     }
  
     public int getCustomerId()
     {
        return customerId;
     }
  
     public void setCustomerId(int customerId)
     {
        this.customerId = customerId;
     }
  
     public String toString()
     {
        StringBuffer buffer = new StringBuffer();
        buffer.append("\nCustomer:\n");
        buffer.append("customer id: " + customerId + "\n");
        buffer.append("first name: " + firstName + "\n");
        buffer.append("last name: " + lastName + "\n");
        buffer.append("street: " + addr.getStreet() + "\n");
        buffer.append("city: " + addr.getCity() + "\n");
        buffer.append("state: " + addr.getState() + "\n");
        buffer.append("zip: " + addr.getZip() + "\n");
  
        return buffer.toString();
     }
  }</programlisting>
  
          <programlisting>public class <emphasis role="bold">Address</emphasis> implements Serializable
  {
     private String street = null;
     private String city = null;
     private String state = null;
     private int zip = -1;
  
     public String getStreet()
     {
        return street;
     }
  
     public void setStreet(String street)
     {
        this.street = street;
     }
  
     public String getCity()
     {
        return city;
     }
  
     public void setCity(String city)
     {
        this.city = city;
     }
  
     public String getState()
     {
        return state;
     }
  
     public void setState(String state)
     {
        this.state = state;
     }
  
     public int getZip()
     {
        return zip;
     }
  
     public void setZip(int zip)
     {
        this.zip = zip;
     }
  }</programlisting>
  
          <para>Next comes the POJO that we want to expose a remote proxy for,
          which is <code>CustomerProcessorImpl</code> class. This implementation
          has one method to process a <code>Customer</code> object. It also
          implements the <code>CustomerProcessor</code> interface.</para>
  
          <programlisting>public class <emphasis role="bold">CustomerProcessorImpl</emphasis> implements <emphasis
              role="bold">CustomerProcessor</emphasis>
  {
     /**
      * Takes the customer passed, and if not null and customer id
      * is less than 0, will create a new random id and set it.
      * The customer object returned will be the modified customer
      * object passed.
      *
      * @param customer
      * @return
      */
     public Customer processCustomer(Customer customer)
     {
        if(customer != null &amp;&amp; customer.getCustomerId() &lt; 0)
        {
           customer.setCustomerId(new Random().nextInt(1000));
        }
        System.out.println("processed customer with new id of " + customer.getCustomerId());
        return customer;
     }
  }</programlisting>
  
          <programlisting>public interface <emphasis role="bold">CustomerProcessor</emphasis>
  {
     /**
      * Process a customer object.  Implementors
      * should ensure that the customer object
      * passed as parameter should have its internal
      * state changed somehow and returned.
      *
      * @param customer
      * @return
      */
     public Customer processCustomer(Customer customer);
  }</programlisting>
  
          <para>So far, nothing special, just plain old java objects. Next need
          to create the server component that will listen for remote request to
          invoke on the target POJO. This is where the transporter comes
          in.</para>
  
          <programlisting>public class <emphasis role="bold">Server</emphasis>
  {
     private String locatorURI = "socket://localhost:5400";
     private TransporterServer server = null;
  
     public void start() throws Exception
     {
        server = <emphasis role="bold">TransporterServer.createTransporterServer(locatorURI, new CustomerProcessorImpl())</emphasis>;
     }
  
     public void stop()
     {
        if(server != null)
        {
           server.stop();
        }
     }
  
     public static void main(String[] args)
     {
        Server server = new Server();
        try
        {
           server.start();
  
           Thread.currentThread().sleep(60000);
  
        }
        catch(Exception e)
        {
           e.printStackTrace();
        }
        finally
        {
           server.stop();
        }
     }
  }</programlisting>
  
          <para>The <code>Server</code> class is a pretty simple one. It calls
          the <code>TransporterServer</code> factory method to create the server
          component for the <code>CustomerProcessorImpl</code> instance using
          the specified remoting locator information.</para>
  
          <para>The <code>TransporterServer</code> returned from the
          <code>createTransporterServer() </code>call will be a running instance
          of a remoting server using the <literal>socket</literal> transport
          that is bound to <literal>localhost</literal> and listening for remote
          requests on port <literal>5400</literal>. The requests that come in
          will be forwarded to the remoting handler which will convert them into
          direct method calls on the target POJO,
          <code>CustomerProcessorImpl</code> in this case, using
          reflection.</para>
  
          <para>The <code>TransporterServer</code> has a <code>start()</code>
          and <code>stop()</code> method exposed to control when to start and
          stop the running of the remoting server. The <code>start()</code>
          method is called automatically within the
          <code>createTransporterServer()</code> method, so is ready to receive
          requests upon the return of this method. The <code>stop()</code>
          method, however, needs to be called explicitly when no longer wish to
          receive remote calls on the target POJO.</para>
  
          <para>Next up is the client side. This is represented by the
          <code>Client</code> class.</para>
  
          <programlisting>public class <emphasis role="bold">Client</emphasis>
  {
     private String locatorURI = "socket://localhost:5400";
  
     public void makeClientCall() throws Exception
     {
        Customer customer = createCustomer();
  
        <emphasis role="bold">CustomerProcessor customerProcessor = (CustomerProcessor) TransporterClient.createTransporterClient(locatorURI, CustomerProcessor.class);</emphasis>
  
        System.out.println("Customer to be processed: " + customer);
        <emphasis role="bold">Customer processedCustomer = customerProcessor.processCustomer(customer);</emphasis>
        System.out.println("Customer is now: " + processedCustomer);
  
        <emphasis role="bold">TransporterClient.destroyTransporterClient(customerProcessor);</emphasis>
     }
  
     private Customer createCustomer()
     {
        Customer cust = new Customer();
        cust.setFirstName("Bob");
        cust.setLastName("Smith");
        Address addr = new Address();
        addr.setStreet("101 Oak Street");
        addr.setCity("Atlanata");
        addr.setState("GA");
        addr.setZip(30249);
        cust.setAddr(addr);
  
        return cust;
     }
  
     public static void main(String[] args)
     {
        Client client = new Client();
        try
        {
           client.makeClientCall();
        }
        catch(Exception e)
        {
           e.printStackTrace();
        }
     }
  }</programlisting>
  
          <para>The <code>Client</code> class is also pretty simple. It creates
          a new <code>Customer</code> object instance, creates the remote proxy
          to the <code>CustomerProcessor</code>, and then calls on the
          <code>CustomerProcessor</code> to process its new
          <code>Customer</code> instance.</para>
  
          <para>To get the remote proxy for the <code>CustomerProcessor</code>,
          all that is required is to call the <code>TransporterClient</code>'s
          method <code>createTransporterClient()</code> method and pass the
          locator uri and the type of the remote proxy (and explicitly cast the
          return to that type). This will create a dynamic proxy for the
          specified type, <code>CustomerProcessor</code> in this case, which is
          backed by a remoting client which in turn makes the calls to the
          remote POJO's remoting server. Once the call to
          <code>createTransportClient()</code> has returned, the remoting client
          has already made its connection to the remoting server and is ready to
          make calls (will throw an exception if it could not connect to the
          specified remoting server).</para>
  
          <para>When finished making calls on the remote POJO proxy, will need
          to explicitly destroy the client by calling
          <code>destroyTransporterClient()</code> and pass the remote proxy
          instance. This allows the remoting client to disconnect from the
          POJO's remoting server and clean up any network resources previously
          used.</para>
  
          <para>To run this example, can run the Server and then the Client. Or
          can go to the examples directory and run the ant target
          'run-transporter-basic-server' and then in another window run the ant
          target 'run-transporter-basic-client'. For example:</para>
  
          <programlisting>ant run-transporter-basic-server</programlisting>
  
          <para>and then:</para>
  
          <programlisting>ant run-transporter-basic-client</programlisting>
  
          <para>The output from the Client console should be similar to:</para>
  
          <programlisting>Customer to be processed:
  Customer:
  customer id: -1
  first name: Bob
  last name: Smith
  street: 101 Oak Street
  city: Atlanata
  state: GA
  zip: 30249
  
  Customer is now:
  Customer:
  customer id: 204
  first name: Bob
  last name: Smith
  street: 101 Oak Street
  city: Atlanata
  state: GA
  zip: 30249
  
  </programlisting>
  
          <para>and the output from the Server class should be similar
          to:</para>
  
          <programlisting>processed customer with new id of 204</programlisting>
  
          <para>The output shows that the <code>Customer</code> instance created
          on the client was sent to the server where it was processed (by
          setting the customer id to 204) and returned to the client (and
          printed out showing that the customer id was set to 204).</para>
        </section>
  
        <section>
          <title>Transporter sample - JBoss serialization</title>
  
          <para>The transporter serialization example (found in
          org.jboss.remoting.samples.transporter.serialization package) is very
          similar to the previous basic example, except in this one, the domain
          objects being sent over the wire will NOT be Serializable. This is
          accomplished via the use of JBoss Serialization. This can be useful
          when don't know which domain objects you may be using in remote calls
          or if adding ability for remote calls on legacy code.</para>
  
          <para>To start, there are a few more domain objects:
          <code>Order</code>, <code>OrderProcessor</code>, and
          <code>OrderProcessorImpl</code>. These will use some of the domain
          objects from the previous example as well, such as
          <code>Customer</code>.</para>
  
          <programlisting>public class <emphasis role="bold">Order</emphasis>
  {
     private int orderId = -1;
     private boolean isProcessed = false;
     private Customer customer = null;
     private List items = null;
  
  
     public int getOrderId()
     {
        return orderId;
     }
  
     public void setOrderId(int orderId)
     {
        this.orderId = orderId;
     }
  
     public boolean isProcessed()
     {
        return isProcessed;
     }
  
     public void setProcessed(boolean processed)
     {
        isProcessed = processed;
     }
  
     public Customer getCustomer()
     {
        return customer;
     }
  
     public void setCustomer(Customer customer)
     {
        this.customer = customer;
     }
  
     public List getItems()
     {
        return items;
     }
  
     public void setItems(List items)
     {
        this.items = items;
     }
  
     public String toString()
     {
        StringBuffer buffer = new StringBuffer();
        buffer.append("\nOrder:\n");
        buffer.append("\nIs processed: " + isProcessed);
        buffer.append("\nOrder id: " + orderId);
        buffer.append(customer.toString());
  
        buffer.append("\nItems ordered:");
        Iterator itr = items.iterator();
        while(itr.hasNext())
        {
           buffer.append("\n" + itr.next().toString());
        }
  
        return buffer.toString();
     }
  }</programlisting>
  
          <programlisting>public class <emphasis role="bold">OrderProcessorImpl</emphasis> implements <emphasis
              role="bold">OrderProcessor</emphasis>
  {
     private CustomerProcessor customerProcessor = null;
  
     public OrderProcessorImpl()
     {
        customerProcessor = new CustomerProcessorImpl();
     }
  
     public Order processOrder(Order order)
     {
        System.out.println("Incoming order to process from customer.\n" + order.getCustomer());
  
        // has this customer been processed?
        if(order.getCustomer().getCustomerId() &lt; 0)
        {
           order.setCustomer(customerProcessor.processCustomer(order.getCustomer()));
        }
  
        List items = order.getItems();
        System.out.println("Items ordered:");
        Iterator itr = items.iterator();
        while(itr.hasNext())
        {
           System.out.println(itr.next());
        }
  
        order.setOrderId(new Random().nextInt(1000));
        order.setProcessed(true);
  
        System.out.println("Order processed.  Order id now: " + order.getOrderId());
        return order;
     }
  }</programlisting>
  
          <programlisting>public interface OrderProcessor
  {
     public Order processOrder(Order order);
  }</programlisting>
  
          <para>The <code>OrderProcessorImpl</code> will take orders, via the
          <code>processOrder() </code>method, check that the customer for the
          order has been processed, and if not have the customer processor
          process the new customer. Then will place the order, which means will
          just set the order id and processed attribute to true.</para>
  
          <para>The most important point to this example is that the
          <code>Order</code> class does NOT implement
          <code>java.io.Serializable</code>.</para>
  
          <para>Now onto the <code>Server</code> class. This is just like the
          previous <code>Server</code> class in the basic example with one main
          difference: the <code>locatorURI</code> value.</para>
  
          <programlisting>public class <emphasis role="bold">Server</emphasis>
  {
     private String locatorURI = "socket://localhost:5400/?<emphasis role="bold">serializationtype=jboss</emphasis>";
     private TransporterServer server = null;
  
     public void start() throws Exception
     {
        server = TransporterServer.createTransporterServer(locatorURI, new OrderProcessorImpl());
     }
  
     public void stop()
     {
        if(server != null)
        {
           server.stop();
        }
     }
  
     public static void main(String[] args)
     {
        Server server = new Server();
        try
        {
           server.start();
  
           Thread.currentThread().sleep(60000);
  
        }
        catch(Exception e)
        {
           e.printStackTrace();
        }
        finally
        {
           server.stop();
        }
     }
  }</programlisting>
  
          <para>The addition of <literal>serializationtype=jboss</literal> tells
          the remoting framework to use JBoss Serialization in place of the
          standard java serialization.</para>
  
          <para>On the client side, there is the <code>Client</code> class, just
          as in the previous basic example.</para>
  
          <programlisting>public class <emphasis role="bold">Client</emphasis>
  {
     private String locatorURI = "socket://localhost:5400/?<emphasis role="bold">serializationtype=jboss</emphasis>";
  
     public void makeClientCall() throws Exception
     {
        Order order = createOrder();
  
        OrderProcessor orderProcessor = (OrderProcessor) TransporterClient.createTransporterClient(locatorURI, OrderProcessor.class);
  
        System.out.println("Order to be processed: " + order);
        Order changedOrder = orderProcessor.processOrder(order);
        System.out.println("Order now processed " + changedOrder);
  
        TransporterClient.destroyTransporterClient(orderProcessor);
  
     }
  
     private Order createOrder()
     {
        Order order = new Order();
        Customer customer = createCustomer();
        order.setCustomer(customer);
  
        List items = new ArrayList();
        items.add("Xbox 360");
        items.add("Wireless controller");
        items.add("Ghost Recon 3");
  
        order.setItems(items);
  
        return order;
     }
  
     private Customer createCustomer()
     {
        Customer cust = new Customer();
        cust.setFirstName("Bob");
        cust.setLastName("Smith");
        Address addr = new Address();
        addr.setStreet("101 Oak Street");
        addr.setCity("Atlanata");
        addr.setState("GA");
        addr.setZip(30249);
        cust.setAddr(addr);
  
        return cust;
     }
  
     public static void main(String[] args)
     {
        Client client = new Client();
        try
        {
           client.makeClientCall();
        }
        catch(Exception e)
        {
           e.printStackTrace();
        }
     }
  }</programlisting>
  
          <para>Again, the biggest difference to note is that have added
          <literal>serializationtype=jboss</literal> to the locator uri.</para>
  
          <para>Note: Running this example requires JDK 1.5.</para>
  
          <para>To run this example, can run the Server and then the Client. Or
          can go to the examples directory and run the ant target 'ant
          run-transporter-serialization-server' and then in another window run
          the ant target 'ant run-transporter-serialization-client'. For
          example:</para>
  
          <programlisting>ant run-transporter-serialization-server</programlisting>
  
          <para>and then:</para>
  
          <programlisting>ant run-transporter-serialization-client</programlisting>
  
          <para>When the server and client are run the output for the
          <code>Client</code> class is:</para>
  
          <programlisting>Order to be processed:
  Order:
  
  Is processed: false
  Order id: -1
  Customer:
  customer id: -1
  first name: Bob
  last name: Smith
  street: 101 Oak Street
  city: Atlanata
  state: GA
  zip: 30249
  
  Items ordered:
  Xbox 360
  Wireless controller
  Ghost Recon 3
  Order now processed
  Order:
  
  Is processed: true
  Order id: 221
  Customer:
  customer id: 861
  first name: Bob
  last name: Smith
  street: 101 Oak Street
  city: Atlanata
  state: GA
  zip: 30249
  
  Items ordered:
  Xbox 360
  Wireless controller
  Ghost Recon 3
  </programlisting>
  
          <para>The client output shows the printout of the newly created order
          before calling the <code>OrderProcessor</code> and then the processed
          order afterwards. Noticed that the processed order has its customer's
          id set, its order id set and the processed attribute is set to
          true.</para>
  
          <para>And the output from the <code>Server</code> is:</para>
  
          <programlisting>Incoming order to process from customer.
  
  Customer:
  customer id: -1
  first name: Bob
  last name: Smith
  street: 101 Oak Street
  city: Atlanata
  state: GA
  zip: 30249
  
  processed customer with new id of 861
  Items ordered:
  Xbox 360
  Wireless controller
  Ghost Recon 3
  Order processed.  Order id now: 221
  </programlisting>
  
          <para>The server output shows the printout of the customer before
          being processed and then the order while being processed.</para>
        </section>
  
        <section>
          <title>Transporter sample - clustered</title>
  
          <para>In the previous examples, there has been one and only one target
          POJO to make calls upon. If that target POJO was not available, the
          client call would fail. In the transporter clustered example (found in
          org.jboss.remoting.samples.transporter.clustered package), will show
          how to use the transporter in clustered mode so that if one target
          POJO becomes unavailable, the client call can be seamlessly failed
          over to another available target POJO on the network, regardless of
          network transport type.</para>
  
          <para>This example uses the domain objects from the first, basic
          example, so only need to cover the client and server code. For this
          example, there are three different server classes. The first class is
          the <code>SocketServer</code> class, which is the exact same as the
          <code>Server</code> class in the basic example, except for the call to
          the <code>TransportServer</code>'s <code>createTransportServer()
          </code>method.</para>
  
          <programlisting>public class <emphasis role="bold">SocketServer</emphasis>
  {
     public static String locatorURI = "socket://localhost:5400";
     private TransporterServer server = null;
  
     public void start() throws Exception
     {
        server = <emphasis role="bold">TransporterServer.createTransporterServer(getLocatorURI(), new CustomerProcessorImpl(),
                                                           CustomerProcessor.class.getName(), true)</emphasis>;
     }
  
     protected String getLocatorURI()
     {
        return locatorURI;
     }
  
     public void stop()
     {
        if(server != null)
        {
           server.stop();
        }
     }
  
     public static void main(String[] args)
     {
        SocketServer server = new SocketServer();
        try
        {
           server.start();
  
           Thread.currentThread().sleep(60000);
  
        }
        catch(Exception e)
        {
           e.printStackTrace();
        }
        finally
        {
           server.stop();
        }
     }
  }</programlisting>
  
          <para>Notice that are now calling on the <code>TransportServer</code>
          to create a server with the locator uri and target POJO
          (<code>CustomerProcessorImpl</code>) as before, but have also added
          the interface type of the target POJO (<code>CustomerProcessor</code>)
          and that want clustering turned on (via the last
          <literal>true</literal> parameter).</para>
  
          <para>The interface type of the target POJO is needed because this
          will be used as the subsystem within the remoting server for the
          target POJO. The subsystem value will be what the client uses to
          determine if discovered remoting server is for the target POJO they
          are looking for.</para>
  
          <sidebar>
            <para>The transporter uses the MulticastDetector from JBoss Remoting
            for automatic discovery when in clustered mode. The actual detection
            of remote servers that come online can take up to a few seconds once
            started. There is a JNDI based detector provided within JBoss
            Remoting, but has not been integrated within the transporters
            yet.</para>
          </sidebar>
  
          <para>The second server class is the <code>RMIServer</code> class. The
          <code>RMIServer</code> class extends the <code>SocketServer</code>
          class and uses a different locator uri specify <literal>rmi</literal>
          as the transport protocol and a different port
          (<literal>5500</literal>).</para>
  
          <programlisting>public class <emphasis role="bold">RMIServer</emphasis> extends <emphasis
              role="bold">SocketServer</emphasis>
  {
     private String localLocatorURI = "r<emphasis role="bold">mi://localhost:5500</emphasis>";
  
     protected String getLocatorURI()
     {
        return localLocatorURI;
     }
  
     public static void main(String[] args)
     {
        SocketServer server = new RMIServer();
        try
        {
           server.start();
  
           Thread.currentThread().sleep(60000);
  
        }
        catch(Exception e)
        {
           e.printStackTrace();
        }
        finally
        {
           server.stop();
        }
     }
  }</programlisting>
  
          <para>The last server class is the <code>HTTPServer</code> class. The
          <code>HTTPServer</code> class also extends the
          <code>SocketServer</code> class and specifies <literal>http</literal>
          as the transport protocol and <literal>5600</literal> as the port to
          listen for requests on.</para>
  
          <programlisting>public class <emphasis role="bold">HTTPServer</emphasis> extends <emphasis
              role="bold">SocketServer</emphasis>
  {
     private String localLocatorURI = "<emphasis role="bold">http://localhost:5600</emphasis>";
  
     protected String getLocatorURI()
     {
        return localLocatorURI;
     }
  
     public static void main(String[] args)
     {
        SocketServer server = new HTTPServer();
        try
        {
           server.start();
  
           Thread.currentThread().sleep(60000);
  
        }
        catch(Exception e)
        {
           e.printStackTrace();
        }
        finally
        {
           server.stop();
        }
     }
  }</programlisting>
  
          <para>On the client side, there is only the <code>Client</code> class.
          This class is very similar to the one from the basic example. The main
          exceptions are (1) the addition of a <code>TransporterClient</code>
          call to create a transporter client and (2) the fact that it
          continually loops, making calls on its <code>customerProcessor</code>
          variable to process customers. This is done so that when we run the
          client, we can kill the different servers and see that the client
          continues to loop making its calls without any exceptions or
          errors.</para>
  
          <programlisting>public class <emphasis role="bold">Client</emphasis>
  {
     <emphasis role="bold">private String locatorURI = SocketServer.locatorURI;</emphasis>
  
     private CustomerProcessor customerProcessor = null;
  
     public void makeClientCall() throws Exception
     {
        Customer customer = createCustomer();
  
        System.out.println("Customer to be processed: " + customer);
        <emphasis role="bold">Customer processedCustomer = customerProcessor.processCustomer(customer);</emphasis>
        System.out.println("Customer is now: " + processedCustomer);
  
        //TransporterClient.destroyTransporterClient(customerProcessor);
     }
  
     public void getCustomerProcessor() throws Exception
     {
        customerProcessor = (CustomerProcessor) <emphasis role="bold">TransporterClient.createTransporterClient(locatorURI, CustomerProcessor.class, true)</emphasis>;
     }
  
     private Customer createCustomer()
     {
        Customer cust = new Customer();
        cust.setFirstName("Bob");
        cust.setLastName("Smith");
        Address addr = new Address();
        addr.setStreet("101 Oak Street");
        addr.setCity("Atlanata");
        addr.setState("GA");
        addr.setZip(30249);
        cust.setAddr(addr);
  
        return cust;
     }
  
     public static void main(String[] args)
     {
        Client client = new Client();
        try
        {
  <emphasis role="bold">         client.getCustomerProcessor();
           while(true)
           {
              try
              {
                 client.makeClientCall();
                 Thread.currentThread().sleep(5000);
              }
              catch(Exception e)
              {
                 e.printStackTrace();
              }
           }
  </emphasis>      }
        catch(Exception e)
        {
           e.printStackTrace();
        }
     }
  }</programlisting>
  
          <para>The first item of note is that the locator uri from the
          <code>SocketServer</code> class is being used. Technically, this is
          not required as once the clustered <code>TransporterClient</code> is
          started, it will start to discover the remoting servers that exist on
          the network. However, this process can take several seconds to occur,
          so unless it is known that no calls will be made on the remote proxy
          right away, it is best to bootstrap with a known target server.</para>
  
          <para>Can also see that in the <code>main()</code> method, the first
          call on the Client instance is to <code>getCustomerProcessor()</code>.
          This method will call the <code>TransporterClient</code>'s
          <code>createTransporterClient()</code> method and passes the locator
          uri for the target POJO server, the type of POJO's remote proxy, and
          that clustering should be enabled.</para>
  
          <para>After getting the customer processor remote proxy, will
          continually loop making calls using the remote proxy (via the
          <code>processCustomer()</code> method on the
          <code>customerProcessor</code> variable).</para>
  
          <para>To run this example, all the servers need to be started (by
          running the <code>SocketServer</code>, <code>RMIServer</code>, and
          <code>HTTPServer</code> classes). Then run the Client class. This can
          be done via ant targets as well. So for example, could open four
          console windows and enter the ant targets as follows:</para>
  
          <programlisting>ant run-transporter-clustered-socket-server</programlisting>
  
          <programlisting>ant run-transporter-clustered-http-server</programlisting>
  
          <programlisting>ant run-transporter-clustered-rmi-server</programlisting>
  
          <programlisting>ant run-transporter-clustered-client</programlisting>
  
          <para>Once the client starts running, should start to see output
          logged to the <code>SocketServer</code>, since this is the one used to
          bootstrap. This output would look like:</para>
  
          <programlisting>processed customer with new id of 378
  processed customer with new id of 487
  processed customer with new id of 980</programlisting>
  
          <para>Once the <code>SocketServer</code> instance has received a few
          calls, kill this instance. The next time the client makes a call on
          its remote proxy, which happens every five seconds, it should fail
          over to another one of the servers (and will see similar output on
          that server instance). After that server has received a few calls,
          kill it and should see it fail over once again to the last server
          instance that is still running. Then, if kill that server instance,
          will see a CannotConnectException and stack trace similar to the
          following:</para>
  
          <programlisting><emphasis role="bold">...
  org.jboss.remoting.CannotConnectException</emphasis>: Can not connect http client invoker.
   at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:147)
   at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:56)
   at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:112)
   at org.jboss.remoting.Client.invoke(Client.java:226)
   at org.jboss.remoting.Client.invoke(Client.java:189)
   at org.jboss.remoting.Client.invoke(Client.java:174)
   at org.jboss.remoting.transporter.TransporterClient.invoke(TransporterClient.java:219)
   at $Proxy0.processCustomer(Unknown Source)
   at org.jboss.remoting.samples.transporter3.client.Client.makeClientCall(Client.java:29)
   at org.jboss.remoting.samples.transporter3.client.Client.main(Client.java:64)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at com.intellij.rt.execution.application.AppMain.main(AppMain.java:86)
  Caused by: java.net.ConnectException: Connection refused: connect
   at java.net.PlainSocketImpl.socketConnect(Native Method)
   at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
   at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
   at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
   at java.net.Socket.connect(Socket.java:507)
   at java.net.Socket.connect(Socket.java:457)
   at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
   at sun.net.www.http.HttpClient.openServer(HttpClient.java:365)
   at sun.net.www.http.HttpClient.openServer(HttpClient.java:477)
   at sun.net.www.http.HttpClient.&lt;init&gt;(HttpClient.java:214)
   at sun.net.www.http.HttpClient.New(HttpClient.java:287)
   at sun.net.www.http.HttpClient.New(HttpClient.java:299)
   at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:792)
   at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:744)
   at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:669)
   at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:836)
   at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:117)
   ... 14 more</programlisting>
  
          <para>since there are no target servers left to make calls on. Notice
          that earlier in the client output there were no errors while was
          failing over to the different servers as they were being
          killed.</para>
  
          <para>Because the CannotConnectException is being caught within the
          while loop, the client will continue to try calling the remote proxy
          and getting this exception. Now re-run any of the previously killed
          servers and will see that the client will discover that server
          instance and begin to successfully call on that server. The output
          should look something like:</para>
  
          <programlisting>...
   at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:669)
   at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:836)
   at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:117)
   ... 14 more
  
  Customer to be processed:
  Customer:
  customer id: -1
  first name: Bob
  last name: Smith
  street: 101 Oak Stree
  city: Atlanata
  state: null
  zip: 30249
  
  Customer is now:
  Customer:
  customer id: 633
  first name: Bob
  last name: Smith
  street: 101 Oak Stree
  city: Atlanata
  state: null
  zip: 30249
  
  ...</programlisting>
  
          <sidebar>
            <para>As demonstrated in this example, fail over can occur across
            any of the JBoss Remoting transports. Clustered transporters is also
            supported using JBoss Serialization, which was introduced in the
            previous example.</para>
  
            <para>It is important to understand that in the context of
            transporters, clustering means invocation fail over. The JBoss
            Remoting transporters themselves do not handle any form of state
            replication. If this feature were needed, could use JBoss Cache to
            store the target POJO instances so that when their state changed,
            that change would be replicated to the other target POJO instances
            running in other processes.</para>
          </sidebar>
        </section>
  
        <section>
          <title>Transporter sample -complex</title>
  
          <para>The complex transporter example (found in
          org.jboss.remoting.samples.transporter.complex package) is based off a
          test case a user, Milt Grinberg, provided (thanks Milt). The example
          is similar to the previous examples, except in this case involves
          matching Doctors and Patients using the ProviderInterface and provides
          a more complex sample in which to demonstrate how to use
          transporters.</para>
  
          <para>This example requires JDK 1.5 to run, since is using JBoss
          Serialization (and non-serialized data objects). To run this example,
          run the Server class and then the Client class. This can be done via
          ant targets 'run-transporter-complex-server' and then
          'run-transporter-complex-server' as well. For example:</para>
  
          <programlisting>ant run-transporter-complex-server</programlisting>
  
          <para>and then:</para>
  
          <programlisting>ant run-transporter-complex-client</programlisting>
  
          <para>The output for the client should look similar to:</para>
  
          <programlisting>*** Have a new patient that needs a doctor.  The patient is:
  
  Patient:
     Name: Bill Gates
     Ailment - Type: financial, Description: Money coming out the wazoo.
  
  *** Looking for doctor that can help our patient...
  
  *** Found doctor for our patient.  Doctor found is:
  Doctor:
     Name: Andy Jones
     Specialty: financial
     Patients:
  
  Patient:
     Name: Larry Ellison
     Ailment - Type: null, Description: null
     Doctor - Name: Andy Jones
  
  Patient:
     Name: Steve Jobs
     Ailment - Type: null, Description: null
     Doctor - Name: Andy Jones
  
  Patient:
     Name: Bill Gates
     Ailment - Type: financial, Description: Money coming out the wazoo.
  
  *** Set doctor as patient's doctor.  Patient info is now:
  
  Patient:
     Name: Bill Gates
     Ailment - Type: financial, Description: Money coming out the wazoo.
     Doctor - Name: Andy Jones
  
  *** Have a new patient that we need to find a doctor for (remember, the previous one retired and there are no others)
  *** Could not find doctor for patient.  This is an expected exception when there are not doctors available.
  org.jboss.remoting.samples.transporter.complex.NoDoctorAvailableException: No doctor available for ailment 'financial'
   at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:183)
   at org.jboss.remoting.Client.invoke(Client.java:325)
   at org.jboss.remoting.Client.invoke(Client.java:288)
   at org.jboss.remoting.Client.invoke(Client.java:273)
   at org.jboss.remoting.transporter.TransporterClient.invoke(TransporterClient.java:237)
   at $Proxy0.findDoctor(Unknown Source)
   at org.jboss.remoting.samples.transporter.complex.client.Client.makeClientCall(Client.java:72)
   at org.jboss.remoting.samples.transporter.complex.client.Client.main(Client.java:90)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at com.intellij.rt.execution.application.AppMain.main(AppMain.java:86)
  </programlisting>
  
          <para>From the output see the creation of a new patient, Bill Gates,
          and the attempt to find a doctor that specializes in his ailment. For
          Mr. Gates, we were able to find a doctor, Andy Jones, and can see that
          he has been added to the list of Dr. Jones' patients. Then we have Dr.
          Jones retire. Then we create a new patient and try to find an
          available doctor for the same ailment. Since Dr. Jones has retired,
          and there are no other doctors that specialize in that particular
          ailment, an exception is thrown. This is as expected.</para>
        </section>
      </section>
  
      <section>
        <title id="section-multiplex-invokers"
        xreflabel="Multiplex invokers">Multiplex invokers</title>
  
        <para>This section illustrates the construction of multiplex invoker
        groups described in the section <xref linkend="section-multiplex" />.
        The directory</para>
  
        <blockquote>
          <para><code>examples/org/jboss/remoting/samples/multiplex/invoker</code></para>
        </blockquote>
  
        <para>contains a server class,
        <classname>MultiplexInvokerServer</classname>, which is suitable for use
        with any of the client classes described below. It may be run in an IDE
        or from the command line using ant target
        <code>run-multiplex-server</code> from the <code>build.xml</code> file
        found in the <code>examples</code> directory. The server will stay
        alive, processing invocation requests as they are presented, until it
        has sent two push callbacks to however many listeners are registered, at
        which time it will shut itself down.</para>
  
        <para>The sample clients are as follows. Each sample client
        <emphasis>&lt;client&gt;</emphasis> may be run in an IDE or by using the
        ant target <code>run-</code><emphasis>&lt;client&gt;</emphasis> (e.g.,
        <code>run-Client2Server1</code>).</para>
  
        <itemizedlist>
          <listitem>
            <para><classname>Client2Server1</classname>: A
            <classname>MultiplexClientInvoker</classname> starts according to
            client rule 2, after which a
            <classname>MultiplexServerInvoker</classname> is started according
            to server rule 1. Note that the <classname>Client</classname> and
            <classname>Connector</classname> are passed matching
            <emphasis>clientMultiplexId</emphasis> and
            <emphasis>serverMultiplexId</emphasis> parameters,
            respectively.</para>
          </listitem>
  
          <listitem>
            <para><classname>Client2Server2</classname>: A
            <classname>MultiplexClientInvoker</classname> starts according to
            client rule 2, after which a
            <classname>MultiplexServerInvoker</classname> is started according
            to server rule 2. Note that no
            <emphasis>clientMultiplexId</emphasis> is passed to the
            <classname>Client</classname> and no
            <emphasis>serverMultiplexId</emphasis> parameter is passed to the
            <classname>Connector</classname> in this example.</para>
          </listitem>
  
          <listitem>
            <para><classname>Client3Server1</classname>: A
            <classname>MultiplexClientInvoker</classname> is created, and,
            lacking binding information, finds itself governed by client rule 3.
            Subsequently, a <classname>MultiplexServerInvoker</classname> is
            started according to server rule 1, providing the binding
            information which allows the
            <classname>MultiplexClientInvoker</classname> to start. Note that
            the <classname>Client</classname> and
            <classname>Connector</classname> are passed matching
            <emphasis>clientMultiplexId</emphasis> and
            <emphasis>serverMultiplexId</emphasis> parameters,
            respectively.</para>
          </listitem>
  
          <listitem>
            <para><classname>Server2Client1</classname>: A
            <classname>MultiplexServerInvoker</classname> starts according to
            server rule 2, after which a
            <classname>MultiplexClientInvoker</classname> is started according
            to client rule 1. Note that the <classname>Connector</classname> and
            <classname>Client</classname> are passed matching
            <emphasis>serverMultiplexId</emphasis> and
            <emphasis>clientMultiplexId</emphasis> parameters,
            respectively.</para>
          </listitem>
  
          <listitem>
            <para><classname>Server2Client2</classname>: A
            <classname>MultiplexServerInvoker</classname> starts according to
            server rule 2, after which a
            <classname>MultiplexClientInvoker</classname> is started according
            to client rule 2. Note that no
            <emphasis>serverMultiplexId</emphasis> is passed to the
            <classname>Connector</classname> and no
            <emphasis>clientMultiplexId</emphasis> parameter is passed to the
            <classname>Client</classname> in this example.</para>
          </listitem>
  
          <listitem>
            <para><classname>Server3Client1</classname>: A
            <classname>MultiplexServerInvoker</classname> is created, and,
            lacking connect information, finds itself governed by server rule 3.
            Subsequently, a <classname>MultiplexClientInvoker</classname> is
            started according to client rule 1, providing the connect
            information which allows the
            <classname>MultiplexServerInvoker</classname> to start. Note that
            the <classname>Connector</classname> and
            <classname>Client</classname> are passed matching
            <emphasis>serverMultiplexId</emphasis> and
            <emphasis>clientMultiplexId</emphasis> parameters,
            respectively.</para>
          </listitem>
        </itemizedlist>
  
        <para>For variety, the examples in which the client invoker starts first
        use the configuration <classname>Map</classname> to pass invoker group
        parameters, and the examples in which the server invoker starts first
        pass parameters in the <classname>InvokerLocator</classname>.</para>
      </section>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap7.xml
  
  Index: chap7.xml
  ===================================================================
    <chapter>
      <title>Serialization</title>
  
      <para>JBoss Remoting allows for the plugging in of custom serialization
      implementations. This is available via the
      <code>org.jboss.remoting.serialization.SerializationStreamFactory</code>
      class, which will provide the implementation as a
      <code>org.jboss.remoting.serialization.SerializationManager</code> . The
      SerializationManager can then be called on to get implementations for
      <code>java.io.ObjectInputStream</code> and
      <code>java.io.ObjectOutputStream</code> . This SerializationManager is
      used by most of the standard remoting marshallers and unmarshallers. There
      are currently two implementations of the SerializationManager; one for the
      standard java serialization, which is the default, and one for JBoss
      Serialization.</para>
  
      <para>JBoss Serialization is a new project under development to provide a
      more performant implementation of object serialization. It complies with
      java serialization standard with three exceptions:</para>
  
      <para>- SerialUID not needed</para>
  
      <para>- java.io.Serializable is not required</para>
  
      <para>- different protocol</para>
  
      <para>JBoss Serialization requires JDK 1.5.</para>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap6.xml
  
  Index: chap6.xml
  ===================================================================
  <chapter>
      <title>Sending streams</title>
  
      <para>Remoting supports the sending of InputStreams. It is important to
      note that this feature DOES NOT copy the stream data directly from the
      client to the server, but is a true on demand stream. Although this is
      obviously slower than reading from a stream on the server that has been
      copied locally, it does allow for true streaming on the server. It also
      allows for better memory control by the user (versus the framework trying
      to copy a 3 Gig file into memory and getting out of memory errors).</para>
  
      <para>Use of this new feature is simple. From the client side, there is a
      method in org.jboss.remoting.Client with the signature:</para>
  
      <programlisting>public Object invoke(InputStream inputStream, Object param) throws Throwable
        </programlisting>
  
      <para>So from the client side, would just call invoke as done in the past,
      and pass the InputStream and the payload as the parameters. An example of
      the code from the client side would be (this is taken directly from
      org.jboss.test.remoting.stream.StreamingTestClient):</para>
  
      <programlisting>
           String param = "foobar";
           File testFile = new File(fileURL.getFile());
           ...
           Object ret = remotingClient.invoke(fileInput, param);
      </programlisting>
  
      <para>From the server side, will need to implement
      <code>org.jboss.remoting.stream.StreamInvocationHandler</code> instead of
      <code>org.jboss.remoting.ServerInvocationHandler</code> .
      StreamInvocationHandler extends ServerInvocationHandler, with the addition
      of one new method:</para>
  
      <programlisting>public Object handleStream(InputStream stream, Object param)</programlisting>
  
      <para>The stream passed to this method can be called on just as any
      regular local stream. Under the covers, the InputStream passed is really
      proxy to the real input stream that exists in the client's VM. Subsequent
      calls to the passed stream will actually be converted to calls on the real
      stream on the client via this proxy. If the client makes an invocation on
      the server passing an InputStream as the parameter and the server handler
      does not implement StreamInvocationhandler, an exception will be thrown to
      the client caller.</para>
  
      <para>It is VERY IMPORTANT that the StreamInvocationHandler implementation
      close the InputStream when it finished reading, as will close the real
      stream that lives within the client VM.</para>
  
      <section>
        <title>Configuration</title>
  
        <para>By default, the stream server which runs within the client JVM
        uses the following values for its locator uri:</para>
  
        <para>transport - socket</para>
  
        <para>host - tries to first get local host name and if that fails, the
        local ip (if that fails, localhost).</para>
  
        <para>port - 5405</para>
  
        <para>Currently, the only way to override these settings is to set the
        following system properties (either via JVM arguments or via
        <code>System.setProperty()</code> method):</para>
  
        <para>remoting.stream.transport - sets the transport type (rmi, http,
        socket, etc.)</para>
  
        <para>remoting.stream.host - host name or ip address to use</para>
  
        <para>remoting.stream.port - the port to listen on</para>
  
        <para>These properties are important because currently the only way for
        a target server to get the stream data from the stream server (running
        within the client JVM) is to have the server invoker make the invocation
        on a new connection back to the client (see issues below).</para>
      </section>
  
      <section>
        <title>Issues</title>
  
        <para>This is a first pass at the implementation and needs some work in
        regards to optimizations and configuration. In particular, there is a
        remoting server that is started to service requests from the stream
        proxy on the target server for data from the original stream. This
        raises an issue with the current transports, since the client will have
        to accept calls for the original stream on a different socket. This may
        be difficult when control over the client's environment (including
        firewalls) may not be available. A bi-directional transport, called
        multiplex, is being introduced as of 1.4.0 release which will allow
        calls from the server to go over the same socket connection established
        by the client to the server (JBREM-91). This will make communications
        back to client much simpler from this standpoint.</para>
      </section>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap12.xml
  
  Index: chap12.xml
  ===================================================================
    <chapter>
      <title>Compatibility and versioning</title>
  
      <para>As of JBossRemoting 2.0.0 versioning has been added to guarantee
      compatibility between different versions. This is accomplished by changing
      serialization formats for certain classes and by using wire versioing. By
      wire versioning, mean that the version used by a client and server will be
      sent on the wire so that the other side will be able to adjust
      accordingly. This will be automatic for JBossRemoting 2.0.0 and later
      versions. However, since versioning was not introduced until the 2.0.0
      release, if need to have a 1.4.x version of remoting communicate to a
      later version, will need to set a system property on the 2.0.0 version so
      that knows to use the older wire protocol version. The system property to
      set is 'jboss.remoting.pre_2_0_compatible' and should be set to true.
      There are a few minor features that will not be fully compatible between
      1.4.x release and 2.0.0, which are listed in the release notes.</para>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap11.xml
  
  Index: chap11.xml
  ===================================================================
    <chapter>
      <title>Client programming model</title>
  
      <para>The approach taken for the programming model on the client side is
      one based on a session based model. This means that it is expected that
      once a Client is created for a particular target server, it will be used
      exclusively to make calls on that server. This expectation dictates some
      of the behavior of the remoting client.</para>
  
      <para>For example, if create a Client on the client side to make server
      invocations, including adding callback listeners, will have to use that
      same instance of Client to remove the callback listeners. This is because
      the Client creates a unique session id that it passes within the calls to
      the server. This id is used as part of the key for registering callback
      listeners on the server. If create a new Client instance and attempt to
      remove the callback listeners, a new session id will be passed to the
      server invoker, who will not recognize the callback listener to be
      removed.</para>
  
      <para>See test case
      <code>org.jboss.test.remoting.callback.push.MultipleCallbackServersTestCase</code>
      .</para>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap14.xml
  
  Index: chap14.xml
  ===================================================================
    <chapter>
      <title>Known issues</title>
  
      <para>All of the known issues and road map can be found on our bug
      tracking system, Jira, at <!--<link linkend="???">http://jira.jboss.com/jira/secure/BrowseProject.jspa?id=10031</link>-->
      <ulink
      url="http://jira.jboss.com/jira/secure/BrowseProject.jspa?id=10031">
      http://jira.jboss.com/jira/secure/BrowseProject.jspa?id=10031 </ulink>
      (require member plus registration, which is free). If you find more,
      please post them to Jira. If you have questions post them to the JBoss
      Remoting users forum <!--<link linkend="???">http://www.jboss.com/index.html?module=bb&amp;op=viewforum&amp;f=222</link>-->
      (<ulink
      url="http://www.jboss.com/index.html?module=bb&amp;op=viewforum&amp;f=222">
      http://www.jboss.com/index.html?module=bb&amp;op=viewforum&amp;f=222
      </ulink>).</para>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap9.xml
  
  Index: chap9.xml
  ===================================================================
    <chapter>
      <title>Transporters - beaming POJOs</title>
  
      <para>There are many ways in which to expose a remote interface to a java
      object. Some require a complex framework API based on a standard
      specification and some require new technologies like annotations and AOP.
      Each of these have their own benefits. JBoss Remoting transporters provide
      the same behavior via a simple API without the need for any of the newer
      technologies.</para>
  
      <para>When boiled down, transporters take a plain old java object (POJO)
      and expose a remote proxy to it via JBoss Remoting. Dynamic proxies and
      reflection are used to make the typed method calls on that target POJO.
      Since JBoss Remoting is used, can select from a number of different
      network transports (i.e. rmi, http, socket, multiplex, etc.), including
      support for SSL. Even clustering features can be included. See the
      transporter samples in the next chapter for detailed examples of how to
      set up use of a transporter.</para>
    </chapter>
  
  
  1.1      date: 2006/07/30 06:56:36;  author: rsigal;  state: Exp;JBossRemoting/docs/guide/en/chap16.xml
  
  Index: chap16.xml
  ===================================================================
    <chapter>
      <title>Release Notes</title>
  
      <bridgehead>API incompatabilities between JBossRemoting 1.0.2 and
      1.2.X</bridgehead>
  
      <para>The following public API for JBossRemoting was changed in release
      1.2.0 which will make it incompatible with previous versions:</para>
  
      <para>- Removed ClientInvokerAdapter and dependent classes</para>
  
      <para>- Callback related classes moved to new remoting callback
      package</para>
  
      <para>- InvokerCallbackHandler accepts Callback type as parameter instead
      of InvocationRequest</para>
  
      <para></para>
  
      <para>Release Notes - JBoss Remoting - Version 1.4.1 final</para>
  
      <para>** Feature Request </para>
  
      <para>* [JBREM-310] - Ability to turn connection checking off </para>
  
      <para>* [JBREM-325] - move IMarshalledValue from jboss-commons to
      jboss-remoting.jar </para>
  
      <para>** Bug </para>
  
      <para>* [JBREM-313] - client lease does not work if client and server in
      same VM (using local invoker) </para>
  
      <para>* [JBREM-317] - HTTPClientInvoker conect sends gratuitous POST
      </para>
  
      <para>* [JBREM-341] - Client ping interval must be lease than lease period
      </para>
  
      <para>* [JBREM-343] - Exceptions on connection closing </para>
  
      <para>* [JBREM-345] - problem using client address and port </para>
  
      <para>* [JBREM-346] - fix ConcurrentModificationException in cleanup of
      MultiplexServerInvoker </para>
  
      <para>* [JBREM-350] - ConcurrentModificationException in InvokerRegistry
      </para>
  
      <para>* [JBREM-361] - Race condition in invoking on Client </para>
  
      <para>** Task </para>
  
      <para>* [JBREM-2] - sample-bindings.xml does not have entry for remoting
      </para>
  
      <para>* [JBREM-220] - clean up remoting wiki </para>
  
      <para>* [JBREM-316] - Maintain tomcat originated code under the ASF
      license. </para>
  
      <para>* [JBREM-319] - ability to inject socket factory by classname or
      instance in all remoting transports </para>
  
      <para>* [JBREM-323] - client lease config changes </para>
  
      <para>* [JBREM-329] - create global transport config for timeout </para>
  
      <para>* [JBREM-330] - create socket server factory based off of
      configuration properties </para>
  
      <para>* [JBREM-335] - Client.invoke() should pass configuration map to
      InvokerRegistry.createClientInvoker(). </para>
  
      <para>* [JBREM-336] - InvokerRegistry doesn't purge InvokerLocators from
      static Set registeredLocators. </para>
  
      <para>* [JBREM-337] - PortUtil.findFreePort() should return ports only
      between 1024 and 65535. </para>
  
      <para>* [JBREM-342] - Thread usage for timers and lease functionality
      </para>
  
      <para>* [JBREM-354] - ServerInvokerCallbackHandler should make its
      subsystem accessible. </para>
  
      <para>* [JBREM-356] - ServerInvoker should destroy its callback handlers.
      </para>
  
      <para>* [JBREM-359] - MultiplexInvokerConfigTestCase should execute
      MultiplexInvokerConfigTestServer instead of
      MultiplexInvokerTestServer.</para>
  
      <para></para>
  
      <para>Release Notes - JBoss Remoting - Version 1.4.0 final</para>
  
      <para>** Feature Request</para>
  
      <para>* [JBREM-91] - UIL2 type transport (duplex calling of same
      socket)</para>
  
      <para>* [JBREM-117] - clean up callback client after several failures
      delivering callbacks</para>
  
      <para>* [JBREM-138] - HTTP/Servlet invokers require content length to be
      set</para>
  
      <para>* [JBREM-229] - Remove dependency on ThreadLocal for
      SerializationManagers and pluggable serialization</para>
  
      <para>* [JBREM-233] - Server side exception listeners for client
      connections</para>
  
      <para>* [JBREM-257] - Append client stack trace to thrown remote
      exception</para>
  
      <para>* [JBREM-261] - Integration with IMarshalledValue from
      JBossCommons</para>
  
      <para>* [JBREM-278] - remoting detection needs ability to accept detection
      of server invoker running locally</para>
  
      <para>* [JBREM-280] - no way to add path to invoker uri when using complex
      configuration</para>
  
      <para>** Bug</para>
  
      <para>* [JBREM-41] - problem using localhost/127.0.0.1</para>
  
      <para>* [JBREM-115] - http server invoker does not wait to finish
      processing on stop</para>
  
      <para>* [JBREM-223] - Broken Pipe if client don't do any calls before the
      timeout value</para>
  
      <para>* [JBREM-224] - java.net.SocketTimeoutException when socket timeout
      on the keep alive</para>
  
      <para>* [JBREM-231] - bug in invoker locator when there are no params
      (NPE)</para>
  
      <para>* [JBREM-234] - StreamCorruptedException in DTM testcase</para>
  
      <para>* [JBREM-240] - TestUtil does not always give free port for
      server</para>
  
      <para>* [JBREM-243] - socket client invoker sharing pooled
      connections</para>
  
      <para>* [JBREM-250] - InvokerLocator doesn't support URL in IPv6 format
      (ex: socket://3000::117:5400/)</para>
  
      <para>* [JBREM-251] - transporter passes method signature based on
      concrete object and not the parameter type</para>
  
      <para>* [JBREM-256] - NullPointer in
      MarshallerLoaderHandler.java:69</para>
  
      <para>* [JBREM-259] - Unmarshalling of server response is not using
      caller's classloader</para>
  
      <para>* [JBREM-271] - http client invoker needs to explicitly set the
      content type if not provided</para>
  
      <para>* [JBREM-277] - error shutting down coyote invoker when using APR
      protocol</para>
  
      <para>* [JBREM-281] - getting random port for connectors is not
      reliable</para>
  
      <para>* [JBREM-282] - ServletServerInvoker not working with depployed for
      use as ejb invoker</para>
  
      <para>* [JBREM-286] - Socket server does not clean up server threads on
      shutdown</para>
  
      <para>* [JBREM-289] - PortUtil only checking for free ports on
      localhost</para>
  
      <para>** Task</para>
  
      <para>* [JBREM-7] - Add more tests for local invoker</para>
  
      <para>* [JBREM-121] - improve connection failure callback</para>
  
      <para>* [JBREM-126] - add tests for client vs. server address
      bindings</para>
  
      <para>* [JBREM-195] - Performance optimization</para>
  
      <para>* [JBREM-199] - remoting clients required to include
      servlet-api.jar</para>
  
      <para>* [JBREM-207] - clean up build file</para>
  
      <para>* [JBREM-214] - multiplex performance tests getting out of memory
      error</para>
  
      <para>* [JBREM-215] - re-write http transport/handler documentation</para>
  
      <para>* [JBREM-216] - Need to add new samples to example build in
      distro</para>
  
      <para>* [JBREM-217] - create samples documentation</para>
  
      <para>* [JBREM-219] - move remoting site to jboss labs</para>
  
      <para>* [JBREM-226] - Release JBoss Remoting 1.4.0 final</para>
  
      <para>* [JBREM-230] - create interface for marshallers to implement for
      swapping out serialization impl</para>
  
      <para>* [JBREM-235] - add new header to source files</para>
  
      <para>* [JBREM-239] - Update the LGPL headers</para>
  
      <para>* [JBREM-242] - Subclass multiplex invoker from socket
      invoker.</para>
  
      <para>* [JBREM-249] - http invoker (tomcat connector) documentation</para>
  
      <para>* [JBREM-253] - Convert http server invoker implementation to use
      tomcat connector and protocols</para>
  
      <para>* [JBREM-255] - HTTPClientInvoker not setting response code or
      message</para>
  
      <para>* [JBREM-275] - fix package error in examle-service.xml</para>
  
      <para>* [JBREM-276] - transporter does not throw original exception from
      server implementation</para>
  
      <para>* [JBREM-279] - socket server invoker spits out error messages on
      shutdown when is not needed</para>
  
      <para>* [JBREM-287] - need to complete javadoc for all user
      classes/interfaces</para>
  
      <para>* [JBREM-288] - update example-service.xml with new
      configurations</para>
  
      <para>** Reactor Event</para>
  
      <para>* [JBREM-241] - Refactor SocketServerInvoker so that can be
      subclassed by MultiplexServerInvoker</para>
  
      <para></para>
  
      <para>Release Notes - JBoss Remoting - Version 1.4.0 beta</para>
  
      <para></para>
  
      <para>** Feature Request</para>
  
      <para>* [JBREM-28] - Marshaller for non serializable objects</para>
  
      <para>* [JBREM-40] - Compression marshaller/unmarshaller</para>
  
      <para>* [JBREM-120] - config for using hostname in locator url instead of
      ip</para>
  
      <para>* [JBREM-140] - can not set response headers from invocation
      handlers</para>
  
      <para>* [JBREM-148] - support pluggable object serialization
      packages</para>
  
      <para>* [JBREM-175] - Remove Dependencies to Server Classes from
      UnifiedInvoker</para>
  
      <para>* [JBREM-180] - add plugable serialization</para>
  
      <para>* [JBREM-187] - Better HTTP 1.1 stack support for HTTP
      invoker</para>
  
      <para>* [JBREM-201] - Remove dependency from JBossSerialization</para>
  
      <para></para>
  
      <para>** Bug</para>
  
      <para>* [JBREM-127] - RMI Invoker will not bind to specified
      address</para>
  
      <para>* [JBREM-192] - distro contains samples in src and examples
      directory</para>
  
      <para>* [JBREM-193] - HTTPClientInvoker doesn't call getErrorStream() on
      HttpURLConnection when an error response code is returned</para>
  
      <para>* [JBREM-194] - multiplex performance tests hang</para>
  
      <para>* [JBREM-202] - getUnmarshaller always calls Class.forName operation
      for creating Unmarshallers</para>
  
      <para>* [JBREM-203] - rmi server invoker hangs if custom
      unmarshaller</para>
  
      <para>* [JBREM-205] - Spurious java.net.SocketException: Connection reset
      error logging</para>
  
      <para>* [JBREM-210] - InvokerLocator should be insensitive to parameter
      order</para>
  
      <para></para>
  
      <para>** Task</para>
  
      <para>* [JBREM-9] - Fix performance tests</para>
  
      <para>* [JBREM-33] - Add GET support within HTTP server invoker</para>
  
      <para>* [JBREM-145] - convert user guide from MS word doc to
      docbook</para>
  
      <para>* [JBREM-182] - Socket timeout too short (and better error
      message)</para>
  
      <para>* [JBREM-183] - keep alive support for http invoker</para>
  
      <para>* [JBREM-196] - reducde the number of retries for socket client
      invoker</para>
  
      <para>* [JBREM-204] - create complex remoting example using dynamic proxy
      to endpoint</para>
  
      <para>* [JBREM-212] - create transporter implementation</para>
  
      <para>* [JBREM-213] - allow config of ignoring https host validation (ssl)
      via metadata</para>
  
      <para></para>
  
      <para></para>
  
      <para>** Patch</para>
  
      <para>* [JBREM-152] - NullPointerException in SocketServerInvoker.stop()
      at line 185.</para>
  
      <para>* [JBREM-153] - LocalClientInvoker's outlive their useful lifetime,
      causing anomalous behavior</para>
  
      <para></para>
  
      <para>Release Notes - JBoss Remoting - Version 1.2.1 final</para>
  
      <para>** Feature Request</para>
  
      <para>* [JBREM-161] - Upgrade JRunit to Beta 2</para>
  
      <para>** Bug</para>
  
      <para>* [JBREM-147] - Invalid reuse of target location</para>
  
      <para>* [JBREM-163] - NPE in Mutlicast Detector</para>
  
      <para>* [JBREM-164] - HTTP Invoker unable to send large amounts of
      data</para>
  
      <para>* [JBREM-176] - Correct inheritance structure for detectors</para>
  
      <para>* [JBREM-177] - configuration attribute spelled incorrectly in
      ServerInvokerMBean</para>
  
      <para>* [JBREM-178] - SocketServerInvoker hanging on Linux</para>
  
      <para>* [JBREM-179] - socket timeout not being set properly</para>
  
      <para>** Task</para>
  
      <para>* [JBREM-156] - Better exception handling within socket server
      invoker</para>
  
      <para>* [JBREM-158] - Clean up test cases</para>
  
      <para>* [JBREM-162] - add version to the remoting jar</para>
  
      <para>Release Notes - JBoss Remoting - Version 1.2.0 final</para>
  
      <para>** Feature Request</para>
  
      <para>* [JBREM-8] - Ability to stream files via remoting</para>
  
      <para>* [JBREM-22] - Manipulation of the client proxy interceptor
      stack</para>
  
      <para>* [JBREM-24] - Allow for specific network interface bindings</para>
  
      <para>* [JBREM-27] - Support for HTTP/HTTPS proxy</para>
  
      <para>* [JBREM-35] - Servlet Invoker - counterpart to HTTP Invoker (runs
      within web container)</para>
  
      <para>* [JBREM-43] - custom socket factories</para>
  
      <para>* [JBREM-46] - Connection failure callback</para>
  
      <para>* [JBREM-87] - Add handler metadata to detection messages</para>
  
      <para>* [JBREM-93] - Callback handler returning a generic Object</para>
  
      <para>* [JBREM-94] - callback server specific implementation</para>
  
      <para>* [JBREM-109] - Add support for JaasSecurityDomain within SSL
      support</para>
  
      <para>* [JBREM-122] - need log4j.xml in examples</para>
  
      <para>** Bug</para>
  
      <para>* [JBREM-58] - Bug with multiple callback handler registered with
      same server</para>
  
      <para>* [JBREM-64] - Need MarshalFactory to produce new instance per get
      request</para>
  
      <para>* [JBREM-84] - Duplicate Connector shutdown using same server
      invoker</para>
  
      <para>* [JBREM-92] - in-VM push callbacks don't work</para>
  
      <para>* [JBREM-97] - Won't compile under JDK 1.5</para>
  
      <para>* [JBREM-108] - can not set bind address and port for rmi and
      http(s)</para>
  
      <para>* [JBREM-114] - getting callbacks for a callback handler always
      returns null</para>
  
      <para>* [JBREM-125] - can not configure transport, port, or host for the
      stream server</para>
  
      <para>* [JBREM-131] - invoker registry not update if server invoker
      changes locator</para>
  
      <para>* [JBREM-134] - can not remove callback listeners from multiple
      callback servers</para>
  
      <para>* [JBREM-137] - Invalid RemoteClientInvoker reference maintained by
      InvokerRegistry after invoker disconnect()</para>
  
      <para>* [JBREM-141] - bug connecting client invoker when client detects
      that previously used one is disconnected</para>
  
      <para>* [JBREM-143] - NetworkRegistry should not be required for detector
      to run on server side</para>
  
      <para>** Task</para>
  
      <para>* [JBREM-11] - Create seperate JBoss Remoting module in CVS</para>
  
      <para>* [JBREM-20] - break out remoting into two seperate projects</para>
  
      <para>* [JBREM-34] - Need to add configuration properties for HTTP server
      invoker</para>
  
      <para>* [JBREM-39] - start connector on new thread</para>
  
      <para>* [JBREM-55] - Clean up Callback implementation</para>
  
      <para>* [JBREM-57] - Remove use of InvokerRequest in favor of Callback
      object</para>
  
      <para>* [JBREM-62] - update UnifiedInvoker to use remote marshall
      loading</para>
  
      <para>* [JBREM-67] - Add ability to set ThreadPool via
      configuration</para>
  
      <para>* [JBREM-98] - remove isDebugEnabled() within code as is now
      depricated</para>
  
      <para>* [JBREM-101] - Fix serialization versioning between releases of
      remoting</para>
  
      <para>* [JBREM-104] - Release JBossRemoting 1.1.0</para>
  
      <para>* [JBREM-110] - create jboss-remoting-client.jar</para>
  
      <para>* [JBREM-113] - Convert remote tests to use JRunit instead of
      distributed test framework</para>
  
      <para>* [JBREM-123] - update detection samples</para>
  
      <para>* [JBREM-128] - standardize address and port binding configuration
      for all transports</para>
  
      <para>* [JBREM-130] - updated wiki for checkout and build</para>
  
      <para>* [JBREM-132] - write test case for JBREM-131</para>
  
      <para>* [JBREM-133] - Document use of Client (as a session object)</para>
  
      <para>* [JBREM-135] - Remove ClientInvokerAdapter</para>
  
      <para>** Reactor Event</para>
  
      <para>* [JBREM-65] - move callback specific classes into new callback
      package</para>
  
      <para>* [JBREM-111] - pass socket's output/inputstream directly to
      marshaller/unmarshaller</para>
  
      <para>Release Notes - JBoss Remoting - Version 1.0.2 final</para>
  
      <para>** Bug</para>
  
      <para>* [JBREM-36] - performance tests fail for http transports</para>
  
      <para>* [JBREM-66] - Race condition on startup</para>
  
      <para>* [JBREM-82] - Bad warning in Connector.</para>
  
      <para>* [JBREM-88] - HTTP invoker only binds to localhost</para>
  
      <para>* [JBREM-89] - HTTPUnMarshaller finishing read early</para>
  
      <para>* [JBREM-90] - HTTP header values not being picked up on the http
      invoker server</para>
  
      <para>** Task</para>
  
      <para>* [JBREM-70] - Clean up build.xml. Fix .classpath and .project for
      eclipse</para>
  
      <para>* [JBREM-83] - Updated Invocation marshalling to support standard
      payloads</para>
  
      <para>Release Notes - JBoss Remoting - Version 1.0.1 final</para>
  
      <para>** Feature Request</para>
  
      <para>* [JBREM-54] - Need access to HTTP response headers</para>
  
      <para>** Bug</para>
  
      <para>* [JBREM-1] - Thread.currentThread().getContextClassLoader() is
      wrong</para>
  
      <para>* [JBREM-31] - Exception handling in http server invoker</para>
  
      <para>* [JBREM-32] - HTTP Invoker - check for threading issues</para>
  
      <para>* [JBREM-50] - Need ability to set socket timeout on socket client
      invoker</para>
  
      <para>* [JBREM-59] - Pull callback collection is unbounded - possible Out
      of Memory</para>
  
      <para>* [JBREM-60] - Incorrect usage of debug level logging</para>
  
      <para>* [JBREM-61] - Possible RMI exception semantic regression</para>
  
      <para>** Task</para>
  
      <para>* [JBREM-15] - merge UnifiedInvoker from remoting branch</para>
  
      <para>* [JBREM-30] - Better integration for registering invokers with
      MBeanServe</para>
  
      <para>* [JBREM-37] - backport to 4.0 branch before 1.0.1 final
      release</para>
  
      <para>* [JBREM-56] - Add Callback object instead of using
      InvokerRequest</para>
  
      <para>** Reactor Event</para>
  
      <para>* [JBREM-51] - defining marshaller on remoting client</para>
  
      <para></para>
  
      <para>Release Notes - JBoss Remoting - Version 1.0.1 beta</para>
  
      <para></para>
  
      <para>** Bug</para>
  
      <para>* [JBREM-19] - Try to reconnect on connection failure within socket
      invoker</para>
  
      <para>* [JBREM-25] - Deadlock in InvokerRegistry</para>
  
      <para></para>
  
      <para>** Feature Request</para>
  
      <para>* [JBREM-12] - Support for call by value</para>
  
      <para>* [JBREM-26] - Ability to use MBeans as handlers</para>
  
      <para></para>
  
      <para>** Task</para>
  
      <para>* [JBREM-3] - Fix Asyn invokers - currently not operable</para>
  
      <para>* [JBREM-4] - Added test for throwing exception on server
      side</para>
  
      <para>* [JBREM-5] - Socket invokers needs to be fixed</para>
  
      <para>* [JBREM-16] - Finish HTTP Invoker</para>
  
      <para>* [JBREM-17] - Add CannotConnectException to all transports</para>
  
      <para>* [JBREM-18] - Backport remoting from HEAD to 4.0 branch</para>
  
      <para></para>
  
      <para></para>
  
      <para>** Reactor Event</para>
  
      <para>* [JBREM-23] - Refactor Connector so can configure transports</para>
  
      <para>* [JBREM-29] - Over load invoke() method in Client so metadata not
      required</para>
  
      <para></para>
    </chapter>
  
  



More information about the jboss-cvs-commits mailing list