Commons Email
  1. Commons Email
  2. EMAIL-6

[email] Errors when sending MultiPartEmail with another email as an attachment

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 1.0
    • Fix Version/s: 1.1
    • Labels:
      None
    • Environment:

      Operating System: other
      Platform: Other

      Description

      Take a look at the code below:

      if( debugMode ) {
      if( logger.isInfoEnabled() )

      { logger.info( "DEBUG mode is on. Sending email to " + debugEmailAddress ); }

      MultiPartEmail debugEmail = new MultiPartEmail();
      if( logger.isDebugEnabled() )

      { debugEmail.setDebug( true ); }

      debugEmail.setBounceAddress( debugEmailAddress );
      debugEmail.setFrom( debugEmailAddress );
      debugEmail.addReplyTo( debugEmailAddress );
      debugEmail.addTo( debugEmailAddress );
      debugEmail.setSubject( "Test Message: " + email.getSubject() );
      debugEmail.setMsg( "The email manager is operating in test mode. " +
      "Attached is a message it would have sent had it been running for real." );
      debugEmail.addPart( new MimeMultipart(
      new MimePartDataSource( email.getMimeMessage() ) ) );

      debugEmail.setMailSession( emailSession );
      messageId = debugEmail.send();
      }

      I get the following exception when I call debugEmail.send():

      2006-03-12 09:07:01,140 [ main] INFO
      com.djinnsoft.jade.email.EmailManager: DEBUG mode is on. Sending email to
      test@djinnsoft.com
      2006-03-12 09:07:01,640 [ main] WARN
      com.djinnsoft.jade.email.EmailManager: Error emailing sent item 2000035: Sending
      the email to the following server failed : null:25
      javax.mail.SendFailedException: Sending failed;
      nested exception is:
      javax.mail.MessagingException: IOException while sending message;
      nested exception is:
      java.io.IOException: "text/plain" DataContentHandler requires String object,
      was given object of type class javax.mail.internet.MimeMultipart
      at javax.mail.Transport.send0(Transport.java:219)
      at javax.mail.Transport.send(Transport.java:81)
      at org.apache.commons.mail.Email.sendMimeMessage(Email.java:863)
      at org.apache.commons.mail.Email.send(Email.java:898)
      at com.djinnsoft.jade.email.EmailManager.processMailing(EmailManager.java:1205)

      (line 1205 corresponds to "messageId = debugEmail.send();" in my code)

        Activity

        Hide
        Dave Cherkassky added a comment -

        More information:
        The "real" email is an instance of HTMLEmail, like so:
        HtmlEmail email = new HtmlEmail();
        email.setFrom( "a@b.c" );
        email.setBounceAddress( "a@b.c" );
        email.addReplyTo( "a@b.c" );
        email.addTo( "a@b.c" );
        email.setSubject( "subject" );
        email.setTextMsg( "textBody" );
        email.setHtmlMsg( "<p>htmlBody</p> );

        I've added the following lines:

        email.addHeader( "Content-Type", "multipart/mixed" );
        and
        debugEmail.addHeader( "Content-Type", "multipart/mixed" );

        Now my exception is:
        javax.mail.SendFailedException: Sending failed;
        nested exception is:
        javax.mail.MessagingException: IOException while sending message;
        nested exception is:
        java.io.IOException: javax.mail.MessagingException: No inputstream from datasource
        at javax.mail.Transport.send0(Transport.java:219)
        at javax.mail.Transport.send(Transport.java:81)
        at org.apache.commons.mail.Email.sendMimeMessage(Email.java:863)
        at org.apache.commons.mail.Email.send(Email.java:898)
        at com.djinnsoft.jade.email.EmailManager.processMailing(EmailManager.java:1205)

        Show
        Dave Cherkassky added a comment - More information: The "real" email is an instance of HTMLEmail, like so: HtmlEmail email = new HtmlEmail(); email.setFrom( "a@b.c" ); email.setBounceAddress( "a@b.c" ); email.addReplyTo( "a@b.c" ); email.addTo( "a@b.c" ); email.setSubject( "subject" ); email.setTextMsg( "textBody" ); email.setHtmlMsg( "<p>htmlBody</p> ); I've added the following lines: email.addHeader( "Content-Type", "multipart/mixed" ); and debugEmail.addHeader( "Content-Type", "multipart/mixed" ); Now my exception is: javax.mail.SendFailedException: Sending failed; nested exception is: javax.mail.MessagingException: IOException while sending message; nested exception is: java.io.IOException: javax.mail.MessagingException: No inputstream from datasource at javax.mail.Transport.send0(Transport.java:219) at javax.mail.Transport.send(Transport.java:81) at org.apache.commons.mail.Email.sendMimeMessage(Email.java:863) at org.apache.commons.mail.Email.send(Email.java:898) at com.djinnsoft.jade.email.EmailManager.processMailing(EmailManager.java:1205)
        Hide
        Dave Cherkassky added a comment -

        One final note: I confirmed that "real" email can be sent by itself. The error
        is definitely happening because I'm trying to add the real email as an
        attachment in the debug email.

        Please confirm and help

        Thanks,
        Dave Cherkassky

        Show
        Dave Cherkassky added a comment - One final note: I confirmed that "real" email can be sent by itself. The error is definitely happening because I'm trying to add the real email as an attachment in the debug email. Please confirm and help Thanks, Dave Cherkassky
        Hide
        dion gillard added a comment -

        Looks like a clash somewhere with the embedded email.
        A test case would be good, taken from the code below.

        Show
        dion gillard added a comment - Looks like a clash somewhere with the embedded email. A test case would be good, taken from the code below.
        Hide
        Dave Cherkassky added a comment -

        Is there an ETA for the fix? My client deliverable is fast approaching – I
        need to know if I need to write a work-around...

        No rush, I just need to know the situation...

        Show
        Dave Cherkassky added a comment - Is there an ETA for the fix? My client deliverable is fast approaching – I need to know if I need to write a work-around... No rush, I just need to know the situation...
        Hide
        Bjorn Townsend added a comment -

        Here's a patch to the MultiPartEmailTest class that reproduces this problem based on Dave's code.

        Show
        Bjorn Townsend added a comment - Here's a patch to the MultiPartEmailTest class that reproduces this problem based on Dave's code.
        Hide
        Ben Speakmon added a comment -

        I'm pretty sure that:

        debugEmail.addPart( new MimeMultipart(new MimePartDataSource( email.getMimeMessage() ) ) );

        isn't what you want; even if that worked correctly (which it doesn't, of which more below), it would only add the content of the HTML message. It looks like you're trying to send the entire HtmlEmail complete with header information, so I figured I'd try using attach():

        debugEmail.attach(new MimePartDataSource(email.getMimeMessage()), "name", "desc");

        but that doesn't work either as the MimePartDataSource constructor throws an IOException complaining "no content" in the MimeMessage's input stream. So something in the assumption that we can build a MimePartDataSource from a HtmlEmail's MimeMessage is incorrect. I'll look into it further.

        Show
        Ben Speakmon added a comment - I'm pretty sure that: debugEmail.addPart( new MimeMultipart(new MimePartDataSource( email.getMimeMessage() ) ) ); isn't what you want; even if that worked correctly (which it doesn't, of which more below), it would only add the content of the HTML message. It looks like you're trying to send the entire HtmlEmail complete with header information, so I figured I'd try using attach(): debugEmail.attach(new MimePartDataSource(email.getMimeMessage()), "name", "desc"); but that doesn't work either as the MimePartDataSource constructor throws an IOException complaining "no content" in the MimeMessage's input stream. So something in the assumption that we can build a MimePartDataSource from a HtmlEmail's MimeMessage is incorrect. I'll look into it further.
        Hide
        Ben Speakmon added a comment -

        I was only able to get this to work by writing out the HtmlEmail as raw RFC822 to a file and then using the existing attach() method. Ick.

        I can tell that what Dave's trying to do will definitely not work for a number of reasons, but going into detail on each is probably unnecessary noise.

        My judgment is that there's no way in the current MultiPartEmail API to do what Dave wants to do; maybe an attach(Email email) method is called for. In any case, it seems within the scope of commons-email to simplify attaching mails to other mails, and it's something the current API cannot handle.

        Show
        Ben Speakmon added a comment - I was only able to get this to work by writing out the HtmlEmail as raw RFC822 to a file and then using the existing attach() method. Ick. I can tell that what Dave's trying to do will definitely not work for a number of reasons, but going into detail on each is probably unnecessary noise. My judgment is that there's no way in the current MultiPartEmail API to do what Dave wants to do; maybe an attach(Email email) method is called for. In any case, it seems within the scope of commons-email to simplify attaching mails to other mails, and it's something the current API cannot handle.
        Hide
        Ben Speakmon added a comment -

        My current thinking on this:

        I'm not convinced that it's useful to support attaching one subclass of Email to another subclass – that is, the original report creates an HtmlEmail and then wants to attach that to a MultiPartEmail. The current design of commons-email would make this very tricky, but aside from that I don't see the general usefulness of doing so.

        One case where I do see a use for this would be when the user wants to attach a MimeMessage he got from somewhere (like a server or a filestore) to a subclass of Email. This would mean adding MultiPartEmail.addMimeMessage() methods which would then be attached like the current addPart() methods. (We'd have to have different names, since MimeMessage doesn't share a common interface ancestor with MimeMultipart.) I'll look into this option.

        Show
        Ben Speakmon added a comment - My current thinking on this: I'm not convinced that it's useful to support attaching one subclass of Email to another subclass – that is, the original report creates an HtmlEmail and then wants to attach that to a MultiPartEmail. The current design of commons-email would make this very tricky, but aside from that I don't see the general usefulness of doing so. One case where I do see a use for this would be when the user wants to attach a MimeMessage he got from somewhere (like a server or a filestore) to a subclass of Email. This would mean adding MultiPartEmail.addMimeMessage() methods which would then be attached like the current addPart() methods. (We'd have to have different names, since MimeMessage doesn't share a common interface ancestor with MimeMultipart.) I'll look into this option.
        Hide
        Ben Speakmon added a comment -

        There's still a problem, though; such a MimeMessage would have arbitrarily complex content in it. It could be multipart, HTML text, full of attachments, etc., and there's no way to know what really needs to be attached.

        I think that this has to fall into that class of problems that would be better served with JavaMail, so I'd recommend this be wontfixed.

        Show
        Ben Speakmon added a comment - There's still a problem, though; such a MimeMessage would have arbitrarily complex content in it. It could be multipart, HTML text, full of attachments, etc., and there's no way to know what really needs to be attached. I think that this has to fall into that class of problems that would be better served with JavaMail, so I'd recommend this be wontfixed.
        Hide
        Dave Cherkassky added a comment -

        If you won't fix this issue, then at least make sure that either
        a) the interface is clear on what can be added as an attachment and what can't
        or
        b) an UnsupportedOperationException is thrown if an unreasonable attachment is added.

        Otherwise, developers will be wasting hours (like I did when I first reported this issue) trying to figure out why the hell things are not working as expected.

        Show
        Dave Cherkassky added a comment - If you won't fix this issue, then at least make sure that either a) the interface is clear on what can be added as an attachment and what can't or b) an UnsupportedOperationException is thrown if an unreasonable attachment is added. Otherwise, developers will be wasting hours (like I did when I first reported this issue) trying to figure out why the hell things are not working as expected.
        Hide
        Ben Speakmon added a comment -

        I think the interface is clear; it accepts String or MimeMultipart content. Since no subclass of Email is also a subclass of MimeMultipart, I don't know how that could be made more explicit. Also, since a MimeMessage may consist of zero or more MimeMultiparts, there's no obvious way to know what (if anything) should be pulled out of it when trying to use addPart(). If there were an existing addPart(MimeMessage), I could see your point. But JavaMail doesn't guarantee that you can create a valid MimeMultipart from a given MimePartDataSource (at least not without custom DataHandlers), so relying on that seems dodgy as well.

        Throwing an exception also assumes that there is some way to determine precisely what a supplied MimeMultipart should be doing. What if the MimeMultipart contains several different encoded binary images under a multipart/related content type? Which one should be attached, and how should that decision be made?

        I think that once you get down to that level of detail, you should be using JavaMail.

        Dave, could you suggest some API comment that might make this clearer? I'd be happy to do a patch for it. (Disclaimer: I am not a commons contributor and I don't have checkin rights; I can only do a patch and then hopefully get Dion to commit it. I don't have the ability to address it directly; I'm just a guy who's used commons-email and decided to spend a lot of effort improving it.)

        Show
        Ben Speakmon added a comment - I think the interface is clear; it accepts String or MimeMultipart content. Since no subclass of Email is also a subclass of MimeMultipart, I don't know how that could be made more explicit. Also, since a MimeMessage may consist of zero or more MimeMultiparts, there's no obvious way to know what (if anything) should be pulled out of it when trying to use addPart(). If there were an existing addPart(MimeMessage), I could see your point. But JavaMail doesn't guarantee that you can create a valid MimeMultipart from a given MimePartDataSource (at least not without custom DataHandlers), so relying on that seems dodgy as well. Throwing an exception also assumes that there is some way to determine precisely what a supplied MimeMultipart should be doing. What if the MimeMultipart contains several different encoded binary images under a multipart/related content type? Which one should be attached, and how should that decision be made? I think that once you get down to that level of detail, you should be using JavaMail. Dave, could you suggest some API comment that might make this clearer? I'd be happy to do a patch for it. (Disclaimer: I am not a commons contributor and I don't have checkin rights; I can only do a patch and then hopefully get Dion to commit it. I don't have the ability to address it directly; I'm just a guy who's used commons-email and decided to spend a lot of effort improving it.)
        Hide
        Ben Speakmon added a comment -

        Setting fix version so I don't forget to make a call on this for 1.1.

        Show
        Ben Speakmon added a comment - Setting fix version so I don't forget to make a call on this for 1.1.
        Hide
        Ben Speakmon added a comment -

        Resolving as a wontfix due to lack of interest.

        Show
        Ben Speakmon added a comment - Resolving as a wontfix due to lack of interest.
        Hide
        Dave Cherkassky added a comment -

        Can't say that I'm not disappointed. I still have interest in seeing this issue resolved but I guess I am the only one who ever attached a MimeMultipart into an Email programatically.

        Best of luck in the next release!

        Dave Cherkassky

        Show
        Dave Cherkassky added a comment - Can't say that I'm not disappointed. I still have interest in seeing this issue resolved but I guess I am the only one who ever attached a MimeMultipart into an Email programatically. Best of luck in the next release! Dave Cherkassky

          People

          • Assignee:
            Ben Speakmon
            Reporter:
            Dave Cherkassky
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development