ひらおかゆみのなげやりブログ

もう、なげやりです…

JavaMailを手軽に使うライブラリ

ハッピーバースデー、私 & @aoetk さん!

ということで、私は23歳になりました。

最初にお断りしておきますが、これはJava Advent Calendar 2013・19日目のエントリです。同日のJava Advent Calndar 2013にも「JavaFXiPhone風のメールクライアントを作る」というタイトルで続編を公開する予定です。

さて、昨日、18日目はToshiaki Makiさんのエントリ「BloomFilterで効率的に大量データセットを持つ」でした。明日、20日目はJavaエバンジェリスト寺田さんの予定です。 

§1. JavaMailラッパー "growslowly" のご紹介

私は、諸般の事情からGitHubで "growslowly" https://github.com/yumix/growslowly というJavaMailのラッパーライブラリを公開しています。"growslowly"という名前は、ゆっくりでいいから育って欲しいという願いと、私の大好きなゆかち(井口裕香さん)の2nd シングル「Grow Slowly」を掛けています(ゆかちの楽曲の中でも一押しなのが「Grow Slowly」なのです)。SMTPの実装は相当前に完成していたのですが、受信側は長らく放置していました。今回JavaFXの簡易MUAを作ることにしたので、 それに先行してPOP3IMAP4のラッパー実装行いました。

§2. "growslowly" によるメール送信

"growslowly"の送信部はMailクラスのメソッドチェーンを利用し、通知メール程度なら1行で作成・送信できるように作ってあります。メールサーバの設定をすべてプロパティファイルに記述するのは事前準備が大変なので、JavaMailセッションのプロバイダをあらかじめ数種類用意しておいて、プロバイダの種類とメールアドレス、ログイン名、パスワードの各項目を指定すればセッションが作成できるようにしています。現時点での対応プロバイダは、GmailOutlook.com、iCloudと、私が契約しているISPであるOCNの4種類です。いずれの実装もメールサーバ固有のプロパティをファイルで保持していますが、そこは実装した私の都合なので、Sessionを作成できるのであればプロパティファイルを使用しなくても構いません。

@btnrougeSo-netBiglobeのプロバイダ実装を頼んでおいたはずなのですが、すっかり忘れられているようです。ちょうど彼が葉月ちゃんに現を抜かしている時期に依頼したのが間違っていたのかもしれません。

JavaMailでは受信側も同じセッションを使用しますので、この部分については共有できます。

では、"growslowly"によるメール送信サンプルです。Mailクラスがエントリポイントで、Builder風のインタフェースに仕上げています。

SessionProviderFactory factory = SessionProviderFactory.getInstance();
Session session = factory.getSession(OutlookProvider.class, "yumix@outlook.com", USERNAME, PASSWORD);
Mail.from("yumix@outlook.com").to(RECEIVER).subject("テストメール").message("growslowly のテストメール送信です。").send(session);

わかりやすさのために3行に分けていますが、実際には1行で記述することができます。また、できればSessionProviderSessionProviderFactoryCDIのインジェクションに置き換えたいのですが、そこは今後の課題として考えています。

§3. "growslowly" のIMAP/POP3対応

JavaMailの受信部分はIMAP4の利用を前提としながらも、POP3でもできるだけIMAP4に近い機能が提供できるように工夫されています。"grawslowly"の受信部はMailBoxクラスがエントリポイントとなり、そこを起点にMailFolderクラスがIMAPのメール・フォルダ階層を表現します。受信メールはMessageDecoderインタフェースを介して他のクラスに保存します。

  • MailBox : メールサーバへの接続と、メールボックス "INBOX" の取得を担当。"INBOX” は受信トレイに相当し、MailFolderのオブジェクトとして表される。
  • MailFolder : 配下のフォルダおよびメールの一覧を取得する。フォルダの取得はIMAP4のみ可能で、POP3の場合は空のフォルダ一覧が返される。
  • MessageDecoder<E> : MailBox.listMessagesクラスの引数に指定するデコーダのインタフェース。実装に当たってはJavaMailMessageMimeMessageの知識が必要です。フォルダ内のメッセージはMessageDecoderの具象クラスによりアプリケーションに合わせた形式に変換される。JavaMailの取得メッセージは遅延ロードになるため、確実にフォルダ内の全メッセージを取り出すためにも有効(だと思う)。

"growslowly"によるメール受信サンプルです。ここではIMAP4による受信例を出しますが、サブフォルダがないことを除けばPOP3でも同様の動きをします。

Session session = factory.getSession(OutlookProvider.class, "yumix@outlook.com", USERNAME, PASSWORD);
session.setDebug(false);
try (MailBox mailBox = new MailBox(session, IMAP)) {
  List<Summary&ht; msgs = mailBox.inbox().listMessages(new TestMessageDecoder());
  // do something
} catch (Exception e) {
  throw new RuntimeException(e.getMessage(), e);
}

§4. プロバイダごとの設定について

プロバイダごとの設定については、今後、修正が頻繁に発生するかと思われます。もちろん移行期間があるでしょうが、ブログに修正差分を掲載するよりは、GitHubのプロパティファイルを参照していただいた方が分かりやすいと思います。

受信プロトコルPOP3IMAP4か)、SMTP認証の要否(最近はSMTP認証必須のサーバが増えています)、SSL/TLSの設定要否がISPごとに異なっている項目です。私の知る限りでは、iCloudSMTP認証が少々厄介で、SSLをOFFにしつつもTLSをONにするという、少々特殊な設定が必要です。また、iCloudIMAP4接続に関する公式情報が内容が古いためかそのままでは使えないことも厄介でした。

§5. まとめ

JavaMailはかなり早い時期から存在するAPIのため、全体的に古臭さは否めません 。しかし、Java環境でメールの送受信を行う手段の第一選択肢であり、JavaMailなしでのメール送受信は少々辛いものがあります。

幸い、今回私が作成した"growslowly"のようなラッパー・ライブラリを用意することで、JavaMailの持つ古臭さをカプセル化することができ、より使いやすいインタフェースを提供できます。"growslowly"はJAX-RSJPAのように実行時例外のみ(具体的にはMailExceptionとそのサブクラス)スローするようにしており、また受信部ではAutoClosableインタフェースを実装しています。

"growslowly"はまだ未熟な実装です。しかし、JavaMailを簡単に使う方向性を示すものとしては、十分な役割を果たせるのではないでしょうか?

最後に、"growslowly"は以下のBSDライセンスで公開しています。

Copyright (c) 2013, Yumi Hiraoka

All rights reserved.

 

Redistribution and use in source and binary forms, with or without modification,

are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of ditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND ONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 "growslowly"は名前の通り、本当にゆっくり成長しますので、長い目で見守っていただければ幸いです。

それでは、次は「JavaFXiPhone風のメールクライアントを作る」でお目にかかりましょう。