Howto: Distributed Message Beans in JOnAS 4.x

JOnAS release 4.1 dramatically simplifies the use of a distributed JORAM platform from within JOnAS servers. For example, such a configuration allows a bean hosted by JOnAS instance "A" to send messages on a JORAM queue, to which a MDB hosted by JOnAS instance "B" listens.

This advancement is due to the following:

Before going through this chapter, it is highly recommended that the JORAM Resource Adapter configuration guide be reviewed.

Scenario and general architecture

The following scenario and general settings are proposed:

Common configuration

The JORAM servers are part of the same JORAM platform described by the following a3servers.xml configuration file:

<?xml version="1.0"?>
<config>
    <domain name="D1"/>
    <server id="0" name="S0" hostname="hostA">
      <network domain="D1" port="16301"/>
      <service class="org.objectweb.joram.mom.proxies.ConnectionManager"
               args="root root"/>
      <service class="org.objectweb.joram.mom.proxies.tcp.TcpProxyService"
               args="16010"/>
      <service class="fr.dyade.aaa.jndi2.distributed.DistributedJndiServer"
               args="16400 0"/>
    </server>
    <server id="1" name="S1" hostname="hostB">
      <network domain="D1" port="16301"/>
      <service class="org.objectweb.joram.mom.proxies.ConnectionManager"
               args="root root"/>
      <service class="org.objectweb.joram.mom.proxies.tcp.TcpProxyService"
               args="16010"/>
      <service class="fr.dyade.aaa.jndi2.distributed.DistributedJndiServer"
               args="16400 0 1"/>

    </server>
</config>

This configuration describes a platform made up of two servers, "s0" and "s1", hosted by machines "hostA" and "hostB", listening on ports 16010, providing a distributed JNDI service (more info on JORAM's JNDI may be found here).

Each JOnAS server must hold a copy of this file in its conf/ directory. In its jonas.properties file, each must declare the joram_for_jonas_ra.rar as a resource to be deployed (and each should remove jms from its list of services).

Specific configuration

JOnAS A embeds JORAM server s0. The jonas-ra.xml descriptor packaged in the joram_for_jonas_ra.rar archive file must provide the following information:

<jonas-config-property>
    <jonas-config-property-name>HostName</jonas-config-property-name>
    <jonas-config-property-value>hostA</jonas-config-property-value>
</jonas-config-property>  

The other default settings do not need to be changed.

JOnAS B embedds JORAM server s1. The jonas-ra.xml descriptor packaged in the joram_for_jonas_ra.rar archive file must provide the following properties values:

<jonas-config-property>
    <jonas-config-property-name>ServerId</jonas-config-property-name>
    <jonas-config-property-value>1</jonas-config-property-value>
</jonas-config-property>
<jonas-config-property>
    <jonas-config-property-name>ServerName</jonas-config-property-name>
    <jonas-config-property-value>s1</jonas-config-property-value>
</jonas-config-property>
<jonas-config-property>
    <jonas-config-property-name>HostName</jonas-config-property-name>
    <jonas-config-property-value>hostB</jonas-config-property-value>
</jonas-config-property>

The other default settings do not need to be changed.

The shared queue will be hosted by JORAM server s1. It must then be declared in the JOnAS B's joramAdmin.xml file as follows:

        <Queue name="sharedQueue">
          <freeReader/>
          <freeWriter/>
          <jndi name="scn:comp/sharedQueue"/>
        </Queue>

The scn:comp/ prefix is a standard way to specify which JNDI provider should be used. In this case, the shared queue will be bound to JORAM's distributed JNDI server, and may be retrieved from both JOnAS A and JOnAS B. To provide this mechanism, both JOnAS servers must provide access to a standard jndi.properties file. For JOnAS A, the file looks as follows, and should be placed in its conf/ directory:

java.naming.factory.url.pkgs    org.objectweb.jonas.naming:fr.dyade.aaa.jndi2
scn.naming.factory.host         hostA
scn.naming.factory.port         16400

For JOnAS B, the file looks as follows, and should be placed in the right conf/ directory:

java.naming.factory.url.pkgs    org.objectweb.jonas.naming:fr.dyade.aaa.jndi2
scn.naming.factory.host         hostB
scn.naming.factory.port         16400

And now, the beans!

The simple bean on JOnAS A needs to connect to its local JORAM server and access the remote queue. The following is an example of consistent resource definitions in the deployment descriptors:

Standard deployment descriptor:

<resource-ref>
  <res-ref-name>jms/factory</res-ref-name>
  <res-type>javax.jms.ConnectionFactory</res-type>
  <res-auth>Container</res-auth>
</resource-ref>
<resource-env-ref>
  <resource-env-ref-name>jms/sharedQueue</resource-env-ref-name>
  <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>

Specific deployment descriptor:

<jonas-resource>
  <res-ref-name>jms/factory</res-ref-name>
  <jndi-name>CF</jndi-name>
</jonas-resource>
<jonas-resource-env>
  <resource-env-ref-name>jms/sharedQueue</resource-env-ref-name>
  <jndi-name>scn:comp/sharedQueue</jndi-name>
</jonas-resource-env>

The ConnectionFactory is retrieved from the local JNDI registry of the bean. However, the Queue is retrieved from the distributed JORAM JNDI server, because its name starts with the scn:comp/ prefix. It is the same queue to which the message-driven bean on JOnAS B listens. For doing so, its activation properties should be set as follows:

<activation-config>
   <activation-config-property>
      <activation-config-property-name>destination</activation-config-property-name>
      <activation-config-property-value>scn:comp/sharedQueue</activation-config-property-value>
   </activation-config-property>
   <activation-config-property>
      <activation-config-property-name>destinationType</activation-config-property-name>
      <activation-config-property-value>javax.jms.Queue</activation-config-property-value>
   </activation-config-property>
</activation-config>