读好书,交益友
分类: Java
2013-08-22 20:40:51
这个问题出现有一阵子了,因为一直忙于开发,不是很在意。
一位同事在自己的计算机测试邮件发送程序时,出现
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,
/**
* The DataSource supplying our InputStream.
*/
protected DataSource ds = null;
DataSource 构造了
public synchronized DataHandler getDataHandler()
throws MessagingException {
if (dh == null)
dh = new MimeBodyPart.MimePartDataHandler(
new MimePartDataSource(this));
return dh;
}
/**
* The DataHandler object representing this Message's content.
*/
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。