У моей команды есть долго работающий прослушиватель почтовых ящиков 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);