This is a consequence of the fix for #17644, since we only call Session.recover() in case of CLIENT_ACKNOWLEDGE now. Note that we did not call recover() before #16631 at all, so what you're relying on is part of a rather recent initiative to make non-transacted JMS more reliable - on a best effort basis, with no strong guarantees.
From a common JMS perspective, Session.recover() is only really meant to be used with CLIENT_ACKNOWLEDGE, so the current behavior seems to be a fine compromise. In the case of AUTO_ACKNOWLEDGE, the JMS broker itself is responsible for redelivery decisions; I'm surprised that you're not seeing redelivery since that's what most brokers do.
So from that perspective, you've been relying on non-guaranteed behavior in AUTO mode before. My recommendation would be to switch to CLIENT_ACKNOWLEDGE if you are expecting best-effort recovery behavior there. For a higher degree of redelivery guarantees, you might want to switch to the traditional sessionTransacted=true instead.
I'm surprised that you're not seeing redelivery since that's what most brokers do.
I was trying it with HornetQ and ActiveMQ. Same behavior. It's because AbstractMessageListenerContainer.executeListener(Session session, Message message) doesn't bubble up exception to JMS listener library when error handler isn't defined. That is why I reopened the issue.
Does that mean this JMS configuration is designed to work in JMS compliant way only when error handler is defined and re-throws exception? Maybe I missed this fact in reference/java docs.
Is it intentional to allow user to control bubbling up exceptions in error handler for JMS module?
Wouldn't be a good idea to re-throw exception in AbstractMessageListenerContainer.invokeErrorHandler(Throwable ex) if default error handler is not defined? I understand that other ack/transacted modes should be considered for such change. But it would help to behave in JMS compliant way in such configuration.(Would you consider such pull request?)
This is actually why we opted to not propagate exceptions to the broker in SimpleMessageListenerContainer. This also brings it in sync with DefaultMessageListenerContainer where such propagation isn't even possible. However, our documentation suggests that SMLC may provide redelivery in AUTO mode while DMLC doesn't; this needs to be rephrased to clarify that exception handling is effectively equivalent. The only difference is what happens when the JVM dies during listener execution: With SMLC, messages are likely to get redelivered in such a scenario; with DMLC, they definitely won't get redelivered since they have been acknowledged before delegating to the listener.
As a consequence, I'm turning this into a documentation task. The current runtime behavior is correct from my perspective, both from our intentions and also following the JMS spec, and just needs to be clearly stated. To get the desired effect of consistent redelivery, you'll have to use CLIENT_ACKNOWLEDGE or sessionTransacted=true.