Announcement Announcement Module
Collapse
No announcement yet.
Not a HornetQ Destination:HornetQQueue Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Not a HornetQ Destination:HornetQQueue

    Hi there,

    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:

    Code:
    <jms-queue name="testQueue">
    
      <entry name="queue/test"/>
    
      <entry name="java:jboss/exported/jms/queue/test"/>
    
    </jms-queue>
    My Spring configuration is as follows:

    Code:
    <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:

    Code:
    @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.InvalidDestinationExceptio n: Not a HornetQ Destination:HornetQQueue[testQueue]; nested exception is javax.jms.InvalidDestinationException: Not a HornetQ Destination:HornetQQueue[testQueue]

    This is thrown from HornetQSession at:

    Code:
    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

  • #2
    HornetQDestination is an abstract class, and HornetQQueue is a concrete class that extends it. Therefore, that instanceof check should be fine. Are you actually seeing that check fail in the debugger?
    Last edited by Mark Fisher; Jul 21st, 2012, 01:13 PM.

    Comment


    • #3
      Originally posted by Mark Fisher View Post
      HornetQDestination is an abstract class, and HornetQQueue is a concreted class that extends it. Therefore, that instanceof check should be fine. Are you actually seeing that check fail in the debugger?
      Hi Mark,

      Yes, strange enough. That is how I traced it to that method. I double checked just now and my cursor is on the line:

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

      The passed in destination is:

      destination HornetQQueue (id=14724)
      address "jms.queue.testQueue" (id=14725)
      name "testQueue" (id=14726)
      queue true
      session null
      simpleAddress SimpleString (id=14727)
      temporary false


      Thanks.

      Comment


      • #4
        Can you verify that you don't have a classloading issue there (maybe parent vs. child loading)?

        Comment


        • #5
          Originally posted by Mark Fisher View Post
          Can you verify that you don't have a classloading issue there (maybe parent vs. child loading)?
          Will try. Not my strongest skill with different contexts in Spring/Web, and my application deployed as a WAR in JBoss I always struggle a bit to fully comprehend how every class gets loaded. Will investigate now.

          Comment


          • #6
            So my WAR has the client JARs:

            hornetq-core-client-2.2.13.Final.jar
            hornetq-jms-client-2.2.13.Final.jar

            and the server (JBoss AS 7.1.1) has:

            hornetq-core-2.2.13.Final
            hornetq-jms-2.2.13.Final

            I also had hornetq-core-2.2.13.Final in my WAR to get around these errors:

            22:35:10,659 ERROR [stderr] (http--127.0.0.1-8080-1) [ModuleClassLoader@557791] error can't determine implemented interfaces of missing type org.hornetq.core.security.HornetQPrincipal
            22:35:10,659 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving type org.hornetq.core.remoting.impl.netty.NettyConnecti on
            22:35:10,660 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving classes
            22:35:10,660 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving
            22:35:10,660 ERROR [stderr] (http--127.0.0.1-8080-1) [Xlint:cantFindType]
            22:35:10,661 ERROR [stderr] (http--127.0.0.1-8080-1) [ModuleClassLoader@557791] error can't determine implemented interfaces of missing type org.hornetq.core.security.HornetQPrincipal
            22:35:10,661 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving type org.hornetq.core.remoting.impl.netty.NettyConnecti on
            22:35:10,662 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving classes
            22:35:10,662 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving
            22:35:10,663 ERROR [stderr] (http--127.0.0.1-8080-1) [Xlint:cantFindType]
            22:35:10,670 ERROR [stderr] (http--127.0.0.1-8080-1) [ModuleClassLoader@557791] error can't determine implemented interfaces of missing type org.hornetq.core.security.HornetQPrincipal
            22:35:10,670 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving type org.hornetq.core.protocol.core.impl.RemotingConnec tionImpl
            22:35:10,671 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving classes
            22:35:10,671 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving
            22:35:10,671 ERROR [stderr] (http--127.0.0.1-8080-1) [Xlint:cantFindType]
            22:35:10,672 ERROR [stderr] (http--127.0.0.1-8080-1) [ModuleClassLoader@557791] error can't determine implemented interfaces of missing type org.hornetq.core.security.HornetQPrincipal
            22:35:10,676 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving type org.hornetq.core.protocol.core.impl.RemotingConnec tionImpl
            22:35:10,677 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving classes
            22:35:10,678 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving
            22:35:10,678 ERROR [stderr] (http--127.0.0.1-8080-1) [Xlint:cantFindType]
            22:35:10,746 ERROR [stderr] (http--127.0.0.1-8080-1) [ModuleClassLoader@557791] error can't determine implemented interfaces of missing type org.hornetq.core.paging.PagedMessage
            22:35:10,747 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving type org.hornetq.core.protocol.core.impl.wireformat.Rep licationPageWriteMessage
            22:35:10,748 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving classes
            22:35:10,748 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving
            22:35:10,748 ERROR [stderr] (http--127.0.0.1-8080-1) [Xlint:cantFindType]
            22:35:10,748 ERROR [stderr] (http--127.0.0.1-8080-1) [ModuleClassLoader@557791] error can't determine implemented interfaces of missing type org.hornetq.core.paging.PagedMessage
            22:35:10,749 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving type org.hornetq.core.protocol.core.impl.wireformat.Rep licationPageWriteMessage
            22:35:10,749 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving classes
            22:35:10,750 ERROR [stderr] (http--127.0.0.1-8080-1) when weaving
            22:35:10,750 ERROR [stderr] (http--127.0.0.1-8080-1) [Xlint:cantFindType]

            but I removed that JAR from my WAR for now (so the above errors do show up in the logs).

            I still see "Not a HornetQ Destination:HornetQQueue[testQueue];" in the logs.

            Comment


            • #7
              So different class loaders loaded the 2 classes:

              I took the source for HornetQSession and added the following to the createProducer(final Destination destination) method call:

              Code:
              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

              I guess because the passed in HornetQQueue is loaded by JBoss server and returned by/over JNDI?

              Question is: can this be worked around? Or can the HornetQSession class be patched (I assume we would get a ClassCastException if we circumvent the instanceof)?

              Thanks

              Comment


              • #8
                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:

                Code:
                <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.

                Thanks Mark for putting me on the right path.

                Nes

                Comment

                Working...
                X