无法加载com.sun.mail.handlers.multipart_mixed

时间:2016-03-29 10:06:46

标签: java javamail tomcat8

我们使用Javamail api创建了一个监听器来读取电子邮件收件箱中新添加的消息。一旦监听器收到新消息,我们就会尝试获取所有标头信息以及内容部分。为了解析内容,我们编写了一个正确的解析逻辑,它适用于所有类型的内容(文本,HTML,多部分等)。这是解析代码。

private String getText(Part p) throws MessagingException, IOException {
        if (p.isMimeType("text/*")) {
            String s = (String) p.getContent();         
            return s;
        }

        if (p.isMimeType("multipart/alternative")) {
            // prefer html text over plain text
            Multipart mp = (Multipart) p.getContent();
            String text = null;
            for (int i = 0; i < mp.getCount(); i++) {
                Part bp = mp.getBodyPart(i);
                if (bp.isMimeType("text/plain")) {
                    if (text == null){
                        text = getText(bp);
                        return text;
                    }

                } else if (bp.isMimeType("text/html")) {
                    String s = getText(bp);
                    if (s != null)
                    return s;

                } else {
                    return getText(bp);
                }
            }
            return text;
        } else if (p.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) p.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                String s = getText(mp.getBodyPart(i));
                if (s != null)
                    return s;
            }
        }

        return null;
    }

上面的监听器和解析,我们运行在一个部署在tomcat容器(版本 - Apache tomcat 8.0.35)中的Web应用程序中。

在我们为IMAP连接获得会话超时的一段时间后,我们正在通过programmatic重新启动监听器。现在,侦听器能够将新添加的消息读取到收件箱,但是消息内容解析失败了以下异常。我们尝试了多种方法来解决问题,但没有取得成功。下面是异常堆栈跟踪

25-Mar-2016 14:08:10.158 INFO [JavaMail-EventQueue] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load [com.sun.mail.handlers.multipart_mixed]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
 java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [com.sun.mail.handlers.multipart_mixed]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
    at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1328)
    at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForClassLoading(WebappClassLoaderBase.java:1316)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1181)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1142)
    at javax.activation.MailcapCommandMap.getDataContentHandler(MailcapCommandMap.java:582)
    at javax.activation.MailcapCommandMap.createDataContentHandler(MailcapCommandMap.java:560)
    at javax.activation.CommandMap.createDataContentHandler(CommandMap.java:221)
    at javax.activation.DataHandler.getDataContentHandler(DataHandler.java:615)
    at javax.activation.DataHandler.getContent(DataHandler.java:542)
    at javax.mail.internet.MimeMessage.getContent(MimeMessage.java:1419)
    at omniquo.awe.util.MailUtil.readMailBody(MailUtil.java:152)
    at omniquo.awe.activitiservice.MailListner$MailThreadListener$2.messagesAdded(MailListner.java:165)
    at javax.mail.event.MessageCountEvent.dispatch(MessageCountEvent.java:150)
    at javax.mail.EventQueue.run(EventQueue.java:134)
    at java.lang.Thread.run(Thread.java:745)

Unable to parse Email com.sun.mail.imap.IMAPInputStream cannot be cast to javax.mail.internet.MimeMultipart
java.lang.ClassCastException: com.sun.mail.imap.IMAPInputStream cannot be cast to javax.mail.internet.MimeMultipart
    at omniquo.awe.util.MailUtil.readMailBody(MailUtil.java:152)
    at omniquo.awe.activitiservice.MailListner$MailThreadListener$2.messagesAdded(MailListner.java:165)
    at javax.mail.event.MessageCountEvent.dispatch(MessageCountEvent.java:150)
    at javax.mail.EventQueue.run(EventQueue.java:134)
    at java.lang.Thread.run(Thread.java:745)

我们需要一个具体的解决方案来解决这个问题。我们正在使用以下环境和api版本

JDK- 1.8.0_65, Tomcat - 8.0.35, Java邮件 - 1.5.5, 春天 - 4

2 个答案:

答案 0 :(得分:0)

如果没有改变,很难理解为什么会失败。你真的需要弄清楚改变了什么。您使用的是较新版本的JDK还是Tomcat?

“程序化重启监听器”究竟是什么意思?您是否正在重新启动Tomcat服务器?

这个问题通常会发生,因为JavaBeans Activation Framework(JAF,现在是JDK的一部分)无法找到描述用于什么MIME类型的Java类的配置文件。此配置文件是JavaMail jar文件的一部分。如果您的应用程序已更改且此文件丢失,则可以解释它。如果你正在使用一些不寻常的类加载方案,它也可能由于ClassLoader的问题而发生。

答案 1 :(得分:0)

如果您正在重新加载webapp,那么javax.mail.EventQueue正在捕获第一个webapp类加载器。创建新线程时,上下文类加载器设置为父线程的上下文类加载器。

synchronized void enqueue(MailEvent event, Vector vector) {
    // if this is the first event, create the queue and start the event task
    if (q == null) {
        q = new LinkedBlockingQueue<QueueElement>();
        if (executor != null) {
            executor.execute(this);
        } else {
            Thread qThread = new Thread(this, "JavaMail-EventQueue");
            qThread.setDaemon(true);  // not a user thread
            qThread.start();
        }
    }
    q.add(new QueueElement(event, vector));
}

修改MessageCountListener以设置上下文类加载器:

public void messagesAdded(MessageCountEvent e) {
    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
    //Your existing code....
}