MimeMessage.writeTo(OutputStream) 挂起
MimeMessage.writeTo(OutputStream) hangs
我正在尝试通读邮箱中的邮件,但在将邮件内容解析为 MimeMessage 期间,某些特定的邮件使进程挂起,它没有显示任何错误消息,日志显示程序停止在MimeMessage.writeTo(OutputStream)的步骤,下面是实际代码
for (int n = message.length; i < n; i++)
{Log25.write("IMAPaccess", "getMessages", "start convert");
MimeMessage msg = (MimeMessage)message[i];
Log25.write("IMAPaccess", "getMessages", "A");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Log25.write("IMAPaccess", "getMessages", "B");
msg.writeTo(bos);
Log25.write("IMAPaccess", "getMessages", "C");
bos.close();
Log25.write("IMAPaccess", "getMessages", "start create bis");
SharedByteArrayInputStream bis = new SharedByteArrayInputStream(bos.toByteArray());
MimeMessage cmsg = new MimeMessage(session, bis);
bis.close();
....
下面是日志信息,没有显示任何异常,而是挂在"B",也就是日志"msg.writeTo(bos);"的那一步
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 36: [Ljavax.mail.internet.InternetAddress;@d522e24d null
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 36: From address length 1
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 36: From address INFORMATION <info@funds.com>
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages complete for loop j
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages start convert
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages A
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages B
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages C
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages start create bis
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages start cmsg to mimeMessage
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages content type: text/html;^M
charset="utf-8"
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 37: [Ljavax.mail.internet.InternetAddress;@9b58d2b8 null
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 37: From address length 1
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 37: From address =?utf-8?B?6ZyN6bmD5Y6a?= <1757158944@qq.com>
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages complete for loop j
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages start convert
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages A
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages B
最后我放弃了转换消息类型,如果转换挂了我直接让for循环跳过继续,这样就省略了一些消息。我认为这无关紧要,因为我发现只有垃圾邮件才能使程序挂起。下面是代码
for (int n = message.length; i < n; i++)
{
Log25.write("IMAPaccess", "getMessages", "start convert");
MimeMessage msg = (MimeMessage)message[i];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// MJN1 has some SPAM email cannot be converted, so use thread to do the conversion
final Runnable stuffToDo = new Thread() {
@Override
public void run() {
try {
Log25.write("IMAPaccess", "run", "write to MimeMessage");
msg.writeTo(bos);
Log25.write("IMAPaccess", "run", "wrote to MimeMessage");
} catch (IOException | MessagingException e) {
Log25.write("IMAPaccess", "run", (new StringBuilder()).append("error = ").append(e.getMessage()).toString());
}
}
};
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future future = executor.submit(stuffToDo);
executor.shutdown(); // This does not cancel the already-scheduled task.
// start the conversion and if the process hangs, the loop should skip and continue
try {
future.get(1, TimeUnit.SECONDS);
}
catch (InterruptedException ie) {
Log25.write("IMAPaccess", "getMessages", (new StringBuilder()).append("error = ").append(ie.getMessage()).toString());
continue;
}
catch (ExecutionException ee) {
Log25.write("IMAPaccess", "getMessages", (new StringBuilder()).append("error = ").append(ee.getMessage()).toString());
continue;
}
catch (TimeoutException te) {
Log25.write("IMAPaccess", "getMessages", (new StringBuilder()).append("error = ").append(te.getMessage()).toString());
continue;
}
catch(Exception e) {
Log25.write("IMAPaccess", "getMessages", (new StringBuilder()).append("error = ").append(e.getMessage()).toString());
continue;
}
if (!executor.isTerminated())
executor.shutdownNow();
bos.close();
我用thread和executor让hang loop继续,这不是一件容易的事
我正在尝试通读邮箱中的邮件,但在将邮件内容解析为 MimeMessage 期间,某些特定的邮件使进程挂起,它没有显示任何错误消息,日志显示程序停止在MimeMessage.writeTo(OutputStream)的步骤,下面是实际代码
for (int n = message.length; i < n; i++)
{Log25.write("IMAPaccess", "getMessages", "start convert");
MimeMessage msg = (MimeMessage)message[i];
Log25.write("IMAPaccess", "getMessages", "A");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Log25.write("IMAPaccess", "getMessages", "B");
msg.writeTo(bos);
Log25.write("IMAPaccess", "getMessages", "C");
bos.close();
Log25.write("IMAPaccess", "getMessages", "start create bis");
SharedByteArrayInputStream bis = new SharedByteArrayInputStream(bos.toByteArray());
MimeMessage cmsg = new MimeMessage(session, bis);
bis.close();
....
下面是日志信息,没有显示任何异常,而是挂在"B",也就是日志"msg.writeTo(bos);"的那一步
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 36: [Ljavax.mail.internet.InternetAddress;@d522e24d null
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 36: From address length 1
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 36: From address INFORMATION <info@funds.com>
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages complete for loop j
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages start convert
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages A
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages B
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages C
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages start create bis
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages start cmsg to mimeMessage
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages content type: text/html;^M
charset="utf-8"
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 37: [Ljavax.mail.internet.InternetAddress;@9b58d2b8 null
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 37: From address length 1
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages 37: From address =?utf-8?B?6ZyN6bmD5Y6a?= <1757158944@qq.com>
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages complete for loop j
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages start convert
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages A
Mon Sep 10 09:44:41 UTC 2018 IMAPaccess getMessages B
最后我放弃了转换消息类型,如果转换挂了我直接让for循环跳过继续,这样就省略了一些消息。我认为这无关紧要,因为我发现只有垃圾邮件才能使程序挂起。下面是代码
for (int n = message.length; i < n; i++)
{
Log25.write("IMAPaccess", "getMessages", "start convert");
MimeMessage msg = (MimeMessage)message[i];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// MJN1 has some SPAM email cannot be converted, so use thread to do the conversion
final Runnable stuffToDo = new Thread() {
@Override
public void run() {
try {
Log25.write("IMAPaccess", "run", "write to MimeMessage");
msg.writeTo(bos);
Log25.write("IMAPaccess", "run", "wrote to MimeMessage");
} catch (IOException | MessagingException e) {
Log25.write("IMAPaccess", "run", (new StringBuilder()).append("error = ").append(e.getMessage()).toString());
}
}
};
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future future = executor.submit(stuffToDo);
executor.shutdown(); // This does not cancel the already-scheduled task.
// start the conversion and if the process hangs, the loop should skip and continue
try {
future.get(1, TimeUnit.SECONDS);
}
catch (InterruptedException ie) {
Log25.write("IMAPaccess", "getMessages", (new StringBuilder()).append("error = ").append(ie.getMessage()).toString());
continue;
}
catch (ExecutionException ee) {
Log25.write("IMAPaccess", "getMessages", (new StringBuilder()).append("error = ").append(ee.getMessage()).toString());
continue;
}
catch (TimeoutException te) {
Log25.write("IMAPaccess", "getMessages", (new StringBuilder()).append("error = ").append(te.getMessage()).toString());
continue;
}
catch(Exception e) {
Log25.write("IMAPaccess", "getMessages", (new StringBuilder()).append("error = ").append(e.getMessage()).toString());
continue;
}
if (!executor.isTerminated())
executor.shutdownNow();
bos.close();
我用thread和executor让hang loop继续,这不是一件容易的事