2016-03-29 25 views
2

Wir haben einen Listener mit Javamail API erstellt, um die neu hinzugefügte Nachricht im E-Mail-Posteingang zu lesen. Sobald der Listener die neue Nachricht empfangen hat, versuchen wir, alle Headerinformationen sowie den Inhaltsteil abzurufen. Um den Inhalt zu parsen, haben wir eine richtige Analyselogik geschrieben und es funktioniert für alle Arten von Inhalten (Text, HTML, Multipart usw.). Hier ist der Parsing-Code.Konnte nicht geladen werden com.sun.mail.handlers.multipart_mixed

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; 
    } 

Die obigen Zuhörer und Parsing, wir sind in einer Web-Anwendung ausgeführt wird, die in einem Tomcat-Containern (Version - Apache Tomcat 8.0.35) eingesetzt wird.

Nach einiger Zeit, wenn wir für eine IMAP-Verbindung eine Sitzungszeitbegrenzung erhalten, starten wir den Listener programmatisch neu. Jetzt ist der Listener in der Lage, die neu hinzugefügte Nachricht im Posteingang zu lesen, aber beim Parsen der Nachrichteninhalte tritt die folgende Ausnahme nicht auf. Wir haben mehrere Optionen ausprobiert, um das Problem zu beheben, haben jedoch keinen Erfolg erzielt. Unten ist die Ausnahme Stack-Spur

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) 

Wir brauchen eine konkrete Lösung, um dies zu beheben. Wir werden mit den folgenden Umwelt und api Versionen

JDK- 1.8.0_65, Tomcat - 8.0.35, Java Mail - 1.5.5, Spring - 4

Antwort

0

Es ist schwer zu verstehen, warum dies würde anfangen fehlgeschlagen, wenn nichts geändert. Sie müssen wirklich herausfinden, was sich geändert hat. Verwenden Sie eine neuere Version des JDK oder Tomcat?

Was genau meinen Sie mit "Neustart des Hörers durch Programmatic"? Starten Sie den Tomcat-Server neu?

Dieses Problem tritt normalerweise auf, weil das JavaBeans Activation Framework (JAF, jetzt ein Teil des JDK) die Konfigurationsdatei nicht finden kann, die beschreibt, welche Java-Klasse für welchen MIME-Typ verwendet werden soll. Diese Konfigurationsdatei ist Teil der JavaMail-JAR-Datei. Wenn Ihre Anwendung geändert wurde und diese Datei verloren gegangen ist, würde das erklären. Es kann auch aufgrund von Problemen mit dem ClassLoader passieren, wenn Sie ein ungewöhnliches Klassenladeschema verwenden.

0

Wenn Sie die Webapp neu laden, fängt der javax.mail.EventQueue den ersten Webapp Classloader ein. Wenn neue Threads erstellt werden, wird der Kontextklassenlader auf den Kontextklassenlader des übergeordneten Threads gesetzt.

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)); 
} 

Ihre MessageCountListener Ändern Sie den Kontext-Klassenlader zu setzen:

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