MimeMessage.writeTo(OutputStream)挂起

问题描述 投票:1回答:1

我正在尝试通过邮箱中的邮件进行阅读,但在将邮件内容解析为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 <[email protected]>
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?= <[email protected]>
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
java email javamail
1个回答
0
投票

最终我放弃了转换消息类型,如果它在转换中挂起,我直接让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();

我使用线程和执行器来使挂起循环继续,这不是一件容易的事。

© www.soinside.com 2019 - 2024. All rights reserved.