How to acknowledge messages in Message Driven Beans

what pattern is applied in java message-driven beans
message-driven bean vs messagelistener
message-driven bean interface
message driven bean rabbitmq
message driven bean example jboss 7
activationconfigproperty(propertyname = destination)
java mdb transaction
jms ejb

In the JMS documentation I read that Message Driven Beans doesn't support CLIENT_ACKNOWLEDGE mode, only DUPS_OK_ACKNOWLEDGE and AUTO_ACKNOWLEDGE.

As I understand it, in AUTO_ACKNOWLEDGE mode, the message is acknowledged (deleted from the destination) when the onMessage method is invoked. What I want is to tell my broker not to delete messages from the destination (queue or topic) when something bad happens

There must be some way to do this. Anyway, why is CLIENT_ACKNOWLEDGE not supported in Message Drven Beans.

What I want is to tell my broker not to delete messages from the destination (queue or topic) when something bad happens.

If you're configured to use PERSISTENT messages, any exceptions in onMessage() will persist the message for redelivery based on broker and destination settings. If you're using NON_PERSISTENT messages, any exception in onMessage() typically discards the message.

Anyway, why is CLIENT_ACKNOWLEDGE not supported in Message Driven Beans.

Message-driven beans are managed by the J2EE container; as such, the container handles acknowledgements. Typically, only stand-alone JMS receivers should use CLIENT_ACKNOWLEDGE.

What messaging middleware are you using?

java, In the JMS documentation I read that Message Driven Beans doesn't support CLIENT_ACKNOWLEDGE mode, only  Creates a message consumer (a QueueReceiver or TopicSubscriber) to receive the messages; Associates the bean with a destination and connection factory at deployment; Registers the message listener and the message acknowledgement mode; The lifecycle of an MDB depends on the lifespan of the EJB Server in which it is deployed.

Just make sure you are using (JTA) transactions (the default is that you are using them). Then make sure your applications server has a redelivery setting and or a Dead Letter Queue (DLQ). Any exceptions thrown from your MDB will then trigger a redelivery and after a certain amount of failures the message will be moved to the DLQ.

The redeilvery setting is called "max-delivery-attempts" in Wildfly for instance

The Message-Driven Bean Class, It is recommended, but not required, that a message-driven bean class the JNDI name of the destination from which the bean will consume messages. Acknowledgment mode; see Controlling Message Acknowledgment for information. All message-driven beans must implement the MessageDrivenBean interface. For JMS messaging, a message-driven bean must also implement the message listener interface, javax.jms.MessageListener. Messages arriving at a destination being processed by a message-driven bean have no client credentials associated with them; the messages are anonymous.

In Mdb you can tell the broker to not delete the message trough 'MessageDrivenContext'. (Without throwing exception - which also rollbacks the transaction)

Some example code, Where you can handle all exceptions in method 'onMessaage' and set a rollback in case of Exception:

@MessageDriven(name = "queueMDB", activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "TestQueue"),
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
}
public class TestMdb implements MessageListener {

    @Resource
    private MessageDrivenContext messageDrivenContext;

    @Override
    public void onMessage(Message message) {
        try {
            // Some usefull code...
        }
        catch (Exception e) {
            messageDrivenContext.setRollbackOnly();
        }
    }
}

Chapter 17 A Message-Driven Bean Example (The Java EE 6 Tutorial), Message-driven beans can implement any messaging type. Acknowledgment mode; see Controlling Message Acknowledgment for information. A message can be delivered to an MDB inside a transaction context. Meaning that all operations within the onMessage() method are part of a single transaction. Therefore, if a rollback happens, message system redelivers the data. 4. Working With Message Driven Beans

Developing an enterprise application to use message-driven beans, For JMS messaging, a message-driven bean must also implement the use the Message.acknowledge() method to acknowledge messages. A Message-Driven Bean Example Introduction. Session beans allow you to send JMS messages and to receive them synchronously, but not asynchronously. To receive messages asynchronously, a Message-driven bean is used. Message driven beans are the light weight components used for communication via messages (e.g., email or IM messages). In message

Designing an enterprise application to use message-driven beans, The message-driven bean class must implement this message listener For example, an EJB message-driven bean class used for JMS messaging must Container Message selector: JMSType='car' Acknowledge mode:  To demonstrate use of message driven bean, we will make use of EJB-persistence chapter and we need to do the following tasks − Step 1 − Create table in database (Refer to EJB-Persistence chapter). Step 2 − Create Entity class corresponding to table (Refer to EJB-Persistence chapter). Step 3 − Create DataSource

A Guide to Message Driven Beans in EJB, In this article, we'll discuss Message Driven Beans (MDB), the acknowledgment method that applies to incoming messages and takes the  A message driven bean receives message from queue or topic, so you must have the knowledge of JMS API. A message driven bean is like stateless session bean that encapsulates the business logic and doesn't maintain state. Message Driven Bean Example. To create the message driven bean, you need to declare @MessageDriven annotation and implement MessageListener interface.

Comments
  • AUTO_ACKNOWLEDGE deletes the message after onMessage is successfully called
  • This is exactly the information I found out today researching. :) But thanks anyway! I use OpenMQ on Glassfish server.
  • "any exceptions in onMessage() will persist the message for redelivery " -- should I throw the exception in onMessage? But I cannot because onMessage method is implemented and it doesn't throw the exception.
  • @NoorSyed That's a problem because once onMessage() completes successfully, it's consumed.
  • Persistence settings are for handling failures ( infra structure or JMS/Application server crashes). They are NOT about redelivery after an exception is thrown from application code