AUTHENTICATIONFAILED 上的 ImapIdleChannelAdapter 无限循环

ImapIdleChannelAdapter infinite loop on AUTHENTICATIONFAILED

我正在使用 ImapIdleChannelAdapter 来侦听邮箱,在数据库中获取带有凭据的列表。 如果密码错误,我会收到 AUTHENTICATIONFAILED。 问题是它永远不会停止尝试重新连接。 我尝试将 shouldReconnectAutomatically 设置为 false,但它只会阻止 IdleTask 重新提交,而不是 ReceivingTask。

来自 ImapIdleChannedAdapter 的代码:

private class ReceivingTask implements Runnable {

        ReceivingTask() {
        }

        @Override
        public void run() {
            if (isRunning()) {
                try {
                    ImapIdleChannelAdapter.this.idleTask.run();
                    logger.debug("Task completed successfully. Re-scheduling it again right away.");
                }
                catch (Exception ex) { //run again after a delay
                    logger.warn(ex, () -> "Failed to execute IDLE task. Will attempt to resubmit in "
                            + ImapIdleChannelAdapter.this.reconnectDelay + " milliseconds.");
                    ImapIdleChannelAdapter.this.receivingTaskTrigger.delayNextExecution();
                    publishException(ex);
                }
            }
        }

    }


    private class IdleTask implements Runnable {

        IdleTask() {
        }

        @Override
        public void run() {
            if (isRunning()) {
                try {
                    logger.debug("waiting for mail");
                    ImapIdleChannelAdapter.this.mailReceiver.waitForNewMessages();
                    Folder folder = ImapIdleChannelAdapter.this.mailReceiver.getFolder();
                    if (folder != null && folder.isOpen() && isRunning()) {
                        Object[] mailMessages = ImapIdleChannelAdapter.this.mailReceiver.receive();
                        logger.debug(() -> "received " + mailMessages.length + " mail messages");
                        for (Object mailMessage : mailMessages) {
                            Runnable messageSendingTask = createMessageSendingTask(mailMessage);
                            if (isRunning()) {
                                ImapIdleChannelAdapter.this.sendingTaskExecutor.execute(messageSendingTask);
                            }
                        }
                    }
                }
                catch (MessagingException ex) {
                    logger.warn(ex, "error occurred in idle task");
                    if (ImapIdleChannelAdapter.this.shouldReconnectAutomatically) {
                        throw new IllegalStateException("Failure in 'idle' task. Will resubmit.", ex);
                    }
                    else {
                        throw new org.springframework.messaging.MessagingException(
                                "Failure in 'idle' task. Will NOT resubmit.", ex);
                    }
                }
            }
        }

    }

所以在我的日志中我得到无限:

WARN 2777 --- [ask-scheduler-3] o.s.i.mail.ImapIdleChannelAdapter        : Failed to execute IDLE task. Will attempt to resubmit in 10000 milliseconds.

org.springframework.messaging.MessagingException: Failure in 'idle' task. Will NOT resubmit.; nested exception is javax.mail.AuthenticationFailedException: [AUTHENTICATIONFAILED] Invalid credentials (Failure)
    at org.springframework.integration.mail.ImapIdleChannelAdapter$IdleTask.run(ImapIdleChannelAdapter.java:290)
    at org.springframework.integration.mail.ImapIdleChannelAdapter$ReceivingTask.run(ImapIdleChannelAdapter.java:246)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
    at java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: javax.mail.AuthenticationFailedException: [AUTHENTICATIONFAILED] Invalid credentials (Failure)
    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:708)
    at javax.mail.Service.connect(Service.java:342)
    at javax.mail.Service.connect(Service.java:222)
    at javax.mail.Service.connect(Service.java:171)
    at org.springframework.integration.mail.AbstractMailReceiver.connectStoreIfNecessary(AbstractMailReceiver.java:331)
    at org.springframework.integration.mail.AbstractMailReceiver.openFolder(AbstractMailReceiver.java:338)
    at org.springframework.integration.mail.ImapMailReceiver.waitForNewMessages(ImapMailReceiver.java:176)
    at org.springframework.integration.mail.ImapIdleChannelAdapter$IdleTask.run(ImapIdleChannelAdapter.java:271)
    ... 11 common frames omitted

那些日志很奇怪:

Failed to execute IDLE task. Will attempt to resubmit in 10000 milliseconds
Failure in 'idle' task. Will NOT resubmit.

是否有可能停止重新连接尝试? 我真的不想将 reconnectDelay 设置为荒谬的持续时间......感觉不对。

谢谢!

添加一个 ApplicationListener<ImapIdleExceptionEvent> bean(或一个 @EventListener 方法)来接收 ImapIdleExceptionEvents。

然后您可以在事件侦听器中停止适配器(通道适配器是事件的source)。