2 Replies Latest reply on Jul 22, 2012 5:41 AM by nesyarug

    Not a HornetQ Destination:HornetQQueue

    nesyarug

      Hi fellow coders,

       

      I'm banging my head on this problem for a while now so thought I better ask this forum.

       

      I'm using JBoss AS 7.1.1 with full-ha configuration. I want to use HornetQ as my messaging server. I'm developing in Spring 3.1.2.

       

      I am experimenting with the testQueue as defined in standalone/configuration/standalone-full-ha.xml:

       

      <jms-queue name="testQueue">

        <entry name="queue/test"/>

        <entry name="java:jboss/exported/jms/queue/test"/>

      </jms-queue>

       

      My Spring configuration is as follows:

       

      <bean name="qConnectionFactory" class="org.hornetq.jms.client.HornetQXAConnectionFactory">

        <constructor-arg name="ha" value="true" />

        <constructor-arg>

          <bean name="transportConfiguration" class="org.hornetq.api.core.TransportConfiguration">

            <constructor-arg value="org.hornetq.core.remoting.impl.netty.NettyConnectorFactory"/>

            <constructor-arg>

              <map key-type="java.lang.String" value-type="java.lang.Object">

                <entry key="host" value="localhost" />

                <entry key="port" value="5445" />

              </map>

            </constructor-arg>

          </bean>

        </constructor-arg>

      </bean>

       

      <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">

        <property name="environment">

          <props>

            <prop key="java.naming.factory.initial">org.jboss.as.naming.InitialContextFactory</prop>

            <prop key="java.naming.provider.url">remote://localhost:4447</prop>

            <prop key="java.naming.security.principal">user</prop>

            <prop key="java.naming.security.credentials">password</prop>

          </props>

        </property>

      </bean>

       

      <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">

        <property name="connectionFactory">

          <ref bean="qConnectionFactory"/>

        </property>

        <property name="destinationResolver">

          <bean class="org.springframework.jms.support.destination.JndiDestinationResolver"/>

        </property>

      </bean>

       

      <!-- A destination in JBoss/HornetQ -->

      <bean id="testQueue" class="org.springframework.jndi.JndiObjectFactoryBean">

        <property name="jndiName">

          <value>java:jboss/exported/jms/queue/test</value>

        </property>

        <property name="jndiTemplate" ref="jndiTemplate"/>

      </bean>

       

      And in my code (Controller) I'm using jmsTemplate as follows:

       

      @Autowired

      private JmsTemplate jmsTemplate;

       

      @Autowired

      private Destination testQueue;

       

      jmsTemplate.send(testQueue, new MessageCreator() {

        public Message createMessage(Session session)

          throws JMSException {

          Message message = session.createMessage();

          return message;

        }

      });

       

      When I try to send the message, I get the following JmsException:

       

      org.springframework.jms.InvalidDestinationException: Not a HornetQ Destination:HornetQQueue[testQueue]; nested exception is javax.jms.InvalidDestinationException: Not a HornetQ Destination:HornetQQueue[testQueue]

       

      This is thrown from HornetQSession at:

       

      public MessageProducer createProducer(final Destination destination) throws JMSException

        {

          if (destination != null && !(destination instanceof HornetQDestination))

          {

            throw new InvalidDestinationException("Not a HornetQ Destination:" + destination);

          }

          ...

       

      This method is expecting a HornetQDestination while Spring autowires a HornetQQueue.

       

      1) I'm not sure how Spring knows to autowire a HornetQQueue (although it should be a HornetQDestination, it is close!)

      2) It should autowire a HornetQDestination, right?

       

      Has anyone worked around this?

       

      Many thanks,

      Nes

        • 1. Re: Not a HornetQ Destination:HornetQQueue
          nesyarug

          So far this has been tracked down as a potential class loading problem by adding some debug information to HornetQSession's createProducer(final Destination destination) method:

           

          log.error("Passed in destination class: " + destination.getClass().toString());

          log.error("Class loader for passed in destination: " + destination.getClass().getClassLoader().toString());

          log.error("Class loader for HornetQDestination: " + HornetQDestination.class.getClassLoader().toString());

           

          The output is:

           

          23:42:29,690 SEVERE [org.hornetq.jms.client.HornetQSession] (http--127.0.0.1-8080-1) Passed in destination class: class org.hornetq.jms.client.HornetQQueue

          23:42:29,691 SEVERE [org.hornetq.jms.client.HornetQSession] (http--127.0.0.1-8080-1) Class loader for passed in destination: ModuleClassLoader for Module "org.hornetq:main" from local module loader @8822a0 (roots: /usr/local/jboss-as-7.1.1.Final/modules)

          23:42:29,693 SEVERE [org.hornetq.jms.client.HornetQSession] (http--127.0.0.1-8080-1) Class loader for HornetQDestination: ModuleClassLoader for Module "deployment.app.war:main" from Service Module Loader

           

          Any thoughts on how to workaround this?

           

          Cheers,

          Nes

          • 2. Re: Not a HornetQ Destination:HornetQQueue
            nesyarug

            Seems to be working now. I marked my client HornetQ libraries as provided (through Maven) so these do not get included in the WAR.

             

            First, I got an error saying class org.hornetq.jms.client.HornetQXAConnectionFactory could not be found. I then changed Spring's configuration to get the connection factory from JNDI:

             

            <bean id="qConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">

                     <property name="jndiName">

                          <value>java:jboss/exported/jms/RemoteConnectionFactory</value>

                     </property>

            </bean>

             

            That seem to do the trick and I can see messages in the queue.

             

            Nes