Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4145646
  • 博文数量: 447
  • 博客积分: 1241
  • 博客等级: 中尉
  • 技术积分: 5786
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-27 06:48
个人简介

读好书,交益友

文章分类

全部博文(447)

文章存档

2023年(6)

2022年(29)

2021年(49)

2020年(16)

2019年(15)

2018年(23)

2017年(67)

2016年(42)

2015年(51)

2014年(57)

2013年(52)

2012年(35)

2011年(5)

分类: 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。

阅读(6874) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

xrhnfpgo2013-08-26 15:57:55

切换台好不好用?