7 Replies Latest reply on Jul 9, 2013 4:55 AM by erasmo2 marciano2

    fail-over using HornetQJMSClient

    Jeff Bride Novice


         I"m making use of the HornetQJMSClient in a standalone JVM similar to how it's being used in SymmetricClusterExample.java .

          My HA configured brokers are configured in domain mode in EAP6.0.1  (all clients and brokers used hornetq libraries from EAP6.0.1 --> hornetq--2.2.23.Final-redhat-1 )


        When using the HornetQJMSClient, fail-over of the client connection bombs when the primary broker is shutdown and its backup comes on line:


      javax.jms.IllegalStateException: Consumer is closed
           [java]           at org.hornetq.core.client.impl.ClientConsumerImpl.checkClosed(ClientConsumerImpl.java:961)
           [java]           at org.hornetq.core.client.impl.ClientConsumerImpl.receive(ClientConsumerImpl.java:186)
           [java]           at org.hornetq.core.client.impl.ClientConsumerImpl.receive(ClientConsumerImpl.java:391)
           [java]           at org.hornetq.jms.client.HornetQMessageConsumer.getMessage(HornetQMessageConsumer.java:225)
           [java]           at org.hornetq.jms.client.HornetQMessageConsumer.receive(HornetQMessageConsumer.java:134)



         As a comparison, with the exact same broker environment, when switching to a client that uses jndi to lookup the ConnectionFactory ..... fail-over behavior of the client occurs flawlessly as per Hornetq documentation.


        Any hints as to where i may have misconfigured something ???


        I've bumped up client-side logging and conducted tests for both a UDP discovery based client and a JNDI based client.

         The results are attached.


        What seems interesting is the following message on line 304 of hornetq.udp log :


      calling cleanup on ClientSessionImpl [name=b3134f40-a3c8-11e2-83ba-3183c7406c01, username=null, closed=false, factory = ClientSessionFactoryImpl 
      [serverLocator=ServerLocatorImpl [initialConnectors=[org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=5645&host=192-168-122-1], 
      discoveryGroupConfiguration=DiscoveryGroupConfiguration [discoveryInitialWaitTimeout=10000, groupAddress=, groupPort=9876, localBindAddress=null, name=b0e6842d-a3c8-11e2-83ba-3183c7406c01, 
      refreshTimeout=10000]], connectorConfig=org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=5645&host=192-168-122-1, backupConfig=org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=5545&host=192-168-122-1], 


      ...and then the previous exception is thrown.  In comparison,  on line 304 of hornetq.jndi, the following message is logged :


      Trying reconnection attempt 0/-1


      ..... and then the connection created from JNDI fails-over to the backup broker just fine.



      thanks!  jeff

        • 1. Re: fail-over using HornetQJMSClient
          Justin Bertram Master

          Can you copy/paste or attach the code where your using HornetQJMSClient to instantiate the connection factory?  Also, can you copy/paste or attach your hornetq-jms.xml?

          • 2. Re: fail-over using HornetQJMSClient
            Jeff Bride Novice

            Hi Justin.


            thanks for taking a look at this.


            code snippet as follows :


                       ConnectionFactory cFactory = null;
                        if(useDiscover) {
                            DiscoveryGroupConfiguration groupConfiguration = new DiscoveryGroupConfiguration(discoverHost, discoverPort);
                            cFactory = (ConnectionFactory)HornetQJMSClient.createConnectionFactoryWithHA(groupConfiguration, JMSFactoryType.QUEUE_CF);
                            gwDObj = HornetQJMSClient.createQueue(gwDObjName);
                        }else {
                            Properties env = new Properties();
                            env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
                            env.put(Context.PROVIDER_URL, "remote://"+labHost+":"+labPort);
                            Context jndiContext = new InitialContext(env);
                            cFactory = (ConnectionFactory)jndiContext.lookup(cFactoryName);
                            gwDObj = (Destination)jndiContext.lookup(gwDObjPath);
                        //session objects have all of the load-balancing and fail-over magic .... only need one Connection object for entire JVM
                        connectionObj = cFactory.createConnection();



            in regards to my configs, our EAP6.0.1 domain mode environments are provisioned via CLI.   So i've attached the domain.xml .  relevant profiles as follows :


            full         :   messaging subsystem starts on line 725.   used as profile for an  MDB  application

            full-ha    :    messaging subsystem starts on line 903.   used as profile for primary hornetq broker

            full-ha-1 :    messaging subsystem starts on line 1135.  used as profile for backup hornetq broker

            • 3. Re: fail-over using HornetQJMSClient
              Justin Bertram Master

              I'm a little confused.  You talked about using HA and fail-over, but none of the profiles in the domain.xml you attached are configured for HA functionality.  Can you clarify this?

              • 4. Re: fail-over using HornetQJMSClient
                Jeff Bride Novice

                F#*$K ....    really sorry about that.  I previously posted the domain.xml used in my project prior to the CLI commands being executed.  no idea what i was thinking.


                anyway, i've updated the previous post with the actual domain.xml used in the runtime along with the line #s where the messaging subsystems begin.


                thanks Justin. 

                • 5. Re: fail-over using HornetQJMSClient
                  Justin Bertram Master

                  So the connection factory you are presumably using from JNDI is this:


                                          <connection-factory name="RemoteConnectionFactory">


                                                  <connector-ref connector-name="netty"/>



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






                  Notice that is has <reconnect-attempts>-1</reconnect-attempts>.  However, the code you are using with HornetQJMSClient is not setting this property, and I believe that is why it is not attempting to reconnect.  You should call org.hornetq.jms.client.HornetQConnectionFactory.setReconnectAttempts(int) passing -1.

                  • 6. Re: fail-over using HornetQJMSClient
                    Jeff Bride Novice

                    excellent.   that was exactly the problem.  Thanks again for your help Justin.



                    • 7. Re: fail-over using HornetQJMSClient
                      erasmo2 marciano2 Master



                      I should do a similar code




                          this is my code



                                      // Set up the context for the JNDI lookup

                                    final Properties env = new Properties();

                                    env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);

                                   env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL));

                                   env.put(Context.SECURITY_PRINCIPAL, System.getProperty("username", DEFAULT_USERNAME));

                                   env.put(Context.SECURITY_CREDENTIALS, System.getProperty("password", DEFAULT_PASSWORD));

                                   context = new InitialContext(env);

                                  //SessionFactory factory = HornetQClient.createClientSessionFactory(new DiscoveryGroupConfiguration(groupAddress, groupPort));


                                  // Perform the JNDI lookups

                                  String connectionFactoryString = System.getProperty("connection.factory", DEFAULT_CONNECTION_FACTORY);

                                  log.info("Attempting to acquire connection factory \"" + connectionFactoryString + "\"");

                                  connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryString);

                                  log.info("Found connection factory \"" + connectionFactoryString + "\" in JNDI");


                                  String destinationString = System.getProperty("destination", DEFAULT_DESTINATION);

                                  log.info("Attempting to acquire destination \"" + destinationString + "\"");

                                  destination = (Destination) context.lookup(destinationString);

                                  log.info("Found destination \"" + destinationString + "\" in JNDI");


                                  // Create the JMS connection, session, producer, and consumer

                                  connection = connectionFactory.createConnection(System.getProperty("username", DEFAULT_USERNAME), System.getProperty("password", DEFAULT_PASSWORD));


                                  session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

                                  producer = session.createProducer(destination);

                                  consumer = session.createConsumer(destination);



                                  int count = Integer.parseInt(System.getProperty("message.count", DEFAULT_MESSAGE_COUNT));

                                  String content = System.getProperty("message.content", DEFAULT_MESSAGE);


                                  log.info("Sending " + count + " messages with content: " + content);





                                 How I can add this code in my code



                                  DiscoveryGroupConfiguration groupConfiguration = new DiscoveryGroupConfiguration(groupAddress, groupPort);

                                  connectionFactory = (ConnectionFactory)HornetQJMSClient.createConnectionFactoryWithHA(groupConfiguration, JMSFactoryType.QUEUE_CF);



                              I have to make a ClientJms that is connect at the DiscoveryGroup