Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing start boundary Exception when reading messages with an attachment file

I don't know why I'm getting the following exception when reading a mail with an attachment file from mail server:

Exception in thread "main" javax.mail.MessagingException: Missing start boundary

        at javax.mail.internet.MimeMultipart.parsebm<MimeMultipart.java:872)
        at javax.mail.internet.MimeMultipart.parse<MimeMultipart.java:493)
        at javax.mail.internet.MimeMultipart.getCount<MimeMultipart.java:240)
        at GetParts.handleMultipart(GetParts.java:57)
        at GetParts.main(GetParts.java:42)

The file which I'm using to read those messages is:

import java.io.*;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

public class GetParts {
  public static void main (String args[]) 
      throws Exception {
    String host = args[0];
    String username = args[1];
    String password = args[2];

    // Get session
    Properties props=new Properties();
    props.put("mail.mime.multipart.ignoremissingboundaryparamete",true);
    Session session = Session.getInstance(
      props, null);
ContentType ct=new ContentType();
    // Get the store
    Store store = session.getStore("pop3");
    store.connect(host, username, password);

    // Get folder
    Folder folder = store.getFolder("INBOX");
    folder.open(Folder.READ_ONLY);

    BufferedReader reader = new BufferedReader (
      new InputStreamReader(System.in));

    // Get directory
    Message message[] = folder.getMessages();
    for (int i=0, n=message.length; i<n; i++) {
       System.out.println(i + ": "
         + message[i].getFrom()[0] 
         + "\t" + message[i].getSubject());
          //message[i].setHeader("Content-Type","multipart/mixed");
      System.out.println("Do you want to get the content? [YES to read/QUIT to end]");
      String line = reader.readLine();
      if ("YES".equals(line)) {
        Object content = message[i].getContent();
        if (content instanceof Multipart) {
          handleMultipart((Multipart)content);
        } else {
          handlePart(message[i]);
        }
      } else if ("QUIT".equals(line)) {
        break;
      }
    }

    // Close connection 
    folder.close(false);
    store.close();
  }
  public static void handleMultipart(Multipart multipart) 
      throws MessagingException, IOException {
      System.out.println(multipart.getCount());
    for (int i=0, n=multipart.getCount(); i<n; i++) {
      handlePart(multipart.getBodyPart(i));
    }
  }
  public static void handlePart(Part part) 
      throws MessagingException, IOException {
    String disposition = part.getDisposition();
    System.out.println("Disposition "+disposition);
    String contentType = part.getContentType();
    System.out.println("contentType "+contentType);
    if (disposition == null) { // When just body
      System.out.println("Null: "  + contentType);
      // Check if plain
      if ((contentType.length() >= 10) && 
          (contentType.toLowerCase().substring(
           0, 10).equals("text/plain"))) {
        part.writeTo(System.out);
      } else { // Don't think this will happen
        System.out.println("Other body: " + contentType);
        part.writeTo(System.out);
      }
    } else if (disposition.equalsIgnoreCase(Part.ATTACHMENT)) {
      System.out.println("Attachment: " + part.getFileName() + 
        " : " + contentType);
      saveFile(part.getFileName(), part.getInputStream());
    } else if (disposition.equalsIgnoreCase(Part.INLINE)) {
      System.out.println("Inline: " + 
        part.getFileName() + 
        " : " + contentType);
      saveFile(part.getFileName(), part.getInputStream());
    } else {  // Should never happen
      System.out.println("Other: " + disposition);
    }
  }
  public static void saveFile(String filename,
      InputStream input) throws IOException {
    if (filename == null) {
      filename = File.createTempFile("xx", ".out").getName();
    }
    // Do no overwrite existing file
    File file = new File(filename);
    for (int i=0; file.exists(); i++) {
      file = new File(filename+i);
    }
    FileOutputStream fos = new FileOutputStream(file);
    BufferedOutputStream bos = new BufferedOutputStream(fos);

    BufferedInputStream bis = new BufferedInputStream(input);
    int aByte;
    while ((aByte = bis.read()) != -1) {
      bos.write(aByte);
    }
    bos.flush();
    bos.close();
    bis.close();
  }
}
like image 797
Stardust Avatar asked Jan 11 '10 18:01

Stardust


1 Answers

I've just had the same problem. The boundary is specified within the Multipart Content-Type. You can find further information in this source. You can also watch the one of your current Message using the getContentType() function. In my case I obtained this result:

multipart/mixed; boundary=--boundary_25_2d74d02b-d0d6-4f28-a311-4d1b7d107417

So the getCount() function uses this boundary to separate all the parts that compose the multiple part. Looks like there could be cases in which this boundary is corrupted.

The mail.mime.multipart.ignoreexistingboundaryparameter System property may be set to true to cause any boundary to be ignored and instead search for a boundary line in the message as with mail.mime.multipart.ignoremissingboundaryparameter.

I followed this instructions and everything works all right. I added the code below:

System.setProperty("mail.mime.multipart.ignoreexistingboundaryparameter", "true");

Hope it helps!

like image 104
Jordi Avatar answered Sep 24 '22 20:09

Jordi