LoginSignup
35
36

JavaMailの罠

Last updated at Posted at 2015-09-05

Javaでメールを扱うライブラリとしてJavaMailが有名ですが、設計が古いため、使いにくかったり、いろいろと罠が潜んでいます。その中で自分が痛い目にあったこと、痛い目にあいそうなことを書いておきます(つД`)ノ

はじめに

  • この記事を書いた時のJavaMailの最新版は1.5.4です。
  • 必ずAPI documentationを読みましょう。動くからとメソッドの意味も分からずに使ってると後で泣きます。

Sessionを取得する方法

javax.mail.Session#getDefaultInstance()を使う例がよく載っていますが、これは避けたほうがいいです。

このprops引数には以下のように書かれています。つまり、同じメソッドを違うプロパティを引数として呼ぶと、2度目は無視され、意図しない挙動になります。

props - Properties object. Used only if a new Session object is created.

対処方法としては、getDefaultInstanceの代わりにgetInstanceを使いましょう。こちらは新しいオブジェクトを返すので安全です。

Returns:
a new Session object

デバッグ情報を出力する方法

デバッグ情報を出力する方法は以下の2種類です。mail.debugの設定はSession作成時のデフォルト、setDebugはSessionごとに設定するメソッドです。

ネットを検索すると「"mail.smtp.debug"を"true"にする」という情報が見つかりますが、com.sun.mail.smtpパッケージの説明にはありません。以前はあったのか、そもそも間違いなのか分かりませんが、設定しても何も起きません(´・ω・`)

送信時のエラー取得

JavaMailでは多数の例外が定義されていますが、全てMessagingExceptionのサブクラスとして定義されています。そのため、以下のようにMessagingExceptionをcatchするだけで、通常は事足ります。

try {
    Transport.send(msg);
} catch(MessagingException e) {
    ...
}

しかし、メールを送信する場合は別です。javax.mail.Transport#send(Message msg)などでメールを送信しますが、このメソッドはSendFailedExceptionという例外も発生します。

Throws:
SendFailedException - if the message could not be sent to some or any of the recipients.
MessagingException - for other failures

このSendFailedExceptionは、送信に成功したアドレス、失敗したアドレスの情報が取得できます。以下のように書くことで、複数人に同時に送ったときに、一部だけ失敗した場合の対処が可能です。ただし、nullを返す場合があるので注意してください

try {
    Transport.send(msg);
} catch(SendFailedException e) {
    // 現在なら当然List<Address>を返すべき
    Address[] sentAddresses = e.getValidSentAddresses();
    Address[] invalidAddresses = e.getInvalidAddresses();
    Address[] unsentAddresses = e.getValidUnsentAddresses();

    ...

    // FIXME: nullチェックしないとダメ!
    for(Address : unsentAddresses)
    {
        ...
    }
} catch(MessagingException e) {
    ...
}
35
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
36