【问题标题】:MimeMessage.writeTo(OutputStream) hangsMimeMessage.writeTo(OutputStream) 挂起
【发布时间】:2019-02-14 18:18:45
【问题描述】:

我正在尝试阅读邮箱中的邮件,但在将邮件内容解析到 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();

....

下面是日志信息,它没有显示任何异常,而是挂在“msg.writeTo(bos);”步骤的“B”处在日志中

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

【问题讨论】:

    标签: java email jakarta-mail


    【解决方案1】:

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

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 2015-07-06
    相关资源
    最近更新 更多