It's not really supported.
If you want to do this, one way is to create a new message (copy?), using a non-transacted JMS connection and send it back to the same queue (or a separate queue) with the exception.
Thanks for your answer. I had considered some similar approaches like the one you propose.
However, if I include a non-transactional component in the design, there is the possibility to introduce a race condition.
Imagine this scenario:
1) The JMS message is delivered for the first time, and starts transaction T1 to process Object A.
2) During the process, a business error is detected and an exception with the message is thrown.
3) As this exception is thrown, somewhere a handler sends also a non-transacitonal message to the process queue.
4) The JMS message is redelivered in T2, and the MDB has to flag this process as failed (and maybe update Object A to a new state?).
5) At the same time, the second message is processed in T3, that has to update Object A to attach the error message to it.
In this hypothetical case, it would be very unlikely that this race condition materializes to a real threat, because we would take care that T2 and T3 will not update the same objects. However, this is not valid for a more general case. Maybe if I don't find a better solution I will have to settle for this.
Like I always say, JMS is not a database.
It only supports add (send) and delete (receive). There is no update or select, etc.