8 Replies Latest reply on Sep 30, 2003 1:27 AM by Adrian Brock

    stopping connection from within

    Mike Hemling Newbie

      a "bean". I have a message listener class that is set as a listener in a queue receiver for a queue. I am using jboss 3.2.1. My listener basically holds a socket connection open to another program and sends the data from the queue.

      If this socket connection fails I want to stop the queue connection temporarily so that my listener does not consume anymore messages. I need to stop the connection from within the listener. Is this possible?

      After restablishing my socket connection I will then restart the queue connection and cosume messages.

      I have tried passing in a reference to the Queue Receiver class and calling queueConnection.stop() but this did not seem to work. Maybe I missed something.

      thanks

        • 1. Re: stopping connection from within
          Stephane Nicoll Master

          Even if it's ok to open a socket inside a Bean, this is not allowed by the spec.

          Why not creating an MBean that listens to your queue and sends info to the socket. If socket failed at some point, you can update the state of your mbean and close your JMS connection till your socket is back. When your socket is back you can reinitialize the JMS session.

          Does it help?

          Regards,

          Stephane

          • 2. Re: stopping connection from within
            Mike Hemling Newbie

            So you mean I should put my message listener class inside of the JBOSS config files and deploy it? How can I update the state of the MBean?

            I am not entirely familiar with MBeans. Is that a message driven bean?

            And is it still a possibility to stop a queue connection from within a message listener? Another possibility would be to throw an exception that maybe the queue receiver class that it's registered with could catch and then stop the connection.

            thanks

            • 3. Re: stopping connection from within
              Stephane Nicoll Master

              No. If you want to react synchronously you should read the queue synchronously as well. However, as you can ADD a listener to a queue you could also remove it normally (I never tried that listener thing so I can't confirm, check the Javadoc).

              An MBean is not a MDB. This is a management object which allows you to do multiple things that J2EE business objet are not supposed to do by themselves (i.e. open a socket)

              Check if you can remove the listener on your session

              Regards,

              Stephane

              • 4. Re: stopping connection from within
                Mike Hemling Newbie

                Well, you can supposedly set the message listener to NULL and that is the equivalent of unsetting the listener. I however cannot get this to work. Every time I send a message to the queue it still calls the onMessage() method of the listener.

                The problem is that my listener is passed in a socket channel. It then uses the socket channel to send the message to another application. This "send" is where I would get a socket exception. I need the Queue Receiver class to then unset the listener temporarily or stop the connection so it doesn't keep consuming messages. It's not working.

                Since using a socket inside of a message driven bean is not in the spec, what is the correct thing to do with the message? Look up another program in JNDI? Other people must have this same problem.

                • 5. Re: stopping connection from within
                  mattygiedt Newbie

                  So presumably your setting up your listener something like the following:

                  String queue = "queue/listenerQueue";
                  String ConnectionFactory = "ConnectionFactory";

                  Queue q = (Queue)ctx.lookup( queue );
                  QueueConnectionFactory qcf =
                  (QueueConnectionFactory)ctx.lookup( connectionFactory );

                  QueueConnection qcon = qcf.createQueueConnection();
                  QueueSession session = qcon.createQueueSession( false,
                  QueueSession.AUTO_ACKNOWLEDGE );
                  QueueListener listener = session.createListener( q );

                  qcon.start();

                  ----------------------------------------------------

                  Adding the following method called when you blow up trying to send on the socket channel doesn't disconnect you from the Queue?

                  public final void stop()
                  throws JMSException
                  {
                  qcon.stop();
                  session.close();
                  qcon.close();
                  listener = null;
                  }

                  • 6. Re: stopping connection from within
                    Stephane Nicoll Master

                    > Since using a socket inside of a message driven bean is not in the spec, what is the correct thing to do with the message?

                    Use a JCA adaptor that could do that kind of things or, as I already told you, use an MBean. You don't need to use an MDB to process a JMS message

                    That's my first point. My second point is: if you want to be able to stop consuming message, then you should consume them synchronously (through a QueueReceiver.receive(timeout)). That way you can stop the reception of message(s) if something happenened (socket timeout or other event). If you have a transactionnal session and the problem occured while you got a message you can simply rollback the session for that message and you have transaction context as well.

                    Are you agains using an MBean? Do you think it's not the right solution? Maybe my explanations are not clear enough.

                    Opening a socket through a MDB is hazardous and shouldn't be done if another solution is available.

                    Let me know if you need more details (in the case you agree with my solution, or at least if you are convinced)

                    Regards,

                    Stephane

                    • 7. Re: stopping connection from within
                      Mike Hemling Newbie

                      Yes, I understand. Using a queueReciever.receive() will give me better control of the situation. If the socket dies I can stop the connection more gracefully. I started with this implementation but ran into problems. I will give it another try.

                      Are there any speed differences between using a listener or using receive()? One seems to 'pull' the data and the other 'pushes'.

                      thanks again for your help.

                      • 8. Re: stopping connection from within
                        Adrian Brock Master

                        To answer your initial question, you can stop the
                        message listener thread by doing
                        queueReceiver.close();

                        It is likely that when you invoke stop() there is
                        already a message inside the session in the process of delivery
                        which is why you see delivery after stop().
                        You shouldn't see more than one message.

                        Both do push() and pull(), receive uses less threads.

                        T1 receive() -> server (no message return and wait)
                        T2 server -> delivers message
                        T1 receive() returns

                        T1 mainThread registers MessageListener
                        T2 messageListener receive() -> server(no message return and wait)
                        T3 server -> delivers message)
                        T2 messageLister -> onMessage()

                        Regards,
                        Adrian