6 Replies Latest reply on Jul 14, 2013 6:55 AM by Andy Taylor

    Make a JMS client without JNDI connect to a JMS server

    diego dug Newbie

      Hi,

       

      I am new at JMs and HornetQ, and I have been working the whole day without getting any result. I just want to code a JMS client to connect to a JMS server.

      The JMS server uses HornetQ as the client, so there should be no problem.

      Nevertheless I am trying to avoid JNDI because I have tried for a week to get my JMS Client work in Felix OSGI, and it has been impossible for me (several problems with classloader, classpaths etc. really anoying), so I have decided to make a client without JNDI using only the HornetQ Objects.

       

      This is what I have got:

       

      import java.util.HashMap;
      import java.util.Map;
      
      
      import javax.jms.Connection;
      import javax.jms.ConnectionFactory;
      import javax.jms.MessageConsumer;
      import javax.jms.MessageProducer;
      import javax.jms.Queue;
      import javax.jms.Session;
      import javax.jms.TextMessage;
      
      
      import org.hornetq.api.core.TransportConfiguration;
      import org.hornetq.api.jms.HornetQJMSClient;
      import org.hornetq.api.jms.JMSFactoryType;
      import org.hornetq.common.example.HornetQExample;
      import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
      import org.hornetq.core.remoting.impl.netty.TransportConstants;
      import org.hornetq.jms.client.HornetQConnectionFactory;
      
      
      public class Snippet extends HornetQExample
      {
         public static void main(final String[] args)
         {
            new Snippet().run(args);
         }
      
      
         @Override
         public boolean runExample() throws Exception
         {
            Connection connection = null;
            try
            {
               // Step 1. Directly instantiate the JMS Queue object.
               Queue queue = HornetQJMSClient.createQueue("exampleQueue");
      
      
               // Step 2. Instantiate the TransportConfiguration object which contains the knowledge of what transport to use,
               // The server port etc.
      
      
               Map<String, Object> connectionParams = new HashMap<String, Object>();
               //connectionParams.put(TransportConstants.PORT_PROP_NAME, 5446);
               //My server's port:
               connectionParams.put(TransportConstants.PORT_PROP_NAME, 1099);
      
      
               TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName(),
                                                                                          connectionParams);
      
      
               // Step 3 Directly instantiate the JMS ConnectionFactory object using that TransportConfiguration
               HornetQConnectionFactory cf = HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);
      
      
               // Step 4.Create a JMS Connection
               connection = cf.createConnection();
      
               // Step 5. Create a JMS Session
               Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      
      
               // Step 6. Create a JMS Message Producer
               MessageProducer producer = session.createProducer(queue);
      
      
               // Step 7. Create a Text Message
               TextMessage message = session.createTextMessage("This is a text message");
      
      
               System.out.println("Sent message: " + message.getText());
      
      
               // Step 8. Send the Message
               producer.send(message);
      
      
               // Step 9. Create a JMS Message Consumer
               MessageConsumer messageConsumer = session.createConsumer(queue);
      
      
               // Step 10. Start the Connection
               connection.start();
      
      
               // Step 11. Receive the message
               TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000);
      
      
               System.out.println("Received message: " + messageReceived.getText());
      
      
               return true;
            }
            finally
            {
               if (connection != null)
               {
                  connection.close();
               }
            }
         }
      
      
      }
      
      

       

       

      And I have these files on my class path:

      hornetq-beans.xml

      <?xml version="1.0" encoding="UTF-8"?>
      
      
      <deployment xmlns="urn:jboss:bean-deployer:2.0">
      
      
         <bean name="Naming" class="org.jnp.server.NamingBeanImpl"/>
      
      
         <!-- JNDI server. Disable this if you don't want JNDI -->
         <!-- <bean name="JNDIServer" class="org.jnp.server.Main">
            <property name="namingInfo">
               <inject bean="Naming"/>
            </property>
            <property name="port">1099</property>
                                                                                  <!-- <property name="bindAddress">localhost</property>
            <property name="bindAddress">jnp://X.Y.Z.T</property>
            <property name="rmiPort">1098</property>
                                                                                  <!-- <property name="rmiBindAddress">localhost</property>
            <property name="bindAddress">jnp://X.Y.Z.T</property>
         </bean>-->
      
         <!-- MBean server -->
         <bean name="MBeanServer" class="javax.management.MBeanServer">
            <constructor factoryClass="java.lang.management.ManagementFactory"
                         factoryMethod="getPlatformMBeanServer"/>
         </bean> 
      
      
         <!-- The core configuration -->
         <bean name="Configuration" class="org.hornetq.core.config.impl.FileConfiguration"/>
      
      
         <!-- The security manager -->
         <bean name="HornetQSecurityManager" class="org.hornetq.spi.core.security.HornetQSecurityManagerImpl">
            <start ignored="true"/>
            <stop ignored="true"/>
         </bean>
      
      
         <!-- The core server -->
         <bean name="HornetQServer" class="org.hornetq.core.server.impl.HornetQServerImpl">
            <constructor>
               <parameter>
                  <inject bean="Configuration"/>
               </parameter>
               <parameter>
                  <inject bean="MBeanServer"/>
               </parameter>
               <parameter>
                  <inject bean="HornetQSecurityManager"/>
               </parameter>        
            </constructor>
            <start ignored="true"/>
            <stop ignored="true"/>
         </bean>
      
         <!-- The JMS server -->
         <bean name="JMSServerManager" class="org.hornetq.jms.server.impl.JMSServerManagerImpl">
            <constructor>         
               <parameter>
                  <inject bean="HornetQServer"/>
               </parameter>
            </constructor>
         </bean>
      
      
      </deployment>
      
      

       

      hornetq-jms.xml

      <configuration xmlns="urn:hornetq"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
      
         <!--the queue used by the example-->
         <queue name="exampleQueue">
            <entry name="/queue/exampleQueue"/>
         </queue>
      
      
      </configuration>
      
      

       

      hornetq-users.xml (There is no need for authentification)

       

      <configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="urn:hornetq /schema/hornetq-users.xsd">
         <!-- the default user.  this is used where username is null
         <defaultuser name="guest" password="guest">
            <role name="guest"/>
         </defaultuser>-->
      </configuration>
      
      
      

       

      hornetq-configuration.xml

      In the "host" tag, putting jnp://, taking it out, putting the port or taking it out does not have any effect. It doesn't change anything, I have tested all the options

      <configuration xmlns="urn:hornetq"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="urn:hornetq /schema/hornetq-configuration.xsd">
      
      
         <!-- Connectors -->
      
      
         <connectors>
            <connector name="netty-connector">
               <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class>
               <param key="host" value="jnp://X.Y.Z.T"/>    
               <param key="port" value="1099"/>
            </connector>
         </connectors>
      
         <!-- Acceptors -->
         <acceptors>
            <acceptor name="netty-acceptor">
               <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class>         
               <param key="host" value="jnp://X.Y.Z.T"/>
               <param key="port" value="1099"/>
            </acceptor>
         </acceptors>
      
      
         <!-- Other config -->
      
      
         <security-settings>
            <!--security for example queue-->
            <security-setting match="jms.queue.exampleQueue">
               <permission type="createDurableQueue" roles="guest"/>
               <permission type="deleteDurableQueue" roles="guest"/>
               <permission type="createNonDurableQueue" roles="guest"/>
               <permission type="deleteNonDurableQueue" roles="guest"/>
               <permission type="consume" roles="guest"/>
               <permission type="send" roles="guest"/>
            </security-setting>
         </security-settings>
      
      
      </configuration>
      
      

       

       

      By executing this code, I have:

      javax.jms.JMSException: Timed out waiting for response when sending packet 30
                at org.hornetq.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:276)
                at org.hornetq.core.client.impl.ClientSessionFactoryImpl.createSessionInternal(ClientSessionFactoryImpl.java:677)
                at org.hornetq.core.client.impl.ClientSessionFactoryImpl.createSession(ClientSessionFactoryImpl.java:249)
                at org.hornetq.jms.client.HornetQConnection.authorize(HornetQConnection.java:589)
                at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:684)
                at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:119)
                at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:114)
                at com.test.Snippet.runExample(Snippet.java:175)
                at org.hornetq.common.example.HornetQExample.run(HornetQExample.java:69)
                at com.test.Snippet.main(Snippet.java:149)
      Caused by: HornetQException[errorCode=3 message=Timed out waiting for response when sending packet 30]
                ... 10 more
      
      
      #####################
      ###    FAILURE!   ###
      #####################
      Exception in thread "main" java.lang.RuntimeException: failure in running example
                at org.hornetq.common.example.HornetQExample.reportResultAndExit(HornetQExample.java:214)
                at org.hornetq.common.example.HornetQExample.run(HornetQExample.java:80)
                at com.test.Snippet.main(Snippet.java:149)
      

       

      The problem is this line: connection = cf.createConnection();

       

       

      More over, this code (my old one using JNDI) works perfectly, like a charm (no config files needed, just a little bit of generic code):

       

      public class Snippet {
      
      
      
                public static void main(String[] args) {
                          System.out.println("Starting");
                          String destName = null;
                          Context jndiContext = null;
                          ConnectionFactory connectionFactory = null;
                          Connection connection = null;
                          Session session = null;
                          Destination dest = null;
                          MessageConsumer consumer = null;
      
      
                          destName = "x.y.z.t";
                          System.out.println("Destination name is " + destName);
      
      
                          /*
                           * Create a JNDI API InitialContext object if none exists yet.
                           */
                          try {
                                    jndiContext = new InitialContext(getJavaNamingProperties());
                          } catch (NamingException e) {
                                    System.out.println("Could not create JNDI API context: " + e.toString());
                                    System.exit(1);
                          }
      
      
                          /*
                           * Look up connection factory and destination. If either does not exist, exit. If you look up a TopicConnectionFactory or a QueueConnectionFactory, program behavior is the same.
                           */
                          try {
                                    connectionFactory = (ConnectionFactory) jndiContext.lookup("/ConnectionFactory");
                                    System.out.println(connectionFactory);
                                    dest = (Destination) jndiContext.lookup("/topic/HandledAlarmTopic");
                                    System.out.println(dest);
                          } catch (Exception e) {
                                    System.out.println("JNDI API lookup failed: " + e.toString());
                                    System.exit(1);
                          }
      
      
                          /*
                           * Create connection. Create session from connection; false means session is not transacted. Create consumer, then start message delivery. Receive all text messages from destination until a
                           * non-text message is received indicating end of message stream. Close connection.
                           */
                          try {
                                    connection = connectionFactory.createConnection();
                                    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                                    consumer = session.createConsumer(dest);
                                    connection.start();
                                    System.out.println("Listening...");
                                    while (true) {
                                              Message m = consumer.receive(1);
      
      
                                              if (m != null) {
                                                        System.out.println("Receive " + m);
      
      
                                                        ObjectMessage om = (ObjectMessage) m;
                                                        HandledAlarmEvent alarm = (HandledAlarmEvent) om.getObject();
                                                        System.out.println("message value = " + alarm);
      
      
                                              }
                                    }
                          } catch (JMSException e) {
                                    System.out.println("Exception occurred: " + e.toString());
                                    e.printStackTrace();
                          } finally {
                                    if (connection != null) {
                                              try {
                                                        connection.close();
                                              } catch (Exception e) {
                                              }
                                    }
                          }
                }
      
      
                private static Properties getJavaNamingProperties() {
                          Properties props = new Properties();
                          String address = "x.Y.Z.T";
                          Integer port = 1099;
      
      
                          Properties returnProps = new Properties();
                          returnProps.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
                          returnProps.put("java.naming.provider.url", "jnp://" + address + ":" + port);
                          returnProps.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
                          return returnProps;
                }
      }
      
      

       

       

      So, my problem is that I have absolutelly no idea of what I am doing wrong with the HornetQ classes. I suspect there is something wrong in the configuration, but I don't know why.

       

      Really, the only thing I need is a little client that listents a topic in a JMS server. That's all, no need to send, just listen.

       

      Any help would be appreciated, I have spent a lot of time on this problem.

       

       

      thank you a lot in advance!