ログ日記

作業ログと日記とメモ

JavaMailが遅い

SMTPを喋ってるから遅いのかな?と思ってsendmail実行に切り替えてみた。

class MailService {
    ...
    private final boolean useSendMail;
    public MailService(){
        if (new File(SENDMAIL_PATH).exists())
            useSendMail = true;
        else
            useSendMail = false;
    }

...
    public void  doSend(String to, String body) throws IOException {
        if (!useSendMail){
            // senderはMimeMessage + Transport のラッパーのようなもの
            sender.setTo(to)
                  .setBody(body)
                  .send();
            return;
        }

        String[] cmd = {SENDMAIL_PATH, "-t", "-f", ENVELOPE_FROM};
        Process process = null;
        try {
            process = Runtime.getRuntime().exec(cmd);
            procSend(process, to, body);
            process.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            if (process != null)
                process.destroy();
        }
    }

    private void procSend(Process process, String to, String body) throws IOException {
        OutputStream out = null;
        InputStream in = null;
        InputStream err = null;
        String[] ignoreHeaders = {"Message-ID"};
        try {
            out = process.getOutputStream();
            in  = process.getInputStream();
            err = process.getErrorStream();

            sender.setTo(to)
                  .setBody(body)
                  .writeTo(out, ignoreHeaders);
        }finally {
            if (err != null)
                err.close();
            if (out != null)
                out.close();
            if (in != null)
                in.close();
        }
    }
}

こんな感じ。
execの例外処理の方法がよく分からなかった。
out、in、errそれぞれのストリームは使わなくても全部closeしなければいけないという記事を見かけたのでcloseしたけど、closeも例外をスローするよね。なんか冗長。このコードの場合、err.closeでIOExceptionが発生したらoutとinは閉じられないよね…tryを三つ書くとか?正しいやり方がわからん。


書きながら今この記事を見付けた。
http://d.hatena.ne.jp/hidepon_mory/20090511/1242043434
出力があるなら読み込む必要もある?更にめんどくさそう…。


また別の問題もあった。
http://d.hatena.ne.jp/Kazumi007/20090930/1254319746
Javaでexecはやめた方がいいのかもわからんね。



で、例外処理はおいといて上のコードでSMTPとコマンド実行を試してみたんだけど、誤差程度しか速度が変わらない。waitForしているから?destroyの書き方が間違ってるぽい?


ややこしい…これだとSMTPでいいかな…。でもwriteToのignoreHeaders引数はMessage-IDを消せるので魅力的だ。
しかしコマンドを実行するだけでこんなに面倒くさいなんて。


あとで
http://www.ne.jp/asahi/hishidama/home/tech/java/process.html#Process
ここもよく読む。