De la especificación JMS 1.1 ...
4.5.2 Entrega asíncrona
un cliente puede registrar un objeto que implementa la interfaz JMS MessageListener con un MessageConsumer. Cuando los mensajes llegan para el consumidor, el proveedor los entrega llamando al método onMessage del oyente.
Es posible que un oyente arroje una RuntimeException; sin embargo, esto se considera un error de programación del cliente. Los oyentes que se portan bien deben captar tales excepciones e intentar desviar los mensajes que los causan a algún tipo de destino 'mensaje no procesable' específico de la aplicación.
El resultado de que un oyente arroje una RuntimeException depende del modo de reconocimiento de la sesión.
- AUTO_ACKNOWLEDGE o DUPS_OK_ACKNOWLEDGE - el mensaje será entregado de nuevo inmediatamente. El número veces que un proveedor JMS dará volverá a enviar el mismo mensaje antes de dando por terminado es dependiente del proveedor. El campo de encabezado de mensaje JMSRedelivered se establecerá para un mensaje reentregado en estas circunstancias.
- CLIENT_ACKNOWLEDGE - se entrega el siguiente mensaje para el oyente. Si un cliente desea que se reenvíe el mensaje anterior sin confirmar, debe recuperar manualmente la sesión.
- Sesión transaccionada: se entrega el siguiente mensaje para el oyente. El cliente puede confirmar o retrotraer la sesión (en otras palabras, un RuntimeException no retrotraer automáticamente la sesión).
Los proveedores de JMS deben marcar a los clientes con escuchas de mensajes que están lanzando RuntimeExceptions como posiblemente un mal funcionamiento.
¿qué pasará si se produce una excepción no controlada dentro de onMessage y el método nunca vuelve? ¿Existe la posibilidad de que el mensaje no se elimine de la cola? ¿significa eso (para un cliente síncrono) que onMessage debe devolver un acuse de recibo para que el mensaje pueda eliminarse de la cola? – bluelurker
@bluelurker - Estoy confundido por tu pregunta. El lenguaje de especificación trata de permitir que una RuntimeException se propague desde el método onMessage(). Si su método finaliza arrojando una excepción, esa es una alternativa a una devolución "normal". Entonces no entiendo la parte "nunca regresa". En lugar de regresar, se completó haciendo que se propagara una excepción. –
@JohnM Desde el método onMessage() si lanzo RunTimeException, ese mensaje permanecerá en la cola y se volverá a entregar. De nuevo se lanzará un mensaje. Será entregado de nuevo. Y así sucesivamente ... ¿es correcto mi entendimiento?Esto es lo que veo que sucede en mis pruebas. –