Ошибка класса DCH с JavaMail
Я пытаюсь настроить простой тест регистрации с 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");
}
}
мою регистрацию.файл свойств содержит следующее:
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.почта.файл 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
что я пропустила?
спасибо, Стив!--9-->
7 ответов
добавьте их перед отправкой сообщения:
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, и он работает.
Я нашел решение здесь:
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 server и попробуйте более "реальный" тест из этого простого тестового случая.
в моем случае я смог решить эту проблему, добавив это до отправить():
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
Это было предложено в связанном блоге, поэтому, если вы хотите узнать больше деталей, прочитайте его. Спасибо Джерри ГУ за то, что он связал его здесь и оригинального блоггера.
URL:http://blog.hpxn.net/2009/12/02/tomcat-java-6-and-javamail-cant-load-dch/
вероятность высока, что если вы работаете на сервере KARAF(OSGI), вышеуказанные предложения будет трудно реализовать, поскольку у Karaf нет класса запуска или пути к классу загрузки.
Я нашел эту активацию.конфликт jar создал эту проблему .
{FUSEESB_HOME Or ServiceMIX_HOME}/etc/jre.properties was loading activation.jar .
после комментария все было гладко.
см. ссылке ниже.
хотя я хотел бы узнать больше о деталях, почему это проблема, и что этот параметр-Xbootclasspath делает для исправления проблемы.
это связано с деревом classloader. Напомним, что дочерним загрузчикам классов разрешено искать классы в Родительском загрузчике классов, но не наоборот. В вашем примере программы дерево classloader выглядит следующим образом:
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 classloader вынужден загрузки загрузчиком что не может найти com.sun.mail.handlers.text_plain
класс, потому что он находится в дочернем загрузчике классов. Из-за этого, модификации MailcapCommandMap
для включения имен классов mailcap не исправит проблему. Когда вы используете -Xbootclasspath
опция вы размещаете все соответствующие классы в загрузчике классов загрузки, который виден LogManager$Cleaner
. Однако не изменяйте свою систему для использования -Xbootclasspath
исправить это вопрос.
glassfish-X.X/glassfish/modules/javax.mail.jar
С более новой версией JavaMail.
неполное исправить применяется к JavaMail 1.4.7, чтобы установить загрузчик класса контекста в загрузчик класса, который загрузил MailHandler
во время закрытия. Этот предполагается, что загрузчик классов, который загрузил MailHandler
должны быть в состоянии найти код активации.
если вы не можете обновить до более новой версии JavaMail, то вы должны применить один из следующих обходных путей:
- очистите или закройте MailHandler перед запуском очистителя.
- очистите все обработчики перед запуском очистителя (т. е. веб-приложение не развертывается). Вы должны синхронизировать на LogManager и собрать все обработчики от каждого регистратора. Промывать все обработчики вне синхронизированного блока.
- расширьте MailHandler и переопределите close, чтобы установить и восстановить загрузчик классов контекста, если загрузчик классов контекста равен null.
- установите новый LogManager и переопределите
reset
для установки и восстановления загрузчика классов контекста, если загрузчик классов контекста равен null. - установите форматер темы, чтобы установить загрузчик классов контекста, если работает очиститель.
- установите уровень нажима на
ALL
или установите емкость в 1, чтобы отправить электронное письмо для каждой записи журнала и получить спам. - запустите версию Java с исправлением с помощью RFE JDK-8025251.
основная проблема в том, что LogManager$Cleaner
заставляет загрузчик классов контекста равняться null перед вызовом close
на каждые Handler
зарегистрированы с LogManager
. Лучшим выбором для LogManager было бы установить context classloader в загрузчик класса обработчика перед вызовом close, тогда в конце концов обработчики закрыты установите загрузчик класса контекста в значение null. Это все еще можно было обмануть обработчиками гнезд, но, по крайней мере, это исправило бы общий случай. Это было подано как RFE JDK-8025251 "logmanager cleaner должен использовать обработчик classloader во время закрытия".
Я столкнулся с этой проблемой сегодня, и это было связано с загрузчиком класса потока.
Если вы делаете sysout на: com.солнце.почта.дрессировщики.multipart_mixed.класс.getClassLoader()
Это может быть не то же самое, что загрузчик классов текущего потока: Нитка.currentThread().getContextClassLoader()
Я смог прийти к этому выводу, добавив следующий arg: -Djavax.активация.debug=true
после добавления этого arg я увидел, что он не смог чтобы загрузить обработчик содержимого данных (DCH) для multipart_mixed.класс.
Как вы решаете свои проблемы с загрузчиком классов, зависит от вас,но это должно заставить вас начать.
для всех, имеющих это сообщение об ошибке выше, оказалось, что в моем случае данные аутентификации были пустыми, это было связано с тем, что я отключил аутентификацию почтового сервера, мне больше не нужны имя пользователя и пароль, но пустые значения были каким-то образом проанализированы и создали отсутствующую ошибку аутентификации, которая не была поймана хорошо в Mail 1.4.0, обновление до Почты 1.4.7 и удаление двух параметров-записей ниже проблема решена.
<appender name="ALARM_MAIL" class="my.utils.SMTPAppender">
<!-- remove this line: <param name="SMTPUsername" value=""/> -->
<!-- remove this line: <param name="SMTPPassword" value=""/> -->
...