Version 5

    What type of Exceptions should an MDB throw?

     

    The quick answer is none.

     

    What the spec says

     

    The onMessage(Message) method is defined in the JMS spec not the EJB spec. In the JMS spec it is described as an application error for onMessage to throw an Exception. It goes onto to say that it is vendor specific what happens in this circumstance (read: not very portable).

     

    From the JMS Spec:

    "It is possible for a listener to throw a RuntimeException; however, this is considered a client programming error. Well-behaved listeners should catch such exceptions and attempt to divert messages causing them to some form of application-specific unprocessable message destination."

     

     

    If a RuntimeException is thrown from the onmesssage the ejb instance is discarded without ejbRemove() being invoked.

     

    From the EJB Spec:

    "The onMessage method of a message-driven bean must not throw application exceptions or the java.rmi.RemoteException.

    Message-driven beans, like other well-behaved JMS MessageListeners, should not, in general, throw RuntimeExceptions.

    A RuntimeException thrown from any method of the message-driven bean class (including the onMessage method and the callbacks invoked by the Container) results in the transition to the does not exist state."

     

     

     

    JCA 1.5 - inbound resource adapters

     

    With other types of message listener interfaces, exceptions maybe supported. The rules are the same as EJB methods. The transaction is only rolled back for

    RuntimeException

    s,

    Error

    s and

    RemoteException

    s.

     

    How should I handle exceptions?

     

    If you have a transaction, i.e. CMT and

    Required

    the answer is easy.

    public void onMessage(Message message)
    {
       try
       {
          // do work
       }
       catch (SomeException e)
       {
          // maybe log it?
    
          // Force a transaction rollback and redelivery
          messageDrivenBeanContext.setRollbackOnly();
       }
    }
    

     

    Without a transaction, you are on your own. There is no way to force a redelivery. Although JBoss does make an effort to do so when you have not chosen a strategy that isolates the MDB from the delivery transaction and an unchecked exception is thrown.

     

    In practice

     

    If your MDB does have an exception like a

    NullPointerException

    it probably means

    something serious has gone wrong. It is probably a good idea to propagate that to the container

    to discard the instance which is probably in an indeterminate state.

     

    If there is a transaction, it will force a rollback and redelivery.

     

    Related

     

    MDB deployment strategies