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

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

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
Accepted answer

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
Community showcase
Published Nov 27, 2018 in Portfolio for Jira

Introducing a new planning experience in Portfolio for Jira (Server/DC)

In the past, Portfolio for Jira required a high degree of detail–foresight that was unrealistic for many businesses to   have–in   order to produce a reliable long-term roadmap. We're tur...

2,646 views 18 21
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you