解决 JavaMail Api 删除邮件时 诡异Exception

javax.mail.MessagingException: A7 NO STORE Can not find message 1;
nested exception is:
com.sun.mail.iap.CommandFailedException: A7 NO STORE Can not find message 1

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at
org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestRe
ference.java:49)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestR
unner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestR
unner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner
.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunne
r.java:197)
Caused by: javax.mail.MessagingException: A7 NO STORE Can not find message 1;
nested exception is:
com.sun.mail.iap.CommandFailedException: A7 NO STORE Can not find message 1
at com.sun.mail.imap.IMAPMessage.setFlags(IMAPMessage.java:847)
at javax.mail.Message.setFlag(Message.java:565)

… 20 more
Caused by: com.sun.mail.iap.CommandFailedException: A7 NO STORE Can not find
message 1
at com.sun.mail.iap.Protocol.handleResult(Protocol.java:294)
at com.sun.mail.imap.protocol.IMAPProtocol.storeFlags(IMAPProtocol.java:1294)
at com.sun.mail.imap.protocol.IMAPProtocol.storeFlags(IMAPProtocol.java:1279)
at com.sun.mail.imap.IMAPMessage.setFlags(IMAPMessage.java:843)
… 22 more

发现这个是exception是setFlag发出的,在网上查了很久没有找到原因。后来发现是频繁调用setFlag方法导致。原因在于如果一个Message被赋
值为某一个Flag,则不能重复赋值。所以解决办法是首先判断一下。

if (message.isSet(Flags.Flag.DELETED)){
    message.setFlag(Flags.Flag.DELETED);
}

另外删除邮件不管是使用imap还是pop都最好不要使用expunge()方法,这个方法不能保证在所有的mail
server上都成功。都还是message.setFlag()吧,这个最保险。

正确写法:

f.open(Folder.READ_WRITE);
                    for (Message message: f.getMessages()) {
                        if(!message.isSet(Flags.Flag.DELETED))
                        message.setFlag(Flags.Flag.DELETED, true);

                    }
                    f.close(true);