Search code examples
javaemailjakarta-mailimap

Using JavaMail's keepConnectionAlive to keep an IMAP IDLE connection alive


I've been struggling with keeping an IMAP IDLE connection alive. My code, which is very similar to this Code Review, works in most instances but sometimes will stop receiving messages.

It looks something like this:

//... some code
ScheduledExecutorService keepAlive = Executors.newScheduledThreadPool(1);
Runnable toKeepAlive = new Runnable() {
    public void run() {
        keepAliveRunner();
    }
};
keepAlive.scheduleAtFixedRate(toKeepAlive,
    KEEP_ALIVE_FREQ, 
    KEEP_ALIVE_FREQ, 
    TimeUnit.MILLISECONDS); 
    //... other code ;)
}

public void keepAliveRunner() {
    try {
        imapFolder.doCommand(new IMAPFolder.ProtocolCommand() {
            public Object doCommand(IMAPProtocol p)
            throws ProtocolException {
                p.simpleCommand("NOOP", null);
                return null;
            }
        });
    } catch (MessagingException e) {
        e.printStackTrace();
    }
}

I saw that JavaMail's IMAPFolder class has a keepConnectionAlive method. I was wondering if anyone had experience using this method. It says that it will "Issue a noop command for the connection if the connection has not been used in more than a second."

Would this method be a good substitute for the code from the Code Review?


Solution

  • Nothing is going to keep your connection alive forever. Your program needs to be able to handle connection failures.

    Normally a server will drop a connection that's been unused for 30 minutes. If you don't care what the server thinks and you want to abuse it by keeping an unused connection open even longer, all you need to do is call Folder.getMessageCount every 29 minutes. (The use of IMAPFolder.doCommand is unnecessarily complicated.) If that still fails, reconnect.