Skip to content

IMAP idle channel adapter reconnect behavior seems to be different when (not) using a mail filter expression #9297

Closed
@smitsjelle

Description

@smitsjelle

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)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions