0

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);
kevinarpe
  • 20,319
  • 26
  • 127
  • 154

1 Answers1

1

If you use a different Session for each connection, you can enable debugging on a per-Session (and thus per-connection) basis. If you provide your own debug OutputStream, you can decide whether to throw away the debug output or keep it.

JavaMail debugging is also sent through java.util.logging. You should be able to enable and disable loggers dynamically, but note that applies to the entire JVM, not just to the Store. You could probably use thread-local variables and your own log handler to further filter the log output.

Also, note that you don't need your own socket factory. You can set the mail.imaps.ssl.trust property.

Bill Shannon
  • 29,579
  • 6
  • 38
  • 40
  • 1
    @kevinarpe Here is an example [java.util.logging filter using a thread-local](https://stackoverflow.com/questions/30201743/how-to-temporarily-disable-protocol-tracing-during-a-javamail-imap-connection/33555550#33555550) to toggle debug output. – jmehrens May 28 '18 at 14:07