JavaMail: возможно ли временно включить отладку магазина во время соединения? - PullRequest
0 голосов
/ 25 мая 2018

У моей команды есть долго работающий прослушиватель почтовых ящиков IMAP, который использует JavaMail v1.6.1 (последняя версия http://search.maven.org на момент написания) вместе с командой IMAP IDLE для автоматической обработки входящих сообщений.Сервер Microsoft Exchange 2010, но я не знаю точный уровень исправлений.

К сожалению, иногда мы видим очень странное поведение.После 3,5 часов бездействия (в ожидании входящих писем) наше соединение внезапно закрывается.(Мы предполагаем, что сервер закрывает наше соединение.) Обычно логика повторного открытия работает.Тем не менее, в какой-то момент почтовый сервер становится «сварливым» и отказывается от повторного подключения: javax.mail.AuthenticationFailedException: LOGIN failed.

Я прочитал достаточно сообщений в блоге JavaMail и вопросов и ответов (неутомимый адвокат и помощник Билл Шеннон), чтобы узнатьпроблема, скорее всего, в нашем коде, а не в JavaMail или IMAP-сервере.

Возможно ли временно включить отладку 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);

1 Ответ

0 голосов
/ 25 мая 2018

Если вы используете разные Сеансы для каждого соединения, вы можете включить отладку для каждой Сессии (и, следовательно, для каждого соединения).Если вы предоставляете свой собственный отладочный OutputStream, вы можете решить, следует ли выбросить выходные данные отладки или оставить их.

Отладка JavaMail также отправляется через java.util.logging.Вы должны иметь возможность включать и отключать регистраторы динамически, но обратите внимание, что это относится ко всей JVM, а не только к Хранилищу.Вероятно, вы могли бы использовать локальные переменные потока и свой собственный обработчик журнала для дальнейшей фильтрации вывода журнала.

Также обратите внимание, что вам не нужна ваша собственная фабрика сокетов.Вы можете установить свойство mail.imaps.ssl.trust.

...