5 Replies Latest reply on May 5, 2011 8:49 AM by clebert.suconic

    JmsBridge between AS6 and JBoss ESB 4.9

    lvanbass

      Hello,

       

      we have the following setup:

      1 JBoss ESB 4.9 server running on standard ports and

      1 JBoss AS 6 server running on ports-01 set running on the same physical server.

       

      The application running in the AS6 must send JMS messages to the ESB JMS queue.

      We thought the most elegant solution was to use a JmsBridge in order to achieve this result. The bridge is configured as follows (btw. the hornetQ documentation contains errors in the package names in the example JMS Bridge onfiguration):

       

      <?xml version="1.0" encoding="UTF-8"?>

       

      <deployment xmlns="urn:jboss:bean-deployer:2.0">

       

             <bean name="JMSBridge" class="org.hornetq.jms.bridge.impl.JMSBridgeImpl">

                 <!-- HornetQ must be started before the bridge -->

                 <depends>HornetQServer</depends>

                 <depends>MBeanServer</depends>

                 <constructor>

                     <!-- Source ConnectionFactory Factory -->

                     <parameter>

                         <inject bean="SourceCFF"/>

                     </parameter>

                     <!-- Target ConnectionFactory Factory -->

                     <parameter>

                         <inject bean="TargetCFF"/>

                     </parameter>

                     <!-- Source DestinationFactory -->

                     <parameter>

                         <inject bean="SourceDestinationFactory"/>

                     </parameter>

                     <!-- Target DestinationFactory -->

                     <parameter>

                         <inject bean="TargetDestinationFactory"/>

                     </parameter>

                     <!-- Source User Name (no username here) -->

                     <parameter><null /></parameter>

                     <!-- Source Password (no password here)-->

                     <parameter><null /></parameter>

                     <!-- Target User Name (no username here)-->

                     <parameter><null /></parameter>

                     <!-- Target Password (no password here)-->

                     <parameter><null /></parameter>

                     <!-- Selector -->

                     <parameter><null /></parameter>

                     <!-- Failure Retry Interval (in ms) -->

                     <parameter>5000</parameter>

                     <!-- Max Retries -->

                     <parameter>10</parameter>

                     <!-- Quality Of Service -->

                     <parameter>ONCE_AND_ONLY_ONCE</parameter>

                     <!-- Max Batch Size -->

                     <parameter>1</parameter>

                     <!-- Max Batch Time (-1 means infinite) -->

                     <parameter>-1</parameter>

                     <!-- Subscription name (no subscription name here)-->

                     <parameter><null /></parameter>

                     <!-- Client ID  (no client ID here)-->

                     <parameter><null /></parameter>

                     <!-- Add MessageID In Header -->

                     <parameter>true</parameter>

                     <!-- register the JMS Bridge in the AS MBeanServer -->

                     <parameter>

                         <inject bean="MBeanServer"/>

                     </parameter>

                     <parameter>org.hornetq:service=JMSBridge</parameter>

                   </constructor>

                 <property name="transactionManager">

                     <inject bean="RealTransactionManager"/>

                 </property>

             </bean>

       

       

             <!-- SourceCFF describes the ConnectionFactory used to connect to the

                  source destination -->

             <bean name="SourceCFF"

                  class="org.hornetq.jms.bridge.impl.JNDIConnectionFactoryFactory">

                 <constructor>

                     <parameter>

                         <inject bean="source-JNDI" />

                     </parameter>

                     <parameter>/ConnectionFactory</parameter>

                 </constructor> 

             </bean>

       

             <!-- TargetCFF describes the ConnectionFactory used to connect to the

              target destination -->

             <bean name="TargetCFF"

                  class="org.hornetq.jms.bridge.impl.JNDIConnectionFactoryFactory">

                 <constructor>

                     <parameter>

                         <inject bean="target-JNDI" />

                     </parameter>

                     <parameter>/ConnectionFactory</parameter>

                 </constructor> 

             </bean>

       

             <!-- SourceDestinationFactory describes the Destination used as the source -->

             <bean name="SourceDestinationFactory"

                  class="org.hornetq.jms.bridge.impl.JNDIDestinationFactory">

                 <constructor>

                     <parameter>

                         <inject bean="source-JNDI" />

                     </parameter>

                     <parameter>/queue/akct_jms_out</parameter>

                 </constructor> 

             </bean>

       

             <!-- TargetDestinationFactory describes the Destination used as the target -->

             <bean name="TargetDestinationFactory"

                  class="org.hornetq.jms.bridge.impl.JNDIDestinationFactory">

                 <constructor>

                     <parameter>

                         <inject bean="target-JNDI" />

                     </parameter>

                     <parameter>/queue/akct_jms_in</parameter>

                 </constructor> 

             </bean>

       

            <!-- Hashtable containing the JNDI properties required to connect to the source resource -->      

            <bean name="source-JNDI" class="java.util.Hashtable">

               <constructor class="java.util.Map">

                  <map class="java.util.Hashtable" keyClass="java.lang.String" valueClass="java.lang.String">

                     <entry>

                        <key>java.naming.factory.initial</key>

                        <value>org.jnp.interfaces.NamingContextFactory</value>

                     </entry>

                     <entry>

                        <key>java.naming.provider.url</key>

                        <value>jnp://localhost:1199</value>

                     </entry>

                     <entry>

                        <key>java.naming.factory.url.pkgs</key>

                        <value>org.jnp.interfaces"</value>

                     </entry>

                     <entry>

                        <key>jnp.timeout</key>

                        <value>5000</value>

                     </entry>

                     <entry>

                        <key>jnp.sotimeout</key>

                        <value>5000</value>

                     </entry>

                  </map>

               </constructor>

            </bean>

       

            <!-- Hashtable containing the JNDI properties required to connect to the target resource -->      

            <bean name="target-JNDI" class="java.util.Hashtable">

               <constructor class="java.util.Map">

                  <map class="java.util.Hashtable" keyClass="java.lang.String" valueClass="java.lang.String">

                     <entry>

                        <key>java.naming.factory.initial</key>

                        <value>org.jnp.interfaces.NamingContextFactory</value>

                     </entry>

                     <entry>

                        <key>java.naming.provider.url</key>

                        <value>jnp://localhost:1099</value>

                     </entry>

                     <entry>

                        <key>java.naming.factory.url.pkgs</key>

                        <value>org.jnp.interfaces"</value>

                     </entry>

                     <entry>

                        <key>jnp.timeout</key>

                        <value>5000</value>

                     </entry>

                     <entry>

                        <key>jnp.sotimeout</key>

                        <value>5000</value>

                     </entry>

                  </map>

               </constructor>

            </bean>

      </deployment>

       

      This setup doesn't work. The JmsBridge fails with the following message:

       

      17:53:44,501 ATTENTION [org.hornetq.jms.bridge.impl.JMSBridgeImpl] Unable to set up connections, bridge will not be started

       

      Debugging the JmsBridgeImpl class, I found out that the exception causing the failure is:

       

      javax.naming.CommunicationException [Root exception is java.lang.ClassNotFoundException: org.jboss.jms.destination.JBossQueue (no security manager: RMI class loader disabled)]

       

      Obviously, this class is part of JBoss messaging so it's not available on the AS6 server. Have you got any suggestion?

      Or if you think of any other option for the setup, please suggest, I'm a newbie in this area.

        • 1. JmsBridge between AS6 and JBoss ESB 4.9
          clebert.suconic

          You should probably use the JBoss Messaging bridge on the client.

           

          hmmm... or maybe you're having classpath issues?

          • 2. JmsBridge between AS6 and JBoss ESB 4.9
            lvanbass

            Can you be a little more specific?

            Does "using the JBoss Messaging bridge on the client" involve completely bypassing HornetQ and adding the jboss-messaging jar on the AS server?

            The classpath issue hypothesis doesn't hold as I'm not running any application in the AS6 yet, just trying to setup the bridge. I'm starting the AS on the "all" profile though, could that be an issue?

            • 3. JmsBridge between AS6 and JBoss ESB 4.9
              clebert.suconic

              You can either use the JBoss Messaging JMS Bridge at the JBoss 5 server, or the HornetQ JMS Bridge at the JBoss 6 server.

               

               

               

              When you bridge, you're bridging from one Server to another, right? Then you need the libraries for that server.

               

               

              That is whenever server you decide to start your bridge on, you will have to install the libraries for the other server.  (BTW: I thought you were having Class Cast Exceptions for some reason.. and I just realized I read it wrong).

               

              The fact you don't have the jar for jms, means you need to install the libraries for JBM at /common/lib. The JNDI operation will deserialize the CF from the other server and you will need JBM libraries on /common/lib

               

               

              Tell me If you have any other issues after you install the libraries.

              • 4. JmsBridge between AS6 and JBoss ESB 4.9
                lvanbass

                Thanks Clebert for your quick and clear answer.

                Adding the jboss-messaging.jar in the /common/lib folder of the JBoss 6 solves the issue.

                 

                Problem solved then, but I must say it leaves me a bit confused as I always considered JMS as a way to abstract from the actual implementation... It is a bit confusing that if I want to change the remote implementation (e.g. by upgrading the ESB to an hypothetical version using another JMS implementation) I'm supposed to change the libs on the source server as well.

                • 5. JmsBridge between AS6 and JBoss ESB 4.9
                  clebert.suconic

                  JMS is a Java interface, hence you need the implementation for the underlying server being used. That's why.