others-how to solve `UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed` when trying to send email in android app?

1. Problem

Sometimes, when we send email in android app, we got this error:

E/app: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed; 
        boundary="----=_Part_0_154698700.1654941335296"
        at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:905)
        at javax.activation.DataHandler.writeTo(DataHandler.java:330)
        at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1485)
        at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1773)
        at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1749)
        at com.bswen.app.ui.misc.GoogleMailActivity$MakeRequestTask.createMessageWithEmail(GoogleMailActivity.java:258)
        at com.bswen.app.ui.misc.GoogleMailActivity$MakeRequestTask.sendMessage(GoogleMailActivity.java:215)
        at com.bswen.app.ui.misc.GoogleMailActivity$MakeRequestTask.getDataFromApi(GoogleMailActivity.java:203)
        at com.bswen.app.ui.misc.GoogleMailActivity$MakeRequestTask.doInBackground(GoogleMailActivity.java:183)
        at com.bswen.app.ui.misc.GoogleMailActivity$MakeRequestTask.doInBackground(GoogleMailActivity.java:164)
        at android.os.AsyncTask$2.call(AsyncTask.java:333)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)

The core error message is :

E/app: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed; 

The code that cause the above error is as follows:

private MimeMessage createEmail(String to,
                                String from,
                                String subject,
                                String bodyText) throws MessagingException {
    Properties props = new Properties();
    Session session = Session.getDefaultInstance(props, null);

    MimeMessage email = new MimeMessage(session);
    InternetAddress tAddress = new InternetAddress(to);
    InternetAddress fAddress = new InternetAddress(from);

    email.setFrom(fAddress);
    email.addRecipient(javax.mail.Message.RecipientType.TO, tAddress);
    email.setSubject(subject);

    // Create Multipart object and add MimeBodyPart objects to this object
    Multipart multipart = new MimeMultipart();

    // Changed for adding attachment and text
    // email.setText(bodyText);

    BodyPart textBody = new MimeBodyPart();
    textBody.setText(bodyText);
    multipart.addBodyPart(textBody);

    //Set the multipart object to the message object
    email.setContent(multipart);
    return email;
}



2. Solution

2.1 What is javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed?

JavaMail depends on some configuration files to map MIME types to Java classes (e.g., multipart/mixed to javax.mail.internet.MimeMultipart). These configuration files are loaded using the ClassLoader for the application. If the ClassLoader doesn’t function properly, these configuration files won’t be found.

2.2 The working solution for me

Just add the following code snippet:

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

MailcapCommandMap(InputStream is) Constructor that allows the caller to specify an InputStream containing a mailcap file. MailcapCommandMap(String fileName) Constructor that allows the caller to specify the path of a mailcap file.

But what is a mailcap? According to this site, a mailcap is:

The “mailcap” format is formally defined by RFC 1524. Basically, a mailcap file is a configuration file that maps MIME types to external viewers. (MIME is defined by RFC 1521.) An example would be mapping MIME type image/gif to the image viewer “xv”.

So the below mailmap:

mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); 

indicates that the text/xml MIME type would be handled by java class com.sun.mail.handlers.text_xml.

So the final working code for me is:

// Method to create email Params
private MimeMessage createEmail(String to,
                                String from,
                                String subject,
                                String bodyText) throws MessagingException {
    Properties props = new Properties();
    Session session = Session.getDefaultInstance(props, null);

    MimeMessage email = new MimeMessage(session);
    InternetAddress tAddress = new InternetAddress(to);
    InternetAddress fAddress = new InternetAddress(from);

    email.setFrom(fAddress);
    email.addRecipient(javax.mail.Message.RecipientType.TO, tAddress);
    email.setSubject(subject);

    // Create Multipart object and add MimeBodyPart objects to this object
    Multipart multipart = new MimeMultipart();

    // Changed for adding attachment and text
    // email.setText(bodyText);

    BodyPart textBody = new MimeBodyPart();
    textBody.setText(bodyText);
    multipart.addBodyPart(textBody);

    //Set the multipart object to the message object
    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");

    email.setContent(multipart);
    return email;
}

Now it’s working!



3. Summary

In this post, I demonstrated how to solve UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed when trying to send email in android app. The key point is to add some mailcaps to our app. That’s it, thanks for your reading.