Message-driven beans, like other well-behaved MessageListeners, should not, in general, throw runtime exceptions. If a message-driven bean’s onMessage method encounters a system-level exception or error that does not allow the method to successfully complete, the Enterprise JavaBeans Specification, v3.0 provides the following guidelines:
If the bean method encounters a runtime exception or error, it should simply propagate the error from the bean method to the container.
If the bean method performs an operation that results in a checked exception that the bean method cannot recover, the bean method should throw the javax.ejb.EJBException that wraps the original exception.
Any other unexpected error conditions should be reported using javax.ejb.EJBException (javax.ejb.EJBException is a subclass of java.lang.RuntimeException).
Under container-managed transaction demarcation, upon receiving a runtime exception from a message-driven bean’s onMessage method, the container rolls back the container-started transaction and the message is redelivered. This is because the message delivery itself is part of the container-started transaction. By default, the Enterprise Server container closes the container’s connection to the JMS provider when the first runtime exception is received from a message-driven bean instance’s onMessage method. This avoids potential message redelivery looping and protects server resources if the message-driven bean’s onMessage method continues misbehaving. To change this default container behavior, use the cmt-max-runtime-exceptions property of the mdb-container element in the domain.xml file.
The cmt-max-runtime-exceptions property specifies the maximum number of runtime exceptions allowed from a message-driven bean’s onMessage method before the container starts to close the container’s connection to the message source. By default this value is 1; -1 disables this container protection.
A message-driven bean’s onMessage method can use the javax.jms.Message getJMSRedelivered method to check whether a received message is a redelivered message.
The cmt-max-runtime-exceptions property might be deprecated in the future.