【问题标题】:JavaMail: Is it possible to temporarily enable Store debugging during connection?JavaMail:是否可以在连接期间临时启用存储调试?
【发布时间】:2018-11-04 17:40:30
【问题描述】:

我的团队有一个长期运行的 IMAP 邮箱侦听器,它使用 JavaMail v1.6.1(在撰写本文时为 http://search.maven.org 的最新版本)以及 IMAP IDLE 命令来自动处理传入的邮件。服务器是 Microsoft Exchange 2010,但我不知道确切的补丁级别。

不幸的是,有时我们会看到非常奇怪的行为。经过 3.5 小时的 IDLE(等待收到的邮件)后,我们的连接突然关闭。 (我们假设服务器正在关闭我们的连接。)通常,重新打开的逻辑是有效的。然而,在某些时候,邮件服务器变得“脾气暴躁”并拒绝我们重新连接:javax.mail.AuthenticationFailedException: LOGIN failed.

我已经阅读了足够多的 JavaMail 博客文章和问答(由不知疲倦的倡导者和帮助者 Bil​​l Shannon 撰写),知道问题可能出在我们的代码中,而不是 JavaMail 或 IMAP 服务器中的错误。 p>

是否可以在连接过程中临时启用Store调试?

虽然我们正在试验各种Session 属性...理想情况下,我想在Store 实例的连接期间临时启用调试。但是,查看IMAPSSLStore(扩展extends IMAPStore)的实现,似乎调试标志取自父Session 实例,以后不能在Store 实例上更改。此外,由于我们仅在连接 3.5 小时后偶尔看到此问题,因此如果在我们的应用程序中启用 JavaMail 调试日志记录将是巨大的。


作为参考,这里是我们的初始连接代码:

    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);

【问题讨论】:

    标签: jakarta-mail


    【解决方案1】:

    如果您为每个连接使用不同的会话,则可以在每个会话(以及每个连接)的基础上启用调试。如果您提供自己的调试输出流,您可以决定是丢弃还是保留调试输出。

    JavaMail 调试也是通过 java.util.logging 发送的。您应该能够动态启用和禁用记录器,但请注意,这适用于整个 JVM,而不仅仅是 Store。您可能可以使用线程局部变量和您自己的日志处理程序来进一步过滤日志输出。

    另外,请注意,您不需要自己的套接字工厂。您可以设置mail.imaps.ssl.trust 属性。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-11
    相关资源
    最近更新 更多