Description
Behavior observed in: Spring Integration 6.2.1 (as no recent changes I assume it applies to later versions as well)
Describe the bug
I have some Imap idle channel adapters set up with various settings. I notice that occasionally, one of the mailservers has a connection hiccup. For a normal jakarta.mail.StoreClosedException: * BYE Jakarta Mail Exception: java.net.SocketException: Connection reset
this results in a resubmission (and reconnection) with logging 'Failed to execute IDLE task. Will attempt to resubmit in 10000 milliseconds.'.
However, on the idle channel adapter that also has a 'mail-filter-expression' it seems that this may also result in a problem while the filter expression is being evaluated, causing a SpelEvaluationException
with as root exception a 'jakarta.mail.FolderClosedException'. Since in this specific case the ImapIdleChannelAdapter#callIdle method will break the while loop in the else clause because the ex.getCause()
is not an instanceof jakarta.mail.MessagingException
(even though ex.getCause().getCause().getCause()
is).
I know that I can register an ApplicationEventListener that acts upon the ApplicationEvent published by the ImapIdleChannelAdapter#publishException
(and essentially restarts the adapter), but I feel that it is odd that there is nice built-in behavior to restart the adapter when some jakarta.mail.MessagingException occurs as the cause of the current exception, but not when it is a deeper nested cause, because built-in SpEL expression logic is used. In my eyes, this would be 'fixed' as well if ImapIdleChannelAdapter line 203 would do check whether the stack trace of the Exception has a MessagingException cause, instead of only checking the cause directly above. (i.e. a (fictional) 'hasCause' instead of 'getCause')?
Expected behavior
The IMAP idle channel adapter has the same reconnect behavior whether a 'mail filter expression' is used or not
Sample
Although this is quite difficult to reproduce, as it is essentially seems to be caused by a server hiccup that is not generally the case for large mail providers such as Gmail or Outlook, I have provided a small XML configuration sample below of the used configuration.
<mail:imap-idle-channel-adapter channel="mailFromImap"
java-mail-properties="mailProperties"
auto-close-folder="true"
id="imapIdle"
mail-filter-expression="subject matches '.*TEST.*'"
should-delete-messages="false"
should-mark-messages-as-read="true"
simple-content="true"
store-uri="imaps://username:password@host/inbox"/>
<util:map id="mailProperties"
key-type="java.lang.String"
map-class="java.util.Properties"
value-type="java.lang.String">
<entry key="mail.imaps.timeout" value="240000"/>
</util:map>
Log message with (reversed) stack trace when the issue occurs:
Failed to execute IDLE task. Won't resubmit since not a 'shouldReconnectAutomatically' or not a 'jakarta.mail.MessagingException'
Stack trace:
jakarta.mail.FolderClosedException: null
at org.eclipse.angus.mail.imap.IMAPMessage.getProtocol(IMAPMessage.java:182)
at org.eclipse.angus.mail.imap.IMAPMessage.loadEnvelope(IMAPMessage.java:1502)
at org.eclipse.angus.mail.imap.IMAPMessage.getSubject(IMAPMessage.java:454)
... 18 common frames omitted
Wrapped by: java.lang.reflect.InvocationTargetException: null
at jdk.internal.reflect.GeneratedMethodAccessor43.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.expression.spel.support.ReflectivePropertyAccessor$OptimalPropertyAccessor.read(ReflectivePropertyAccessor.java:694)
... 14 common frames omitted
Wrapped by: org.springframework.expression.AccessException: Unable to access property 'subject' through getter method
at org.springframework.expression.spel.support.ReflectivePropertyAccessor$OptimalPropertyAccessor.read(ReflectivePropertyAccessor.java:698)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:215)
... 13 common frames omitted
Wrapped by: org.springframework.expression.spel.SpelEvaluationException: EL1021E: A problem occurred whilst attempting to access the property 'subject': 'Unable to access property 'subject' through getter method'
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:220)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:111)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:99)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:212)
at org.springframework.expression.spel.ast.OperatorMatches.getValueInternal(OperatorMatches.java:88)
at org.springframework.expression.spel.ast.OperatorMatches.getValueInternal(OperatorMatches.java:42)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:119)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:376)
at org.springframework.integration.mail.AbstractMailReceiver.filterMessagesThruSelector(AbstractMailReceiver.java:556)
at org.springframework.integration.mail.AbstractMailReceiver.searchAndFilterMessages(AbstractMailReceiver.java:425)
at org.springframework.integration.mail.AbstractMailReceiver.receive(AbstractMailReceiver.java:380)
at org.springframework.integration.mail.ImapIdleChannelAdapter.processIdle(ImapIdleChannelAdapter.java:229)
at org.springframework.integration.mail.ImapIdleChannelAdapter.callIdle(ImapIdleChannelAdapter.java:198)
at java.base/java.lang.Thread.run(Unknown Source)