Chapter 5. Configuration

This chapter 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), 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. In the presence of the JBoss Microcontainer, Remoting servers may be configured by the injection of an org.jboss.remoting.ServerConfiguration object specified in an *-beans.xml file.

5.1. General transport configuration

Remoting offers a variety of ways of configuring transports on the server side and client side. This section presents an overview, and the rest of the chapter elaborates the material presented here. For easy reference the configuration parameters discussed throughout the chapter are gathered together at the end of the chapter in section Configuration by properties

5.1.1. Server side configuration

The heart of the server side is the Connector, and it is through the Connector that the server side of a transport is configured. The central goals of configuration on the server side are to establish a server invoker and supply it with a set of invocation handlers. Only one invoker can be declared per Connector. 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.

There are two general approaches to server side configuration: programmatic and declarative. A variety of programmatic techniques work in any environment, including the JBoss Application Server (JBossAS). Moreover, JBossAS adds the option of declarative configuration. In particular, the SARDeployer (see The JBoss 4 Application Server Guide on the labs.jboss.org web site) can read information from a *-service.xml file and use it to configure MBeans such as Connectors.

5.1.1.1. Programmatic configuration.

The simplest way to configure a Connector is to pass an InvokerLocator to a Connector constructor. For example, the code fragment

String locatorURI = "socket://test.somedomain.com:8084";
String params = "/?clientLeasePeriod=10000&timeout=120000";
locatorURI += params;
InvokerLocator locator = new InvokerLocator(locatorURI);
Connector connector = new Connector(locator);
connector.create();
SampleInvocationHandler invocationHandler = new SampleInvocationHandler();
connector.addInvocationHandler("sample", invocationHandler);
connector.start();

creates a server invoker based on the socket transport, directs it to listen for invocations on port 8084 of host test.somedomain.com, and passes two configuration parameters, "clientLeasePeriod" and "timeout". It also supplies the server invoker with an invocation handler.

One limitation of the InvokerLocator is that it can only represent string values. An alternative that overcomes this limitation is to pass some or all of the parameters to the Connector by way of a configuration map. The following code fragment accomplishes all that the previous fragment does, but it passes one parameter by way of the InvokerLocator and passes the other by way of a configuration map. It also passes in a non-string object, a ServerSocketFactory:

String locatorURI = "socket://test.somedomain.com:8084";
String params = "/?clientLeasePeriod=10000";
locatorURI += params;
InvokerLocator locator = new InvokerLocator(locatorURI);
HashMap config = new HashMap();
config.put(ServerInvoker.TIMEOUT, "120000");
config.put(ServerInvoker.SERVER_SOCKET_FACTORY, new MyServerSocketFactory());
Connector connector = new Connector(locator, config);
connector.create();
SampleInvocationHandler invocationHandler = new SampleInvocationHandler();
connector.addInvocationHandler("sample", invocationHandler);
connector.start();

Note that the value of ServerInvoker.TIMEOUT is "timeout", and the value of ServerInvoker.SERVER_SOCKET_FACTORY is "serverSocketFactory". These configuration map keys are discussed throughout the chapter and accumulated in section Configuration by properties. Also, server socket factory configuration is covered in Socket factories and server socket factories.

A third programmatic option is available for those configuration properties which happen to be server invoker MBean properties. In the following fragment, the server invoker is obtained from the Connector and a ServerSocketFactory is passed to it by way of a setter method:

String locatorURI = "socket://test.somedomain.com:8084";
String params = "/?clientLeasePeriod=10000";
locatorURI += params;
InvokerLocator locator = new InvokerLocator(locatorURI);
HashMap config = new HashMap();
config.put(ServerInvoker.TIMEOUT, "120000");
Connector connector = new Connector(locator, config);
connector.create();
ServerInvoker serverInvoker = connector.getServerInvoker();
ServerSocketFactory ssf = new MyServerSocketFactory();
serverInvoker.setServerSocketFactory(ssf);
SampleInvocationHandler invocationHandler = new SampleInvocationHandler();
connector.addInvocationHandler("sample", invocationHandler);
connector.start();

Note. The Connector creates the server invoker during the call to Connector.create(), so this option only works after that method has been called. Also, depending on the parameter and the transport, this option may or may not be effective after the call to Connector.start(), which calls start() on the server invoker.

A fourth option, which exists primarily to support the declarative mode of configuration presented below, is to pass an XML document to the Connector. The following fragment duplicates the behavior of the first and second examples above.

HashMap config = new HashMap();
config.put(ServerInvoker.TIMEOUT, "120000");
Connector connector = new Connector(config);

// Set xml configuration element.
StringBuffer buf = new StringBuffer();
buf.append("<?xml version=\"1.0\"?>\n");
buf.append("<config>");
buf.append("   <invoker transport=\"socket\">");
buf.append("      <attribute name=\"serverBindAddress\">test.somedomain.com</attribute>");
buf.append("      <attribute name=\"serverBindPort\">8084</attribute>");
buf.append("      <attribute name=\"clientLeasePeriod\">10000</attribute>");
buf.append("   </invoker>");
buf.append("   <handlers>");
buf.append("      <handler subsystem=\"mock\">");
buf.append("         org.jboss.remoting.transport.mock.SampleInvocationHandler");
buf.append("      </handler>");
buf.append("   </handlers>");
buf.append("</config>");

ByteArrayInputStream bais = new ByteArrayInputStream(buf.toString().getBytes());
Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bais);
connector.setConfiguration(xml.getDocumentElement());

connector.create();
connector.start();

Note that there is no InvokerLocator in this example. If the Connector gets an InvokerLocator, it ignores the presence of the xml document. Note also that this method only supports the use of string values, so it is necessary to include the fully qualified name of the invocation handler, from which the handler is created by calling the default constructor.

An example of this option in use can be found in org.jboss.test.remoting.configuration.SocketClientConfigurationTestCase.

A fifth option, which exists primarily to support the injection of POJOs in the presence of the JBoss Microcontainer, is to pass an org.jboss.remoting.ServerConfiguration object to the Connector.setServerConfiguration() method. The following fragment duplicates the behavior of the first and second examples above.

HashMap config = new HashMap();
config.put(ServerInvoker.TIMEOUT, "120000");
Connector connector = new Connector(config);

// Create ServerConfiguration object for socket transport
ServerConfiguration serverConfig = new ServerConfiguration("socket");

// Add invokerLocatorParameters (applicable to client and server)
Map locatorConfig = new HashMap();
locatorConfig.put("serverBindAddress", "test.somedomain.com");
locatorConfig.put("serverBindPort", "8084");
serverConfig.setInvokerLocatorParameters(locatorConfig);

// Add serverParameters (applicable to server)
Map serverParameters = new HashMap();
locatorConfig.put("clientLeasePeriod", "10000");
serverConfig.setServerParameters(serverParameters);

// Add invocation handlers
Map handlers = new HashMap();
handlers.put("mock", "org.jboss.remoting.transport.mock.SampleInvocationHandler");
serverConfig.setInvocationHandlers(handlers);

connector.setServerConfiguration(serverConfig);
connector.create();
connector.start();

For more information about ServerConfiguration, see the section "Declarative configuration: POJOs".

5.1.1.2. Declarative configuration: MBeans

One configuration option discussed in Section Programmatic configuration, passing an XML document to the Connector, works in conjunction with the service archive deployer (SARDeployer) inside the JBoss Application Server to allow declarative configuration on the server side. In particular, the SARDeployer reads XMl documents containing MBean descriptors from files whose name has the form "*-service.xml". When it sees a descriptor for a Connector MBean, it passes the descriptor's <config> element to a newly created Connector.

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:

<mbean code="org.jboss.remoting.transport.Connector"
       name="jboss.remoting:service=Connector,transport=Socket"
       display-name="Socket transport Connector">
   <attribute name="InvokerLocator">
      <![CDATA[socket://test.somedomain.com:8084]]>
   </attribute>
   <attribute name="Configuration">
      <config>
         <handlers>
            <handler subsystem="mock">
               org.jboss.remoting.transport.mock.MockServerInvocationHandler
            </handler>
         </handlers>
      </config>
   </attribute>
</mbean>

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.

The other way to configure the Connector and its server invoker in greater detail is to provide an invoker 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, or http). 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 isParam 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:

<mbean code="org.jboss.remoting.transport.Connector"
       name="jboss.remoting:service=Connector,transport=Socket"
       display-name="Socket transport Connector">
   
   <attribute name="Configuration">
      <config>
          
         <invoker transport="socket">
            <attribute name="numAcceptThreads">1</attribute>
            <attribute name="maxPoolSize">303</attribute>
            <attribute name="clientMaxPoolSize" isParam="true">304</attribute>
            <attribute name="socketTimeout">60000</attribute>
            <attribute name="serverBindAddress">192.168.0.82</attribute>
            <attribute name="serverBindPort">6666</attribute>
            <attribute name="clientConnectAddress">216.23.33.2</attribute>
            <attribute name="clientConnectPort">7777</attribute>
            <attribute name="enableTcpNoDelay" isParam="true">false</attribute>
            <attribute name="backlog">200</attribute>
         </invoker>
         
         <handlers>
            <handler subsystem="mock">
               org.jboss.remoting.transport.mock.MockServerInvocationHandler
            </handler>
         </handlers>
      </config>
   </attribute>
   
</mbean>

Also note that ${jboss.bind.address} 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).

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.

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:

<attribute name="InvokerLocator">
   <![CDATA[socket://test.somedomain.com:8084/foo/bar]]>
</attribute>

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:

<attribute name="Configuration">
   <config>
      <invoker transport="socket">
         <attribute name="serverBindAddress">test.somedomain.com</attribute>
         <attribute name="serverBindPort">8084</attribute>
         <attribute name="path">foo/bar</attribute>
      </invoker>
      ...

Note: The value for the 'path' attribute should NOT start or end with a / (slash).

5.1.1.3. Declarative configuration: POJOs

The last configuration option discussed in Section Programmatic configuration, passing an org.jboss.remoting.ServerConfiguration object to the Connector.setServerConfiguration() method, works in conjunction with the JBoss Microcontainer, which supports the injection of POJOs. In particular, the Microcontainer reads XML documents containing POJO descriptors from files whose name has the form "*-beans.xml".

A ServerConfiguration object holds four components:

  • transport (supplied by constructor)

  • invokerLocatorParameters: this is a map of all parameter names and values that will go into the org.jboss.remoting.InvokerLocator

  • serverParameters: this is a map of parameter names and values that will be used by the server but will not go into the InvokerLocator

  • invocationHandlers: this is a map of invocation handlers. The key is the subsystem, or comma separated list of subsystems.

A sample remoting-beans.xml file which duplicates the example in the previous sections is:

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
            
   <bean name="remoting:invocationHandler"
         class="org.jboss.remoting.transport.mock.SampleInvocationHandler"/>
             
   <bean name="remoting:serverConfiguration"
         class="org.jboss.remoting.ServerConfiguration">
      <constructor>
         <parameter>socket</parameter>
      </constructor>
      <property name="invokerLocatorParameters">
         <map keyClass="java.lang.String" valueClass="java.lang.String">
            <entry>
               <key>serverBindAddress</key>
               <value>test.somedomain.com</value>
            </entry>
            <entry>
               <key>serverBindPort</key>
               <value>8084</value>
            </entry>
         </map>
      </property>
      <property name="serverParameters">
         <map keyClass="java.lang.String" valueClass="java.lang.String">
            <entry>
               <key>clientLeasePeriod</key>
               <value>10000</value>
            </entry>
         </map>
      </property>
      <property name="invocationHandlers">
         <map keyClass="java.lang.String" 
              valueClass="org.jboss.remoting.ServerInvocationHandler">
            <entry>
               <key>mock</key>
               <value><inject bean="remoting:invocationHandler"/></value>
            </entry>
         </map>
      </property>
   </bean>
             
   <bean name="remoting:connector" class="org.jboss.remoting.transport.Connector">
      <property name="serverConfiguration">
         <inject bean="remoting:serverConfiguration"/>
      </property>
   </bean>
             
</deployment>

For more information about using the JBoss Microcontainer, see http://www.jboss.org/jbossmc/.

5.1.1.4. Callback client configuration

Remoting supports asynchronous computation and delivery of results through a callback mechanism, as described in Section Callbacks. Callbacks are sent from the server side to the client side on a callback connection which is the reverse of the usual client to server connection. That is, a client invoker on the server side communicates with a server invoker on the client side (in the case of push callbacks - again, see Section Callbacks). When a callback connection is created, all of the configuration information passed to the server side Connector is passed on to the server side callback client invoker. It follows that callback client invokers are configured by way of the server side Connector.

5.1.2. Client side configuration

Invoker configuration on the client side parallels configuration on the server side, with the exception that (1) it operates in a simpler environment (in particular, it does not assume the presence of an MBeanServer) and (2) it does not support a declarative option. However, it does support versions of the first three server side programmatic options, with the Client class playing the central role played by the Connector class on the server side.

Again, the most straightforward form of configuration is to put the configuration parameters on the InvokerLocator. For example, the fragment

String locatorURI = "socket://test.somedomain.com:8084";
String params = "/?clientMaxPoolSize=10&timeout=360000";
locatorURI += params;
InvokerLocator locator = new InvokerLocator(locatorURI);
Client client = new Client(locator);
client.connect();

creates a Client using the socket transport to connect to a server on host test.somedomain.com, listening on port 8084. It also passes in two parameters, "clientMaxPoolSize" and "timeout", that will be used by the client invoker.

It is also possible to use configuration maps on the client side. The following code fragment accomplishes all that the previous fragment does, but it passes one parameter by way of the InvokerLocator and passes the other by way of a configuration map. It also passes in a non-string object, a SocketFactory:

String locatorURI = "socket://test.somedomain.com:8084";
String params = "/?clientMaxPoolSize=10";
locatorURI += params;
InvokerLocator locator = new InvokerLocator(locatorURI);
HashMap config = new HashMap();
config.put(ServerInvoker.TIMEOUT, "360000");
config.put(Remoting.CUSTOM_SOCKET_FACTORY, new MySocketFactory());
Client client = new Client(locator, config);
client.connect();

Note that the value of ServerInvoker.TIMEOUT is "timeout", and the value of Remoting.CUSTOM_SOCKET_FACTORY is "customSocketFactory". These configuration map keys are discussed throughout the chapter and accumulated in section Configuration by properties. Also, socket factory configuration is covered in Socket factories and server socket factories.

Finally, a third programmatic option is available for those configuration properties which happen to be settable client invoker properties. In the following fragment, the client invoker is obtained from the Client and a SocketFactory is passed to it by way of a setter method:

String locatorURI = "socket://test.somedomain.com:8084";
String params = "/?clientMaxPoolSize=10";
locatorURI += params;
InvokerLocator locator = new InvokerLocator(locatorURI);
HashMap config = new HashMap();
config.put(ServerInvoker.TIMEOUT, "360000");
Client client = new Client(locator, config);
client.connect();
SocketFactory sf = new MySocketFactory();
ClientInvoker clientInvoker = client.getInvoker();
clientInvoker.setSocketFactory(sf);
      

Note. The Client creates the client invoker during the call to Client.connect(), so this option only works after that method has been called.

Note. Preference is given to values in the InvokerLocator. For example, in

String locatorURI = "socket://test.somedomain.com:8084/?clientMaxPoolSize=10";
InvokerLocator locator = new InvokerLocator(locatorURI);
HashMap config = new HashMap();
config.put("clientMaxPoolSize", "20");
Client client = new Client(locator, config);
      

the value of the variable clientMaxPoolSize would be set to 10. As of release 2.5.2, that behavior can be reversed by setting the parameter org.jboss.remoting.Remoting.CONFIG_OVERRIDES_LOCATOR (actual value "configOverridesLocator") to true. As always, in determining the value of the variable configOverridesLocator, preference is given to the InvokerLocator. But if the value of "configOverridesLocator" is set to true in the InvokerLocator, or if "configOverridesLocator" is absent from the InvokerLocator but it is set to "true" in the configuration map, then preference will be given to values in the configuration map. For example, in

String locatorURI = "socket://test.somedomain.com:8084/?clientMaxPoolSize=10";
InvokerLocator locator = new InvokerLocator(locatorURI);
HashMap config = new HashMap();
config.put("clientMaxPoolSize", "20");
config.put("configOverridesLocator", "true");
Client client = new Client(locator, config);
      

the value of the variable clientMaxPoolSize would be set to 20.

5.2. Handlers

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 org.jboss.remoting.ServerInvocationHandler 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 Connector::addInvocationHandler(String subsystem, ServerInvocationHandler handler). For example (from org.jboss.remoting.samples.simple.SimpleServer):

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();

To pass the handler by ObjectName, call Connector::addInvocationHandler(String subsystem, ObjectName handlerObjectName) . For example (from org.jboss.test.remoting.handler.mbean.ServerTest):

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);

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).

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:

<handlers>
   <handler subsystem="mock">
      org.jboss.remoting.transport.mock.MockServerInvocationHandler
   </handler>
</handlers>

where MockServerInvocationHandler will be constructed upon startup and registered with the Connector as a handler.

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 mbeanhandler-service.xml under remoting tests for full example):

<handlers>
   <handler subsystem="mock">test:type=handler</handler>
</handlers>

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.

Handler implementations

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.

Stream handler

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.

HTTP handlers

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.

Server invoker for the http transport will add the following to the InvocationRequest's request payload map:

MethodType - 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.

Path - 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.

HttpVersion - 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.

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.

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).

The handlers receiving http invocations can also set the response code, response message, response headers, and content-type. 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:

ResponseCode - Can use the constant value HTTPMetaDataConstants.RESPONSE_CODE, if don't want to use the actual string 'ResponseCode' as they key. IMPORTANT - The value put into map for this key MUST be of type java.lang.Integer.

ResponseCodeMessage - 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.

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.

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 http://www.ietf.org/rfc/rfc2616.txt?number=2616 , section 9.6 for details on response codes and error responses).

HTTP Client

The HttpClientInvoker will now put the return from HttpURLConnection 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:

Object response = remotingClient.invoke((Object) null, metadata); 
String allowValue = (String) ((List) metadata.get("Allow").get(0);

Can reference org.jboss.test.remoting.transport.http.method.HTTPInvokerTestClient for an example of this.

Note that when making a http request using the OPTIONS method type, the return from the Client's invoke() method will ALWAYS be null.

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.

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:

ResponseCode - Can use the constant value HTTPMetaDataConstants.RESPONSE_CODE, if don't want to use the actual string 'ResponseCode' as the key. IMPORTANT - The value returned for this key will be of type java.lang.Integer.

ResponseCodeMessage - 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.

An example of getting the response code can be found within org.jboss.test.remoting.transport.http.method.HTTPInvokerTestClient.

5.3. Discovery (Detectors)

Domains

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:

public void setConfiguration(org.w3c.dom.Element xml)

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:

public org.w3c.dom.Element getConfiguration()

The configuration xml is a MBean attribute of the detector, so can be set or retrieved via JMX.

There are three possible options for setting up the domains that a detector will accept. The first is to not call the setConfiguration() 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).

The second is to call the setConfiguration() method (or add the configuration attribute to the service xml) with the following xml element:

<domains>
   <domain>domain1</domain>
   <domain>domain2</domain>
</domains>

where domain1 and domain2 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.

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:

<domains>
</domains>

This will cause the detector to accept all detections from any domain.

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:

<domains>
   <domain>domain1</domain>
   <domain>domain2</domain>
</domains>
<local/>

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:

<mbean code="org.jboss.remoting.detection.multicast.MulticastDetector"
       name="jboss.remoting:service=Detector,transport=multicast">
   <attribute name="Port">5555</attribute>
   <attribute name="Configuration">
      <domains>
         <domain>roxanne</domain>
         <domain>sparky</domain>
      </domains>
      <local/>
   </attribute>
</mbean>

Global Detector Configuration

The following are configuration attributes for all the remoting detectors.

DefaultTimeDelay - 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.

HeartbeatTimeDelay - amount of time to wait between sending (and sometimes receiving) detection messages. The default is 1000 milliseconds.

JNDIDetector

Port - port to which detector will connect for the JNDI server.

Host - host to which the detector will connect for the JNDI server.

ContextFactory - context factory string used when connecting to the JNDI server. The default is org.jnp.interfaces.NamingContextFactory .

URLPackage - url package string to use when connecting to the JNDI server. The default is org.jboss.naming:org.jnp.interfaces .

CleanDetectionNumber - 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.

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:

<mbean code="org.jboss.remoting.detection.jndi.JNDIDetector"
       name="jboss.remoting:service=Detector,transport=jndi">
   <attribute name="Host">localhost</attribute>
   <attribute name="Port">5555</attribute>
</mbean>

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.

MulticastDetector

DefaultIP - 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.

Port - The port that is used to broadcast detection messages on via multicast. Default is 2410.

BindAddress - The address to bind to for the network interface.

Address - The IP of the multicast group that the detector will join. The default will be that of the DefaultIP if not explicitly set.

BufferSize - The size of the buffer used by the MulticastSocket. The default is 10000.

If any of these are set programmatically, need to be done before the detector is started (otherwise will use default values).

5.4. Transports (Invokers)

This section covers configuration issues for each of the transports, beginning with material that applies to all transports. The material in a later section in this chapter, Socket factories and server socket factories, also applies to all transports.

5.4.1. Features introduced in Remoting version 2.4

A number of transport independent features are introduced in Remoting version 2.4.

5.4.1.1. Binding to 0.0.0.0

Before version 2.4, a Remoting server could bind to only one specific IP address. In particular, the address 0.0.0.0 was translated to the host returned by java.net.InetAddress.getLocalHost() (or its equivalent IP address). As of version 2.4 [and later releases in the 2.2 series], a server started with the address 0.0.0.0 binds to all available interfaces.

Note. If 0.0.0.0 appears in the InvokerLocator, it needs to be translated to an address that is usable on the client side. If the system property InvokerLocator.BIND_BY_HOST (actual value "remoting.bind_by_host") is set to "true", the InvokerLocator host will be transformed to the value returned by InetAddress.getLocalHost().getHostName(). Otherwise, it will be transformed to the value returned by InetAddress.getLocalHost().getHostAddress().

5.4.1.2. Multihome servers

As of release 2.4, besides binding to all available interfaces, it is also possible to configure a server to bind to a subset of the interfaces available on a given host. Suppose, for example, that a host machine has NICs configured with addresses 10.32.4.2, 192.168.4.2, and 192.168.8.2, and suppose that 192.168.8.2 is on a LAN from which access is meant to be denied. It is now possible to create a single server that binds to 10.32.4.2 and 192.168.4.2.

It would be convenient to be able to create an InvokerLocator that looks something like:

socket://10.32.4.2&192.168.4.2:6500

but, unfortunately, that violates the URI syntax. Instead, a special placeholder, "multihome", is used in the host position, and the actual host addresses are given in the query component, e.g.,

socket://multihome/?homes=10.32.4.2:6500!192.168.4.2:6500

An abbreviated syntax allows factoring out the bind port:

socket://multihome:6500/?homes=10.32.4.2!192.168.4.2

The value in the port position is treated as a default value which can be overriden in the "homes" parameter:

socket://multihome:6500/?homes=10.32.4.2!192.168.4.2:6501

binds to 10.32.4.2:6500 and 192.168.4.2:6501.

In the presence of a NAT router, it may be necessary for the client to connect to addresses different than the bind addresses, and a set of connect addresses may be specified with a "connecthomes" parameter:

socket://multihome/?homes=10.32.4.2:6500!192.168.4.2:6501
       &connecthomes=10.32.42.2:7500!192.168.42.2:7501

specifies a server that binds to 10.32.4.2:6500 and 192.168.4.2:6501, as before, but now a client connects to it using the addresses 10.32.42.2:7500 and 192.168.42.2:7501.

Multihome servers may be configured, also, in *-service.xml MBean files and *-beans.xml POJO files. The following MBean definition is equivalent to the preceding locator:

<mbean code="org.jboss.remoting.transport.Connector"
       name="jboss.remoting:service=Connector,transport=Socket"
       display-name="Socket transport Connector">
    
   <attribute name="Configuration">
      <config>
         <invoker transport="socket">
            
            <attribute name="homes">
               <home>10.32.4.2:6500</home>
               <home>192.168.4.2:6501</home>
            </attribute>
            <attribute name="connecthomes">
               <connecthome>10.32.42.2:7500</connecthome>
               <connecthome>192.168.42.2:7501</connecthome>
            </attribute>
            
         </invoker>
         <handlers>
            ...
         </handlers>
      </config>
   </attribute>
</mbean>

The "serverBindPort" and "clientConnectPort" attributes may be used to give default values for bind ports and connect ports, respectively.

The same server may be configured with the org.jboss.remoting.ServerInvocation object as well. For example,

Connector connector = new Connector();
         
// Create ServerConfiguration object for socket transport
ServerConfiguration serverConfig = new ServerConfiguration("socket");
            
// Add invokerLocatorParameters (applicable to client and server)
Map locatorConfig = new HashMap();

locatorConfig.put("homes", "10.32.4.2:6500!192.168.4.2:6501");
locatorConfig.put("connecthomes", "10.32.42.2:7500!192.168.42.2:7501");

serverConfig.setInvokerLocatorParameters(locatorConfig);
                   
// Add invocation handlers
...
             
connector.setServerConfiguration(serverConfig);
connector.create();
connector.start();

is equivalent to the preceding MBean definition.

Note. The Strings "homes" and "connecthomes" are available as constants in the InvokerLocator class: InvokerLocator.HOMES_KEY and InvokerLocator.CONNECT_HOMES_KEY.

5.4.1.3. Socket creation listeners

Sometimes it is useful to be able to grab a socket right after it has been created to either apply some additional configuration or retrieve some information. It is possible to configure Remoting with instantions of the interface org.jboss.remoting.socketfactory.SocketCreationListener

public interface SocketCreationListener
{
   /**
    * Called when a socket has been created.
    * 
    * @param socket socket that has been created
    * @param source SocketFactory or ServerSocket that created the socket
    * @throws IOException
    */
   void socketCreated(Socket socket, Object source) throws IOException;
}

Socket creation listeners can be configured through the use of the keys org.jboss.remoting.Remoting.SOCKET_CREATION_CLIENT_LISTENER (actual value "socketCreationClientListener") and org.jboss.remoting.Remoting.SOCKET_CREATION_SERVER_LISTENER (actual value "socketCreationServerListener"), which install listeners for javax.net.SocketFactorys and java.net.ServerSockets, respectively. The value associated with these keys may be (1) an object that implements SocketCreationListener or (2) a string that names a class that implements SocketCreationListener. In the latter case, the default constructor will be used to create an object of the designated class.

5.4.1.4. Making client IP address available to application

All of the transports (bisocket, sslbisocket, http, https, rmi, sslrmi, servlet, sslservlet, socket, and sslsocket) capture the IP address of the client side of a TCP connection from client to server and make it available to application code on both the client side and server side. On the client side, the method org.jboss.remoting.Client.getAddressSeenByServer(), with signature

public InetAddress getAddressSeenByServer() throws Throwable

returns the IP address of the client as seen by the server. On the server side, the same IP address is placed in the request payload map held by the org.jboss.remoting.InvocationRequest. It may be retrieved by the org.jboss.remoting.ServerInvocationHandler as follows:

public Object invoke(InvocationRequest invocation throws Throwable
{
   ...
   InetAddress address = invocation.getRequestPayload().get(Remoting.CLIENT_ADDRESS);
   ...
}

5.4.1.5. Support for IPv6 addresses

org.jboss.remoting.InvokerLocator will now accept IPv6 IP addresses. For example,

socket://[::1]:3333/?timeout=10000
socket://[::]:4444/?timeout=10000
socket://[::ffff:127.0.0.1]:5555/?timeout=10000
socket://[fe80::205:9aff:fe3c:7800%7]:6666/?timeout=10000
socket://multihome/?homes=[fe80::205:9aff:fe3c:7800%7]:7777![fe80::214:22ff:feef:68bb%4]:8888

5.4.1.6. Delayed destruction of client invokers

Multiple clients may share a single client invoker. For example, in the code

InvokerLocator locator = new InvokerLocator("socket://127.0.0.1:5555");
Client client1 = new Client(locator);
Client client2 = new Client(locator);

client1 and client2 will both communicate with the server through a single org.jboss.remoting.transport.socket.MicroSocketClientInvoker. The number of Clients using a single client invoker is tracked, and the invoker is destroyed when the count goes to zero. It may be useful to delay the destruction of the invoker when it is known that another Client will want to use it in the near future. The delayed destruction of a client invoker may be achieved through the use of the key Client.INVOKER_DESTRUCTION_DELAY (actual value "invokerDestructionDelay"). For example,

InvokerLocator locator =
        new InvokerLocator("socket://127.0.0.1:5555/?invokerDestructionDelay=5000");
Client client = new Client(locator);
client.connect();
...
client.disconnect();

will cause client to delay the destruction of its client invoker (assuming client is the only user), by 5000 milliseconds. Of course, "invokerDestructionDelay" may be passed to the Client by way of a configuration map, as well.

5.4.2. Server Invokers

The following configuration properties are common to all the current server invokers.

serverBindAddress - 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 InetAddress.getLocalHost() .

serverBindPort - The port to listen for requests on. A value of 0 or less indicates that a free anonymous port should be chosen.

maxNumThreadsOneway - 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 MaxNumberOfOnewayThreads property.

onewayThreadPool - specifies either the fully qualified class name for a class that implements the org.jboss.util.threadpool.ThreadPool interface or the JMX ObjectName for an MBean that implements the org.jboss.util.threadpool.ThreadPool interface. This will replace the default org.jboss.util.threadpool.BasicThreadPool used by the server invoker.

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 OnewayThreadPool property programmatically.

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.

5.4.3. Configurations affecting the invoker client

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.

clientConnectPort - 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.

clientConnectAddress - 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.

If no client connect address or server bind address specified, will use the local host's address (via InetAddress.getLocalHost().getHostAddress() ).

Note The role played by "clientConnectAddress" and "clientConnectPort" deserves some further elaboration. When a server is set up, it is either given an InvokerLocator explicitly, or it is given enough information in an MBean XML file or a ServerConfiguration POJO from which to construct an InvokerLocator, and a client uses the host field and port field in the InvokerLocator to determine how to connect to the server. It follows that if an explicit InvokerLocator is passed to the server, then the host and port fields are either given explicitly or are generated, so there is no need for "clientConnectAddress" or "clientConnectPort" fields. However, if the server is configured by way of an MBean XML file or a ServerConfiguration, and no explicit InvokerLocator is specified, then the "clientConnectAddress" and "clientConnectPort" parameters can be used to specify the host and port fields in the InvokerLocator. If they are omitted, then the host and port fields will be derived from the values of the "serverBindAddress" and "serverBindPort" parameters (or generated, if those fields are omitted). Therefore, there is a role for the "clientConnectAddress" and "clientConnectPort" parameters only if clients are meant to connect to a host and port different than the bind host and bind port. Such a situation might occur in the presence of a translating firewall between the client and the server.

5.4.4. How the server bind address and port is determined

If the serverBindAddress property is set, the server invoker will bind to that address. Otherwise, it will, with one exception, use the address in the InvokerLocator (if there is one). The exception is the case in which the clientConnectAddress property is set, which indicates that the adddess in the InvokerLocator is not the real address of the server's host. In that case, and in the case that there is no address in the InvokerLocator, the server will bind to the address of the local host, as determined by the call

InetAddress.getLocalHost().getHostAddress();

In other words, the logic is

if (serverBindAddress is set)
   use it
else if (the host is present in the InvokerLocator and clientConnectAddress is not set)
   use host from InvokerLocator
else
   use local host address

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.

Note. In the case that a bind port isn't specified, the utility class org.jboss.remoting.transport.PortUtil is used to supply an available port. By default, it will look for a port in the range 1024 to 65535, inclusively. As of release 2.5.2, PortUtil can be configured to search a smaller range by setting the values PortUtil.MIN_PORT (actual value "minPort") and / or PortUtil.MAX_PORT (actual value "maxPort") in the InvokerLocator, a configuration map, an MBean XML file, or a ServerConfiguration object. The range is static; that is, whenever "minPort" or "maxPort" are set, they affect all subsequent calls in the JVM. Note that PortUtil will apply a new "minPort" value only if it is greater than the current value, and it will apply a new "maxPort" value only if it is less than the current value. And it will never apply a new value when the result would be such that the value of "maxPort" would be less than the value of "minPort".

5.4.5. Socket transport

The Socket transport is one of the more complicated invokers mainly because allows the highest degree of configuration. To better understand how changes to configuration properties for the Socket invoker (both client and server) will impact performance and scalability, will discuss the implementation and how it works in detail.

5.4.5.1. How the Socket transport works

Server

When the socket server invoker is started, it will create one, and only one, instance of java.net.ServerSocket for each configured bind address. Typically there would exactly one ServerSocket, but there would be more than one for a multihome server with multiple bind addresses. Upon being started, it will also create and start a number of threads to be used for accepting incoming requests from the ServerSocket. These threads are called the accept threads and the number of them created is controlled by the "numAcceptThreads" property. If "numAcceptThreads" is set to "n" (it defaults to 1), there will be "n" accept threads per ServerSocket. When these accept threads are started, they will call accept() on the ServerSocket and block until the ServerSocket receives a request from a client, where it will return a Socket back to the accept thread who called the accept() method. As soon as this happens, the accept thread will try to pass off the Socket to another thread for processing.

The threads that actually process the incoming request, referred to as server threads (org.jboss.remoting.transport.socket.ServerThread), are stored in a pool. The accept thread will try to retrieve the first available server thread from the pool and hand off the Socket for processing. If the pool does not contain any available server threads and the max pool size has not been reached, a new server thread will be created for processing. Otherwise, if the max pool size has been reached, the accept thread will wait for one to become available (will wait until socket timeout has been reached). The size of the server thread pool is defined by the 'maxPoolSize' property. As soon as the accept thread has been able to hand off the Socket to a server thread for processing, it will loop back to ServerSocket and call accept() on it again. This will continue until the socket server invoker is stopped.

The server thread processing the request will be the thread of execution through the unmarshalling of the data, calling on the server invocation handler, and marshalling of response back to the client. After the response has been sent, the server thread will then hold the socket connection and wait for another request to come from this client. It will wait until the socket is closed by the client, a socket timeout occurs, or receives another request from the client in which to process. When the client socket connection session is closed, meaning timeout or client closed socket connection, then the thread will return itself to the pool.

If all the server threads from the pool are in use, meaning have a client connection established, and the pool has reached its maximum value, the accept threads (no matter how many there are) will have to wait until one of the server threads is available for processing. This why having a large number of accept threads does not provide any real benefit. If all the accept threads are blocked waiting for server thread, new client requests will then be queued until it can be accepted. The number of requests that can be queued is controlled by the "backlog" property and can be useful in managing sudden bursts in requests.

If take an example with a socket server invoker that has max pool set to 300, accept threads is 2, and backlog is 200, will be able to make 502 concurrent client calls. The 503rd client request will get an exception immediately. However, this does not mean all 502 requests will be guaranteed to be processed, only the first 300 (as they have server threads available to do the processing). If 202 of the server threads finish processing their requests from their initial client connections and the connection is released before the timeout for the other 202 that are waiting (200 for backlog and 2 for accept thread), then they will be processed (of course this is a request by request determination).

As of JBossRemoting 2.2.0 release, can also add configuration for cleaning up idle server threads using the 'idleTimeout' configuration property. Setting this property to a value of greater than zero will activate idle timeout checking, which is disabled by default. When enabled, the idle timeout checker will periodically iterate through the server threads that are active and inactive and if have not processed a request within the designated idle timeout period, the server thread will be shutdown and removed from corresponding pool. Active server threads are ones that have a socket connection associated with it and are in a blocked read waiting for data from the client. Inactive server threads are ones that have finished processing on a particular socket connection and have been returned to the thread pool for later reuse.

Note. A server thread that is engaged in a long invocation when the idle timeout checker is activated can be removed from its thread pool and marked for later destruction once the invocation is complete. The "idleTimeout" value should be configured accordingly.

Note. As of Remoting version 2.4, some changes have been made to ServerThread.

  1. Once a server thread has completed an invocation, it will try to read another invocation instead of returning to the thread pool. It follows that the fact that a server thread is not in the thread pool does not necessarily indicate that it is busy: it might just be blocked in a InputStream.read(). Therefore, when an accept thread needs a server thread and the thread pool is empty, it will try to appropriate server threads which are not in the thread pool. While a server thread is in the middle of processing an invocation, it cannot be interrupted, but if it is blocked waiting for the next invocation, it is available to be interrupted. However, when the server is busy, it is conceivable for an accept thread to grab a server thread and before the server thread gets a chance to read an invocation, it gets interrupted again by the accept thread. To prevent server threads from bouncing around like that, the parameter ServerThread.EVICTABILITY_TIMEOUT (actual value "evictabilityTimeout) has been introduced. If less than that period has elapsed since the server thread has started waiting for the next invocation, it will not allow itself to be pre-empted.

  2. Prior to version 2.4, if a server thread experienced a java.net.SocketTimeoutException, it would return itself to the thread pool and could not be reused until a new socket connection was created for it to use. In principle, it would be more efficient for the server thread simply to try again to read the next invocation. Unfortunately, java.io.ObjectInputStream ceases to function once it experiences a SocketTimeoutException. The good news is that org.jboss.serial.io.JBossObjectInputStream, made available by the JBossSerialization project, does not suffer from that problem. Therefore, when it experiences a SocketTimeoutException, a server thread will check whether it is using a JBossObjectInputStream or not and act accordingly. Just to allow for the possibility that an application is using yet another version of ObjectInputStream, the parameter ServerThread.CONTINUE_AFTER_TIMEOUT (actual value "continueAfterTimeout") allows the behavior following a SocketTimeoutException to be configured explicitly.

Note. When a ServerThread receives an invocation, it enters a synchronized method to prevent itself from being interrupted while it is processing the invocation. When SocketServerInvoker.stop() is called, it calls the synchronized method ServerThread.shutdown() for each ServerThread, which insures that the server does not shut down until all currently invocations are complete.

However, if it happens that an invocation gets hung up for some reason, the server would be prevented from shutting down. For example, the ServerInvocationHandler could have a bug, or an attempt to write to a disconnected network could get hung up. As of Release 2.5.2, there is an option to shut down a SocketServerInvoker immediately without waiting for current invocations to complete. This option can be enabled by setting the property "immediateShutdown" to "true".

Client

When the socket client invoker makes its first invocation, it will check to see if there is an available socket connection in its pool. Since is the first invocation, there will not be and will create a new socket connection and use it for making the invocation. Then when finished making invocation, will return the still active socket connection to the pool. As more client invocations are made, is possible for the number of socket connections to reach the maximum allowed (which is controlled by 'clientMaxPoolSize' property). At this point, when the next client invocation is made, it will wait up to some configured number of milliseconds, at which point it will throw an org.jboss.remoting.CannotConnectException. The number of milliseconds is given by the parameter MicroSocketClientInvoker.CONNECTION_WAIT (actual value "connectionWait"), with a default of 30000 milliseconds. Note that if more than one call retry is configured (see next paragraph), the CannotConnectException will be swallowed.

Once the socket client invoker get an available socket connection from the pool, are not out of the woods yet. For example, a network problem could cause a java.net.SocketException. There is also a possibility that the socket connection, while still appearing to be valid, has "gone stale" while sitting in the pool. For example, a ServerThread on the other side of the connection could time out and close its socket. If the attempt to complete an invocation fails, then MicroSocketClientInvoker will make a number of attempts, according to the parameter "numberOfCallRetries", with a default value of 3. Once the configured number of retries has been exhausted, an org.jboss.remoting.InvocationFailureException will be thrown.

5.4.5.2. Configuration

The following configuration properties can be set at any time. If the SocketServerInvoker has already started, they will not take effect until it is stopped and restarted.

timeout - 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).

backlog - 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.

numAcceptThreads - The number of threads that exist for accepting client connections. The default is 1.

maxPoolSize - The number of server threads for processing client. The default is 300.

serverSocketClass - specifies the fully qualified class name for the custom SocketWrapper implementation to use on the server.

socket.check_connection - indicates if the invoker should try to check the connection before re-using it by sending a single byte ping from the client to the server and then back from the server. This config needs to be set on both client and server to work. This if false by default.

idleTimeout - indicates the number of seconds a pooled server thread can be idle (meaning time since last invocations request processed) before it should be cleaned up and removed from the thread pool. The value for this property must be greater than zero in order to enable idle timeouts on pooled server threads (otherwise they will not be checked). Setting to value less than zero will disable idle timeout checks on pooled server threads, in the case was previously enabled. The default value for this property is -1.

evictabilityTimeout - indicates the number of milliseconds during which a server thread waiting for the next invocation will not be interruptible.

continueAfterTimeout - indicates what a server thread should do after experiencing a java.net.SocketTimeoutException. If set to "true", or if JBossSerialization is being used, the server thread will continue to wait for an invocation; otherwise, it will return itself to the thread pool.

immediateShutdown - indicates, when set to "true", that, when Connector.stop() is called and it calls SocketServerInvoker.stop(), all ServerThreads are shut down immediately, even if they are processing an invocation.

acceptThreadPriorityIncrement - can be used to increment the priority of the accept thread, which manages the ServerSocket. The value is added to java.lang.Thread.NORM_PRIORITY, and the resulting value must be no more than java.lang.Thread.MAX_PRIORITY. This parameter might be useful on a heavily loaded machine if the accept thread is getting starved.

Configurations affecting the Socket invoker client

There are some configurations which will impact the socket invoker client. They can be set in the InvokerLocator, an MBean or bean XML configuration file, or can be passed in the configuration map when the Client is created.

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.

timeout - The socket timeout value passed to the Socket.setSoTimeout() method. The default on the client side is 1800000 (or 30 minutes).

clientMaxPoolSize - the client side maximum number of active socket connections. This basically equates to the maximum number of concurrent client calls that can be made from the socket client invoker. The default is 50.

numberOfCallRetries - the number of times a failed invocation will be retried. For example, it is possible that the server side of a socket connection could time out, leaving the connection invalid. In that case, the socket will be discarded and another, possibly new, socket will be used. Note that after numberOfCallRetries - 2 attempts, the connection pool will be flushed on the assumption that all connections are invalid. After numberOfCallRetries attempts, an InvocationFailureException, whose cause is the original exception, will be thrown. The default value is 3. See also the "generalizeSocketException" parameter, below

generalizeSocketException - If set to false, a failed invocation will be retried in the case of SocketExceptions. If set to true, a failed invocation will be retried in the case of SocketExceptions and also any IOException whose message matches the regular expression ^.*(?:connection.*reset|connection.*closed|broken.*pipe).*$. See also the "numberOfCallRetries" parameter, above. The default value is false.

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.

socket.check_connection - indicates if the invoker should try to check the connection before re-using it by sending a single byte ping from the client to the server and then back from the server. This config needs to be set on both client and server to work. This if false by default.

useOnewayConnectionTimeout - indicates if, during a client side oneway invocation, MicroSocketClientInvoker should wait for a version byte from the server, which prevents the anomalous behavior described in JBREM-706 "In socket transport, prevent client side oneway invocations from artificially reducing concurrency". The default value is "true".

idempotent - if set to "false", indicates that an invocation should not be retried, even if the parameter "numberOfCallRetries" is greater than 1, after the invocation has been written to the socket. The default value is "true".

Note. As of Remoting version 2.4, the following socket parameters, in addition to SO_TIMEOUT and TCP_NODELAY, can be configured on the client client side: SO_KEEPALIVE, OOBINLINE, SO_RCVBUF, SO_REUSEADDR, SO_SNDBUF, SO_LINGER, and "traffic class". They are configured by the following parameter keys:

keepAlive - sets socket parameter SO_KEEPALIVE

oOBInline - sets socket parameter OOBINLINE

receiveBufferSize - sets socket parameter SO_RCVBUF

reuseAddress - sets socket parameter SO_REUSEADDR

sendBufferSize - sets socket parameter SO_SNDBUF

soLinger - sets socket parameter SO_LINGER

soLingerDuration - when socket parameter SO_LINGER is set to "true", sets linger duration

trafficClass - sets socket traffic class

For more information about these parameters, see the java.net.Socket javadoc ( http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html) or a book about the TCP protocol.

5.4.6. SSL Socket transport

Supports all the configuration attributes as the Socket Invoker. The main difference is that the SSL Socket Invoker uses an SSLServerSocket by default, created by an SSLServerSocketFactory. See section Socket factories and server socket factories for more information.

5.4.7. RMI transport

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.

Note. The RMI server invoker creates a socket factory and passes it to a client invoker along with the RMI stub, so the socket factory must be serializable. Therefore, if a socket factory is passed in to the server invoker by one of the methods discussed in section Socket factories and server socket factories, then the user is responsible for supplying a serializable socket factory.

Note. Prior to Remoting version 2.4, the RMI transport performed marshalling and unmarshalling only in the client to server direction. As of version 2.4, it will use a marshaller and unmarshaller in the server to client direction, as well. Moreover, marshalling and unmarshalling in the client to server direction has been made more efficient, which results in the transmission of a different sequence of bytes. In case a version 2.4 release of Remoting needs to communicate with an older version, it is possible to request the original marshalling behavior by setting the parameter org.jboss.remoting.transport.rmi.RMIServerInvoker.RMI_ONEWAY_MARSHALLING (actual value "rmiOnewayMarshalling") to "true".

5.4.8. SSL RMI Invoker

This is essentially identical to the RMI invoker, except that it creates SSL socket and server socket factories by default.

Note. The SSL RMI server invoker creates a socket factory and passes it to a client invoker along with the RMI stub, so the socket factory must be serializable. If the SSL RMI server invoker is allowed to create an SSLSocketFactory from SSL parameters, as discussed in section Socket factories and server socket factories, it will take care to create a serializable socket factory. However, if a socket factory is passed in to the server invoker (also discussed in section Socket factories and server socket factories), then the user is responsible for supplying a serializable socket factory. See sslrmi below for more information.

5.4.9. HTTP transport

The HTTP server invoker implementation is based on the Coyote HTTP/1.1 Connector Tomcat component, which is supplied by the JBossWeb implementation in jbossweb.jar.

Note. Prior to release 2.5.0.GA, Remoting also was compatible with the Apache implementation of Tomcat, which is no longer the case. Since JBossWeb requires jdk 1.5 or above, it follows that the HTTP transport in Remoting 2.5.0.GA and above has the same requirement.

The coyote Connector supports GET, POST, HEAD, OPTIONS, and HEAD method types and keep-alive, and 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 http://tomcat.apache.org/tomcat-6.0-doc/config/http.html. The Tomcat parameters passed into the http server invoker are passed on to Tomcat. For example, the Tomcat attribute "maxThreads" can be used to set the maximum number of threads to be used to accept incoming http requests. The only exceptions are the Remoting attributes "serverBindAddress" and "serverBindPort", which should be used instead of the Tomcat attributes "address" and "port".

Note. An executor, subclassed from java.util.concurrent.Executor, can be configured and injected into the coyote Connector. As of release 2.5.4.SP2, Remoting can configure and inject an instance of org.apache.catalina.core.StandardThreadExecutor, using attributes passed to Remoting using the key "executor" and a string of the form "attribute0=value0,...,attributeN=valueN". For example, a *-service.xml configuration file could contain

<attribute name="executor">minSpareThreads=20,maxThreads=100</attribute>

Remoting will parse the comma separated list, ignoring white space, create and configure a StandardThreadExecutor, and inject it into the coyote Connector. Note that if an executor is injected, the other threadpool related attributes such as "maxThreads", which would otherwise be applied to a threadpool created by the coyote Connector, are ignored. The configurable attributes of the StandardThreadExecutor are described in http://tomcat.apache.org/tomcat-6.0-doc/config/executor.html.

A feature introduced in Remoting version 2.4 is the ability to configure HTTPClientInvoker to make multiple attempts to complete an invocation. The feature is invoked by setting parameter HTTPClientInvoker.NUMBER_OF_CALL_ATTEMPTS (actual value "numberOfCallAttempts") to the desired integer. The parameter can be configured in the InvokerLocator or in the configuration map passed to the Client. The default value is 1.

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 org.apache.coyote.http11.Http11Protocol. However, it is possible to switch to use the org.apache.coyote.http11.Http11AprProtocol protocol, which is based on the Apache Portable Runtime (see http://tomcat.apache.org/tomcat-6.0-doc/apr.html for more details). To use the APR implementation, simply put the tcnative-1.dll (or tcnative-1.so) on the system path so it can be loaded. The JBossWeb native libraries, which include tcnative-1.dll/tcnative-1.so, may be downloaded from http://www.jboss.org/jbossweb/.

Client request headers

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:

sessionId - 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 guarantee that the sessionId supplied to the invocation handler will always indicate the request from the same client.

subsystem - 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).

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.

Response headers

If a request on the HTTP transport is made with the org.jboss.remoting.Client method

public Object invoke(Object param, Map metadata) throws Throwable

then org.jboss.remoting.transport.http.HTTPClientInvoker returns the HTTP response headers in a map in metadata, associated with the key org.jboss.remoting.transport.http.HTTPMetadataConstants.RESPONSE_HEADERS (actual value "ResponseHeaders"). For example, the response header "Date" can be retrieved as follows:

Object payload = ... ;
HashMap metadata = new HashMap();
client.invoke(payload, metadata);
Map responseHeaders = (Map) metadata.get(HTTPMetadataConstants.RESPONSE_HEADERS);
String date = (String) responseHeaders.get("Date");

CR/LF in HTTP transport

By default, the HTTP transport uses org.jboss.remoting.marshal.http.HTTPMarshaller and org.jboss.remoting.marshal.http.HTTPUnMarshaller to marshal and unmarshal invocations and responses. Prior to Remoting version 2.4, HTTPUnMarshaller stripped CR/LF characters. As of version 2.4, the default behavior remains the same, but it is possible to change the behavior, on the client and the server, by setting the parameter HTTPUnMarshaller.PRESERVE_LINES (actual value "preserveLines") to "true".

5.4.10. HTTPS transport

Supports all the configuration attributes as the HTTP Invoker, plus the following:

SSLImplementation - Sets the Tomcat SSLImplementation to use. This should always be org.jboss.remoting.transport.coyote.ssl.RemotingSSLImplementation.

The main difference with the HTTP invoker is that the HTTPS Invoker uses an SSLServerSocket by default, created by an SSLServerSocketFactory. See section Socket factories and server socket factories for more information.

5.4.10.1. HTTP(S) Client Invoker - proxy and basic authentication

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).

proxy

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: http.proxyHost and http.proxyPort.

An example would be:

Map metadata = new HashMap();
...

// proxy info
metadata.put("http.proxyHost", "ginger");
metadata.put("http.proxyPort", "80");

...

response = client.invoke(payload, metadata);

The http.proxyPort property is not required and if not present, will use default of 80. Note: setting the proxy config in this way can ONLY be done if using JDK 1.5 or higher.

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 System.setProperty() method call or via JVM arguments): http.proxyHost, http.proxyPort, and proxySet.

An example would be setting the following JVM arguments:

-Dhttp.proxyHost=ginger -Dhttp.proxyPort=80 -DproxySet=true

Note: when testing with Apache 2.0.48 (mod_proxy and mod_proxy_http), all of the properties above were required.

Setting the system properties can be used for JDK 1.4 and higher. However, will not be able to specify proxy server per remoting client if use system properties..

Basic authentication - direct and via proxy

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: http.proxy.username and http.proxy.password.

For non-proxied invocations, the following properties need to be set: http.basic.username and http.basic.password.

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.

Note: Only the proxy authentication has been tested using Apache 2.0.48; non-proxied authentication has not.

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 (http://jira.jboss.com) 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 ( http://www.jboss.org/index.html?module=bb&op=viewforum&f=222 ).

Host name verification

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, but it is possible to override the default behavior

One option is to use the key HTTPSClientInvoker.HOSTNAME_VERIFIER (actual value "hostnameVerifier") to supply the name of a class that implements the javax.net.ssl.HostnameVerifier interface, passing it either in the metadata map supplied with an invocation or in the configuration map supplied when the HTTPSClientInvoker was created. If the key appears in both maps, the value in the metadata map takes precedence.

In the absence of an explicitly declared HostnameVerifier, another way to configure the hostname verification behavior is to declare that all host names are acceptable, which can be accomplished by setting the HTTPSClientInvoker.IGNORE_HTTPS_HOST property (actual value "org.jboss.security.ignoreHttpsHost") to true. In order of increasing precedence, the property may be set (1) as a system property, (2) in the configuration map supplied when the HTTPSClientInvoker was created, or in the metadata map supplied with an invocation.

Finally, in the absence of both an explicitly declared HostnameVerifier and an explicit directive to ignore host names, an HTTPSClientInvoker will check to see if its SocketFactory is an instance of org.jboss.remoting.security.CustomSSLSocketFactory and, if so, if authentication has been turned off. If that is the case, host names will be ignored. See Section Socket factories and server socket factories for more information about SocketFactory configuration.

5.4.10.2. HTTPS client socket factory configuration

If a socket factory is not passed into the HTTPS client invoker, it will use org.jboss.remoting.security.SSLSocketBuilder to create one. However, it might be desirable to allow it to fall back to a default socket factory passed into HttpsURLConnection. As of release 2.5.4.SP4, a configuration parameter is available to allow that to happen.

useDefaultSslSocketFactory - If the parameter is set to "true", HTTPSClientInvoker.createSocketFactory() will call HttpsURLConnection.getDefaultSSLSocketFactory() instead of trying to build a socket factory.

5.4.11. Servlet transport

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.

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:

<mbean code="org.jboss.remoting.transport.Connector"
       name="jboss.remoting:service=Connector,transport=Servlet"
       display-name="Servlet transport Connector">

   <attribute name="InvokerLocator">
      servlet://localhost:8080/servlet-invoker/ServerInvokerServlet
   </attribute>

   <attribute name="Configuration">
      <config>
         <handlers>
            <handler subsystem="test">
               org.jboss.test.remoting.transport.web.WebInvocationHandler
            </handler>
         </handlers>
      </config>
   </attribute>
</mbean>

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 if using automatic discovery, as this is the locator url that will be discovered and used by clients to connect to this server invoker.

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 lib directory of 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:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
   "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
   <servlet>
      <servlet-name>ServerInvokerServlet</servlet-name>
      <description>
         The ServerInvokerServlet receives requests via HTTP protocol from 
         within a web container and passes it onto the ServletServerInvoker 
         for processing.
      </description>
      <servlet-class>
         org.jboss.remoting.transport.servlet.web.ServerInvokerServlet
      </servlet-class>
      <init-param>
         <param-name>invokerName</param-name>
         <param-value>jboss.remoting:service=invoker,transport=servlet</param-value>
         <description>The servlet server invoker</description>
         <!--
         <param-name>locatorUrl</param-name>
         <param-value>
            servlet://localhost:8080/servlet-invoker/ServerInvokerServlet
         </param-value>
         <description>The servlet server invoker locator url</description>
         -->
      </init-param>
      <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>ServerInvokerServlet</servlet-name>
      <url-pattern>/ServerInvokerServlet/*</url-pattern>
   </servlet-mapping>
</web-app>

There are two ways in which the servlet can obtain a reference to the servlet server invoker it needs to pass its request onto. The first is by using the param 'invokerName', as is shown above. The value for this should be the JMX ObjectName for the servlet server invoker that was deployed as a service mbean (see service xml above). The other way is to provide a param 'locatorUrl' with a value that matches the locator url of the servlet server invoker to use. In this case, will use the InvokerRegistry to find the server invoker instead of using JMX, which is useful if not deploying server invoker as a mbean service or if want to run in web container other than the JBoss application server. Note, one or the other param is required. If both are provided, the 'locatorUrl' param take precedence.

This file can be changed to meet any web requirements you might have, such as adding security (see sslservlet) 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.

Note. Prior to Remoting version 2.4, org.jboss.remoting.transport.servlet.ServletServerInvoker generated a single MBean ObjectName for representing ServletServerInvokers as MBeans, which meant that an MBeanServer could be aware of only a single ServletServerInvoker MBean. As of version 2.4, that restriction has been eliminated.

Note. Prior to Remoting version 2.4, when org.jboss.remoting.transport.servlet.web.ServerInvokerServlet retrieved an MBeanServer, it looked only for an MBeanServer whose default domain was "jboss". As of version 2.4, the default domain can be configured by adding an "mbeanServer" init-param element to the web.xml file. If the "mbeanServer" value is set to "*platform*" and jdk 1.5 or greater is in use, ServerInvokerServlet will retrieve the platform MBeanServer by calling java.lang.management.ManagementFactory.getPlatformMBeanServer(). In the absence of a configured default domain, ServerInvokerServlet will still use "jboss" as the default domain.

5.4.11.1. Configuration

unwrapSingletonArrays - If the map returned by javax.servlet.http.HttpServletRequest.getParameterMap() maps a String key to an array of length one, the value in the array will be extracted and associated with the key.

5.4.12. SSL Servlet transport

The SSL Servlet Invoker is exactly the same as its parent, Servlet Invoker, with the exception that it uses the protocol of 'sslservlet'. On the server side it is deployed exactly the same as a servlet invoker would be but requires setting up ssl within the web container (i.e. enabling the ssl connector within Tomcat's server.xml). This will usually require specifing a different port as well.

An example of the mbean service xml for deploying the ssl servlet server invoker would be:

<?xml version="1.0" encoding="UTF-8"?>
<server>
   <mbean code="org.jboss.remoting.transport.Connector"
          name="jboss.remoting:service=Connector,transport=SSLServlet"
          display-name="SSL Servlet transport Connector">

      <attribute name="InvokerLocator">
         sslservlet://localhost:8443/servlet-invoker/ServerInvokerServlet
      </attribute>
      <attribute name="Configuration">
         <config>
            <handlers>
               <handler subsystem="test">
                  org.jboss.test.remoting.transport.web.WebInvocationHandler
               </handler>
            </handlers>
         </config>
      </attribute>
   </mbean>
</server>

An example of servlet-invoker.war/WEB-INF/web.xml for the ssl server invoker servlet would be:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
   <servlet>
      <servlet-name>ServerInvokerServlet</servlet-name>
      <description>
         The ServerInvokerServlet receives requests via HTTP protocol from 
         within a web container and passes it onto the ServletServerInvoker
         for processing.
      </description>
      <servlet-class>
         org.jboss.remoting.transport.servlet.web.ServerInvokerServlet
      </servlet-class>
      <init-param>
         <param-name>locatorUrl</param-name>
         <param-value>
            sslservlet://localhost:8443/servlet-invoker/ServerInvokerServlet
         </param-value>
         <description>The servlet server invoker locator url</description>
      </init-param>
      <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>ServerInvokerServlet</servlet-name>
      <url-pattern>/ServerInvokerServlet/*</url-pattern>
   </servlet-mapping>
</web-app>

5.4.13. Exception handling for web based clients

Web based clients, meaning remoting clients that call on web based remoting servers (i.e. http, https, servlet, and sslservlet) have special needs when it comes to handling exceptions that come from the servers they are calling on. The main reason for this is that depending on what type of server they are calling on, they might receive the error in different formats.

By default, web based clients will throw an exception when the response code from the server is greater than 400. The exact exception type thrown will depend on the type of web server the client is interacting with. If it is a JBoss Remoting server (http or https server invoker), the exception thrown will be the one originally generated on the server side. If the server is not a JBoss Remoting server (e.g. JBossAS, Tomcat, Apache Web Server, etc.), the exception thrown will be org.jboss.test.remoting.transport.http.WebServerError. The WebServerError's message will be the error html returned by the web server. Throwing an exception may be turned off with the parameter HTTPMetadataConstants.NO_THROW_ON_ERROR (actual text value "NoThrowOnError") set to "true". This parameter may be passed in the InvokerLocator or configuration map when the org.jboss.remoting.Client is created, or it may be included in the metadata map passed to

public Object invoke(Object param, Map metadata) throws Throwable;
.

This will cause the http client invoker to not throw an exception, but instead return the data from the web server error stream. In the case that the data returned from this error stream is of type java.lang.String (i.e. is error html), it will be wrapped in a WebServerError and returned as this type. The raw data from the web server can the be retrieved by getting the WebServerError's message.

Note. Prior to Remoting version 2.4, the servlet transport returned a simple error message in the event of an error on the server side. As of version 2.4, the discussion about exception handling applies to the servlet and sslservlet transports as well. The original behavior of returning an error message can be requested by configuring the server with the parameter org.jboss.remoting.transport.http.HTTPMetadataConstants.DONT_RETURN_EXCEPTION (actual value "dont-return-exception") set to "true".

5.4.14. Multiplex transport

As of Remoting version 2.4, the multiplex transport is deprecated and will no longer be supported.

5.4.15. SSL Multiplex transport

As of Remoting version 2.4, the sslmultiplex transport is deprecated and will no longer be supported.

5.4.16. Bisocket transport

The bisocket transport, like the multiplex transport, is a bidirectional transport that can function in the presence of restrictions that would prevent a unidirectional transport like socket or http from creating a server to client push callback connection. (See Section Callbacks for more information about callbacks and bidirectional and unidirectional transports.) For example, security restrictions could prevent the application from opening a ServerSocket on the client, or firewall restrictions could prevent the server from contacting a ServerSocket even if it were possible to create one.

5.4.16.1. Overview

The bisocket client and server invokers inherit most of their functionality from the socket invokers, with the principal exception of overriding a method in the client invoker called createSocket(). If the client invoker is on the client side, then createSocket() simply calls the super implementation. The heart of the bisocket transport is in handling the case of creating a connection from a callback client invoker on the server side to a callback server invoker on the client side, which is mandated to occur without the use of a ServerSocket on the client side. Whenever the bisocket transport is informed by an application of its intention to use push callbacks, the client side creates a secondary "control" connection, and subsequently, whenever the callback client invoker needs to create a connection to the callback server, it sends a request over the control connection asking the client side to establish the connection. The server side of the transport maintains a secondary ServerSocket that accepts connection requests from the client side, and whenever a socket is created it is passed to whichever callback client invoker requested it. The client invoker, which inherits the socket transport's connection pool management facility, adds the new socket to its connection pool.

Note that if the control connection were to fail, no new connections could be created for the callback client invoker, and eventually callback transmission could come to a halt. The client and server invokers work together, therefore, to maintain a heartbeat on the control connection and to recreate the control connection automatically should it fail. In particular, the server side sends out ping messages on the control connection, and the client side needs to receive a ping message within some configured window in order to consider the connection to be functional.

In addition to the configuration options inherited from the socket transport, the bisocket transport may be configured with the following parameters, which are defined as constants in the org.jboss.remoting.transport.bisocket.Bisocket class. A parameter can be configured on the server side by appending it to the InvokerLocator or by adding it to the configuration map passed to the Connector's constructor. On the client side, where all parameters are used by the callback server invoker, there are several options for setting parameter values. If the callback Connector is created explicitly, then a parameter can be configured by appending it to the callback Connector's InvokerLocator or by adding it to the configuration map passed to the callback Connector's constructor. If the callback Connector is created implicitly by the Client.addListener() method, then its configuration map is the union of the Client's configuration map and the metadata map passed as a parameter to Client.addListener().

IS_CALLBACK_SERVER (actual value is "isCallbackServer"): when a bisocket server invoker receives this parameter with a value of true, it avoids the creation of a ServerSocket. Therefore, IS_CALLBACK_SERVER should be used on the client side for the creation of a callback server. The default value is false.

PING_FREQUENCY (actual value is "pingFrequency"): The server side uses this value to determine the interval, in milliseconds, between pings that it will send on the control connection. The client side uses this value to calculate the window in which it must receive pings on the control connection. In particular, the window is ping frequency * ping window factor. See also the definition of PING_WINDOW_FACTOR. The default value is 5000.

PING_WINDOW_FACTOR (actual value is "pingWindowFactor"): The client side uses this value to calculate the window in which it must receive pings on the control connection. In particular, the window is ping frequency * ping window factor. See also the definition of PING_FREQUENCY. The default value is 2.

MAX_RETRIES (actual value is "maxRetries"): This parameter is relevant only on the client side, where the BisocketClientInvoker uses it to govern the number of attempts it should make to get the address and port of the secondary ServerSocket, and the BisocketServerInvoker uses it to govern the number of attempts it should make to create both ordinary and control sockets. The default value is 10.

MAX_CONTROL_CONNECTION_RESTARTS (actual value is "maxControlConnectionRestarts"): The client side uses this value to limit the number of times it will request a new control connection after a ping timeout. The default value is 10.

SECONDARY_BIND_PORT (actual value is "secondaryBindPort"): The server side uses this parameter to determine the bind port for the secondary ServerSocket.

SECONDARY_BIND_PORTS (actual value is "secondaryBindPorts"): The server side uses this parameter to determine the bind ports for the secondary ServerSockets in a multihome server.

SECONDARY_CONNECT_PORT (actual value is "secondaryConnectPort"): The server side uses this parameter to determine the connect port used by the client side to connect to the secondary ServerSocket.

SECONDARY_CONNECT_PORTS (actual value is "secondaryConnectPorts"): The server side uses this parameter to determine the connect ports used by the client side to connect to the secondary ServerSockets in a multihome server.

SECONDARY_MAX_THREADS (actual value is "secondaryMaxThreads"): Determines the maximum number of sockets accepted by the secondary ServerSocket that can be processed simultaneously. Introduced in release 2.5.4.SP2. Default value is 50.

SECONDARY_TIMEOUT (actual value is "secondaryTimeout"): Determines the timeout used when reading initial data from a socket accepted by the secondary ServerSocket. Introduced in release 2.5.4.SP2. Default value is 60000 ms.

Also, the parameter "acceptThreadPriorityIncrement", inherited from org.jboss.remoting.transport.socket.SocketServerInvoker, can be used to increment the priority of the thread that manages the secondary ServerSocket. The value is added to java.lang.Thread.NORM_PRIORITY, and the resulting value must be no more than java.lang.Thread.MAX_PRIORITY. This parameter might be useful on a heavily loaded machine if the secondary ServerSocket thread is getting starved.

5.4.16.2. Details

Using the bisocket transport certainly does not require understanding its implementation details, but some further information is presented in this section for those who might be interested.

In the following discussion, the client side client invoker and the server side server invoker will be referred to simply as "client invoker" and "server invoker." The callback client invoker and callback server invoker will be explicitly identified as such.

The following sequence of events occurs in the course of creating a control connection. For simplicity it is assumed that the Client and Connector have already been created, and that the callback server is created implicitly by the Client. These events are illustrated in Figure 5.1.

  1. The application calls Client.addListener().
  2. The Client creates a callback Connector and the callback server invoker registers itself in a static map.
  3. The Client sends an "addListener" message to the server invoker by way of the client invoker.
  4. The client invoker intercepts the "addListener" message, which tells it that a callback server is being created. It retrieves the callback server invoker from the static map and tells it to create a control connection for the callback connection that is being constructed.
  5. The callback server invoker sends an internal message to the server invoker requesting the address and port of the secondary ServerSocket
  6. The callback server invoker connects to the secondary ServerSocket to create a Socket for the control connection. If it has not already done so, the callback server invoker creates a TimerTask which will monitor the state of all of its control connections. (Note that if the callback Connector is created explicitly, it could have multiple InvokerCallbackHandlers registered with it.)
  7. On the server side, the Socket just created by the secondary ServerSocket is stored in a static map, awaiting the creation of the callback client invoker.
  8. The client invoker transmits the "addListener" message to the server invoker.
  9. The server invoker creates a callback client invoker.
  10. The callback client invoker retrieves the waiting socket and uses it for the control connection.
  11. The callback client invoker begins pinging on the control connection.
Creating a control connection.

Figure 5.1. Creating a control connection.

The following sequence of events occurs in the course of creating a connection for the callback client invoker to use for sending callbacks. It is illustrated in Figure 5.2.

  1. The ServerInvocationHandler calls InvokerCallbackHandler.handleCallback().
  2. The InvocationCallbackHandler calls invoke() on the callback Client.
  3. The Client calls invoke() on the callback client invoker.
  4. If there are no connections in its connection pool, the callback client invoker sends a message on the control connection asking the callback server invoker to connect to the server side secondary ServerSocket. It then waits for the Socket to appear in a static map.
  5. The callback server invoker receives the request and calls upon either a Socket constructor or a SocketFactory to create a new Socket. It passes the new Socket to a worker thread to process subsequent callback invocations.
  6. The secondary ServerSocket creates a new Socket, which is placed in a static map.
  7. The callback client invoker retrieves the new Socket
  8. The callback client uses the new Socket to transmit a callback, and adds the new connection to its connection pool for later use.
Creating a callback connection.

Figure 5.2. Creating a callback connection.

The following sequence of events occurs when a control connection fails. It is illustrated in Figure 5.3.

  1. The callback server invoker notices that a ping has not been received during the control connection's current window.
  2. The callback server invoker reacquires the host and port of the secondary ServerSocket, just in case it has changed.
  3. The callback server invoker calls on a Socket constructor or SocketFactory to create a new Socket.
  4. The callback server invoker sends an internal message on the new connection directing the server to replace the current control connection with the new connection.
  5. After the secondary ServerSocket creates a new Socket, the Socket is passed directly to the client invoker in a method that replaces the old control connection with a new one.
Replacing a failed control connection.

Figure 5.3. Replacing a failed control connection.

5.4.17. SSL Bisocket transport

The SSL bisocket transport has the same relation to the bisocket transport as the SSL socket transport has to the socket transport. That is, it uses an SSLServerSocket and creates SSLSockets by default. See Section Socket factories and server socket factories for more information.

SSL bisocket transport supports all the configuration attributes supported by the bisocket transport.

5.5. Marshalling

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.

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.

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:

socket://myhost:5400/?datatype=serializable

This can be done for types that are statically bound within the MarshalFactory, 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 MarshalFactory during runtime (on both the client and server side). This can be done by the following method call within the MarshalFactory:

public static void addMarshaller(
        String dataType, Marshaller marshaller, UnMarshaller unMarshaller)

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:

socket://myhost:5400/?datatype=invocation

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:

socket://myhost:5400/?datatype=invocation&
            marshaller=org.jboss.invocation.unified.marshall.InvocationMarshaller&
            unmarshaller=org.jboss.invocation.unified.marshall.InvocationUnMarshaller
         

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.

Another requirement of the actual Marshaller and UnMarshaller classes is that they have a void constructor. Otherwise loading of these will fail.

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:

<attribute name="InvokerLocator">
   <![CDATA[socket://${jboss.bind.address}:8084/?datatype=invocation&
      marshaller=org.jboss.invocation.unified.marshall.InvocationMarshaller&
      unmarshaller=org.jboss.invocation.unified.marshall.InvocationUnMarshaller]]>
</attribute>

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:

<invoker transport="socket">
   <attribute name="dataType" isParam="true">invocation</attribute>
   <attribute name="marshaller" isParam="true">
      org.jboss.invocation.unified.marshall.InvocationMarshaller
   </attribute>
   <attribute name="unmarshaller" isParam="true">
      org.jboss.invocation.unified.marshall.InvocationUnMarshaller
   </attribute>
</invoker>

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:

<invoker transport="socket">
   <attribute name="dataType" isParam="true">invocation</attribute>
   <attribute name="marshaller" isParam="true">
      org.jboss.invocation.unified.marshall.InvocationMarshaller
   </attribute>
   <attribute name="unmarshaller" isParam="true">
      org.jboss.invocation.unified.marshall.InvocationUnMarshaller
   </attribute>
   <attribute name="loaderport" isParam="true">5401</attribute>
</invoker>

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).

Note. Prior to release 2.5.2, only the parameters in the InvokerLocator were used to configure marshallers and unmarshallers. As of release 2.5.2 the parameters in the configuration map passed to an org.jboss.remoting.Client or org.jboss.remoting.transport.Connector will also be used if the parameter org.jboss.remoting.Remoting.PASS_CONFIG_MAP_TO_MARSHAL_FACTORY (actual value "passConfigMapToMarshalFactory") is set to "true".

Http marshalling

By default, the http, https, servlet, and sslservlet transports use org.jboss.remoting.marshal.http.HTTPMarshaller and org.jboss.remoting.marshal.http.HTTPUnMarshaller, which are distinct from their parent classes org.jboss.remoting.marshal.serializable.SerializableMarshaller and org.jboss.remoting.marshal.serializable.SerializableUnMarshaller only insofar as they treat Strings as a special case in the interest of efficiency. However, prior to release 2.5.2, HTTPUnMarshaller incorrectly uses the content-type set by the ServerInvocationHandler (if any), which would normally apply to the application payload of a response rather than the type of the envelope. As of release 2.5.2, this behavior remains the default, but it can be corrected by setting the parameter org.jboss.remoting.transport.http.HTTPMetadataConstants.USE_REMOTING_CONTENT_TYPE (actual value "useRemotingContentType") to "true".

Compression marshalling

A compression marshaller/unmarshaller is available as well which uses gzip to compress and uncompress large payloads for wire transfer. The implementation classes are org.jboss.remoting.marshal.compress.CompressingMarshaller and org.jboss.remoting.marshal.compress.CompressingUnMarshaller. They extend the org.jboss.remoting.marshal.serializable.SerializableMarshaller and org.jboss.remoting.marshal.serializable.SerializableUnMarshaller interfaces and maintain the same behavior with the addition of compression.

5.6. Callbacks

5.6.1. Callback overview

Although this section covers callback configuration, it will be useful to begin with a little general information about callbacks within Remoting. In addition to the ordinary remote method invocation model, in which invocation results are returned synchronously, Remoting also supports an invocation model in which the server asynchronously generates information to be returned to the client.

There are two models for callbacks, push callbacks and pull callbacks. In the push model, the client registers a client side callback server 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. The other model, pull callbacks, allows the client to call on the target server to collect the callback messages waiting for it.

5.6.1.1. Callback connections

A callback connection is initiated by the invocation of one of the overloaded addListener() methods in the org.jboss.remoting.Client class, as described below in Section Registering callback handlers. The creation of a callback connection results in a server side call to the

public void addListener(InvokerCallbackHandler callbackHandler);

method of the application's org.jboss.remoting.ServerInvocationHandler. The org.jboss.remoting.callback.InvokerCallbackHandler parameter (actual type org.jboss.remoting.callback.ServerInvokerCallbackHandler) is the server side representation of the callback connection, essentially a proxy for the client side InvokerCallbackHandler passed to the addListener() method. The ServerInvocationHandler is free to do whatever it wants with the InvokerCallbackHandler, but a typical practice would be to keep a list of them and transmit each generated callback to some or all of them.

Note. As of release 2.5.1, ServerInvokerCallbackHandler has a new method, shutdown(), which can be used by, for example, the ServerInvocationHandler with which it is registered, or by an org.jboss.remoting.ConnectionListener upon being informed of a connection failure, to clean up the ServerInvokerCallbackHandler and references thereto.

The client side of a callback connection is identified in one of two ways, according to whether there is a callback Connector associated with the connection. If the connection has a callback Connector, then it is identifed by the combination of the Connector and the InvokerCallbackHandler. It follows that if an InvokerCallbackHandler is registered twice with the same Connector (through a call to Client.addListener()), only a single callback connection is created. That is, the second call has no effect. If there is no callback Connector, which is the case for pull callbacks and simulated push callbacks (see Section Registering callback handlers), then the callback connection is identified by the combination of the Client on which addListener() was invoked and the InvokerCallbackHandler. It follows that if an InvokerCallbackHandler is registered twice with the same Client for pull or simulated push callbacks, only a single callback connection is created. That is, the second call has no effect.

Each callback connection is tagged with a unique identifier, which can be retrieved from the InvokerCallbackHandler passed to ServerInvocationHandler.addListener() by casting it to type org.jboss.remoting.callback.ServerInvokerCallbackHandler and calling getCallbackSessionId(). It is also possible to retrieve the unique identifier of the Client upon which addListener() was invoked by casting the InvokerCallbackHandler to type ServerInvokerCallbackHandler and calling getClientSessionId().

5.6.1.2. Transmitting callbacks

Once the ServerInvocationHandler has generated information to be sent to the client, it can be packaged in an org.jboss.remoting.callback.Callback and transmitted on one or more callback connections in one of two ways. One way to transmit a callback is by invoking the

public void handleCallback(Callback callback) throws HandleCallbackException;

method of InvokerCallbackHandler. The subsequent disposition of the callback depends on whether the callback connection is configured for push or pull callbacks. For a pull callback connection, the Callback is simply stored on the server, and for a push callback connection, handleCallback() is analogous to (and is implemented by) an ordinary Client.invoke() invocation.

An alternative method of transmitting a callback is by casting an InvokerCallbackHandler to type org.jboss.remoting.callback.AsynchInvokerCallbackHandler and invoking one of the overloaded handleCallbackOneway() methods

public void handleCallbackOneway(Callback callback) throws HandleCallbackException;
  
public void handleCallbackOneway(Callback callback, boolean serverSide)
        throws HandleCallbackException;

of AsynchInvokerCallbackHandler. (Note that all InvokerCallbackHandlers passed in to ServerInvocationHandler.addListener() implement AsynchInvokerCallbackHandler.) For a pull callback connection handleCallbackOneway() has the same behavior as handleCallback(), but for a push callback connection it is analogous to (and implemented by) a Client.invokeOneway() invocation. The serverSide parameter is analogous to the clientSide parameter in the

public void invokeOneway(Object param, Map sendPayload, boolean clientSide) throws Throwable;

method of org.jboss.remoting.Client. That is, if serverSide is true, then the oneway invocation is handed off to a separate thread on the server side and the call to handleCallbackOneway() returns immediately. If serverSide is false, then callback Client makes an invocation on the callback server, which hands the invocation off to a separate thread on the client side and returns, after which the call to handleCallbackOneway() returns.

5.6.1.3. Callback stores.

For pull callbacks (and also simulated push callbacks - see Section Registering callback handlers), the server has to manage callback messages 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.

The persistence 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 memPercentCeiling attribute (see more on configuring this below).

By default, the persistent store used by the invokers is the org.jboss.remoting.NullCallbackStore. 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:

Callback has been lost because not enough free memory to hold object.

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 org.jboss.remoting.NullCallbackStore.FailedCallback class when they call to get their callbacks. This class will throw a RuntimeException with the following message when getCallbackObject() is called:

This is an invalid callback. The server ran out of memory, so callbacks were lost.

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.

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.

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.

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:

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 Section Callback store configuration). 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

CallbackStore is also a service mbean, so can be run as a service within JBoss AS or stand alone.

Remoting also offers the BlockingCallbackStore, which is described as follows.

This callback store does not persist callback messages when memory is running low, but instead will block the thread making the handle callback call from the server invoker. The intention is that this will throttle the server invoker from generating/sending any more callbacks until client as called to get the in-memory callbacks that have already been collected and memory has been released.

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).

Once a callback client has been removed as a listener, all persisted callbacks will be removed from disk.

5.6.1.4. Callback acknowledgements

Unlike the Client.invoke() method, InvokerCallbackHandler.handleCallback() has a void return type, so it does not provide a way of knowing if the callback has been received by the client. In fact, a void return type is appropriate since the immediate effect of a call to InvokerCallbackHandler.handleCallback() may be no more than storing the callback for later retrieval. However, it may be useful for the application to be informed when the callback has made its way to the client, and Remoting has a listener mechanism that can provide callback acknowledgements.

An object that implements the org.jboss.remoting.callback.CallbackListener interface

public interface CallbackListener
{
   /**
    * @param callbackHandler InvokerCallbackHandler that handled this callback
    * @param callbackId id of callback being acknowledged
    * @param response either (1) response sent with acknowledgement or (2) null
    */
   void acknowledgeCallback(
           InvokerCallbackHandler callbackHandler, Object callbackId, Object response);
}

may be registered to receive an acknowledgement for a particular callback by adding it to the callback's returnPayload map with the key org.jboss.remoting.callback.ServerInvokerCallbackHandler.CALLBACK_LISTENER (actual value "callbackListener"). It is also necessary to assign an identifier to the callback by adding some unique object, recognizable by the application, to the callback's returnPayload map with the key ServerInvokerCallbackHandler.CALLBACK_ID (actual value "callbackId"). This identifier will be passed as the callbackId parameter of the CallbackListener.acknowledgeCallback() method.

There are two ways in which callbacks can be acknowledged:

  1. explicit acknowledgements, and
  2. automatic acknowledgements.

Note that automatic acknowledgements are available only for push callbacks and simulated push callbacks (see Section Registering callback handlers) transmitted by the InvokerCallbackHandler.handleCallback() method.

Callbacks may be acknowledged explicitly by the client side application code by calling one of the overloaded acknowledgeCallback() and acknowledgeCallbacks() methods

public int acknowledgeCallback(
        InvokerCallbackHandler callbackHandler, Callback callback) throws Throwable;
           
public int acknowledgeCallback(
        InvokerCallbackHandler callbackHandler, Callback callback, Object response) throws Throwable;
           
public int acknowledgeCallbacks(
        InvokerCallbackHandler callbackHandler, List callbacks) throws Throwable;
           
public int acknowledgeCallbacks(
        InvokerCallbackHandler callbackHandler, List callbacks, List responses) throws Throwable;

of the Client class. In each case the callbackHandler parameter is the client side InvokerCallbackHandler which received the callback. The first two and the latter two methods acknowledge a single callback and a list of callbacks, respectively. In the latter case, each of the callbacks must have the same registered CallbackListener. The second and fourth methods also allow a response value to be associated with each callback acknowledgement, which will passed as the response parameter of the CallbackListener.acknowledgeCallback() method. For the fourth method, the lengths of the callbacks list and the responses list must be the same.

It is also possible to request that Remoting automatically supply acknowledgements for push callbacks and simulated push callbacks by adding the key ServerInvokerCallbackHandler.REMOTING_ACKNOWLEDGES_PUSH_CALLBACKS (actual value "remotingAcknowledgesPushCallbacks") to the callback's returnPayload map with the value of true, along with the ServerInvokerCallbackHandler.CALLBACK_LISTENER and ServerInvokerCallbackHandler.CALLBACK_ID entries. The acknowledgement is generated after the callback has been delivered by a call to handleCallback() on the client side InvokerCallbackHandler.

For an example of code that uses callback acknowledgements, see the classes in the package org.jboss.remoting.samples.callback.acknowledgement.

5.6.2. Registering callback handlers.

There are several ways in which callback handlers can be configured. The main distinction in type of callback setup is whether the callbacks will be push (asynchronous) or pull (synchronous) callbacks.

5.6.2.1. Pull callbacks.

A pull callback connection is implemented by an object (an org.jboss.remoting.callback.ServerInvokerCallbackHandler) on the server side which stores information that is generated asynchronously on the server and subsequently retrieved by the client. It is set up by invoking one of the following overloaded addListener() methods in the Client class:

public void addListener(
        InvokerCallbackHandler) throws Throwable;
          
public void addListener(
        InvokerCallbackHandler callbackHandler, InvokerLocator clientLocator) throws Throwable;
          
public void addListener(
        InvokerCallbackHandler callbackHandler,  InvokerLocator clientLocator,
        Object callbackHandlerObject) throws Throwable;

where, in the latter two cases, the clientLocator parameter is set to null.

The callbacks stored for a pull callback connection may be retrieved by calling the

public List getCallbacks(InvokerCallbackHandler callbackHandler) throws Throwable

method of the Client class. Note that for pull callbacks, the InvokerCallbackHandler registered on the client side doesn't really participate in the handling of callbacks. However, when client.getCallbacks(callbackHandler) is called for a particular Client and InvokerCallbackHandler, the two objects together identify a particular callback connection.

Note. As of Remoting version 2.4 there are two versions of pull callbacks: non-blocking (original) and blocking (new). [The new version has been ported to Remoting release 2.2.2.GA, so it exists in later versions of the 2.2 family]. In the original, non-blocking mode, a call to Client.getCallbacks() will return more or less immediately, whether or not any callbacks are waiting on the server side. In the new, blocking mode, the call will block on the server side until either it times out or a callback becomes available. The blocking mode eliminates the overhead of busy polling. Blocking and non-blocking mode are configured on a per-invocation basis by setting org.jboss.remoting.ServerInvoker.BLOCKING_MODE (actual value "blockingMode") to either ServerInvoker.BLOCKING (actual value "blocking") or ServerInvoker.NONBLOCKING (actual value "nonblocking") in the metadata map passed to

public List getCallbacks(
        InvokerCallbackHandler callbackHandler, Map metadata) throws Throwable;

in org.jboss.remoting.Client. The default value is ServerInvoker.NONBLOCKING. The blocking timeout value may be configured in two ways:

  1. the Connector can be configured with a default value; and

  2. a per-invocation timeout value can be configured with the key ServerInvoker.BLOCKING_TIMEOUT in the metadata map passed to Client.getCallbacks().

In the absence of any configured timeout, the default value is 5000 ms.

5.6.2.2. Push callbacks.

A push callback connection is implemented by a pair of objects, one on the server side and one on the client side, which facilitate transmitting to the client some information which has been generated asynchronously on the server. There are two versions of push callbacks: true push callbacks and simulated push callbacks, also known as polled callbacks.

In the case of true push callbacks, there is a Remoting object on the server side (an org.jboss.remoting.callback.ServerInvokerCallbackHandler) which uses a Client to make invocations to the client side. On the client side there is a Connector and an implementation of the org.jboss.remoting.callback.InvokerCallbackHandler interface which functions as an invocation handler for callbacks. Like implementations of org.jboss.remoting.ServerInvocationHandler on the server side, implementations of InvokerCallbackHandler are supplied by the application. When a ServerInvocationHandler generates a callback object, it will be sent to the callback Connector, which will, in turn, deliver it to the InvokerCallbackHandler

For simulated push callbacks, the server side Remoting object stores callbacks for later retrieval by the client, exactly as in the case of pull callbacks. However, there is a Remoting poller (an org.jboss.remoting.callback.CallbackPoller) on the client side which periodically retrieves the callbacks and, as in the case of true push callbacks, delivers them to the InvokerCallbackHandler.

There are two ways to set up push callback handling, each of which entails the use of one of the overloaded addListener() methods in the Client class:

  1. explicit creation of a Connector
  2. implicit configuration.

In the first case, the application creates a Connector and passes its InvokerLocator, along with an implementation of InvokerCallbackHandler, to one of the following versions of addListener():

public void addListener(
        InvokerCallbackHandler callbackHandler, InvokerLocator clientLocator) throws Throwable;
          
public void addListener(
        InvokerCallbackHandler callbackHandler,InvokerLocator clientLocator,
        Object callbackHandlerObject) throws Throwable;

Because there is a Connector, explicit configuration always results in true push callbacks.

In the case of implicit configuration, only the InvokerCallbackHandler is passed and Remoting takes care of the rest. One of the following versions of addListener() is used:

public void addListener(
        InvokerCallbackHandler callbackhandler, Map metadata) throws Throwable;
          
public void addListener(
        InvokerCallbackHandler callbackhandler, Map metadata,
        Object callbackHandlerObject) throws Throwable;
          
public void addListener(
        InvokerCallbackHandler callbackhandler, Map metadata,
        Object callbackHandlerObject, boolean serverToClient) throws Throwable;

Note that the latter three methods are distinguished from the first two by the presence of the metadata parameter, which can be used to configure the callback connection. Depending on the transport being used and the parameters supplied to addListener(), Remoting will set up either true or simulated push callbacks. If the client is in an environment where the server will be allowed to establish a connection to the client, then the final version of addLIstener() could be used with the serverToClient parameter set to true. In this case, regardless of the transport, Remoting will automatically create a callback Connector on behalf of the user, which behaves just as though the user had created it and passed the InvokerLocator as a parameter to addListener().

Note. Since release 2.5.1, if the first instance of the parameter org.jboss.remoting.Client.USE_ALL_PARAMS (actual value "useAllParams") found successively in the InvokerLocator, the Client's configuration map, or the metadata map is set to "true", then polled callbacks can be configured by parameters in the InvokerLocator and Client's configuration map as well as the metadata map passed to addListener().

If the client is in an environment where the server is not allowed to establish a network connection to the client (e.g. firewall rules disallow it or security rules prohibit the creation of a ServerSocket), then there are two options. One is to use one of the bidirectional transports, each of which has a strategy for the creation of a connection from the server to the client without connecting a client Socket to a ServerSocket. There are currently three bidirectional transports: local (i.e., the client and server reside in the same JVM), bisocket, and multiplex (deprecated). When one of the second set of addListener() methods is invoked for a bidirectional transport, it will create a callback Connector, even if serverToClient is set to false. The other option is to use any of the unidirectional transports (socket, http, rmi) with serverToClient set to false (which is the default value if it is not an explicit parameter), in which case, Remoting will configure polled callbacks.

The implicitly created callback Connectors are available for reuse. Each Client maintains a set of all callback Connectors it has implicitly created for each InvokerCallbackHandler that is passed in by way of one of the addListener() methods. For example,

InvokerCallbackHandler callbackHandler = new SampleCallbackHandler();
client.addListener(callbackHandler, new HashMap(), null, true);
client.addListener(callbackHandler, new HashMap(), null, true);

would result in a set of two callback Connectors associated with callbackHandler. These sets of callback Connectors are accessible by way of the Client method

public Set getCallbackConnectors(InvokerCallbackHandler callbackHandler);

A callback Connector could be reused as in the following code:

InvokerCallbackHandler callbackHandler1 = new SampleCallbackHandler();
client.addListener(callbackHandler1, new HashMap(), null, true);
Set callbackConnectors = client.getCallbackConnectors(callbackHandler1);
Connector callbackConnector = (Connector) callbackConnectors.iterator().next();
InvokerCallbackHandler callbackHandler2 = new SampleCallbackHandler();
client.addListener(callbackHandler2, callbackConnector.getLocator());

which would result in the implicitly created callback Connector having two registered InvokerCallbackHandlers. Note, by the way, that if the InvokerCallbackHandler were reused as in the following:

InvokerCallbackHandler callbackHandler1 = new SampleCallbackHandler();
client.addListener(callbackHandler1, new HashMap(), null, true);
Set callbackConnectors = client.getCallbackConnectors(callbackHandler1);
Connector callbackConnector = (Connector) callbackConnectors.iterator().next();
client.addListener(callbackHandler1, callbackConnector.getLocator());

then only one callback connection would be created, because a single (Connector, InvokerCallbackHandler) pair can be associated with only one callback connection.

Note. As of Remoting version 2.4, there are two versions of pull callbacks: non-blocking (original) and blocking (new). For more information, see Pull callbacks. Since the CallbackPoller uses pull callbacks, this distinction is relevant to polled callbacks as well. The default behavior of CallbackPoller is to use non-blocking mode, but blocking mode can be requested by using the key ServerInvoker.BLOCKING_MODE set to ServerInvoker.BLOCKING in the metadata map passed to Client.addListener().

There are nine parameters that can be passed to Client.addListener() in the metadata map which are specific to push callback configuration. The first three apply to push callbacks and the latter six apply to polled callbacks. For convenience, the keys related to push callbacks are defined as constants in the org.jboss.remoting.Client class, and the keys related to polled callbacks are defined in the org.jboss.remoting.callback.CallbackPoller class (with the exception of ServerInvoker.BLOCKING_MODE and ServerInvoker.BLOCKING_TIMEOUT).

CALLBACK_SERVER_PROTOCOL (actual value is "callbackServerProtocol): the transport protocol to be used for callbacks. By default it will be the protocol used by the Client upon which addListener() is invoked.

CALLBACK_SERVER_HOST (actual value is "callbackServerHost"): the host name to be used by the callback server. By default it will be the result of calling InetAddress.getLocalHost().getHostAddress().

CALLBACK_SERVER_PORT (actual value is "callbackServerPort"): the port to be used by the callback server. By default it will be a randomly chosen unused port.

CALLBACK_POLL_PERIOD (actual value is "callbackPollPeriod"): the interval in milliseconds between attempts to download callbacks from the server.

CALLBACK_SCHEDULE_MODE (actual value is "scheduleMode"): may be set to either CallbackPoller.SCHEDULE_FIXED_RATE (actual value "scheduleFixedRate") or CallbackPoller.SCHEDULE_FIXED_DELAY (actual value "scheduleFixedDelay"). In either case, polling will take place at approximately regular intervals, but in the former case the scheduler will attempt to perform each poll CALLBACK_POLL_PERIOD milliseconds after the previous attempt, and in the latter case the scheduler will attempt to schedule polling so that the average interval will be approximately CALLBACK_POLL_PERIOD milliseconds. CallbackPoller.SCHEDULE_FIXED_RATE is the default.

REPORT_STATISTICS (actual value is "reportStatistics"): The presence of this key in metadata, regardless of its value, will cause the CallbackPoller to print statistics that might be useful for configuring the other parameters..

MAX_ERROR_COUNT (actual value is "maxErrorCount"): determines the maximum number of errors that may be experienced during polling before CallbackPoller will shut itself down. The default value is "5".

SYNCHRONIZED_SHUTDOWN (actual value is "doSynchronizedShutdown"): if set to "true", CallbackPoller.stop() will wait for Client.getCallbacks() to return, and if set to "false" it will not wait. For blocking polled callbacks, the default value is "false" and for non-blocking polled callbacks, the default value is "true".

BLOCKING_MODE (actual value is "blockingMode"): if set to ServerInvoker.BLOCKING (actual value "blocking"), CallbackPoller will do blocking polled callbacks, and if set to ServerInvoker.NONBLOCKING (actual value "nonblocking"), CallbackPoller will do non-blocking polled callbacks.

BLOCKING_TIMEOUT (actual value is "blockingTimeout"): the value is used as the per-invocation timeout

Note that all of the elements in metadata will be passed to the callback Connector and appended to its InvokerLocator.

Note. As of Remoting version 2.4, it is possible to configure a server side timeout value for sending push callbacks that is distinct from the timeout value used by the server. [This feature has been ported to Remoting release 2.2.2.GA, so it exists in later versions of the 2.2 family]. The parameter is org.jboss.remoting.callback.ServerInvokerCallbackHandler.CALLBACK_TIMEOUT (actual value "callbackTimeout"), and it should be used to configure the Connector. In the absence of ServerInvokerCallbackHandler.CALLBACK_TIMEOUT, the timeout value configured for the Connector will be used.

5.6.3. Unregistering callback handlers

Callback connections are torn down through a call to the method

public void removeListener(InvokerCallbackHandler callbackHandler) throws Throwable;

in the org.jboss.remoting.Client class. A Client can unregister only those InvokerCallbackHandlers that it originally registered.

It is good practice to eliminate callback connections when they are no longer needed. For example, callback Connectors can, depending on the transport, occupy TCP ports, and CallbackPollers will continue to poll as long as a connection exists.

5.6.4. Callback store configuration.

All callback store configuration will need to be defined within the server invoker configuration, since the server invoker is the parent that creates the callback stores as needed (when client registers for pull callbacks). Example service xml files are included below.

The following general callback store parameters may be configured. They are defined as constants in the org.jboss.callback.ServerInvokerCallbackHandler class.

CALLBACK_MEM_CEILING (actual value is "callbackMemCeiling"): 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.

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.

CALLBACK_STORE_KEY (actual value is "callbackStore"): 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.

The following parameters specific to CallbackStore can be configured via the invoker configuration as well. They are defined as constants in the CallbackStore class.

FILE_PATH_KEY (actual value is "StoreFilePath"): 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'.

FILE_SUFFIX_KEY (actual value is "StoreFileSuffix"): indicates the file suffix to use for the callback objects written to disk. The default value is 'ser'.

Sample service configuration

Socket transport with callback store specified by class name and memory ceiling set to 30%:

<mbean code="org.jboss.remoting.transport.Connector"
       name="jboss.remoting:service=Connector,transport=Socket"
       display-name="Socket transport Connector">

   <attribute name="Configuration">
      <config>
         <invoker transport="socket">
            <attribute name="callbackStore">
               org.jboss.remoting.callback.CallbackStore
            </attribute>
            <attribute name="callbackMemCeiling">30</attribute>
         </invoker>
         <handlers>
            <handler subsystem="test">
               org.jboss.remoting.callback.pull.memory.CallbackInvocationHandler
            </handler>
         </handlers>
      </config>
   </attribute>
</mbean>

Socket transport with callback store specified by MBean ObjectName and declaration of CallbackStore as service:

<mbean code="org.jboss.remoting.callback.CallbackStore"
       name="jboss.remoting:service=CallbackStore,type=Serializable"
       display-name="Persisted Callback Store">

   <!-- the directory to store the persisted callbacks into -->
   <attribute name="StoreFilePath">callback_store</attribute>
   <!-- the file suffix to use for each callback persisted to disk -->
   <attribute name="StoreFileSuffix">cbk</attribute>
</mbean>

<mbean code="org.jboss.remoting.transport.Connector"
       name="jboss.remoting:service=Connector,transport=Socket"
       display-name="Socket transport Connector">

   <attribute name="Configuration">
      <config>
         <invoker transport="socket">
            <attribute name="callbackStore">
               jboss.remoting:service=CallbackStore,type=Serializable
            </attribute>
         </invoker>
         <handlers>
            <handler subsystem="test">
               org.jboss.remoting.callback.pull.memory.CallbackInvocationHandler
            </handler>
         </handlers>
      </config>
   </attribute>
</mbean>

Socket transport with callback store specified by class name and the callback store's file path and file suffix defined:

<mbean code="org.jboss.remoting.transport.Connector"
       name="jboss.remoting:service=Connector,transport=Socket"
       display-name="Socket transport Connector">

   <attribute name="Configuration">
      <config>
         <invoker transport="socket">
            <attribute name="callbackStore">
               org.jboss.remoting.callback.CallbackStore
            </attribute>
            <attribute name="StoreFilePath">callback</attribute>
            <attribute name="StoreFileSuffix">cst</attribute>
         </invoker>
         <handlers>
            <handler subsystem="test">
               org.jboss.remoting.callback.pull.memory.CallbackInvocationHandler
            </handler>
         </handlers>
      </config>
   </attribute>
</mbean>

5.6.5. Callback Exception Handling

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 org.jboss.remoting.callback.CallbackErrorHandler interface. Implementations of this interface can be registered with the Connector to control the behavior when callback exceptions occur.

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, org.jboss.remoting.callback.DefaultCallbackErrorHandler 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.

Note. As of Remoting version 2.4, an org.jboss.remoting.callback.ServerInvokerCallbackHandler, which manages both push and pull callbacks on the server side, can register to be informed of a failure on the connection to the client that it is servicing. In particular, if there is a lease registered for the connection for that particular client, then the ServerInvokerCallbackHandler can be registered as a org.jboss.remoting.ConnectionListener for that lease. The default behavior is to do the registration, but the parameter org.jboss.remoting.ServerInvoker.REGISTER_CALLBACK_LISTENER (actual value "registerCallbackListener") may be set to "false" to prevent registration. If leasing is enabled and registration is turned on, a ServerInvokerCallbackHandler will shut itself down upon being informed of a connection failure. For more information about leasing, see Network Connection Monitoring.

5.7. Socket factories and server socket factories

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.

5.7.1. Server side programmatic configuration

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 (except for the servlet invokers).

5.7.1.1. Server socket factories.

For ServerSocketFactorys, there are ten options for programmatic configuration:

  1. Get the ServerInvoker by calling Connector.getServerInvoker() and call ServerInvoker.setServerSocketFactory().

  2. Call Connector.setServerSocketFactory().

  3. Put a constructed ServerSocketFactory in a configuration map, using key Remoting.CUSTOM_SERVER_SOCKET_FACTORY, and pass the map to one of the Connector constructors.

  4. Create an xml document with root element <config>, setting the <serverSocketFactory> attribute to the name of a ServerSocketFactoryMBean and pass the document to Connector.setConfiguration(). For example:

    StringBuffer buf = new StringBuffer();
    buf.append("<?xml version=\"1.0\"?>\n");
    buf.append("<config>");
    buf.append("   <invoker transport=\"sslsocket\">");
    buf.append("      <attribute name=\"serverBindAddress\">" + getHostName() + "</attribute>");
    buf.append("      <attribute name=\"serverBindPort\">" + freeport + "</attribute>");
    buf.append("      <attribute name=\"serverSocketFactory\">" + socketFactoryObjName + "</attribute>");
    buf.append("   </invoker>");
    buf.append("</config>");
    
    ByteArrayInputStream bais = new ByteArrayInputStream(buf.toString().getBytes());
    Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bais);
    connector.setConfiguration(xml.getDocumentElement());
  5. Create an xml document with root element <config>, setting the <serverSocketFactory> attribute to the class name of a ServerSocketFactory and pass the document to Connector.setConfiguration(). The <serverSocketFactory> class must have a default constructor, which will be used to create a ServerSocketFactory.

  6. Put the ObjectName of a ServerSocketFactoryMBean in a configuration map, using key ServerInvoker.SERVER_SOCKET_FACTORY, and pass the map to one of the Connector constructors.

  7. Put the class name of a ServerSocketFactory in a configuration map, using key ServerInvoker.SERVER_SOCKET_FACTORY, and pass the map to one of the Connector constructors. The <serverSocketFactory> class must have a default constructor, which will be used to create a ServerSocketFactory.

  8. Put a set of SSL parameters, using the keys in org.jboss.remoting.security.SSLSocketBuilder, in a configuration map and pass the map to one of the Connector constructors. These will be used by SSLSocketBuilder (see below) to create a CustomSSLServerSocketFactory.

  9. Configure an appropriate set of SSL system properties and use one of the SSL transports (https, sslrmi, or sslsocket). The properties will be used to create some kind of SSLServerSocketFactory, as determined by the transport.

  10. Use one of the non-SSL transports and do nothing. A default ServerSocketFactory will be constructed.

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 FactoryConfigSample and options 4, 6, 8, and 9 are illustrated in FactoryConfigSSLSample, both of which are in package org.jboss.remoting.samples.config.factories.

Timing considerations. The ServerInvoker, for any transport, is created during the call to Connector.create(), before which option 1 is unavailable. Option 2, on the other hand, is only available before the call to Connector.create(). Once the ServerInvoker has been created, it selects a ServerSocketFactory, according to the rules enumerated above, during the create() phase. For all current transports, the actual ServerSocket is created during the call to Connector.start(), so that a call to ServerInvoker.setServerSocketFactory() (option 1) can override the selected ServerSocketFactory until Connector.start() is called.

5.7.1.2. Socket factories

For SocketFactorys, 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 ServerSocketFactoryMBean, if it exists, is given precedence over class names:

  1. Call Connector.setSocketFactory().

  2. Get the ServerInvoker by calling Connector.getServerInvoker() and call ServerInvoker.setSocketFactory().

  3. Put a constructed SocketFactory in a configuration map, using key Remoting.CUSTOM_SOCKET_FACTORY, and pass the map to one of the Connector constructors.

  4. Create an xml document with root element <config>, setting the <serverSocketFactory> attribute to the name of a ServerSocketFactoryMBean and pass the document to Connector.setConfiguration(). If the MBean has type SSLServerSocketFactoryServiceMBean, its configuration information will be gathered and used to construct a CustomSSLSocketFactory. Note. 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.

  5. Put the ObjectName of a ServerSocketFactoryMBean in a configuration map, using key ServerInvoker.SERVER_SOCKET_FACTORY, and pass the map to one of the Connector constructors. If the MBean has type SSLServerSocketFactoryServiceMBean, its configuration information will be gathered and used to construct a CustomSSLSocketFactory. Note. 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.

  6. Create an xml document with root element <config>, setting the <socketFactory> attribute to the class name of a SocketFactory and pass the document to Connector.setConfiguration(). For example:

    StringBuffer buf = new StringBuffer();
    buf.append("<?xml version=\"1.0\"?>\n");
    buf.append("<config>");
    buf.append("   <invoker transport=\"sslsocket\">");
    buf.append("      <attribute name=\"serverBindAddress\">" + getHostName() + "</attribute>");
    buf.append("      <attribute name=\"serverBindPort\">" + freeport + "</attribute>");
    buf.append("      <attribute name=\"socketFactory\">" + socketFactoryClassname + "</attribute>");
    buf.append("   </invoker>");
    buf.append("</config>");
    
    ByteArrayInputStream bais = new ByteArrayInputStream(buf.toString().getBytes());
    Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bais);
    connector.setConfiguration(xml.getDocumentElement());

    The SocketFactory class must have a default constructor, which will be used to create a SocketFactory.

  7. Put the class name of a SocketFactory in a configuration map, using key Remoting.SOCKET_FACTORY_CLASS_NAME, and pass the map to one of the Connector constructors. The SocketFactory class must have a default constructor.

  8. Put a set of SSL parameters, using the keys in org.jboss.remoting.security.SSLSocketBuilder, in a configuration map and pass the map to one of the Connector constructors. These will be used by SSLSocketBuilder (see below) to create a CustomSSLSocketFactory.

  9. Configure an appropriate set of SSL system properties and use one of the SSL transports (https, sslrmi, or sslsocket). The properties will be used to create some kind of SSLSocketFactory, as determined by the transport.

  10. Use one of the non-SSL transports and do nothing. Ordinary Sockets will be used.

Again, these are essentially in descending order of precedence. Options 1, 2, 3, 6, and 7 are illustrated in FactoryConfigSample and options 4, 5, 8, and 9 are illustrated in FactoryConfigSSLSample, both of which are in package org.jboss.remoting.samples.config.factories.

Timing considerations. A new Client, with a client invoker, is created on the server side whenever a callback listener is registered by a call to Client.addListener(). If a SocketFactory is supplied by any of options 1 to 5, it will be passed to the Client. Otherwise, any information from options 6 to 9 will be passed to the client invoker, which will create a SocketFactory according to the rules given below in the section on client side socket factory configuration. Once Connector.create() has been called, ServerInvoker.setSocketFactory(), may be called at any time to determine the SocketFactory used by the next callback client invoker.

5.7.2. Client side programmatic configuration

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 MBeanServer is assumed to be present, and the Client has no facilities for parsing xml documents.

5.7.2.1. Server socket factories.

For ServerSocketFactorys 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 MBeanServer on the client side:

  1. Get the ServerInvoker by calling Connector.getServerInvoker() and call ServerInvoker.setServerSocketFactory().

  2. Call Connector.setServerSocketFactory().

  3. Put a constructed ServerSocketFactory in a configuration map, using key Remoting.CUSTOM_SERVER_SOCKET_FACTORY, and pass the map to one of the Connector constructors.

  4. Create an xml document with root element <config>, setting the <serverSocketFactory> attribute to the class name of a ServerSocketFactory and pass the document to Connector.setConfiguration(). For example:

    StringBuffer buf = new StringBuffer();
    buf.append("<?xml version=\"1.0\"?>\n");
    buf.append("<config>");
    buf.append("   <invoker transport=\"sslsocket\">");
    buf.append("      <attribute name=\"serverBindAddress\">" + getHostName() + "</attribute>");
    buf.append("      <attribute name=\"serverBindPort\">" + freeport + "</attribute>");
    buf.append("      <attribute name=\"serverSocketFactory\">" + serverSocketFactoryClassname + "</attribute>");
    buf.append("   </invoker>");
    buf.append("</config>");
    
    ByteArrayInputStream bais = new ByteArrayInputStream(buf.toString().getBytes());
    Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bais);
    connector.setConfiguration(xml.getDocumentElement());

    The ServerSocketFactory class must have a default constructor, which will be used to create a ServerSocketFactory.

  5. Put the class name of a ServerSocketFactory in a configuration map, using key ServerInvoker.SERVER_SOCKET_FACTORY, and pass the map to one of the Connector constructors. The ServerSocketFactory class must have a default constructor, which will be used to create a ServerSocketFactory.

  6. Put a set of SSL parameters, using the keys in org.jboss.remoting.security.SSLSocketBuilder, in a configuration map and pass the map to one of the Connector constructors. These will be used by SSLSocketBuilder (see below) to create a CustomSSLServerSocketFactory.

  7. Configure an appropriate set of SSL system properties and use one of the SSL transports (https, sslrmi, or sslsocket). The properties will be used to create some kind of SSLServerSocketFactory, as determined by the transport.

  8. Use one of the non-SSL transports and do nothing. A default ServerSocketFactory will be constructed.

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 FactoryConfigSample and options 6 and 7 are illustrated in FactoryConfigSSLSample, both of which are in package org.jboss.remoting.samples.config.factories.

Timing considerations. See the discussion in the section on the creation of server socket factories on the server side.

5.7.2.2. Socket factories.

For SocketFactorys 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 (Client has no facility for parsing xml documents:

  1. Get the ClientInvoker by calling Client.getInvoker() and call ClientInvoker.setSocketFactory().

  2. Call Client.setSocketFactory().

  3. Put a constructed SocketFactory in a configuration map, using key Remoting.CUSTOM_SOCKET_FACTORY, and pass the map to one of the Client constructors.

  4. Put the class name of a SocketFactory in a configuration map, using key Remoting.SOCKET_FACTORY_CLASS_NAME, and pass the map to one of the Client constructors. The SocketFactory class must have a default constructor, which will be used to create a SocketFactory.

  5. Put a set of SSL parameters, using the keys in org.jboss.remoting.security.SSLSocketBuilder, in a configuration map and pass the map to one of the Client constructors. These will be used by SSLSocketBuilder (see below) to create a CustomSSLSocketFactory.

  6. Configure an appropriate set of SSL system properties and use one of the SSL transports (https, sslrmi, or sslsocket). The properties will be used to create some kind of SSLSocketFactory, as determined by the transport.

  7. Use one of the non-SSL transports and do nothing. Ordinary Sockets will be used.

Again, these are essentially in descending order of precedence. Options 1, 2, 3, and 4 are illustrated in FactoryConfigSample and options 5 and 6 are illustrated in FactoryConfigSSLSample, both of which are in package org.jboss.remoting.samples.config.factories.

Timing considerations. A SocketFactory is created in the constructor for RemoteClientInvoker, the ancestor of all current remote client invokers (that is, all client invokers except LocalClientInvoker, 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.

  1. https: HTTPSClientInvoker sets the socket factory on its HttpsURLConnection each time Client.invoke() is called. Option 1 may be used to reset the SocketFactory for future invocations at any time.

  2. sslrmi: A SocketFactory is either created or configured for future creation during Client.create(). No further configuration is possible.

  3. sslsocket: SSLSocketClientInvoker uses the current SocketFactory to create a new socket whenever it runs out of available pooled connections. Option 1 may be used to reset the SocketFactory for future connections at any time.

5.7.3. Server side configuration in the JBoss Application Server

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 SARDeployer (see The JBoss 4 Application Server Guide on the labs.jboss.org web site) can read information from a *-service.xml file, as discussed above in the section "General Connector and Invoker configuration," and use it to configure MBeans such as Connectors.

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.

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

  1. the JMX ObjectName of an MBean that implements the org.jboss.remoting.security.ServerSocketFactoryMBean interface, or

  2. the class name of a ServerSocketFactory with a default constructor.

An example of the first case would be:

<mbean code="org.jboss.remoting.transport.Connector"
       name="jboss.remoting:service=Connector,transport=Socket"
       display-name="Socket transport Connector">

   <attribute name="Configuration">
      <config>
         <invoker transport="sslsocket">
            <attribute name="serverSocketFactory">
               jboss.remoting:service=ServerSocketFactory,type=SSL
            </attribute>
            <attribute name="numAcceptThreads">1</attribute>
            ...

The serverSocketFactory attribute is processed as follows:

  1. Take its String value, create an ObjectName from it, and look up an MBean with that name from the MBeanServer that the invoker has been registered with (by way of the Connector). If an MBean with that name is found, create a proxy to it of type org.jboss.remoting.security.ServerSocketFactoryMBean. (Technically, a user could set the serverSocketFactory property with the locator url, but the preferred method is to use the explicit configuration via the invoker element's attribute, as discussed above.)

  2. If no MBean is found with a matching ObjectName, treat the serverSocketFactory attribute as a class name and try to create an instance using the default constructor.

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.

Note that these two options correspond exactly to options 4 and 5 in section Server socket factories (on the server side), which is how these two new options are implemented.

Timing considerations. If a Connector is accessed by way of the MBeanServer, then most of the options for configuring the server socket factory discussed in Server socket factories are irrelevant since ConnectorMBean does not expose methods for using them. However, when a Connector that is registered with an MBeanServer creates a server invoker during a call to Connector.create(), it also registers the server invoker with the same MBeanServer, which means that the server invoker is accessible by way of its ObjectName, which has the form

jboss.remoting:service=invoker,transport=socket,host=www.jboss.com,port=8765

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 ObjectNames.) Now, if another MBean is configured in a *-service.xml file to be dependent on the server invoker MBean, e.g.

<mbean code="org.jboss.BlueMonkey" name="jboss.remoting:bluemonkey,name=diamond">
   <depends optional-attribute-name="serverInvoker">
      jboss.remoting:service=invoker,transport=socket,host=www.jboss.com,port=8765
   </depends>
</mbean>

then org.jboss.BlueMonkey.create() will have access to the designated server invoker after the invoker has been created but before it has been started, which means that ServerInvoker.setServerSocketFactory() will be effective. (See the The JBoss 4 Application Server Guide, Chapter 2, for more information about the life cycle of JBoss MBeans.)

5.7.4. Client side configuration from the JBoss Application Server

As described in sections Declarative configuration: MBeans and Declarative configuration: POJOs, the declarative xml files used by the Application Server can be used to configure the client by way of the parameters included in the InvokerLocator. However, a peculiarity in the way socket factories are created on the client restricts the parameters taken into consideration to those passed in the configuration map passed to the org.jboss.remoting.Client constructor. The following two parameters, introduced in releases 2.4.0.SP1 and 2.5.2, respectively, eliminate that restriction.

org.jboss.remoting.Remoting.SOCKET_FACTORY_NAME (actual value is 'socketFactory') - key for giving the name of the socket factory class to be used by clients.

org.jboss.remoting.Remoting.USE_ALL_SOCKET_FACTORY_PARAMS (actual value is 'useAllSocketFactoryParams') - key for indicating that all socket factory parameters in the InvokerLocator should be used by clients.

Note that the parameter org.jboss.remoting.Remoting.CONFIG_OVERRIDES_LOCATOR (actual value "configOverridesLocator"), described in section org.jboss.remoting.Remoting, is also relevant.

5.7.5. Socket creation listeners

Every Remoting transport uses Sockets, but the creation and management of the Sockets is generally inaccessible from the application code. Remoting has a hook that can provide access to Sockets, in the form of a listener interface in the org.jboss.remoting.socketfactory package:

public interface SocketCreationListener
{
   /**
    * Called when a socket has been created.
    * 
    * @param socket socket that has been created
    * @param source SocketFactory or ServerSocket that created the socket
    * @throws IOException
    */
   void socketCreated(Socket socket, Object source) throws IOException;
}

Socket creation listeners can be registered to be informed every time a socket is created by a SocketFactory or ServerSocket. The mechanisms for registering listeners are the usual ones, e.g., by putting them in configuration maps passed to client and server invokers. (See Section General transport configuration for a general discussion of parameter configuration in Remoting.) In any case they should be associated with one of the following keys from org.jboss.remoting.Remoting:

/**
 * Key for the configuration map passed to a Client or Connector to indicate
 * a socket creation listener for sockets created by a SocketFactory.
 */
public static final String SOCKET_CREATION_CLIENT_LISTENER = "socketCreationClientListener";
      
/**
 * Key for the configuration map passed to a Client or Connector to indicate
 * a socket creation listener for sockets created by a ServerSocket.
 */
public static final String SOCKET_CREATION_SERVER_LISTENER = "socketCreationServerListener";

The value associated with either of these keys can be an actual object, or, to facilitate configuration by InvokerLocator or xml, it can be the name of a class that implements SocketCreationListener and has a default constructor

Note that client and server invokers always use the respective keys SOCKET_CREATION_CLIENT_LISTENER and SOCKET_CREATION_SERVER_LISTENER, whether they are on the client side or server side. For example, a callback client invoker would be configured by putting a listener with the key SOCKET_CREATION_CLIENT_LISTENER in the configuration map passed to the server side Connector, which will find its way to the callback client invoker when a callback handler is registered.

The creation listener facility currently is supported by the following transports: bisocket, sslbisocket, https, rmi, sslrmi, socket, and sslsocket. It is not supported by http because HttpURLConnection does not expose its socket factory (though HttpsURLConnection does). It is not supported by the servlet transport because invocations with the servlet transport go through a servlet container, which is outside the scope of Remoting.

5.7.6. SSL transports

There are now four transports that support SSL: https, sslrmi, and sslsocket (plus sslservlet, which is not relevant here). All of the 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.

https

Configuration of the https transport is a bit different from that of the other transports since the implementation is based off the Tomcat connectors. One difference is that, in order to use SSL connections, the SSLImplementation attribute must be set and must always have the value org.jboss.remoting.transport.coyote.ssl.RemotingSSLImplementation. The SSLImplementation is used by the Tomcat connector to create ServerSocketFactorys, and RemotingSSLImplementation presents Tomcat with the ServerSocketFactory configured according to the options described above.

An example of setting up https via service.xml configuration would be:

<mbean code="org.jboss.remoting.transport.Connector"
       name="jboss.remoting:service=Connector,transport=HTTPS"
       display-name="HTTPS transport Connector">

   <attribute name="Configuration">
      <config>
         <invoker transport="https">
            <attribute name="serverSocketFactory">
               jboss.remoting:service=ServerSocketFactory,type=SSL
            </attribute>
            <attribute name="SSLImplementation">
               org.jboss.remoting.transport.coyote.ssl.RemotingSSLImplementation
            </attribute>
            <attribute name="serverBindAddress">${jboss.bind.address}</attribute>
            <attribute name="serverBindPort">6669</attribute>
         </invoker>
         <handlers>
            <handler subsystem="mock">
               org.jboss.test.remoting.transport.mock.MockServerInvocationHandler
            </handler>
         </handlers>
      </config>
   </attribute>
   <!-- This depends is included because need to make sure
        this mbean is running before configure invoker. -->
   <depends>jboss.remoting:service=ServerSocketFactory,type=SSL</depends>
</mbean>

See section SSLServerSocketFactoryService below for a discussion of the "jboss.remoting:service=ServerSocketFactory,type=SSL" MBean that appears in this configuration element.

Note that the configuration for SSL support only works when using the java based http processor and not with the APR based transport. See section HTTP Invoker for more information on using the APR based transport.

sslrmi

The extra twist in the sslrmi invoker is that the server invoker creates the (client) socket factory and packages it with its own stub, from which it follows that the socket factory must be serializable. If the sslrmi server invoker is allowed to create an SSLSocketFactory from SSL parameters, it will take care to create a serializable socket factory. In particular, the server invoker creates a copy of org.jboss.remoting.transport.rmi.ssl.SerializableSSLClientSocketFactory, 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 an sslrmi client invoker is created, it stores its own configuration map in a static variable which the transferred SerializableSSLClientSocketFactory 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 SerializableSSLClientSocketFactory will use it. If not, then SerializableSSLClientSocketFactory will use any key store and trust store information passed to the client to create and configure a socket factory.

Note. If instead of using SerializableSSLClientSocketFactory, a socket factory is passed in to the server invoker by one of the methods discussed above, then the user is responsible for supplying a serializable socket factory.

sslsocket

In addition to the various configuration options discussed above, the sslsocket transport exposes the

public void setServerSocketFactory(ServerSocketFactory serverSocketFactory)

method as a JMX operation.

Also, the sslsocket server invoker inherits from the socket server invoker a method with signature

public void setNewServerSocketFactory(ServerSocketFactory serverSocketFactory)

which supports dynamic replacement of server socket factories. The principal motivation for this facility is to be able to swap in a new SSLServerSocketFactory configured with an updated keystore.

5.7.7. SSLSocketBuilder

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 org.jboss.remoting.security.SSLSocketBuilder, 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.

Once a SSLSocketBuilder has been constructed and configured, a call to its method createSSLServerSocketFactory() will return a custom instance of a SSLServerSocketFactory, and a call to createSSLSocketFactory() will return a custom instance of SSLSocketFactory.

There are two modes in which the SSLSocketBuilder can be run. The first is the default mode where all that is needed is to declare the SSLSocketBuilder and set the system properties javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword. This will use the JVM vendor's default configuration for creating the SSL server socket factory.

In order to customize any of the SSL properties, the first requirement is that the default mode is turned off. This is IMPORTANT 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 UseSSLServerSocketFactory attribute to false. This can also be done programmatically by calling the setUseSSLServerSocketFactory() and passing false as the parameter value.

There are two ways to configure a SSLSocketBuilder

  1. set its bean attributes, either programmatically or by xml configuration, or

  2. pass to a SSLSocketBuilder constructor a configuration map with keys defined in the SSLSocketBuilder class.

The configuration properties for SSLSocketBuilderare as follows. Note that in the "key name" column, the name in capital letters (e.g., REMOTING_CLIENT_AUTH_MODE) is a handy constant in the SSLSocketBuilder class with the value given in parentheses (e.g. "org.jboss.remoting.clientAuthMode"). It is the latter that should be used for declarative configuration in, for example, MBean descriptors.

Table 5.1. SSLSocketBuilder configuration parameters.

attribute

key name

type

default

description

ClientAuthMode

REMOTING_CLIENT_AUTH_MODE ("org.jboss.remoting.clientAuthMode")

String

need

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".

KeyAlias

REMOTING_KEY_ALIAS ("org.jboss.remoting.keyAlias")

String

The preferred identity in key store to be used by key managers

KeyPassword

REMOTING_KEY_PASSWORD ("org.jboss.remoting.keyPassword")

String

Sets the password to use for the keys within the key store. This only needs to be set if setUseSSLServerSocketFactory() 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.

KeyStoreAlgorithm

REMOTING_KEY_STORE_ALGORITHM ("org.jboss.remoting.keyStoreAlgorithm")

String

SunX509

The algorithm for the key manager factory.

KeyStorePassword

REMOTING_KEY_STORE_PASSWORD ("org.jboss.remoting.keyStorePassword")

String

The password to use for the key store. This only needs to be set if setUseSSLServerSocketFactory() 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.

KeyStoreType

REMOTING_KEY_STORE_TYPE ("org.jboss.remoting.keyStoreType")

String

JKS

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.

KeyStoreURL

REMOTING_KEY_STORE_FILE_PATH ("org.jboss.remoting.keyStore")

String

Property used to define where SSLSocketBuilder 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. It can also be set to "NONE", in which case the keystore will be initialized but not populated from a file. This feature might be useful in the case of a PKCS#11 smart card.

Provider

none

java.security.Provider

Java Security API implementation to use.

ProviderName

REMOTING_SSL_PROVIDER_NAME ("org.jboss.remoting.sslProviderName")

String

Name of Java Security API implementation to use.

SecureRandom

none

java.security.SecureRandom

new SecureRandom()

Random number generator to use.

SecureSocketProtocol

REMOTING_SSL_PROTOCOL ("org.jboss.remoting.sslProtocol")

String

TLS

The protocol for the SSLContext. Some acceptable values are TLS, SSL, and SSLv3

ServerAuthMode

REMOTING_SERVER_AUTH_MODE ("org.jboss.remoting.serverAuthMode")

boolean/String

true

Determines if a client should attempt to authenticate a server certificate as one it trusts.

ServerSocketUseClientMode

REMOTING_SERVER_SOCKET_USE_CLIENT_MODE ("org.jboss.remoting.serversocket.useClientMode")

boolean/String

false

Determines if the server sockets will be in client or server mode.

SocketUseClientMode

REMOTING_SOCKET_USE_CLIENT_MODE ("org.jboss.remoting.socket.useClientMode")

boolean/String

true

Determines if the sockets will be in client or server mode.

TrustStoreAlgorithm

REMOTING_TRUST_STORE_ALGORITHM ("org.jboss.remoting.trustStoreAlgorithm")

String

value of KeyStoreAlgorithm, or SunX509 if KeyStoreAlgorithm is not set

trust store key management algorithm

TrustStorePassword

REMOTING_TRUST_STORE_PASSWORD ("org.jboss.remoting.trustStorePassword")

String

trust store password

TrustStoreType

REMOTING_TRUST_STORE_TYPE ("org.jboss.remoting.trustStoreType")

String

value of KeyStoreType, or JKS if KeyStoreType is not set

type of trust store

TrustStoreURL

REMOTING_TRUST_STORE_FILE_PATH ("org.jboss.remoting.trustStore")

String

location of trust store. It can also be set to "NONE", in which case the truststore will be initialized but not populated from a file. This feature might be useful in the case of a PKCS#11 smart card.

UseSSLServerSocketFactory

none

boolean

true

Determines if default SSLServerSocketFactory should be created.

UseSSLSocketFactory

none

boolean

true

Determines if default SSLSocketFactory should be created.

Note. If any of the attributes KeyStoreURL, KeyStorePassword, KeyStoreType, TrustStoreURL, TrustStorePassword, or TrustStoreType are left unconfigured, SSLSocketBuilder 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 KeyStoreType and TrustStoreType, SSLSocketBuilder will then go on to use default values after checking the system properties.

The following is an example of configuring a SSLSocketBuilder and using it to create a custom SSLSocketFactory:

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();
}

More examples of configuring SSLSocketBuilder can be found in the class FactoryConfigSSLSample in the package org.jboss.remoting.samples.config.factories.

The following is an example of configuring SSLSocketBuilder in a *-service.xml file:

<!-- This service is used to build the SSL Server socket factory -->
<!-- This will be where all the store/trust information will be set. -->
<!-- If do not need to make any custom configurations, no extra attributes -->
<!-- need to be set for the SSLSocketBuilder and just need to set the -->
<!-- javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword system properties. -->
<!-- This can be done by just adding something like the following to the run -->
<!-- script for JBoss -->
<!-- (this one is for run.bat): -->
<!-- set JAVA_OPTS=-Djavax.net.ssl.keyStore=.keystore -->
<!-- -Djavax.net.ssl.keyStorePassword=opensource %JAVA_OPTS% -->
<!-- Otherwise, if want to customize the attributes for SSLSocketBuilder, -->
<!-- will need to uncomment them below. -->
<mbean code="org.jboss.remoting.security.SSLSocketBuilder"
       name="jboss.remoting:service=SocketBuilder,type=SSL"
       display-name="SSL Server Socket Factory Builder">
   <!-- IMPORTANT - If making ANY customizations, this MUST be set to false. -->
   <!-- Otherwise, will used default settings and the following attributes will be ignored. -->
   <attribute name="UseSSLServerSocketFactory">false</attribute>
   <!-- This is the url string to the key store to use -->
   <attribute name="KeyStoreURL">.keystore</attribute>
   <!-- The password for the key store -->
   <attribute name="KeyStorePassword">opensource</attribute>
   <!-- The password for the keys (will use KeystorePassword if this is not set explicitly. -->
   <attribute name="KeyPassword">opensource</attribute>
   <!-- The protocol for the SSLContext. Default is TLS. -->
   <attribute name="SecureSocketProtocol">TLS</attribute>
   <!-- The algorithm for the key manager factory. Default is SunX509. -->
   <attribute name="KeyManagementAlgorithm">SunX509</attribute>
   <!-- The type to be used for the key store. -->
   <!-- Defaults to JKS. 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. -->
   <attribute name="KeyStoreType">JKS</attribute>
</mbean>

It is also possible to set the default socket factory to be used when not using customized settings (meaning UseSSLSocketFactory property value is true, which is the default). This can be done by setting system property of org.jboss.remoting.defaultSocketFactory to the fully qualified class name of the javax.net.SocketFactory implementation to use. Will then call the getDefault() method on that implementation to get the SocketFactory instance to use.

5.7.8. SSLServerSocketFactoryService

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 org.jboss.remoting.security.SSLServerSocketFactoryService class. The SSLServerSocketFactoryService class extends the javax.net.ServerSocketFactory class and also implements the SSLServerSocketFactoryServiceMBean interface (so that it can be set using the socketServerFactory attribute described previously). Other than providing the proper interfaces, this class is a simple wrapper around the org.jboss.remoting.security.SSLSocketBuilder class.

The following is an example of configuring SSLServerSocketFactoryService in a *-service.xml file. Note that it depends on the SSLSocketBuilder MBean defined in the xml fragment above:

<!-- This service provides the exact same API as the ServerSocketFactory, so -->
<!-- can be set as an attribute of that type on any MBean requiring an ServerSocketFactory. -->
<mbean code="org.jboss.remoting.security.SSLServerSocketFactoryService"
       name="jboss.remoting:service=ServerSocketFactory,type=SSL"
       display-name="SSL Server Socket Factory">
   <depends optional-attribute-name="SSLSocketBuilder"
            proxy-type="attribute">jboss.remoting:service=SocketBuilder,type=SSL</depends>
</mbean>

5.7.9. General Security How To

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.

To get started, will need to create key store and trust store.

Generating key entry into keystore:

C:\tmp\ssl>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 <remoting>
(RETURN if same as keystore password):

Since did not specify the -keystore filename parameter, created the keystore in $HOME/.keystore (or C:\Documents and Settings\Tom\.keystore).

Export the RSA certificate (without the private key)

C:\tmp\ssl>keytool -export -alias remoting -file remoting.cer
Enter keystore password: opensource
Certificate stored in file <remoting.cer>

Import the RSE certificate into a new truststore file.

C:\tmp\ssl>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

Now have two files, .keystore for the server and .truststore for the client.

5.7.10. Troubleshooting Tips

Common errors when using server socket factory:

javax.net.ssl.SSLException: No available certificate corresponds to the SSL cipher suites
                            which are enabled.

The 'javax.net.ssl.keyStore' system property has not been set and are using the default SSLServerSocketFactory.

java.net.SocketException: Default SSL context init failed: Cannot recover key

The 'javax.net.ssl.keyStorePassword' system property has not been set and are using the default SSLServerSocketFactory.

java.io.IOException: Can not create SSL Server Socket Factory due to the url to the key store
                     not being set.

The default SSLServerSocketFactory is NOT being used (so custom configuration for the server socket factory) and the key store url has not been set.

java.lang.IllegalArgumentException: password can't be null

The default SSLServerSocketFactory is NOT being used (so custom configuration for the server socket factory) and the key store password has not been set.

5.8. Timeouts

The handling of timeouts in Remoting is surveyed in this section. On the whole, timing out network connections is handled differently by each transport, but there are some transport independent methods for timeout configuration, extended by some transport specific methods.

5.8.1. General timeout configuration

As with all configuration parameters, there are several avenues for specifying parameter values. See Section General transport configuration for a general discussion of parameter configuration in Remoting. The transport independent key for setting timeouts is "timeout", also available as org.jboss.remoting.ServerInvoker.TIMEOUT. All server invokers also have the getter/setter methods

public int getTimeout();

public void setTimeout(int timeout);

where the values are given in milliseconds. The default timeout value is 60000 for server invokers.

5.8.2. Per invocation timeouts

As of version 2.4, all Remoting transports offer a per invocation transport facility, which allows a timeout value to be set for a particular invocation, overriding the client invoker's previously configured timeout value. The per invocation timeout is set by passing the String representation of the timeout value in the invocation's metadata map, using the key "timeout". For example,

HashMap metadata = new HashMap();
metadata.put("timeout", "2000");
client.invoke("testInvocation", metadata);

will allow approximately 2 seconds for this particular invocation, after which the timeout value will be reset to its previously configured value.

Each transport handles per invocation timeouts a little differently. More details are given below.

5.8.3. Transport specific timeout handling

5.8.3.1. Socket and bisocket transports

These two transports are handled together because bisocket inherits most of its timeout handling from socket. The discussion also applies to their SSL versions, sslbisocket and sslsocket. On the server side, the timeout value, whatever the source of its value, is used to set the timeout value of all Sockets managed by the server invoker's worker threads. On the client side, the configured timeout value is used to limit the time required by Socket.connect() when a new Socket is created, as well as to set the Socket timeout value for all connections in its connection pool.

The socket and bisocket transports support per invocation timeouts. The processing subject to the timeout period starts when the client invoker begins to acquire a network connection and extends to the point at which it begins reading the reponse to the invocation. Note that the acquisition of the network connection might involve multiple attempts to connect to the server.

5.8.3.1.1. Write timeouts

The socket timeout facility offered by the JDK applies only to read operations on the socket. As of release 2.5.2, the socket and bisocket (and also sslsocket and sslbisocket) transports offer a write timeout facility. When a client or server is configured, in any of the usual ways, with the parameter org.jboss.remoting.transport.socket.SocketWrapper.WRITE_TIMEOUT (actual value "writeTimeout") set to a positive value (in milliseconds), all write operations will time out if they do not complete within the configured period. When a write operation times out, the socket upon which the write was invoked will be closed, which is likely to result in a java.net.SocketException.

Note. A SocketException is considered to be a "retriable" exception, so, if the parameter "numberOfCallRetries" is set to a value greater than 1, an invocation interrupted by a write timeout can be retried.

Note. The write timeout facility applies to writing of both invocations and responses. It applies to push callbacks as well.

5.8.3.2. HTTP and HTTPS transports

The http server invoker looks for a configured timeout value at initialization time, which it uses to set the "connectionTimeout" property on its Tomcat connector. (See Section HTTP Invoker for more information.) Note that subsequent calls to setTimeout() will have no effect.

The http client invoker treats timeouts configured for the connection and per invocation timeouts the same, since it opens a new HttpURLConnection with each invocation. Any nonnegative per invocation timeout value will override a timeout value configured at client invoker creation time.

If the application is using a jdk of generation 1.5 or later, then the client invoker will use the java.net.HttpURLConnection methods setConnectTimeout() and setReadTimeout() methods. Note that in this case the timeout value will be allowed twice, once to create the connection and once to read the invocation result.

If an earlier jdk is being used, the client invoker will simulate a timeout by making the connection and executing the invocation in a separate thread, which it waits on for the specified timeout. The threads are drawn from a thread pool, which is configurable. A custom thread pool may be set by calling the HTTPClientInvoker method

public void setTimeoutThreadPool(org.jboss.util.threadpool.ThreadPool pool);

where the ThreadPool interface is available from the anonomous JBoss svn repository at http://anonsvn.jboss.org/repos/common/common-core/trunk/src/main/java/. If a thread pool is not set, it will default to an instance of org.jboss.util.threadpool.BasicThreadPool, which may be configured with the following parameters, defined as constants in org.jboss.remoting.transport.http.HTTPClientInvoker:

MAX_NUM_TIMEOUT_THREADS (actual value "maxNumTimeoutThreads"): the number of threads in the threadpool. The default value is 10.

MAX_TIMEOUT_QUEUE_SIZE (actual value "maxTimeoutQueueSize"): the size of the thread pool queue, which holds execution requests when all of the threads are in use. The default value is 1024.

5.8.3.3. RMI and SSLRMI transports

Connection timeouts are handled on the server side by passing the configured timeout value to the org.jboss.remoting.transport.rmi.RemotingRMIClientSocketFactory and org.jboss.remoting.transport.rmi.RemotingRMIServerSocketFactory objects passed when the org.jboss.remoting.transport.RMIServerInvoker is exported by the java.rmi.server.UnicastRemoteObject.exportObject() method.

org.jboss.remoting.transport.rmi.RMIClientInvoker handles per invocation timeouts by executing the invocation in a separate thread, which it waits on for the specified timeout. The threads are drawn from a org.jboss.util.threadpool.BasicThreadPool, which may be configured with the following parameters, defined as constants in org.jboss.remoting.transport.rmi.RMIClientInvoker:

MAX_NUM_TIMEOUT_THREADS (actual value "maxNumTimeoutThreads"): the number of threads in the threadpool. The default value is 10.

MAX_TIMEOUT_QUEUE_SIZE (actual value "maxTimeoutQueueSize"): the size of the thread pool queue, which holds execution requests when all of the threads are in use. The default value is 1024.

5.8.3.4. Quick client disconnect

org.jboss.remoting.Client applies per invocation timeouts in its removeListener() and disconnect() methods to create a "quick disconnect" facility. If, for example, an org.jboss.remoting.ConnectionValidator (see Network Connection Monitoring) reports its suspicion that a connection is failing, the application might want to restrict, or even eliminate, the time spent trying to access the network while unregistering callback handlers and disconnecting. The quick disconnect facility is invoked by calling the Client method

public void setDisconnectTimeout(int disconnectTimeout);

to set the disconnect timeout value to a nonnegative value. If the disconnect timeout value is set, it will be applied as the per invocation timeout value for all network activity in the methods removeListener() and disconnect(). As a special case, if the disconnect timeout value is set to 0, Client will simply skip any network i/o in these two methods.

5.9. Running with a security manager

As of version 2.4, Remoting is prepared to run in the presence of an installed java.lang.SecurityManager. In Java, certain security sensitive system calls, e.g., java.io.File.exists(), java.lang.Class.getClassLoader(), and java.lang.System.getProperty(), consult a SecurityManager, if one has been installed, to determine if the calling code has permission to execute the action performed by the method.

In fact, the standard behavior is for the Java Virtual Machine to examine, not only the calling code, but all methods on the stack, for the appropriate permissions. This strategy prevents untrusted code from using trusted code for its own nefarious purposes. However, the same strategy could prevent trusted code from accomplishing security sensitive activities without granting suitable permissions to any code that calls the trusted code. The loophole that gets around this problem is the ability to wrap security sensitive method calls in a "privileged block" which prevents the JVM from proceeding up the stack. In other words, the code in the privileged block can employ its granted permissions even if the calling code does not have those same permissions.

More precisely, a privileged block consists of an java.security.PrivilegedAction or java.security.PrivilegedExceptionAction object passed to a java.security.AccessController.doPrivileged() call. As of version 2.4, Remoting wraps all security sensitive method calls appropriately. For example, the call java.net.ServerSocket.accept() has been replaced by org.jboss.remoting.utility.SecurityUtility.accept():

static public Socket accept(final ServerSocket ss) throws IOException
{
   if (skipAccessControl)
   {
      return ss.accept();
   }

   try
   {
      return (Socket)AccessController.doPrivileged( new PrivilegedExceptionAction()
      {
         public Object run() throws Exception
         {
            return ss.accept();
         }
      });
   }
   catch (PrivilegedActionException e)
   {
      throw (IOException) e.getCause();
   }
}

Note that the AccessController.doPrivileged() call, with its creation of a PrivilegedExceptionAction object, is made only if the static variable SecurityUtility.skipAccessControl is set to false, which is the case if

  • no SecurityManager is installed, or

  • the system property org.jboss.remoting.Remoting.SKIP_ACCESS_CONTROL is set to "false".

The Remoting code needs quite a few permissions since it interacts extensively with the network, file system, etc., and there are a couple of strategies for granting these permissions. The standard java.lang.SecurityManager can read permission information from an XML file, as described in http://java.sun.com/j2se/1.5.0/docs/guide/security/PolicyFiles.html, and one straightforward strategy is to treat Remoting as highly trusted code and to give it all possible permissions in a file that looks like

grant codeBase "file:${remoting.dir}/jboss-remoting.jar"
{
   permission java.security.AllPermission;
};

This file grants all permissions to any class loaded from jboss-remoting.jar. Alternatively, a more precisely tailored set of permissions can be crafted to give Remoting, or some subset of its facilities, sufficient permissions to function. The Remoting distribution contains a sample permission set in etc/remoting.security.policy.core. It may be necessary or desirable to modify the file, according to which Remoting components are used, where certain files are located, etc:

  1. It may be necessary to change the java.io.FilePermission permissions, according to the configuration of certain files.

  2. If Remoting is configured to operate with one or more MBeans in place of POJOs, it might be necessary to grant additional MBeanPermissions.

  3. Some facilities always use MBeans. The MBean permissions given in remoting.security.policy.core may be restricted to particular ObjectNames.

  4. Some permission may be eliminated, according to which Remoting facilities are used.

Other than changes made according to items 1 and 2, it should not be necessary to grant any additional permissions.

The etc directory also contains the policy files remoting.security.policy.tests, remoting.security.policy.tests.marshal, and remoting.security.policy.tests.minimal, which are used by the Remoting functional test suite. These files give examples of modifying the permissions given in remoting.security.policy.core.

Note. As of release 2.5.3, state changing methods of org.jboss.remoting.InvokerRegistry require permission java.lang.RuntimePermission("invokerRegistryUpdate"). These methods are

  • createClientInvoker()

  • createServerInvoker()

  • destroyClientInvoker()

  • destroyServerInvoker()

  • isSSLSupported()

  • registerInvokerFactories()

  • unregisterInvokerFactories()

  • unregisterLocator()

  • updateServerInvokerLocator()

Sample policy file etc/remoting.security.policy.core has been modified accordingly.

5.10. Wire version

Remoting has, on occasion, changed the format of communications over the network, which could make it difficult for one version of Remoting to communcate with another version. However, it is possible to configure newer versions to communicate with older versions.

There are currently three wire versions:

  • org.jboss.remoting.Version.VERSION_1 (actual value 1), used by Remoting versions 1.2 and 1.4;
  • org.jboss.remoting.Version.VERSION_2 (actual value 2), used by Remoting version 2.0; and
  • org.jboss.remoting.Version.VERSION_22 (actual value 22), used by Remoting versions 2.2 and 2.4.

Versinos 2.0, 2.2, and 2.4 can be configured to communicate with versions 1.2 and 1.4 in one of three ways:

  1. set system property org.jboss.remoting.Version.PRE_2_0_COMPATIBLE (actual value "jboss.remoting.pre_2_0_compatible") to "true";

  2. set system property org.jboss.remoting.Version.REMOTING_VERSION_TO_USE (actual value "jboss.remoting.version") to org.jboss.remoting.Version.VERSION_1 (actual version "1");

  3. configure the org.jboss.remoting.Client or org.jboss.remoting.transport.Connector with the parameter org.jboss.remoting.Remoting.REMOTING_VERSION (actual value "remotingVersion") set to org.jboss.remoting.Version.VERSION_1 (actual version "1").

Similarly, versions 2.2 and 2.4 can be configured to communicate with version 2.0:

  1. set system property org.jboss.remoting.Version.REMOTING_VERSION_TO_USE (actual value "jboss.remoting.version") to org.jboss.remoting.Version.VERSION_2 (actual version "2");

  2. configure the org.jboss.remoting.Client or org.jboss.remoting.transport.Connector with the parameter org.jboss.remoting.Remoting.REMOTING_VERSION (actual value "remotingVersion") set to org.jboss.remoting.Version.VERSION_2 (actual version "2").

Versions 2.2. and 2.4 use the same wire format, so there's no need to configure version 2.4 to communicate with version 2.2.

Note. Setting these versions is not necessary in all circumstances. For example, it is not necessary when using JBossSerialization. But, upon encountering a problem when using mismatched clients and servers, be sure that the versions are set properly.

5.11. Configuration by properties

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.

5.11.1. org.jboss.remoting.InvokerLocator

SERVER_BIND_ADDRESS (actual value is 'jboss.bind.address') - indicates the system property key for bind address that should be used.

BIND_BY_HOST (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).

DATATYPE (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 automatically registered with the MarshalFactory and associated by default with 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:

socket://myhost:6500/?datatype=test

which would cause the socket invoker to use the marshaller and unmarshaller registered with the MarshalFactory under the datatype 'test'. Of course, this requires that the marshaller and unmarshaller implementations to be used have already been registered with the MarshalFactory (otherwise will get an exception).

SERIALIZATIONTYPE (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.

MARSHALLER (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).

UNMARSHALLER (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, have a void constructor, and implement the org.jboss.remotng.marshal.UnMarshaller interface).

LOADER_PORT (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 the server 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:

socket://myhost:6500/?datatype=test&loaderport=6501&
        marshaller=org.jboss.test.remoting.marshall.dynamic.remote.http.TestMarshaller&
        unmarshaller=org.jboss.test.remoting.marshall.dynamic.remote.http.TestUnMarshaller

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 retrieved from the server, will be registered locally, so is a one time only event (as next time will be found in the registry).

This can work for loading any remote server classes, but requires the loaderport be included in the invoker locator url.

BYVALUE (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'. In releases prior to 2.0.0, using this configuration setting would have forced invokers to be remote, which can now be done via FORCE_REMOTE config (see below).

FORCE_REMOTE (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'.

CLIENT_LEASE (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'.

CLIENT_LEASE_PERIOD (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.

SUPPRESS_HOST_WARNING (actual value is 'suppressHostWarning') - the boolean valued system property that determines if InvokerLocator should log a warning that the hostname is null. The default value is "false", i.e., the warning is logged by default.

5.11.2. org.jboss.remoting.Client

RAW (actual value is 'rawPayload') - key to use for the metadata Map passed when making an 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 an http POST request to a web service).

ENABLE_LEASE (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.

HANDSHAKE_COMPLETED_LISTENER (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.

USE_ALL_PARAMS (actual value is 'useAllParameters') - used by org.jboss.remoting.ConnectionValidator and org.jboss.remoting.callback.CallbackPoller to determine if configuration parameters should be retrieved from the InvokerLocator or the Client's configuration map.

The following three configuration properties are only useful when using one of the following Client methods:

public void addListener(
        InvokerCallbackHandler callbackhandler, Map metadata,
        Object callbackHandlerObject) throws Throwable
public void addListener(
        InvokerCallbackHandler callbackhandler, Map metadata,
        Object callbackHandlerObject, boolean serverToClient) throws Throwable

CALLBACK_SERVER_PROTOCOL (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, etc.).

CALLBACK_SERVER_HOST (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().

CALLBACK_SERVER_PORT (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.

Bean properties (meaning have getter/setter):

SessionId - 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.

Subsystem - 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.

MaxNumberOfThreads - 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).

OnewayThreadPool - the thread pool being used for making one way invocations on the client side. If one has not been specifically set via configuration or call to set it, will always return instance of org.jboss.util.threadpool.BasicThreadPool.

SocketFactory - 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.

Marshaller - the marshaller implementation that should be used by the client invoker (transport). This overrides the client's default marshaller (or any set within configuration).

UnMarshaller - the unmarshaller implementation that should be used by the client invoker (transport). This overrides the client's default unmarshaller (or any set within configuration).

5.11.3. org.jboss.remoting.Remoting

CUSTOM_SERVER_SOCKET_FACTORY (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.

CUSTOM_SOCKET_FACTORY (actual value is 'customSocketFactory') - key for the configuration map passed to a Client to indicate the socket factory to be used. Value must be instance of javax.net.SocketFactory.

SOCKET_FACTORY_CLASS_NAME (actual value is 'socketFactoryClassName') - 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.

SOCKET_CREATION_CLIENT_LISTENER (actual value is "socketCreationClientListener") - key for the configuration map passed to a Client or Connector to indicate a socket creation listener for sockets created by a SocketFactory.

SOCKET_CREATION_SERVER_LISTENER (actual value is "socketCreationServerListener") - key for the configuration map passed to a Client or Connector to indicate a socket creation listener for sockets created by a ServerSocket.

CLIENT_ADDRESS (actual value is "clientAddress") - key with which host address of client will be associated in InvocationRequest request payload.

REMOTING_VERSION (actual value is "remotingVersion") - key for configuring Remoting wire version.

SKIP_ACCESS_CONTROL (actual value is "skipAccessControl") - key for telling Remoting to execute security sensitive code outside of java.security.AccessController.doPrivileged() calls..

CONFIG_OVERRIDES_LOCATOR (actual value is "configOverridesLocator") - key for indicating that parameter values found in the configuration map passed to an org.jboss.remoting.Client constructor should take precedence over values found in the InvokerLocator.

USE_CLIENT_CONNECTION_IDENTITY (actual value "useClientConnectionIdentity") - tells Remoting to adhere to the new "connection identity" semantics described in Chapter Network Connection Monitoring.

PASS_CONFIG_MAP_TO_MARSHAL_FACTORY (actual value "passConfigMapToMarshalFactory") - if set to "true", tells clients and servers to take parameters for configuring marshallers and unmarshallers from the configuration map passed to Clients and Connectors in addition to the parameters in the InvokerLocator.

5.11.4. org.jboss.remoting.ServerInvoker

MAX_NUM_ONEWAY_THREADS_KEY (actual value is 'maxNumThreadsOneway') - key for the maximum number of threads 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.

ONEWAY_THREAD_POOL_CLASS_KEY (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.

SERVER_BIND_ADDRESS_KEY (actual value is 'serverBindAddress') - key for setting the address the server invoker should bind to. The value can be either host name or IP.

CLIENT_CONNECT_ADDRESS_KEY (actual value is 'clientConnectAddress') - key for setting the address 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.

SERVER_BIND_PORT_KEY (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.

CLIENT_CONNECT_PORT_KEY (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.

CLIENT_LEASE_PERIOD (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 queries server for leasing information.

TIMEOUT (actual value is 'timeout') - key for setting the timeout value (in milliseconds) for socket connections.

SERVER_SOCKET_FACTORY (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()), or, if not a JMX ObjectName, will assume is the fully qualified classname to the implementation to be used and will load the class and 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.

BLOCKING_MODE (actual value is "blockingMode"): if set to ServerInvoker.BLOCKING (actual value "blocking"), org.jboss.remoting.Client.getCallbacks() will do blocking pull callbacks and CallbackPoller will do blocking polled callbacks; if set to ServerInvoker.NONBLOCKING (actual value "nonblocking"), Client.getCallbacks() will do non-blocking pull callbacks and CallbackPoller will do non-blocking polled callbacks.

BLOCKING_TIMEOUT (actual value is "blockingTimeout"): the timeout value used for blocking callback.

REGISTER_CALLBACK_LISTENER (actual value is "registerCallbackListener"): determines if org.jboss.remoting.callback.ServerInvokerCallbackHandlers should register as org.jboss.remoting.ConnectionListeners with leases. The default value is "true".

Bean properties (meaning have getter/setter):

ServerSocketFactory - implementation of javax.net.ServerSocketFactory to be used by the server invoker. This takes precedence over any other configuration for the server socket factory.

Timeout - timeout (in milliseconds) for socket connection. If set after create() method called, this value will override value set by TIMEOUT key.

LeasePeriod - 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 queries server for leasing information. If set after create() method called, this value will override value set by CLIENT_LEASE_PERIOD key.

MaxNumberOfOnewayThreads - the maximum number of threads 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.

OnewayThreadPool - the oneway thread pool to use.

5.11.5. org.jboss.remoting.callback.CallbackPoller

CALLBACK_POLL_PERIOD (actual value is 'callbackPollPeriod') - key for setting the frequency (in milliseconds) in which Client's internal callback poller should poll server for waiting callbacks. The default value is five seconds.

CALLBACK_SCHEDULE_MODE (actual value is "scheduleMode"): may be set to either CallbackPoller.SCHEDULE_FIXED_RATE (actual value "scheduleFixedRate") or CallbackPoller.SCHEDULE_FIXED_DELAY (actual value "scheduleFixedDelay"). In either case, polling will take place at approximately regular intervals, but in the former case the scheduler will attempt to perform each poll CALLBACK_POLL_PERIOD milliseconds after the previous attempt, and in the latter case the scheduler will attempt to schedule polling so that the average interval will be approximately CALLBACK_POLL_PERIOD milliseconds. CallbackPoller.SCHEDULE_FIXED_RATE is the default.

REPORT_STATISTICS (actual value is "reportStatistics"): The presence of this key in metadata, regardless of its value, will cause the CallbackPoller to print statistics that might be useful for configuring the other parameters..

SYNCHRONIZED_SHUTDOWN (actual value is "doSynchronizedShutdown"): if set to "true", CallbackPoller.stop() will wait for Client.getCallbacks() to return, and if set to "false" it will not wait. For blocking polled callbacks, the default value is "false" and for non-blocking polled callbacks, the default value is "true".

MAX_ERROR_COUNT (actual value is "maxErrorCount"): determines the maximum number of errors that may be experienced during polling before CallbackPoller will shut itself down. The default value is "5".

CallbackPoller configuration is only necessary when using one of the following Client methods:

public void addListener(
        InvokerCallbackHandler callbackhandler, Map metadata,
        Object callbackHandlerObject) throws Throwable
public void addListener(
        InvokerCallbackHandler callbackhandler, Map metadata,
        Object callbackHandlerObject, boolean serverToClient) throws Throwable

The keys should be among 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.

5.11.6. org.jboss.remoting.callback.CallbackStore

FILE_PATH_KEY (actual value is 'StoreFilePath') - key for setting the directory in which 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'.

FILE_SUFFIX_KEY (actual value is 'StoreFileSuffix') - key for setting the file suffix to use for the callback objects written to disk. The default value is 'ser'.

5.11.7. org.jboss.remoting.callback.DefaultCallbackErrorHandler

CALLBACK_ERRORS_ALLOWED (actual value is 'callbackErrorsAllowed') - key for setting the number of callback exceptions that 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.

5.11.8. org.jboss.remoting.callback.ServerInvokerCallbackHandler

CALLBACK_STORE_KEY (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.

CALLBACK_ERROR_HANDLER_KEY (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.

CALLBACK_MEM_CEILING (actual value is 'callbackMemCeiling') - key for specifying 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.

CALLBACK_TIMEOUT (actual value is 'callbackTimeout') - key for specifying the timeout to be used for doing push callbacks. In the absence of ServerInvokerCallbackHandler.CALLBACK_TIMEOUT, the timeout value configured for the Connector will be used.

5.11.9. org.jboss.remoting.detection.jndi.JNDIDetector

Bean properties (meaning have getter/setter):

SubContextName - sub context name under which detection messages will be bound and looked up.

5.11.10. org.jboss.remoting.marshal.http.HTTPUnMarshaller

PRESERVE_LINES (actual value is "preserveLines"): the key used to turn on or off HTTPUnMarshaller's behavior of stripping CR/LF characters.

5.11.11. org.jboss.remoting.transport.bisocket.Bisocket

IS_CALLBACK_SERVER (actual value is "isCallbackServer"): when a bisocket server invoker receives this parameter with a value of true, it avoids the creation of a ServerSocket. Therefore, IS_CALLBACK_SERVER should be used on the client side for the creation of a callback server. The default value is false.

PING_FREQUENCY (actual value is "pingFrequency"): The server side uses this value to determine the interval, in milliseconds, between pings that it will send on the control connection. The client side uses this value to calculate the window in which it must receive pings on the control connection. In particular, the window is ping frequency * ping window factor. See also the definition of PING_WINDOW_FACTOR. The default value is 5000.

PING_WINDOW_FACTOR (actual value is "pingWindowFactor"): The client side uses this value to calculate the window in which it must receive pings on the control connection. In particular, the window is ping frequency * ping window factor. See also the definition of PING_FREQUENCY. The default value is 2.

MAX_RETRIES (actual value is "maxRetries"): This parameter is relevant only on the client side, where the BisocketClientInvoker uses it to govern the number of attempts it should make to get the address and port of the secondary ServerSocket, and the BisocketServerInvoker uses it to govern the number of attempts it should make to create both ordinary and control sockets. The default value is 10.

SECONDARY_BIND_PORT (actual value is "secondaryBindPort"): The server side uses this parameter to determine the bind port for the secondary ServerSocket.

SECONDARY_BIND_PORTS (actual value is "secondaryBindPorts"): The server side uses this parameter to determine the bind ports for the secondary ServerSockets in a multihome server.

SECONDARY_CONNECT_PORT (actual value is "secondaryConnectPort"): The server side uses this parameter to determine the connect port used by the client side to connect to the secondary ServerSocket.

SECONDARY_CONNECT_PORTS (actual value is "secondaryConnectPorts"): The server side uses this parameter to determine the connect ports used by the client side to connect to the secondary ServerSockets in a multihome server.

SECONDARY_MAX_THREADS (actual value is "secondaryMaxThreads"): Determines the maximum number of sockets accepted by the secondary ServerSocket that can be processed simultaneously. Introduced in release 2.5.4.SP2. Default value is 50.

SECONDARY_TIMEOUT (actual value is "secondaryTimeout"): Determines the timeout used when reading initial data from a socket accepted by the secondary ServerSocket. Introduced in release 2.5.4.SP2. Default value is 60000 ms.

5.11.12. org.jboss.remoting.transport.coyote.CoyoteInvoker

"executor": a comma separated list of attributes associated with this key will be used to configure an org.apache.catalina.core.StandardThreadExecutor, which will then be injected into the underlying Coyote Connector. See http://tomcat.apache.org/tomcat-6.0-doc/config/executor.html. for the available configurable attributes.

5.11.13. org.jboss.remoting.transport.http.HTTPClientInvoker

DISCONNECT_AFTER_USE (actual value is "disconnectAfterUse") - key indicating if the java.net.HttpURLConnection should be disconnected after the invocation. The default value is "false".

IGNORE_ERROR_RESPONSE_MESSAGE (actual value is "ignoreErrorResponseMessage") - key indicating if org.jboss.remoting.transport.http.HTTPClientInvoker should try to get a response message and response code in the event of an exception. The default value is "false".

NUMBER_OF_CALL_ATTEMPTS (actual value is "numberOfCallAttempts"): This parameter is relevant only on the client side, where it determines the maximum number of attempts that will be made to complete an invocation. The default value is 1.

UNMARSHAL_NULL_STREAM (actual value is "unmarshalNullStream") - key indicating if org.jboss.remoting.transport.http.HTTPClientInvoker should make the call to UnMarshaller.read() when the InputStream is null. The default value is "true".

5.11.14. org.jboss.remoting.transport.http.HTTPMetadataConstants

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:

public Object invoke(InvocationRequest invocation) throws Throwable
{
   Map headers = invocation.getRequestPayload();
   ...

where variable 'headers' will contain entries for the following keys.

METHODTYPE (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:

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"))
      ...

PATH (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:

public Object invoke(InvocationRequest invocation) throws Throwable
{
   Map headers = invocation.getRequestPayload();
   String path = (String) headers.get(HTTPMetadataConstants.PATH);
   ...

HTTPVERSION (actual value is 'HttpVersion') - key for getting the HTTP version from the calling client request (e.g. HTTP/1.1).

RESPONSE_CODE (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:

Map metadata = new HashMap();
Object response = remotingClient.invoke(myPayloadObject, metadata);
Integer responseCode = (Integer) metadata.get(HTTPMetadataConstants.RESPONSE_CODE);

Will be used as key to put the response code in the return payload map from invocation handler. For example:

public Object invoke(InvocationRequest invocation) throws Throwable
{
   Map responseHeaders = invocation.getReturnPayload();
   responseHeaders.put(HTTPMetadataConstants.RESPONSE_CODE, new Integer(202)); 

RESPONSE_CODE_MESSAGE (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:

Map metadata = new HashMap();
Object response = remotingClient.invoke(myPayloadObject, metadata);
String responseCodeMessage = (String) metadata.get(HTTPMetadataConstants.RESPONSE_CODE_MESSAGE);

Will be used as key to put the response code message in the return payload map from invocation handler. For example:

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");

RESPONSE_HEADERS (actual value is 'ResponseHeaders') - key for returning the value of java.net.URLConnection.getHeaderFields(). In other words, a map containing all of the response headers is stored in the metadata map. For example,

Object payload = ... ;
HashMap metadata = new HashMap();
client.invoke(payload, metadata);
Map responseHeaders = (Map) metadata.get(HTTPMetadataConstants.RESPONSE_HEADERS);

NO_THROW_ON_ERROR (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.

DONT_RETURN_EXCEPTION (actual value is 'dont-return-exception') - key indicating if org.jboss.remoting.transport.servlet.ServletServerInvoker should revert to the orginal error handling behavior of returning an error message.

USE_REMOTING_CONTENT_TYPE (actual value is 'useRemotingContentType') - key indicating if org.jboss.remoting.marshal.http.HTTPUnMarshaller should determine that it is reading a String by using the "content-type" return header (if set to "false") or the "remotingContentType" header if set to "true". The default value is "false", to avoid introducing any inconsistent behavior between versions, but, if the org.jboss.remoting.ServerInvocationHandler sets the content-type return header, then this parameter should be set to "true".

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'.

5.11.15. org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker

IGNORE_HTTPS_HOST (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.

HOSTNAME_VERIFIER (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.

USE_DEFAULT_SSL_SOCKET_FACTORY (actual value is 'useDefaultSslSocketFactory') - if set to true, then HTTPSClientInvoker.createSocketFactory() will call HttpsURLConnection.getDefaultSSLSocketFactory() instead of trying to build a SocketFactory.

5.11.16. org.jboss.remoting.transport.rmi.RMIServerInvoker

REGISTRY_PORT_KEY (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.

RMI_ONEWAY_MARSHALLING (actual value is 'rmiOnewayMarshalling') - if set to "true" will cause the RMI transport to use the original client to server marshalling behavior.

5.11.17. org.jboss.remoting.transport.servlet.ServletServerInvoker

UNWRAP_SINGLETON_ARRAYS (actual value is 'unwrapSingletonArrays') - If the map returned by javax.servlet.http.HttpServletRequest.getParameterMap() maps a String key to an array of length one, the value in the array will be extracted and associated with the key.

5.11.18. org.jboss.remoting.transport.socket.MicroSocketClientInvoker

TCP_NODELAY_FLAG (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.

MAX_POOL_SIZE_FLAG (actual value is 'clientMaxPoolSize') - the client side maximum number of threads. The default is 50.

CLIENT_SOCKET_CLASS_FLAG (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.

USE_ONEWAY_CONNECTION_TIMEOUT (actual value "useOnewayConnectionTimeout") - indicates if, during a client side oneway invocation, MicroSocketClientInvoker should wait for a version byte from the server, which prevents the anomalous behavior described in JBREM-706 "In socket transport, prevent client side oneway invocations from artificially reducing concurrency". The default value is "true".

5.11.19. org.jboss.remoting.transport.socket.ServerThread

EVICTABILITY_TIMEOUT (actual value "evictabilityTimeout") - indicates the number of milliseconds during which a server thread waiting for the next invocation will not be preemptible.

CONTINUE_AFTER_TIMEOUT (actual value "continueAfterTimeout") - indicates what a server thread should do after experiencing a java.net.SocketTimeoutException. If set to "true", or if JBossSerialization is being used, the server thread will continue to wait for an invocation; otherwise, it will return itself to the thread pool.

5.11.20. org.jboss.remoting.transport.socket.SocketServerInvoker

CHECK_CONNECTION_KEY (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.

SERVER_SOCKET_CLASS_FLAG (actual value is 'serverSocketClass') - specifies the fully qualified class name for the custom SocketWrapper implementation to use on the server.

Bean properties (meaning have getter/setter):

acceptThreadPriorityIncrement - can be used to increment the priority of the accept thread, which manages the ServerSocket. The value is added to java.lang.Thread.NORM_PRIORITY, and the resulting value must be no more than java.lang.Thread.MAX_PRIORITY. This parameter might be useful on a heavily loaded machine if the accept thread is getting starved.

ImmediateShutdown - a flag for indicating that SocketServerInvoker should shut down all of its ServerThreads immediately instead of waiting for any current invocations to finish.

5.11.21. org.jboss.remoting.transport.socket.SocketWrapper

WRITE_TIMEOUT (actual value is 'writeTimeout') - key for configuring the "write timeout" facility. If set to a value greater than 0, then a write operation that does not complete within the configured number of milliseconds will be terminated and the socket will be closed. The default value is -1.