发送多部分消息时 Javamail ClassCastException

标签 java jboss jax-ws jakarta-mail classloader

尝试发送多部分消息时出现以下异常:

java.lang.ClassCastException: com.sun.xml.internal.ws.encoding.StringDataContentHandler cannot be cast to javax.activation.DataContentHandler
at javax.activation.MailcapCommandMap.getDataContentHandler(MailcapCommandMap.java:609)
at javax.activation.MailcapCommandMap.createDataContentHandler(MailcapCommandMap.java:563)
at javax.activation.DataHandler.getDataContentHandler(DataHandler.java:625)
at javax.activation.DataHandler.writeTo(DataHandler.java:329)
at javax.mail.internet.MimeUtility.getEncoding(MimeUtility.java:268)
at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1366)
at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1021)
at javax.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:419)
at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1345)
at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1021)
at javax.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:419)
at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1345)
at javax.mail.internet.MimeMessage.updateHeaders(MimeMessage.java:2106)
at javax.mail.internet.MimeMessage.saveChanges(MimeMessage.java:2074)
at com.ex.notificationservice.email.MailSender.send(MailSender.java:324)

MailSender.send 方法的代码:

MimeMessage message = new MimeMessage(session);

message.setSubject(subject);

message.setFrom(new InternetAddress(fromAddr));

if (toAddrs != null) {
    for (String toAddr : toAddrs) {
        if (isEmpty(toAddr) == false) {
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddr));
        }
    }
} else {
    throw new MessagingException("MailSender: Destination address(es) not specified.");
}

Multipart multipart = new MimeMultipart("mixed");

MimeBodyPart mbp1 = new MimeBodyPart();

Multipart alternativeMultipart = new MimeMultipart("alternative");

MimeBodyPart textBodyPart = null;
MimeBodyPart htmlBodyPart = null;
MimeBodyPart xmlBodyPart = null;

if (isEmpty(textContent) == false) {
    textBodyPart = new MimeBodyPart();
    textBodyPart.setText(textContent);

    alternativeMultipart.addBodyPart(textBodyPart);
}

if (isEmpty(htmlContent) == false) {
    htmlBodyPart = new MimeBodyPart();
    htmlBodyPart.setContent(htmlContent, "text/html; charset=utf-8");

    alternativeMultipart.addBodyPart(htmlBodyPart);
}

if (isEmpty(xmlContent) == false) {
    xmlBodyPart = new MimeBodyPart();
    xmlBodyPart.setContent(xmlContent, "text/xml; charset=utf-8");

    alternativeMultipart.addBodyPart(xmlBodyPart);
}

mbp1.setContent(alternativeMultipart);

multipart.addBodyPart(mbp1);

if (files != null) {
    for (File file : files) {
        MimeBodyPart mimeBodyPart = new MimeBodyPart();

        mimeBodyPart.attachFile(file);

        multipart.addBodyPart(mimeBodyPart);
    }
}

message.setContent(multipart);

message.setSentDate(new Date());

//Exception occurs here
message.saveChanges();

Transport.send(message);

通常,它会在服务器启动后一段时间内正常工作并按预期发送电子邮件。使用 Jax-WS 调用不相关的 Web 服务似乎会加剧该问题。

我的理解是,此异常是典型的类加载器问题,尽管我的项目中没有任何包含异常中显示的包的库。

是否有可能另一个类加载器在启动时或运行时加载这些类之一?我看到 JBoss 有一个 javax.activation.api 模块,但太多其他模块依赖于它,无法使用 jboss-deployment-struction.xml 排除它。

我使用的是 JDK 1.7、JBoss 7.0.2、Java Mail 1.4.4。

最佳答案

有一个bug JavaMail 和 JAX-WS 之间的交互。最新版本的 JDK 修复了此错误。升级到 JDK 1.8,或最新版本的 JDK 1.7。

解决方法可能是在 JAX-WS 初始化后执行此操作:

    MailcapCommandMap mailMap = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
    mailMap.addMailcap("multipart/mixed;;x-java-content-handler=com.sun.mail.handlers.multipart_mixed");

如果 JAX-WS 需要处理多部分消息,这可能会导致 JAX-WS 失败。

关于发送多部分消息时 Javamail ClassCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30792143/

相关文章:

java - WebParam 不允许使用 XmlElement 注释

java - 在不调用 Web 服务的情况下获取 soap 消息

java - 快速处理数组以进行波形渲染的方法

Java - 如果没有 flush() 和 close(),ByteArrayOutputStream 是否安全?

java - 没有这样的元素异常扫描器

java - 如何使用 JDBC 在 PostgreSQL 中传递一组复合类型 (UDT)

java - "A WebService annotation is not present"异常

java - 验证电子邮件(不发送确认)

java - 在 Spring Boot 2 中使用实体管理器时,没有类型 'javax.persistence.EntityManager' 的合格 bean

java - 在 JBoss v7.1 中使用 Seam v2.2.2.Final 和 JSF v1.2 – JSF 标签不会呈现 – 为什么?