Search code examples
javawso2jakarta-mailwso2-enterprise-integratorwso2-micro-integrator

Java Email is sent with no content and not attachment when sending email from WSO2


I am trying to send email from WSO2 class mediator, when sending the email with no attachment it works fine but when sending with attachment I get the following exception:

javax.mail.MessagingException: IOException while sending message;
  nested exception is:
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;

I am using micro-integrator 4.1.0

The java code to send the email with attachment is as follows:

    emailHostSMTPs = getConfig("email.host.smtps");
    emailHostSMTP = getConfig("email.host.smtp");
    emailProtocol = getConfig("email.protocol");
    senderEmail = getConfig("email.sender");
    senderPassword = Encryptor.decrypt(getConfig("email.password"));
    senderUser = getConfig("email.sender.user");
    emailPort = getConfig("email.port");
    

    MimeMultipart multipart = new MimeMultipart();
    Authenticator authenticator = new SMTPAuthenticator();
    MailSSLSocketFactory sslSocketFactory = new MailSSLSocketFactory();
    MimeBodyPart bodyPart = new MimeBodyPart();

    String html = "";

    Properties props = System.getProperties();

    props.put("mail.transport.protocol", emailProtocol);
    props.put("mail.smtp.host", emailHostSMTP);
    props.put("mail." + emailProtocol + ".auth", "true");
    props.put("mail.smtp.port", emailPort);

    sslSocketFactory.setTrustAllHosts(true);
    props.put("mail.smtp.ssl.socketFactory", sslSocketFactory);

    Session session = Session.getInstance(props, authenticator);

    html = "<html><body dir='rtl' style='font-size:12pt;color:#000000;background-color:#FFFFFF;font-family:Calibri,Arial,Helvetica,sans-serif;'> "
            + emailBody + " </body></html>";
    bodyPart.setContent(html, "text/html; charset=UTF-8");
    multipart.addBodyPart(bodyPart);

    MimeMessage message = new MimeMessage(session);

    message.setFrom(new InternetAddress(senderEmail, fromDisplayName));
    message.setReplyTo(new Address[] { new InternetAddress(fromEmail) });

    if (toList != null && toList.size() > 0) {
        for (String to : toList) {
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
        }
    } else {
        throw new Exception("List of users to send email to is empty");
    }

    if (ccList != null && ccList.size() > 0) {
        for (String cc : ccList) {
            message.addRecipient(Message.RecipientType.CC, new InternetAddress(cc));
        }
    }

    if (bccList != null && bccList.size() > 0) {
        for (String bcc : bccList) {
            message.addRecipient(Message.RecipientType.BCC, new InternetAddress(bcc));
        }
    }

    

    
    MimeBodyPart mimeBodyPart = new PreencodedMimeBodyPart("base64");
    mimeBodyPart.setContent(fileDataStrBase64, "application/*");
    mimeBodyPart.setFileName(MimeUtility.encodeText(fileName, "utf-8", "B"));
    multipart.addBodyPart(mimeBodyPart);

    
    message.setSubject(subject, "UTF-8");
    message.setContent(multipart);
    message.setSentDate(new Date());

    Transport transport = session.getTransport(emailProtocol);
    transport.connect(senderEmail, senderPassword);
    transport.sendMessage(message, message.getAllRecipients());

My class mediator is deployed as jar file inside MI_HOME/lib

jars used:

  • javax.mail-1.6.2.jar
  • activation-1.1.1.jar

JDK Version : 11.0.8

EDIT:

After adding the following code (from another post) the email is sent but I get no email content and no attachment just subject !

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");
mc.addMailcap("multipart/report;;  x-java-content-handler=com.sun.mail.dsn.multipart_report");
mc.addMailcap("message/delivery-status;; x-java-content-handler=com.sun.mail.dsn.message_deliverystatus");
mc.addMailcap("message/disposition-notification;; x-java-content-handler=com.sun.mail.dsn.message_dispositionnotification");
mc.addMailcap("text/rfc822-headers;;   x-java-content-handler=com.sun.mail.dsn.text_rfc822headers");

Below is the mail debug:

DEBUG: failed to load any providers, using defaults
DEBUG: Tables of loaded providers from javamail.providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle,1.6.2], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle,1.6.2], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle,1.6.2], com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle,1.6.2], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle,1.6.2], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle,1.6.2]}
DEBUG: Providers Listed By Protocol: {imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle,1.6.2], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle,1.6.2], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle,1.6.2], imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle,1.6.2], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle,1.6.2], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle,1.6.2]}
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle,1.6.2]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: protocolConnect returning false, host=mail.mydomain.com, user=myemail, password=<null>
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "mail.mydomain.com", port 587, isSSL false
220 MyMailServer Microsoft ESMTP MAIL Service ready at Sun, 28 May 2023 14:33:31 +0300
DEBUG SMTP: connected to host "mail.mydomain.com", port: 587
EHLO host.docker.internal
250-MyMailServer Hello [10.x.x.x]
250-SIZE 41943040
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-AUTH GSSAPI NTLM
250-8BITMIME
250-BINARYMIME
250 CHUNKING
DEBUG SMTP: Found extension "SIZE", arg "41943040"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "AUTH", arg "GSSAPI NTLM"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
STARTTLS
220 2.0.0 SMTP server ready
EHLO host.docker.internal
250-MyMailServer Hello [10.x.x.x]
250-SIZE 41943040
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-AUTH GSSAPI NTLM LOGIN
250-8BITMIME
250-BINARYMIME
250 CHUNKING
DEBUG SMTP: Found extension "SIZE", arg "41943040"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "AUTH", arg "GSSAPI NTLM LOGIN"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: protocolConnect login, host=mail.mydomain.com, user=mysenderemail, password=<non-null>
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2 
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
DEBUG SMTP: use8bit false
MAIL FROM:<[email protected]>
250 2.1.0 Sender OK
RCPT TO:<[email protected]>
250 2.1.5 Recipient OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   [email protected]
DATA
354 Start mail input; end with <CRLF>.<CRLF>
Date: Sun, 28 May 2023 14:33:31 +0300 (AST)
From: [email protected]
To: [email protected]
Message-ID: <[email protected]>
Subject: test attachment localhost 2.24
MIME-Version: 1.0
Content-Type: multipart/mixed; 
    boundary="----=_Part_6_2147206188.1685273611445"

.
250 2.6.0 <[email protected]> [InternalId=91379724192809, Hostname=MyMailServer2] 1339 bytes in 0.293, 4.462 KB/sec Queued mail for delivery
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 2.0.0 Service closing transmission channel

Solution

  • Here is a working Class Mediator to send Emails with a body and an attachment. I tested this on JDK 8. This should work with JavaX dependencies on JDK 11 as well.

    package org.ycr;
    
    import org.apache.synapse.MessageContext;
    import org.apache.synapse.mediators.AbstractMediator;
    
    import java.util.*;
    import javax.mail.*;
    import javax.mail.internet.*;
    
    public class MailSend extends AbstractMediator { 
    
        public boolean mediate(MessageContext context) {
            log.info("Starting Main sending");
            // Storing the current class loader of the thread, so we can restore it later. 
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            try {
                String host = "smtp.gmail.com";
                int port = 587;
                final String username = "[email protected]";
                final String password = "xxxx";
                final String atachmentFilePath = "/home/xx/xx/xxxx/log.txt";
                final String toAddress = "[email protected]";
    
                // Setting a new class loader so Javax is able to find the Mime dependencies.   
                Thread.currentThread().setContextClassLoader(javax.mail.Message.class.getClassLoader());
    
                Properties props = new Properties();
                props.put("mail.smtp.host", host);
                props.put("mail.smtp.port", port);
                props.put("mail.smtp.auth", "true");
                props.put("mail.smtp.starttls.enable", "true");
    
                Session session = Session.getInstance(props, new Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                    }
                });
    
                // Create a new message
                MimeMessage message = new MimeMessage(session);
                message.setFrom(new InternetAddress(username));
                message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toAddress));
                message.setSubject("Email Sample");
    
                Multipart multipart = new MimeMultipart();
    
                // Create the HTML body part
                MimeBodyPart htmlPart = new MimeBodyPart();
                String htmlContent = "<h1>Sample</h1>"
                        + "<p>This is an Sample Mail</p>";
                htmlPart.setContent(htmlContent, "text/html");
    
                // Add the HTML body part to the multipart message
                multipart.addBodyPart(htmlPart);
    
                // File attaching
                MimeBodyPart attachmentPart = new MimeBodyPart();
                attachmentPart.attachFile(atachmentFilePath);
    
                // Add the attachment part to the multipart message
                multipart.addBodyPart(attachmentPart);
    
                // Set the content of the message to the multipart message
                message.setContent(multipart);
                Transport.send(message);
    
                log.info("Done sending Email");
                return true;
    
            }catch (Exception e){
                handleException("Error occurred.", context);
            }finally {
                Thread.currentThread().setContextClassLoader(classLoader);
            }
            return true;
        }
    }
    
    

    enter image description here

    On a side note, I'm not sure why you are trying this with a class mediator, but you can do the same without the class mediator as well. Either by using the Email COnnector or by using Email Transport.