Announcement Announcement Module
Collapse
No announcement yet.
ImapIdleChannelAdapter: after the first mail it stops receiving mail - Is this a bug? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • ImapIdleChannelAdapter: after the first mail it stops receiving mail - Is this a bug?

    Using the ImapIdleChannelAdapter with a GMail account will only receive and process the first email. When I send the second email it will not be received. For testing purposes I've reproduced this behaviour with the Spring Integration basic mail sample.

    Steps to reproduce:
    1. Create GMail account, activate IMAP access, delete all messages (to start with an empty inbox)
    2. Clone Spring Integration sample from git://git.springsource.org/spring-integration/samples.git
    3. Use sample project "basic/mail"
    4. Modify gmail-imap-idle-config.xml to contain the correct IMAP username/password
    5. Start GmailInboundImapIdleAdapterTestApp
    6. Send first test mail
    7. Watch console output which shows that the test mail is received
    8. Send second test mail
    9. Watch console which shows nothing :-(


    Here ist the console output:
    Code:
    DEBUG: org.springframework.integration.mail.ImapIdleChannelAdapter - waiting for mail
    INFO : org.springframework.integration.mail.ImapIdleChannelAdapter - started customAdapter
    DEBUG: org.springframework.integration.mail.ImapMailReceiver - connecting to store [imaps://[email protected]:*****@imap.gmail.com:993/inbox]
    DEBUG: org.springframework.integration.mail.ImapMailReceiver - opening folder [imaps://[email protected]:*****@imap.gmail.com:993/inbox]
    INFO : org.springframework.integration.mail.ImapMailReceiver - attempting to receive mail from folder [INBOX]
    DEBUG: org.springframework.integration.mail.ImapMailReceiver - This email server does not support RECENT flag, but it does support USER flags which will be used to prevent duplicates during email fetch.
    DEBUG: org.springframework.integration.mail.ImapMailReceiver - found 1 new messages
    DEBUG: org.springframework.integration.mail.ImapMailReceiver - Recieved 1 messages
    DEBUG: org.springframework.integration.mail.ImapMailReceiver - USER flags are supported by this mail server. Flagging message with 'spring-integration-mail-adapter' user flag
    DEBUG: org.springframework.integration.mail.ImapIdleChannelAdapter - received 1 mail messages
    INFO : org.springframework.integration.samples.mail.imapidle.GmailInboundImapIdleAdapterTestApp - Message: [Payload=javax.mail.internet.MimeMessage@435a3a][Headers={timestamp=1314963028427, id=ca7f2b38-ee03-4321-b237-a704a29b5c6f}]
    I've analyzed this a little bit further. What I can see is the following.

    When GmailInboundImapIdleAdapterTestApp starts there are 4 threads running:
    • task-scheduler-1
    • task-scheduler-2
    • SimpleAsyncTaskExecutor-1
    • DestroyJavaVM

    Using the debugger I can see that the SimpleAsyncTaskExecutor-1 is doing the IMAP IDLE command. Inside ImapMailReceiver.waitForNewMessages() it's calling imapFolder.idle(). When the first mail arrives the idle() call returns and the mail is received and further processed. Everything is fine up to here.

    But afterwards there are only 3 threads remaining:
    • task-scheduler-1
    • task-scheduler-2
    • DestroyJavaVM

    Using the debugger I can see that there is no thread waiting in the idle() call anymore!?

    I've tried to understand the logic behind this and from my understanding the idea is, that the task which does the IMAP IDLE should receive the mail and afterwards schedules itself to run again. The code for this is inside ImapIdleChannelAdapter.doStart()


    Code:
    ...
    	public void run() {
    		try {
    			idleTask.run();
    			if (mailReceiver.getFolder().isOpen()){
    			if (logger.isDebugEnabled()){
    				logger.debug("Task completed successfully. Re-scheduling it again right away");
    			}
    			scheduler.schedule(this, new Date());
    							}					
    		}
    		catch (IllegalStateException e) { //run again after a delay
    			logger.warn("Failed to execute IDLE task. Will atempt to resubmit in " + reconnectDelay + " milliseconds", e);
    			scheduler.schedule(this, new Date(System.currentTimeMillis() + reconnectDelay));
    		}
    	}
    ...
    But after receiving the first mail the check for mailReceiver.getFolder().isOpen() returns false and so re-scheduling is stopped.

    Is this a bug or a misconfiguration?

    Thanks.

    Greetings
    Olli

  • #2
    What is te version of Spring Integration you are using?

    Comment


    • #3
      I've cloned the basic/mail sample from git and use the provided pom.xml.

      This gives me the following dependencies:
      • spring-integration 2.0.5.RELEASE
      • spring-framework 3.0.5.RELEASE
      • mail 1.4.1
      • activation 1.1.1

      I've also tried mail 1.4.3 and 1.4.4 but this makes no difference.

      Olli

      Comment


      • #4
        Ok, I am going to verify this shortly (hopefully its miss-configuration), but mail 1.4.3. should probably be the minimum dependency. I remember issues with IDLE on the smaller versions.

        Comment


        • #5
          Yes, this is a bug which is easy to fix. Here is what's happening:
          The IMAPFolder gets closed as soon as this Messages are received:

          Message[] mailMessages = mailReceiver.receive();

          So the check for if (mailReceiver.getFolder().isOpen()) in ImapIdleChannelAdapter is invalid and always returns false after a first email and the task never gets rescheduled. The folder will be automatically opened as soon as idle() command returns successfully, so we basically have to remove this check.

          I've raised https://jira.springsource.org/browse/INT-2104 which wil be fixed in the next minute and will be available with tonight's nightly build as well as 2.1.M1 which fortunately should be in the next few days.

          Comment


          • #6
            Meanwhile you can try to downgrade to 2.0.4 or 2.0.3 temporarily. This bug was introduced as part of the refactoring. We know it worked before so you should be fine with this temp workaround.

            Comment


            • #7
              Hi Oleg,

              thanks for your support. It's always a pleasure to work with such a supportive and professional open source project.

              Glad to hear that you will fix it soon and that there is a temporary workaround available.

              Greetings.
              Olli

              Comment


              • #8
                Olli

                Thank you!. Actually Spring Integration 2.1.M1 was released last night and includes this fix, so you can upgrade and let us know

                Comment

                Working...
                X