5 Replies Latest reply on Jun 30, 2008 5:44 PM by Matthieu Labour

    help on JmsXA

    Matthieu Labour Newbie

      Hi

      I am new to jboss messaging and i apologize if my question turns out to be silly.


      I have a sender that createConnection, createSession and createProducer on every message. I am concerned this is very inefficient. I read on some other posts that it is acceptable if one uses JmsXA

      public class JmsPublisher
      {
      
       private ConnectionFactory bizConnectionFactory ;
       private Destination bizDestination;
      
      
       public ConnectionFactory getBizConnectionFactory() {
       return bizConnectionFactory;
       }
       public void setBizConnectionFactory(ConnectionFactory bizConnectionFactory) {
       this.bizConnectionFactory = bizConnectionFactory;
       }
       public Destination getBizDestination() {
       return bizDestination;
       }
       public void setBizDestination(Destination bizDestination) {
       this.bizDestination = bizDestination;
       }
      
       public JmsPublisher(){}
      
       public void sendEvent(SignalAbstract ev)
       throws
       JMSException
       {
       Connection connection = null;
       Session session = null;
       MessageProducer messageProducer = null;
      
       try
       {
      
       connection = bizConnectionFactory.createConnection();
       session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
       messageProducer = session.createProducer(bizDestination);
      
       ObjectMessage msg = session.createObjectMessage(ev);
      
       messageProducer.send(msg);
      
       }
       finally
       {
       if (messageProducer != null) try { messageProducer.close(); } catch (Exception ignore) { }
       if (session != null) try { session.close(); } catch (Exception ignore) { }
       if (connection != null) try { connection.close(); } catch (Exception ignore) { }
      
       }
      
       }
      
      }
      



      I inject the jndi name via Spring

       <jee:jndi-lookup id="bizConnectionFactory"
       jndi-name="${biz.messagingConnectionFactoryName}">
       <jee:environment>
       java.naming.provider.url=${biz.messagingProviderUrl}
       java.naming.factory.url.pkgs=org.jnp.interfaces:org.jboss.naming
       java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
       </jee:environment>
       </jee:jndi-lookup>
      
       <jee:jndi-lookup id="bizDestination"
       jndi-name="${biz.messagingDestinationName}">
       <jee:environment>
       java.naming.provider.url=${biz.messagingProviderUrl}
       java.naming.factory.url.pkgs=org.jnp.interfaces:org.jboss.naming
       java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
       </jee:environment>
       </jee:jndi-lookup>
      
       <bean class="com.strateer.biz.impl.JmsPublisher"
       id="bizJmsPublisher">
       <property name="bizConnectionFactory" ref="bizConnectionFactory" />
       <property name="bizDestination" ref="bizDestination" />
       </bean>
      


      It works when

      biz.messagingProviderUrl=localhost:1099
      biz.messagingConnectionFactoryName=ConnectionFactory
      


      but it doesn't when i change the connectionFactoryName to java:/JmsXA

      biz.messagingProviderUrl=localhost:1099
      biz.messagingConnectionFactoryName=java:/JmsXA
      



      The logs say the following:
      Error creating bean with name 'bizConnectionFactory': Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: JmsXA

      And i don't seem to be able to get it working.

      I would appreciate some tips

      Thank you for your help

      matt

        • 1. Re: help on JmsXA
          Clebert Suconic Master

          JmsXA is only available inside the application server, for MDBs and EJBs.

          If you run it outside of the application server container, you will need to use a regular ConnectionFactory.

          If you are not using JCA, not reusing the JMSProducer (also Session and Connection) is a serious anti-pattern.

          • 2. Re: help on JmsXA
            Matthieu Labour Newbie

            Clebert

            Thank you for your response

            I am not sure i fully understand it

            I do run the app inside Jboss. I deployed it in server/messaging/deploy

            The log error is taken from the messaging/log/server.log

            do you mean i should transform the publisher into a stateless EJB?

            Thank you

            • 3. Re: help on JmsXA
              Clebert Suconic Master

              I assumed you were out of the container.

              I don't know how Spring works. maybe they already include the "java:/", and that's why it's working for you.


              And well.. if it works.. it works!

              Just measure your performance. If you can't send more than 1 dozen msgs/second.. you're not using JCA ;-) But it looks like you should be fine.

              • 4. Re: help on JmsXA
                Clebert Suconic Master

                Actually.. I understood it was working when you were doing JmsXA... I'm sorry. Just ignore the last post.

                Well.. Anyway.. I don't know how Spring works.. you need to make it use java:/JmsXA. You will need to make the right configuration at spring.

                Maybe some other user might help you here... but your best choice would be to ask help at some spring user's forum.

                Or maybe.. you don't need Spring at all to make those sends. From what I have seen.. spring doesn't help you much on JMS. If I were you i would just :

                ConnectionFactory cf = (ConnectionFactory)jndi.lookup("java:/JmsXA");
                Connection conn = cf.createConnection(...);
                Session sess = conn.createSession(...);
                ....
                
                etc, etc... etc...


                • 5. Re: help on JmsXA
                  Matthieu Labour Newbie

                  Clebert

                  Thank you for your response

                  In jboss-4.2.2.GA/server/messaging/deploy/jms-ds.xml , I set
                  <use-java-context>false</use-java-context>

                  and i was able to successfully use JmsXA

                  However

                  1. Enqueuing 100 messages with the implementation that i posted at the root of this thread-post takes 6 seconds

                  2. I also used JmsTemplate with JmsXA and got the same results

                  3. Then following your advice, i implemented the following and it took 7 seconds to enqueue messages (enqueuing loop below)

                  So i am concerned about the performance which are not in line with
                  http://www.jboss.org/file-access/default/members/jbossmessaging/freezone/docs/userguide-2.0.0.alpha1/html/performance.html
                  Am i doing something wrong? Where can look into to investigate the problem? Thanks a lot for your advice

                  public class JMSProvider {
                  
                   private InitialContext ic = null;
                   private ConnectionFactory connectionFactory = null;
                   private Queue queue = null;
                   private Connection connection = null;
                   private Session session = null;
                   private MessageProducer messageProducer = null;
                  
                   public JMSProvider() throws JMSException, NamingException
                   {
                   ic = new InitialContext();
                   connectionFactory = (ConnectionFactory)ic.lookup("/ConnectionFactory");
                   queue = (Queue)ic.lookup("queue/D");
                   connection = connectionFactory.createConnection();
                   session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                   messageProducer = session.createProducer(queue);
                   }
                  
                   public void simpleSend(final User user)
                   {
                  
                   try
                   {
                  
                   ObjectMessage msg = session.createObjectMessage(user);
                   messageProducer.send(msg);
                  
                   }
                   catch(JMSException e)
                   {
                  
                   }
                   }
                  
                   public void destroy() throws JMSException
                   {
                   messageProducer.close();
                   session.close();
                   connection.close();
                   }
                  
                  
                  
                  }
                  



                  public class JmsTestServlet extends HttpServlet {
                  
                   private final Log logger = LogFactory.getLog(JmsTestServlet.class);
                  
                   /**
                   *
                   */
                   private static final long serialVersionUID = -7696232061073152339L;
                  
                   @Override
                   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                   throws ServletException, IOException {
                  
                   WebApplicationContext context = WebApplicationContextUtils
                   .getWebApplicationContext(this.getServletContext());
                  
                   final JMSProvider provider = (JMSProvider) context
                   .getBean("jmsProvider");
                  
                   int perf = 100;
                  
                   Calendar startTime = Calendar.getInstance();
                   for (int i = 0; i < perf; i++) {
                  
                   User user = new User();
                   user.setId(new Long(i));
                   user.setFirstName("first_" + i);
                   user.setLastName("last_" + i);
                  
                   provider.simpleSend(user);
                  
                   }
                   Calendar endTime = Calendar.getInstance();
                   long millisec = endTime.getTimeInMillis() - startTime.getTimeInMillis();
                   logger.info(perf+" messages sent in " + millisec + " milliseconds");
                  
                   }
                  
                  }