Ошибка класса DCH с JavaMail - PullRequest
       77

Ошибка класса DCH с JavaMail

11 голосов
/ 23 сентября 2011

Я пытаюсь настроить простой тест регистрации с JavaMail в Java EE 6, используя файлы jar, поставляемые с Glassfish 3.1.Кажется, есть множество вопросов по этому вопросу, но я не нашел ответов, которые помогли бы еще.Мой тестовый код выглядит следующим образом:

import java.util.logging.Logger;

public class MyClass {
  private static final Logger LOGGER = Logger.getLogger("MyClass");

  public static void main(String[] args) {
    LOGGER.severe("This is a test");
  }
}

Мой файл logging.properties содержит это:

com.sun.mail.util.logging.MailHandler.mail.smtp.host={my mail hub FQDN}
com.sun.mail.util.logging.MailHandler.mail.smtp.port=25
com.sun.mail.util.logging.MailHandler.mail.to={me}
com.sun.mail.util.logging.MailHandler.mail.from={support address}
com.sun.mail.util.logging.MailHandler.level=WARNING
com.sun.mail.util.logging.MailHandler.verify=local
com.sun.mail.util.logging.MailHandler.subject=Application Error
com.sun.mail.util.logging.MailHandler.formatter=java.util.logging.SimpleFormatter

Я создаю класс, используя:

javac -cp $AS_INSTALL/glassfish/modules/javax.mail.jar:$AS_INSTALL/install/lib/external/jaxb/activation.jar:. MyClass.java

Затем язапустите программу, используя:

java -cp $AS_INSTALL/glassfish/modules/javax.mail.jar:$AS_INSTALL/install/lib/external/jaxb/activation.jar:. -Djava.util.logging.config.file=logging.properties MyClass

Это приводит к следующей ошибке:

Sep 22, 2011 4:19:25 PM MyClass main
SEVERE: This is a test
java.util.logging.ErrorManager: 3: SEVERE: no object DCH for MIME type multipart/mixed;
        boundary="----=_Part_1_26867996.1316722766145"
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;
        boundary="----=_Part_1_26867996.1316722766145"
        at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:877)
        at javax.activation.DataHandler.writeTo(DataHandler.java:302)
        at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1476)
        at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1772)
        at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1748)
        at com.sun.mail.util.logging.MailHandler.toRawString(MailHandler.java:2196)
        at com.sun.mail.util.logging.MailHandler.send(MailHandler.java:1597)
        at com.sun.mail.util.logging.MailHandler.close(MailHandler.java:552)
        at java.util.logging.LogManager.resetLogger(LogManager.java:693)
        at java.util.logging.LogManager.reset(LogManager.java:676)
        at java.util.logging.LogManager$Cleaner.run(LogManager.java:221)

javax.mail.MessagingException: IOException while sending message;
  nested exception is:
        javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;
        boundary="----=_Part_1_26867996.1316722766145"
        at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1141)
        at javax.mail.Transport.send0(Transport.java:195)
        at javax.mail.Transport.send(Transport.java:124)
        at com.sun.mail.util.logging.MailHandler.send(MailHandler.java:1594)
        at com.sun.mail.util.logging.MailHandler.close(MailHandler.java:552)
        at java.util.logging.LogManager.resetLogger(LogManager.java:693)
        at java.util.logging.LogManager.reset(LogManager.java:676)
        at java.util.logging.LogManager$Cleaner.run(LogManager.java:221)
Caused by: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;
        boundary="----=_Part_1_26867996.1316722766145"
        at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:877)
        at javax.activation.DataHandler.writeTo(DataHandler.java:302)
        at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1476)
        at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1772)
        at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1099)
        ... 7 more

Я убедился, что мой файл javax.mail.jar содержит многоэлементный обработчик:

unzip -l $AS_INSTALL/glassfish/modules/javax.mail.jar | grep multipart
     2617  01-14-2011 15:37   com/sun/mail/handlers/multipart_mixed.class

Я даже запускал программу с включенной отладкой активации.Это показывает мне следующие связанные части:

parse: multipart/*;;            x-java-content-handler=com.sun.mail.handlers.multipart_mixed; x-java-fallback-entry=true
  Type: multipart/*
    Command: content-handler, Class: com.sun.mail.handlers.multipart_mixed

MailcapCommandMap: createDataContentHandler for multipart/mixed
  search DB #1
  search DB #2
  search fallback DB #1
    got content-handler
      class com.sun.mail.handlers.multipart_mixed
Can't load DCH com.sun.mail.handlers.multipart_mixed; Exception: java.lang.ClassNotFoundException: com/sun/mail/handlers/multipart_mixed

Я даже получаю дубликат вышеупомянутого для типа text / plain.

MailcapCommandMap: createDataContentHandler for text/plain
  search DB #1
    got content-handler
      class com.sun.mail.handlers.text_plain
Can't load DCH com.sun.mail.handlers.text_plain; Exception: java.lang.ClassNotFoundException: com/sun/mail/handlers/text_plain

Что мне здесь не хватает?

Спасибо, Стив

Ответы [ 7 ]

10 голосов
/ 08 марта 2012

Добавьте их перед отправкой сообщения:

MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
        mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
        mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
        mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
        mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
        mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
        CommandMap.setDefaultCommandMap(mc);

У меня проблема в приложении Android, и она работает.

5 голосов
/ 23 сентября 2011

Я нашел решение здесь:

http://blog.hpxn.net/2009/12/02/tomcat-java-6-and-javamail-cant-load-dch/

Хотя мне бы хотелось узнать больше о причинах этой проблемы и о том, что делает опция -Xbootclasspath для ее устранения. Если я проведу свой класс так:

java -Djava.util.logging.config.file=logging.properties -Xbootclasspath/p:/app/glassfish-3.1/glassfish/modules/javax.mail.jar MyClass

Он находит необходимые классы, и я получаю свою электронную почту. Теперь мне просто нужно выяснить, как перевести эту конфигурацию на мой сервер Glassfish, и попробовать более «реальный» тест из этого простого теста.

4 голосов
/ 07 августа 2012

В моем случае я смог решить эту проблему, добавив это перед send () :

Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );

Это было предложено в связанном блоге, поэтому, если вы хотите узнать больше подробностей, прочитайте его. Спасибо Джерри Гу за ссылку здесь и оригинальный блоггер.

URL: http://blog.hpxn.net/2009/12/02/tomcat-java-6-and-javamail-cant-load-dch/

3 голосов
/ 28 мая 2013

Хотя мне бы хотелось узнать больше о причинах этой проблемы и о том, что делает опция -Xbootclasspath для ее устранения.

Это связано с загрузчиком классовдерево.Напомним, что дочерним загрузчикам классов разрешено искать классы в родительском загрузчике классов, но не наоборот.В вашем примере программы дерево загрузчика классов выглядит следующим образом:

Running under JDK6, JDK7, and JDK8
+---Boot ClassLoader--+
| java.util.logging.* |
| javax.activation .* |
+---------------------+
          ^
          |
+-----System ClassLoader------+
| javax.mail.*                |
| com.sun.mail.handlers.*     |
| com.sun.mail.util.logging.* |
+-----------------------------+

Когда запускается ловушка отключения LogManager$Cleaner (JDK6 +), загрузчик контекста context вынужден загрузчик загрузчика классов , который не может найти класс com.sun.mail.handlers.text_plain, потому что он находится в дочернем загрузчике классов.Из-за этого изменение MailcapCommandMap для включения имен классов mailcap не решит проблему.Когда вы используете опцию -Xbootclasspath, вы помещаете все соответствующие классы в загрузчик классов загрузки, который виден для LogManager$Cleaner.Однако не изменяйте свою систему, чтобы использовать -Xbootclasspath для решения этой проблемы.

Вместо этого обновите до JavaMail 1.5.3 или более поздней версии, в котором содержится исправление для Ошибка K6552|GH133 - Используйте эргономику загрузчика классов в MailHandler .Если вы хотите обновить JavaMail-модуль GlassFish, вы можете заменить glassfish-X.X/glassfish/modules/javax.mail.jar более новой версией JavaMail.

Неполное fix , примененное к JavaMail 1.4.7, было для установки контекстазагрузчик класса в загрузчик класса, который загрузил MailHandler во время закрытия.Предполагается, что загрузчик классов, который загрузил MailHandler, сможет найти код активации.

Если вы не можете перейти на более новую версию JavaMail, вам необходимо применить один из следующих обходных путей:

  1. Промойте или закройте MailHandler перед запуском очистителя.
  2. Сбросьте все обработчики перед запуском очистителя (IE веб-приложение отменено).Вы должны синхронизироваться в LogManager и собрать все обработчики из каждого регистратора.Очистите все обработчики за пределами синхронизированного блока.
  3. Расширьте MailHandler и переопределите значение close для установки и восстановления загрузчика класса контекста, если загрузчик класса контекста равен нулю.
  4. Установите новый LogManager и переопределите reset, чтобы установить и восстановить загрузчик класса контекста, если загрузчик класса контекста равен нулю.
  5. Установите предметный форматер, чтобы установить загрузчик класса контекста, если уборщик работает.
  6. Установите уровень push-уведомлений на ALL или установите емкость 1, чтобы электронное письмо отправлялось для каждой записи журнала и получало спам.
  7. Запуск на версии Java с исправлением с помощью RFE JDK-8025251.

Основная проблема заключается в том, что LogManager$Cleaner заставляет загрузчик классов контекста обнуляться, прежде чем он вызовет close для каждого Handler, зарегистрированного в LogManager.Лучшим выбором для LogManager было бы установить загрузчик классов контекста на загрузчик классов обработчиков перед вызовом close, а затем после закрытия всех обработчиков установить загрузчик класса контекста в null.Это все еще может быть одурачено вложенными обработчиками, но по крайней мере это исправит общий случай.Это было подано как RFE JDK-8025251 «Очиститель LogManager должен использовать загрузчик классов обработчика во время закрытия».

3 голосов
/ 05 сентября 2012

Вероятность высока, что если вы работаете на сервере KARAF (OSGI), приведенные выше предложения будет сложно реализовать, поскольку у Karaf нет класса запуска или пути загрузки.

Я обнаружил, что Activation.jar конфликтсоздал эту проблему.

{FUSEESB_HOME Or ServiceMIX_HOME}/etc/jre.properties was loading activation.jar .

После того, как прокомментировал все было гладко.

Пожалуйста, обратитесь ссылку ниже .

1 голос
/ 26 сентября 2013

Я столкнулся с этой проблемой сегодня, и это было связано с загрузчиком классов потока.

, если вы выполните sysout для: com.sun.mail.handlers.multipart_mixed.class.getClassLoader ()

он может не совпадать с загрузчиком классов текущего потока: Thread.currentThread (). GetContextClassLoader ()

Я смог прийти к такому выводу, добавив следующий аргумент: -Djavax.activation.debug = true

После добавления этого аргумента я увидел, что не удалось загрузить обработчик содержимого данных (DCH) для multipart_mixed.class.

Способ решения проблем загрузчика классов зависит отты, но это должно начать тебя.

0 голосов
/ 09 августа 2013

Для всех, имеющих это сообщение об ошибке выше, оказалось, что в моем случае данные аутентификации были пустыми, это было связано с тем, что я отключил аутентификацию почтового сервера, мне больше не требовалось имя пользователя и пароль, но пустые значения былиКак-то проанализировал и создал отсутствующую ошибку аутентификации, которая не была хорошо поймана в Почте 1.4.0, обновление до Почты 1.4.7 и удаление двух записей параметров ниже решило проблему.1005 *

<appender name="ALARM_MAIL" class="my.utils.SMTPAppender">
  <!-- remove this line: <param name="SMTPUsername" value=""/> -->
  <!-- remove this line: <param name="SMTPPassword" value=""/> -->
  ...
...