Version 27

    Please note that this procedure applies for JBoss MQ. For JBoss Messaging substitute "jboss.messaging" for "jboss.mq" and "XAConnectionFactory?" for "UIL2XAConnectionFactory"

     

    Note:  These instructions are for EJB 2.1 MDBs and not for EJB3 MDBs.  The invoker proxy binding is no longer functional for ejb3.

    TODO:  Put in EJB3 instructions

     

    How do I configure an MDB to talk to a remote queue?

     

    1. Create a remote JMS provider, which identifies how to access the remote JNDI.

    2. Create an invoker-proxy-binding that uses the remote JMS provider, this controls delivery of messages to the MDB.

    3. Configure the MDB to use the invoker-proxy-binding to receive messages.

    4. Note: If you don't have access to a remote JNDI service, create and bind the factories using an MBean and JNDI. BindMBeanToJNDI. Then use the JBoss JNDI, i.e. leave the Properties attribute blank.

     

    For the purpose of this example, we will use the conventional names specified below. Change them to fit your operational environment.

    • The machine running the queue will be conventionally identified as queuehost.

    • The machine running the message driven bean will be conventionally identified as mdbhost.

     

    1. Create a remote JMS Provider

     

    You need to configure a remote provider, this is similar to local one in jms-ds.xml, except you specify how to access the objects bound in remote JNDI server. The remote provider must be deployed on the server instance running on mdbhost, since the remote provider will be used by the MDB container. To deploy it, you have several choices. You can either add the following <mbean> declaration under the <connection-factories> tag of deploy/jms/jms-ds.xml, or you can create an entirely new deployment descriptor, containing the mbean definition specified inside a <server></server> tag pair and deploy it under deploy/jms or even under deploy directories.

     

      <mbean code="org.jboss.jms.jndi.JMSProviderLoader" 
             name="jboss.mq:service=JMSProviderLoader,name=RemoteMQProvider,server=queuehost">
        <attribute name="ProviderName">QueuehostJMSProvider</attribute>
        <attribute name="ProviderUrl">jnp://queuehost:1099</attribute>
        <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JBossMQProvider</attribute>
        <attribute name="QueueFactoryRef">UIL2XAConnectionFactory</attribute>
        <attribute name="TopicFactoryRef">UIL2XAConnectionFactory</attribute>
      </mbean>
    

     

    Since 3.2.4 there is an improved ProviderAdapterClass that lets you specify all JNDI properties.

     

      <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
          name="jboss.mq:service=JMSProviderLoader,name=RemoteJMSProvider,server=queuehost">
        <attribute name="ProviderName">QueuehostJMSProvider</attribute>
        <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
        <!-- The queue connection factory -->
        <attribute name="QueueFactoryRef">XAConnectionFactory</attribute>
        <!-- The topic factory -->
        <attribute name="TopicFactoryRef">XAConnectionFactory</attribute>
        <!-- Connect to JNDI on the host "queuehost" port 1099 -->
        <attribute name="Properties">
           java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
           java.naming.factory.url.pkgs=org.jnp.interfaces
           java.naming.provider.url=queuehost:1099
        </attribute>
      </mbean>
    

     

    The machine acting as the queue host must be able to resolve itself as given in the JNDI provider URL (here, "queuehost").  Client lookups will otherwise fail, often with a somewhat cryptic stack trace beginning with "Initialization failed DLQHandler."

     

    2. Create the Invoker Proxy Binding

     

    Provide your own invoker binding that uses the above provider to deliver messages to the MDB. If you plan to have more than one independent MDB deployments that will access the same remote queue, it's not a bad idea to specifiy the invoker binding in standardjboss.xml. Otherwise, you can always specify it in your jboss.xml. The example shows a jboss.xml fragment:

    <jboss>
       ...
    
       <invoker-proxy-bindings>
          <invoker-proxy-binding>
             <name>my-mdb-invoker</name>
             <invoker-mbean>does-not-matter</invoker-mbean>
             <proxy-factory>org.jboss.ejb.plugins.jms.JMSContainerInvoker</proxy-factory>
             <proxy-factory-config>
                <JMSProviderAdapterJNDI>QueuehostJMSProvider</JMSProviderAdapterJNDI>
                <ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
                <MinimumSize>1</MinimumSize>
                <MaximumSize>15</MaximumSize>
                <KeepAliveMillis>30000</KeepAliveMillis>
                <MaxMessages>1</MaxMessages>
                <MDBConfig>
                   <ReconnectIntervalSec>10</ReconnectIntervalSec>
                   <DLQConfig>
                      <DestinationQueue>queue/DLQ</DestinationQueue>
                      <MaxTimesRedelivered>10</MaxTimesRedelivered>
                      <TimeToLive>0</TimeToLive>
                   </DLQConfig>
                </MDBConfig>
             </proxy-factory-config>
          </invoker-proxy-binding>
       </invoker-proxy-bindings>
    
       ...
    </jboss>
    

     

     

     

    3. Configure the MDB

    Finally use the invoker proxy binding for your MDB in jboss.xml. The queue "queue/myQueue" should be available on queuehost.

    <jboss>
       ...
    
       <enterprise-beans>
          <message-driven>
             <ejb-name>MyMessageBean</ejb-name>
             <destination-jndi-name>queue/myQueue</destination-jndi-name>
             <invoker-bindings>
                <invoker>      
                   <invoker-proxy-binding-name>my-mdb-invoker</invoker-proxy-binding-name>
                </invoker>
             </invoker-bindings>
          </message-driven>
    
          ...
       </enterprise-beans>
    
       ...
    </jboss>
    * Note: To do this with XDoclet, you will have to upgrade to XDoclet 1.3+ (currently only available via CVS) 
    and use the following tag in your MDB -> @jboss.invoker-proxy-binding 
    name="my-mdb-invoker"