My team has a long running IMAP mailbox listener that uses JavaMail v1.6.1 (latest on http://search.maven.org as of writing), along with the IMAP IDLE
command, to automatically process incoming mails. The server is Microsoft Exchange 2010, but I don't know the exact patch level.
Unfortunately, sometimes we see very strange behaviour. After 3.5 hours of IDLEs (waiting for incoming mails), suddenly our connection is closed. (We assume server is closing our connection.) Usually, the re-open logic works. However, at some point, the mail server gets "grumpy" and refuses our re-connect: javax.mail.AuthenticationFailedException: LOGIN failed.
I have read enough JavaMail blog posts and Q&As (by tireless advocate and helper Bill Shannon) to know the issue is likely within our code, not a bug in JavaMail or the IMAP server.
Is it possible to temporarily enable Store
debugging during connection?
While we are experimenting with various Session
properties... ideally, I would like to temporarily enable debugging during connection on the Store
instance. However, looking at the implementation for IMAPSSLStore
(which extends extends IMAPStore
), it seems the debug flag is taken from parent Session
instance and cannot be later changed on the Store
instance. Further, since we only sporadically see the issue after 3.5 hours of connection, the JavaMail debug logging would be huge if enabled in our application.
For reference, here is our initial connect code:
final Properties p = new Properties();
// Ref: https://community.oracle.com/message/10503406?#10501406
// Ref: https://stackoverflow.com/questions/11719205/how-to-use-javamail-for-accessing-additional-mailboxes-imap-exchange-2010
p.setProperty("mail.imaps.ssl.enable", "true");
p.setProperty("mail.imaps.auth.plain.disable", "true");
p.setProperty("mail.imaps.auth.ntlm.disable", "true");
p.setProperty("mail.imaps.auth.gssapi.disable", "true");
p.setProperty("mail.imaps.starttls.enable", "false");
p.setProperty("mail.imaps.host", config.host);
p.setProperty("mail.imaps.port", String.valueOf(config.port));
p.setProperty("mail.imaps.socketFactory.fallback", "false");
// Ref: https://stackoverflow.com/questions/35532797/how-to-speed-up-time-when-using-java-mail-to-save-attachments
p.setProperty("mail.imaps.partialfetch", "false");
p.setProperty("mail.imaps.fetchsize", "1048576");
// Ref: http://www.obsidianscheduler.com/blog/ignoring-self-signed-certificates-in-java/
final SSLContext c =
// Ref: https://stackoverflow.com/a/13138554/257299
SSLContext.getInstance("TLS");
// SSLContext.getInstance("SSL");
// SSLContext.getDefault();
c.init(
(KeyManager[]) null,
new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {
@DebugBreakpoint int dummy = 1;
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {
@DebugBreakpoint int dummy = 1;
}
@Override
public X509Certificate[]
getAcceptedIssuers() {
return null;
}
}
},
(SecureRandom) null);
final SSLSocketFactory socketFactory = c.getSocketFactory();
p.put("mail.imaps.ssl.socketFactory", socketFactory);
final Session session = Session.getInstance(p);
// Ref: https://stackoverflow.com/questions/30613622/java-mail-store-type-imap-vs-imaps
final Store store = session.getStore("imaps"); // Type: IMAPSSLStore
store.connect(config.username, config.password);