Sending email with attach in Jira via MailQueue fails with javax.activation.UnsupportedDataTypeException: no object DCH for MIME type

Alex May 12, 2015

Hi all,

I'm trying to send a mail with attach via MailQueue in my plugin but I get the following exception:

015-05-12 20:35:06,915 Sending mailitem To='test@testdomain.ru' Subject='asdfffff' From='jira-testcncuser@testdomain.ru' FromName='null' Cc='null' Bcc='null' ReplyTo='null' InReplyTo='null' MimeType='multipart/mixed' Encoding='UTF-8' Multipart='javax.mail.internet.MimeMultipart@3329db97' MessageId='null' ERROR admin 1235x5644x1 190d8dm 77.75.154.20 /secure/admin/MailQueueAdmin.jspa [atlassian.mail.queue.MailQueueImpl] Error occurred in sending e-mail: To='platonov@yamoney.ru' Subject='asdfffff' From='jira-testcncuser@yamoney.ru' FromName='null' Cc='null' Bcc='null' ReplyTo='null' InReplyTo='null' MimeType='multipart/mixed' Encoding='UTF-8' Multipart='javax.mail.internet.MimeMultipart@3329db97' MessageId='null'

[INFO] [talledLocalContainer] com.atlassian.mail.MailException: javax.mail.MessagingException: IOException while sending message;
[INFO] [talledLocalContainer]   nested exception is:
[INFO] [talledLocalContainer] 	javax.activation.UnsupportedDataTypeException: no object DCH for MIME type image/jpeg
[INFO] [talledLocalContainer] 	at com.atlassian.mail.server.impl.SMTPMailServerImpl.sendWithMessageId(SMTPMailServerImpl.java:213)
[INFO] [talledLocalContainer] 	at com.atlassian.mail.queue.SingleMailQueueItem.send(SingleMailQueueItem.java:44)
[INFO] [talledLocalContainer] 	at com.atlassian.mail.queue.MailQueueImpl.sendBuffer(MailQueueImpl.java:66)
[INFO] [talledLocalContainer] 	at com.atlassian.jira.mail.JiraMailQueue$1.apply(JiraMailQueue.java:57)
[INFO] [talledLocalContainer] 	at com.atlassian.jira.mail.JiraMailQueue$1.apply(JiraMailQueue.java:53)
[INFO] [talledLocalContainer] 	at com.atlassian.jira.util.velocity.DefaultVelocityRequestContextFactory.runWithStaticBaseUrl(DefaultVelocityRequestContextFactory.java:127)

...
[INFO] [talledLocalContainer] Caused by: javax.mail.MessagingException: IOException while sending message;
[INFO] [talledLocalContainer]   nested exception is:
[INFO] [talledLocalContainer] 	javax.activation.UnsupportedDataTypeException: no object DCH for MIME type image/jpeg
[INFO] [talledLocalContainer] 	at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1177)
[INFO] [talledLocalContainer] 	at com.atlassian.mail.server.impl.SMTPMailServerImpl.sendWithMessageId(SMTPMailServerImpl.java:175)
[INFO] [talledLocalContainer] 	... 196 more
[INFO] [talledLocalContainer] Caused by: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type image/jpeg
[INFO] [talledLocalContainer] 	at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:896)
[INFO] [talledLocalContainer] 	at javax.activation.DataHandler.writeTo(DataHandler.java:317)
[INFO] [talledLocalContainer] 	at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1485)
[INFO] [talledLocalContainer] 	at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:865)
[INFO] [talledLocalContainer] 	at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:462)
[INFO] [talledLocalContainer] 	at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:103)
[INFO] [talledLocalContainer] 	at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:889)
[INFO] [talledLocalContainer] 	at javax.activation.DataHandler.writeTo(DataHandler.java:317)
[INFO] [talledLocalContainer] 	at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1485)
[INFO] [talledLocalContainer] 	at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1773)
[INFO] [talledLocalContainer] 	at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1121)
[INFO] [talledLocalContainer] 	... 197 more

Component is event listener component with code: 

package ru.yamoney.jira.plugins.jatresss.logic.mail.outgoing;

import com.atlassian.event.api.EventListener;
import com.atlassian.event.api.EventPublisher;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.config.util.AttachmentPathManager;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.event.type.EventType;
import com.atlassian.jira.issue.attachment.Attachment;
import com.atlassian.jira.mail.Email;
import com.atlassian.jira.project.ProjectCategory;
import com.atlassian.jira.util.PathUtils;
import com.atlassian.mail.queue.MailQueue;
import com.atlassian.mail.queue.SingleMailQueueItem;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import ru.yamoney.jira.plugins.jatresss.conf.Settings;
import ru.yamoney.jira.plugins.jatresss.conf.mapping.issue.Ticket.Direction;
import ru.yamoney.jira.plugins.jatresss.conf.mapping.issue.Ticket.TicketType;
import ru.yamoney.jira.plugins.jatresss.localization.SystemMessages;
import ru.yamoney.jira.plugins.jatresss.logic.issue.servcie.conversion.IssueConverter;
import ru.yamoney.jira.plugins.jatresss.model.TicketIssue;

import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.ws.rs.core.MediaType;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;

/**
 * EventNotifier
 * <p>
 *     Sends a message on the offensive expected event
 * </p>
 *
 * @author Plat
 * @version 1.0 23.04.15
 */
public class EventNotifier implements InitializingBean, DisposableBean {

    private final EventPublisher eventPublisher;
    private final Settings settings;
    private final IssueConverter issueConverter;
    private final MailQueue jiraMailQue;
    private static Logger LOGGER = LoggerFactory.getLogger(EventNotifier.class);

    /**
     * Constructor
     *
     * @param eventPublisher    jira event publisher
     * @param settings          plugin settings
     * @param issueConverter    plugin issue converter
     * @param jiraMailQue       jira mail que
     */
    public EventNotifier(
            EventPublisher eventPublisher, Settings settings,
            IssueConverter issueConverter, MailQueue jiraMailQue) {
        this.eventPublisher = eventPublisher;
        this.settings = settings;
        this.issueConverter = issueConverter;
        this.jiraMailQue = jiraMailQue;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void destroy() throws Exception {
        eventPublisher.unregister(this);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        eventPublisher.register(this);
    }

    /**
     * Send email notification on special event
     *
     * @param issueEvent    jira event
     */
    @EventListener
    public void onIssueEvent(IssueEvent issueEvent) {
        if (!isObservableEvent(issueEvent)) {
            return;
        }

        final TicketIssue ticketIssue = issueConverter.convert(TicketIssue.class, issueEvent.getIssue());

        if (!isNotifyTicket(ticketIssue)) {
            return;
        }

        sendNotify(ticketIssue);
    }

    /**
     * Shows that event should be notified
     *
     * @param issueEvent jira event
     * @return true if event should be notified
     */
    private boolean isObservableEvent(IssueEvent issueEvent) {
        final ProjectCategory projectCategoryObject = issueEvent.getProject().getProjectCategoryObject();

        return issueEvent.getEventTypeId().equals(EventType.ISSUE_CREATED_ID)
                && projectCategoryObject != null
                && projectCategoryObject.getName().equals(settings.getObservableProjectsCategory());
    }

    /**
     * Shows that ticket should be notified
     *
     * @param ticketIssue ticket to check for notify
     * @return true if ticket should be notified
     */
    private boolean isNotifyTicket(TicketIssue ticketIssue) {
        return ticketIssue.getType().equals(TicketType.MAIL)
                && Direction.OUTGOING.equals(ticketIssue.getDirection());
    }

    /**
     * Send notify using jira mail que
     *
     * @param ticketIssue issue to notify
     */
    private void sendNotify(TicketIssue ticketIssue) {
        final Email emailToSend =
                new Email(StringUtils.defaultIfBlank(ticketIssue.getReplyTo(), ticketIssue.getTo()));
        emailToSend.setCc(ticketIssue.getCc());
        emailToSend.setFrom(ticketIssue.getFrom());
        emailToSend.setSubject(ticketIssue.getTitle());
        emailToSend.setMimeType("multipart/mixed");

        final Multipart mailMultipart = new MimeMultipart();
        final MimeBodyPart bodyPart = new MimeBodyPart();

        try {
            bodyPart.setContent(ticketIssue.getBody(), MediaType.TEXT_HTML);
            mailMultipart.addBodyPart(bodyPart);
        } catch (MessagingException e) {
            LOGGER.error(
                    MessageFormat.format(
                            SystemMessages.NOTIFY_SENDING_FAILED.getLocalizedMessage(), ticketIssue.getKey()), e);
            return;
        }

        try {
            addAttachmentsToMessage(mailMultipart, ticketIssue.getAttachments(), ticketIssue);
        } catch (MessagingException e) {
            LOGGER.error(
                    MessageFormat.format(
                            SystemMessages.NOTIFY_SENDING_FAILED.getLocalizedMessage(), ticketIssue.getKey()), e);
            return;
        }

        emailToSend.setMultipart(mailMultipart);
        final SingleMailQueueItem queueItem = new SingleMailQueueItem(emailToSend);
        jiraMailQue.addItem(queueItem);
    }

    private void addAttachmentsToMessage(
            Multipart mailMultipart, List<Attachment> issueAttachments, TicketIssue ticketIssue)
            throws MessagingException {
        if (issueAttachments == null || issueAttachments.isEmpty()) {
            return;
        }

        for (Attachment issueAttachment : issueAttachments) {
            final MimeBodyPart attachBody = new MimeBodyPart();
            final AttachmentPathManager attachmentPathManager = ComponentAccessor.getAttachmentPathManager();

            final String attachmentFilePath = PathUtils.joinPaths(
                    attachmentPathManager.getAttachmentPath(),
                    ticketIssue.getProjectKey(),
                    ticketIssue.getKey(),
                    issueAttachment.getId().toString());


            if (attachmentFilePath == null) {
                throw new MessagingException(
                        MessageFormat.format("Path for attachment {0} is null", issueAttachment.getFilename()));
            }

            final File attachmentFile = new File(attachmentFilePath);
            try (FileInputStream fileInputStream = new FileInputStream(attachmentFile)) {
                attachBody.setFileName(attachmentFilePath);
                attachBody.setContent(fileInputStream, issueAttachment.getMimetype());
            } catch (IOException e) {
                throw new MessagingException(
                        MessageFormat.format("Can't add attachment: {0}", attachmentFilePath), e);
            }

            mailMultipart.addBodyPart(attachBody);
        }
    }
}

Version:

JIRA 6.3.10 (6340) / Atlassian SDK 5.0.4 / FastDev 2.4 / Dev Toolbox 2.0.12

1 answer

1 accepted

0 votes
Answer accepted
Alex May 13, 2015

Mistake was to use class:  

 

final MimeBodyPart attachBody = new MimeBodyPart();

 

If your want to attach files you should use BodyPart abstract class:

 

final BodyPart attachBody = new MimeBodyPart();

 

Correct variant for function addAttachmentsToMessage

 

/**
 * add attached files to the message
 *
 * @param mailMultipart         multipart content
 * @param issueAttachments      attachments of issue
 * @param ticketIssue           ticket
 * @throws MessagingException   if attachment
 */
private void addAttachmentsToMessage(
        Multipart mailMultipart, List<Attachment> issueAttachments, TicketIssue ticketIssue)
        throws MessagingException {
    if (issueAttachments == null || issueAttachments.isEmpty()) {
        return;
    }

    for (Attachment issueAttachment : issueAttachments) {
        final BodyPart attachBody = new MimeBodyPart();
        final AttachmentPathManager attachmentPathManager = ComponentAccessor.getAttachmentPathManager();

        final String attachmentFilePath = PathUtils.joinPaths(
                attachmentPathManager.getAttachmentPath(),
                ticketIssue.getProjectKey(),
                ticketIssue.getKey(),
                issueAttachment.getId().toString());


        if (attachmentFilePath == null) {
            throw new MessagingException(
                    MessageFormat.format(
                            NOTIFY_NULL_ATTACHMENT_PATH.getLocalizedMessage(), issueAttachment.getFilename()));
        }

        final File attachmentFile = new File(attachmentFilePath);
        attachBody.setFileName(issueAttachment.getFilename());
        FileDataSource attachSource = new FileDataSource(attachmentFile);
        attachBody.setDataHandler(new DataHandler(attachSource));
        mailMultipart.addBodyPart(attachBody);
    }
}

Suggest an answer

Log in or Sign up to answer