天天看點

javax.mail.internet.MimeUtility.getEncoding(MimeUtility.java:226)

​轉載http://blog.chinaunix.net/uid-192452-id-3861773.html

這個問題出現有一陣子了,因為一直忙于開發,不是很在意。

一位同僚在自己的計算機測試郵件發送程式時,出現

Exception in thread "main" java.lang.NullPointerException

 at javax.mail.internet.MimeUtility.getEncoding(MimeUtility.java:226)

 at javax.mail.internet.MimeUtility.getEncoding(MimeUtility.java:299)

 at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1375)

 at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1021)

 at javax.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:419)

 at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1354)

 at javax.mail.internet.MimeMessage.updateHeaders(MimeMessage.java:2107)

 at javax.mail.internet.MimeMessage.saveChanges(MimeMessage.java:2075)

 at javax.mail.Transport.send(Transport.java:123)

對于javamail 我并不陌生,使用已經超過十年。因為時間的匆忙,發現線上上系統不出問題,是以本機的事情,就忽略了,直到有一天必須本機調試,這才硬着頭皮解決問題。

javamail相對簡單,

出現問題是MimeUtility.getEncoding(MimeUtility.java:226)

代碼如下

finally {

     // Close the input stream

     try {

  is.close();

     } catch (IOException ioex) { }

 }

is類型 InputStream is = null;

is從ds中得來的,

  is = ds.getInputStream();

當時沒有想清楚datasource具體來源,主要還是對源碼不熟。片面的認為是使用上出了問題,

MimeBodyPart.java 

static void updateHeaders(MimePart part) 中

 if (part.getHeader("Content-Transfer-Encoding") == null)

      setEncoding(part, MimeUtility.getEncoding(dh));

隻要設定了Content-Transfer-Encoding了,就不會出現問題,

message.setHeader("Content-Transfer-Encoding", "quoted-printable");

最後發現不行。

冷靜的一思考,ds.getInputStream();來源于DataSource,

    protected DataSource ds = null;

DataSource 構造了

public synchronized DataHandler getDataHandler() 

  throws MessagingException {

 if (dh == null)

     dh = new MimeBodyPart.MimePartDataHandler(

      new MimePartDataSource(this));

 return dh;

    }

    protected DataHandler dh;

如此推理,代碼出現在内容上面,使用DataSource的隻有附件

messageBodyPart = new MimeBodyPart();

 DataSource source = new FileDataSource(filename);

 messageBodyPart.setDataHandler(new DataHandler(source));

 messageBodyPart.setFileName(filename);

 multipart.addBodyPart(messageBodyPart);

// Put parts in message

 message.setContent(multipart);

// Send the message

 Transport.send(message);

出現問題的原因,就是附件不存在。

解決問題很簡單,先使用File判斷一下檔案存在不存在,存在後再調用addBodyPart。

或者 source.getOutputStream().close()

sun的工程師處理也很不合理,source.getFile(),傳回File,直接判斷檔案存在不存在,不存在的話,直接抛出FileNotFoundException

異常。

其實最早就可以判斷不是程式問題,因為釋出後不出現問題,肯定是環境有問題。

作為EDM的開發者,看來也得學習一下linux_china,好好看看 javamail api。