8 Replies Latest reply on Sep 24, 2001 3:16 AM by pra

    QueueReceiver class doesn't work when JBoss manage JMS resou

    eddy

      Am I able to use the QueueReceiver.receive() method inside a statless bean for which JBoss managed the JMS resource? I knew I can use MDB instead; however, MDB is not allow to set message selector to receive a specific message. I am using JBoss-2.4.1. The following is my code. When I call the QueueReceiver.receive() method inside my remove() method, it simply hung.

      Thanks in advance!

      import java.rmi.*;
      import javax.ejb.*;
      import javax.jms.Queue;
      import javax.jms.QueueConnection;
      import javax.jms.QueueSession;
      import javax.jms.QueueConnectionFactory;
      import javax.jms.QueueSender;
      import javax.jms.QueueReceiver;
      import javax.jms.QueueBrowser;
      import javax.jms.JMSException;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      import javax.jms.Message;
      import javax.jms.TextMessage;
      import javax.jms.ObjectMessage;
      import javax.jms.Session;
      import java.util.Enumeration;
      import java.io.Serializable;
      import java.util.Vector;
      import java.util.HashMap;
      import com.seitel.gos.util.GOSConstant;
      import javax.jms.MessageListener;
      
      public class QueueManagerSLB implements SessionBean {
       private SessionContext sessionContext;
       private static final String QUEUE_CONNECTION_FACTORY_JNDI =
       "java:comp/env/jms/QueueConnectionFactory";
       private static final String QUEUE_JNDI = "java:comp/env/jms/Queue";
       private long m_timeToLive = 400000;
       private QueueConnection m_qeueConn = null;
       private Queue m_queue = null;
      
       private boolean DEBUG_ON = true;
       private void debug(Object mesg){
       if (DEBUG_ON)
       System.out.println("DEBUG: QueueManagerSLB: " + mesg);
       }
      
      
       public void ejbCreate() throws CreateException{
       try{
       Context ctx = new InitialContext();
       this.m_queue = (Queue)ctx.lookup(QUEUE_JNDI);
       QueueConnectionFactory qFactory = (QueueConnectionFactory)ctx.lookup(
       QUEUE_CONNECTION_FACTORY_JNDI);
       this.m_qeueConn = qFactory.createQueueConnection();
       }catch(NamingException namex){
       throw new CreateException(namex.getMessage());
       }catch(JMSException jmsex){
       throw new CreateException("JMS Error Code: " +jmsex.getErrorCode()+
       jmsex.getMessage());
       }
       }
       public void ejbRemove() throws RemoteException {
       if (this.m_qeueConn != null){
       try{
       this.m_qeueConn.close();
       }catch(JMSException jmsex){
       jmsex.printStackTrace();
       }
       }
       }
       public void ejbActivate() throws RemoteException {
       }
       public void ejbPassivate() throws RemoteException {
       }
       public void setSessionContext(SessionContext sessionContext) throws RemoteException {
       this.sessionContext = sessionContext;
       }
      
      
       public void add(HashMap info,int deliveryMode,
       int priority){
       QueueSession qSession = null;
       try{
       qSession = this.m_qeueConn.createQueueSession(true,
       Session.AUTO_ACKNOWLEDGE);
       QueueSender qSender = qSession.createSender(this.m_queue);
       //this.debug("Default delivery Mode: " + qSender.getDeliveryMode());
       //this.debug("Default Priority : " + qSender.getPriority());
       //this.debug("Default Time to Live : " + qSender.getTimeToLive());
       ObjectMessage objMessage = qSession.createObjectMessage();
       objMessage.setJMSCorrelationID((String)info.get(
       GOSConstant.TRANSACTION_ID));
       objMessage.setObject(info);
       qSender.send(objMessage,deliveryMode,priority,this.m_timeToLive);
       }catch(JMSException jmsex){
       this.sessionContext.setRollbackOnly();
       throw new EJBException(jmsex);
       }finally{
       if (qSession != null){
       try{
       qSession.close();
       }catch(JMSException jmsex){
       jmsex.printStackTrace();
       }
       }
       }
       }
      
       public Vector list(){
       QueueSession qSession = null;
       try{
       qSession = this.m_qeueConn.createQueueSession(true,
       Session.AUTO_ACKNOWLEDGE);
       QueueBrowser qBrowser = qSession.createBrowser(this.m_queue);
       Enumeration enu = qBrowser.getEnumeration();
      
       Vector tmp = new Vector();
       Message m = null;
       while(enu.hasMoreElements()){
       m = (Message)enu.nextElement();
       tmp.add(m);
       }
      
       return tmp;
       }catch(JMSException jmsex){
       throw new EJBException(jmsex);
       }finally{
       if (qSession != null){
       try{
       qSession.close();
       }catch(JMSException jmsex){
       jmsex.printStackTrace();
       }
       }
       }
       }
      
      
       public Message remove(String transactionId){
       QueueSession qSession = null;
       QueueReceiver qReceiver = null;
       Message obj = null;
       String messageFilter = "JMSCorrelationID='" + transactionId + "'";
       try{
       qSession = this.m_qeueConn.createQueueSession(true,
       Session.AUTO_ACKNOWLEDGE);
       qReceiver = qSession.createReceiver(this.m_queue,messageFilter);
       obj = (Message)qReceiver.receive();
      
       }catch(JMSException jmsex){
       jmsex.printStackTrace();
       throw new EJBException(jmsex);
       }finally{
       if (qReceiver != null){
       try{ qReceiver.close();
       }catch(JMSException jmsex){
       jmsex.printStackTrace();
       }
       }
       if (qSession != null){
       try{ qSession.close();
       }catch(JMSException jmsex){
       jmsex.printStackTrace();
       }
       }
       }
       return obj;
       }
      
       private class DumpMessageListener implements MessageListener{
       public void onMessage(Message m){
       System.out.println("Message Received: " + m);
       }
      
       }
      }
      


        • 1. Re: QueueReceiver class doesn't work when JBoss manage JMS r
          eddy

          just want to clearify, the queue definitely is not empty.

          • 2. Re: QueueReceiver class doesn't work when JBoss manage JMS r

            Hi,
            I don't think this was ever tested. I write the ra stuff mostly to get pooled publishers. Does your list() method work?

            //Peter

            • 3. Re: QueueReceiver class doesn't work when JBoss manage JMS r
              eddy

              The list and add method both work.

              • 4. Re: QueueReceiver class doesn't work when JBoss manage JMS r

                Hi, I am sorry to say this: you have reported a bug. The connection is not started in the ra stuff (I thought this was not needed because it supports no async stuff). I will have to test this a litle further to see that it does not brake anything. It will take a couple of days. I am sorry.

                If yoy dare, you may change it yourself in your own server. Edit org/jboss/jms/ra/JmsManagedConnection. In method setup() Add con start at the end of the method, for example:

                logger.log(Level.FINE, "xaQueueSession: " + xaQueueSession);
                logger.log(Level.FINE, "queueSession: " + queueSession);
                }
                con.start();// NEW start
                logger.log(Level.FINE, "transacted: " + transacted);
                logger.log(Level.FINE, "ack mode: " + ack);
                }
                catch (NamingException e) {
                CommException ce = new CommException(e.toString());
                ce.setLinkedException(e);
                throw ce;
                }

                I will fix it if it does not brake anything, and do it in the 2.4.1 series to.

                Again, I am sorry.

                //Peter

                • 5. Re: QueueReceiver class doesn't work when JBoss manage JMS r
                  eddy

                  No problem. Thanks your consideration.

                  • 6. Re: QueueReceiver class doesn't work when JBoss manage JMS r

                    It's fixed now, but on HEAD and in the .2.4 branch.

                    //Peter

                    • 7. Re: QueueReceiver class doesn't work when JBoss manage JMS r
                      hchirino

                      Peter,

                      It seems to me that doing a start() on the connection should be something that the app should do and not the RA.

                      It's quite clear in the JMS api that no messages are delivered until the app starts() the connection.

                      What do you think?

                      • 8. Re: QueueReceiver class doesn't work when JBoss manage JMS r

                        Hm, tricky question. I have to admit I did not read the spec thorough enought when I did this. Naively I asumed that start() and stop() was only interesting when you have async semantic.

                        To send you don't need to run start(), and I actually just thought that to receive sync you should not have to run start() either. But you had.

                        I actually do not really fancy the idea to expose the underlying connection to the client here, well to be true it is not even possible the way the ra is currently designed (the pooling is based on the sessions, not the connection: the connection is only a facade for the sessions and have no reference down into the pooling stuff.

                        Today, start() and stop() will throw a IllegalStateException if invoked...maybe not to good.

                        Ugh, I do not have the time to redesign this just now ;-(

                        //Peter