Javamail ClassCastException when sending multipart messages

1.9k views Asked by At

I am getting the following exception when attempting to send a multipart message:

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)

Code for the MailSender.send method:

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

Usually it works and sends emails as expected for a little while after bringing up the server. Calling an unrelated webservice using Jax-WS seems to precipitate the problem.

My understanding is that this exception is typical of classloader issues, though I don't have any libraries in my project containing the packages shown in the exception.

Is it possible that another classloader is loading one of these classes upon startup or at runtime? I see that JBoss has a javax.activation.api module, but too many other modules depend on it to exclude it using jboss-deployment-structure.xml.

I am using JDK 1.7, JBoss 7.0.2, Java Mail 1.4.4.

1

There are 1 answers

1
Bill Shannon On BEST ANSWER

There was a bug in the interaction between JavaMail and JAX-WS. The latest versions of the JDK include a fix for this bug. Upgrade to JDK 1.8, or the latest version of JDK 1.7.

A workaround may be to do this after JAX-WS is initialized:

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

That may cause JAX-WS to fail if it needs to handle a multipart message.