2 Replies Latest reply on May 20, 2005 1:00 AM by Paul Bober

    Implementing a JMS message aggregator

    Paul Bober Newbie

      I am trying to implement a JMS message Aggregator which reads N messages from an input queue and writes a single aggregate message to an output queue (see http://www.eaipatterns.com/Aggregator.html) . I have the constraint that messages cannot be lost, although I suppose that messages can be duplicated under extenuating circumstances.

      To maximize performance, I'd prefer to avoid persisting the messages while they are being collected by the aggregator. My initial thought is to use the CLIENT_ACKNOWLEDGE delivery mode and delay acknowledging messages until they have been successfully placed in the output queue. In this way messages that are being processed into an aggregate should be redelivered if my service crashes.

      MDBs seem to be the preferred way to use JMS within a J2EE server, but unfortunately they don't permit use of the CLIENT_ACKNOWLEDGE mode. If I want to avoid writing the messages to a persistent store while they are being collected in the aggregator, the only options I see are to write a standalone JMS client or a JMX MBean.

      My questions are:

      1) Does my approach of using CLIENT_ACKNOWLEDGE and delaying acknowledgment of messages until an aggregate has been written to the output queue make sense? Is this a misuse of JMS?

      2) I discovered that JBoss doesn't allow you to register a JMS MessageListener in an MBean, so I switched to the synchronous receive() method. Is there any problem with this?

      3) Can anyone propose a better way to do this?

      I am using JBoss 4.0.2 and JBoss MQ.

      Thanks in advance for your assistance,

        • 1. Re: Implementing a JMS message aggregator
          Elias Ross Master

          1. No, you can probably work something out using a UserTransaction.
          2. I didn't know about that... You could fork a thread to receive.
          3. Your best bet might be use a message selector to aggregate, then ACK the last message, however if the queue grows substantially, you're not going to have good performance.

          Another technique would be to continuously read until all sets are aggregated, then ack the Session. It may be hard to reach a boundry in some cases.

          Unfortunately, you can't ACK part of a set of messages received from a session. You can also try to create a large number of sessions, one per message.

          • 2. Re: Implementing a JMS message aggregator
            Paul Bober Newbie

            It took me a few minutes to figure out what you were proposing and then I realized that what I need is simpler than the example I referenced from the EAI patterns book. In my application there is only one type of aggregate. Thus, I don't have to worry about not being able to ack messages in a completed aggregate when there are still messages in another unfilled aggregate.

            I managed to get working solution using blocking receive() calls. It seems to work well, but I haven't stress tested it. If someone would like me to post it on the Wiki or elsewhere, please send me a private message.