雑記帳 2006年 4月第4週

2006/04/16 Sun.

東証」でストップ安の勢いが見られる今こそ、「アイフル」は「どうする?アイフル」とのCMを流すべきだと思うのだが。
読売新聞」などでは「チワワのCMの陰で違法取り立て」などと笑わせてくれるキャッチコピーを見せてくれているな。
mixi」で「アイフル」利用者のコミュニティがないかと探してみるも、どうやら存在しないっぽい。安田美沙子ネタばっかり。
武富士」で検索してみても見つからないことから、消費者金融系のコミュニティは何らかの規制があったりするのだろう。

【アイフル業務停止】 「アイフル、刑事事件に近い事案も」と金融相が不快感…株は消費者金融各社大幅安

23 :名無しさん@6周年 :2006/04/15 14:59:36 ID:Jwcu0Ap40
アイルフってCMのチワワとかメガネのおっさんとかうっかり字をミスするアイフルの女性社員
とかでほのぼのしたイメージだったんだけど、本性は闇金業者と同じだったとは・・・・
イメージ植え付けってのは恐ろしい
25 :名無しさん@6周年 :2006/04/15 15:01:35 ID:8Cd8FA3D0
>>23
そんなのを信じているという人間がいるほうが恐ろしい
51 :名無しさん@6周年 :2006/04/15 15:55:11 ID:Jwcu0Ap40
>>25
いやいや、>>23が一般人の普通の感想だよ
「どうする~アイフル~?」とか明るい雰囲気で楽しいCMばっかり流してるから、
会社の体質っていうか雰囲気もそんな感じで取り立ても「さっさと返さんかいぼけぇ!」
みたいな闇金業者じゃなくて「返済期限そろそろですよ」とかもっと寛容な取立てだと思ってた。

金融業者の取立てに寛容も何もあるはずがないのですが。ってか、このまま上場廃止になりそうな予感が満載。
上場してようが、かわいいCM流そうが、サラ金はサラ金。サラ金に金を貸して儲けている銀行も同類に見えてきた。

2006/04/17 Mon.

延々とアプリを書きまくる一日。シェルで実行したアプリでエラーを検出したら管理者宛にメール通知するモノ。
去年の9月6日の雑記にメモしておいたアプリのソースが非常に役に立った。役に立つと思ったメモは残しておくモンだ。
設定ファイルのハッシュを取得する処理がjarファイルの中だから、そっちの修正も加えなきゃいけないってのがメンドい。
外部のメソッドを使わないで、自分自身で設定ファイルのハッシュを取得するように書き換えた方がいいのかも。
設定ファイルに項目を一つ付け加えるだけで複数のソースの修正が発生するというのは、構造上問題ありっぽい。
しかも、開発環境、試験環境、本番環境でそれぞれ違うjarファイルを使っているため、ソース管理が煩雑になる。
ってか、別々のソースを使うのが嫌なのではなく、環境ごとで別々のソースをローカルで管理するのが嫌になってくる。
最近はまともにファイルの整理もしてないし、近いうちにリリースするファイルのバージョンの選択ミスでも犯しそう。

2006/04/18 Tue.

import java.util.*;
import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
public class sendmail {
    public static void main(String args[]) {
        try {
            (略)
            MailSend(sAddressTo,
                         sNameTo,
                         sAddressFrom,
                         sNameFrom,
                         sSubject,
                         sText,
//                      sAttachFile,
                         sSMTP_HOST);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void MailSend(String sAddressTo,
                                              String sNameTo,
                                              String sAddressFrom,
                                              String sNameFrom,
                                              String sSubject,
                                              String sText,
//                                           String sAttachFile,
                                              String sSMTP_HOST) throws Exception {
        try {
            //    システムプロパティ
            Properties ps = System.getProperties();
            //    SMTPサーバーのアドレスを設定
            ps.put("mail.smtp.host", sSMTP_HOST);
            //    デフォルトのセッションオブジェクトを取得
            Session session = Session.getDefaultInstance(ps, null);
            //    インスタンス生成
            MimeMessage mimeMessage = new MimeMessage(session);
            //    マルチパート領域の設定
            MimeBodyPart mbp1 = new MimeBodyPart();
//         MimeBodyPart mbp2 = new MimeBodyPart();
            //    送信元アドレスと送信元名前を設定
            mimeMessage.setFrom(new InternetAddress(sAddressFrom, sNameFrom, "iso-2022-jp"));
            //    インスタンス生成
            InternetAddress[] internetAddress = new InternetAddress[1];
            //    送信先アドレスと送信先名前を設定
            internetAddress[0] = new InternetAddress(sAddressTo, sNameTo, "iso-2022-jp");
            mimeMessage.setRecipients(Message.RecipientType.TO, internetAddress);
            //    件名を設定
            mimeMessage.setSubject(sSubject, "iso-2022-jp");
            //    マルチパートの領域に本文を設定
            mbp1.setText(sText, "iso-2022-jp");
            //    添付ファイル名を指定
//         FileDataSource fds = new FileDataSource(sAttachFile);
            //    マルチパートの領域に添付ファイルをセット
//         mbp2.setDataHandler(new DataHandler(fds));
//         mbp2.setFileName(MimeUtility.encodeWord(fds.getName()));
            //    マルチパート格納用
            Multipart mp = new MimeMultipart();
            mp.addBodyPart(mbp1);
//         mp.addBodyPart(mbp2);
            //    複数のマルチパートの領域をセット
            mimeMessage.setContent(mp);
            //    送信日付を設定
            mimeMessage.setSentDate(new java.util.Date());
            //    メール送信を実行
            javax.mail.Transport.send(mimeMessage);
            //    終了
            return;
        } catch (Exception e) {
            throw e;
        }
    }
}

例えば添付ファイルを付けないといって、sAttachFileに空文字を渡すと動かなくなる。上手く処理してくれりゃいいのに。
ってか、このやり方だとファイル名は絶対パスを含めて指定しないと動かない。何か他にやりやすい方法は無いのか?
せめて添付ファイルを無視してメールだけでも送信してくれんかね。このメソッドをオーバーロードして書くしかないか。
相対パスを渡すと絶対パスに変換して返してくれるメソッドでも書く必要があるかな。上記のソースを修正してみよう。

import java.io.*;
import java.util.*;
import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
public class sendmail {
    public static void main(String args[]) {
        try {
            (略)
            MailSend(sAddressTo,
                         sNameTo,
                         sAddressFrom,
                         sNameFrom,
                         sSubject,
                         sText,
                         //    sAttachFileに添付ファイルのパスを指定する
                         getAbsolutePath(sAttachFile),
                         sSMTP_HOST);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void MailSend(String sAddressTo,
                                              String sNameTo,
                                              String sAddressFrom,
                                              String sNameFrom,
                                              String sSubject,
                                              String sText,
                                              String sAttachFile,
                                              String sSMTP_HOST) throws Exception {
        try {
            Properties ps = System.getProperties();
            ps.put("mail.smtp.host", sSMTP_HOST);
            Session session = Session.getDefaultInstance(ps, null);
            MimeMessage mimeMessage = new MimeMessage(session);
            MimeBodyPart mbp1 = new MimeBodyPart();
            MimeBodyPart mbp2 = new MimeBodyPart();
            mimeMessage.setFrom(new InternetAddress(sAddressFrom, sNameFrom, "iso-2022-jp"));
            InternetAddress[] internetAddress = new InternetAddress[1];
            internetAddress[0] = new InternetAddress(sAddressTo, sNameTo, "iso-2022-jp");
            mimeMessage.setRecipients(Message.RecipientType.TO, internetAddress);
            mimeMessage.setSubject(sSubject, "iso-2022-jp");
            mbp1.setText(sText, "iso-2022-jp");
            //    添付ファイル設定用
            FileDataSource fds = null;
            //    ファイル判定用
            File file = new File(sAttachFile);
            //    対象がファイルであり、かつ存在する場合
            if (file.isFile() && file.exists()) {
                //    添付ファイル名を指定
                fds = new FileDataSource(sAttachFile);
                //    マルチパートの領域に添付ファイルをセット
                mbp2.setDataHandler(new DataHandler(fds));
                mbp2.setFileName(MimeUtility.encodeWord(fds.getName()));
            }
            Multipart mp = new MimeMultipart();
            mp.addBodyPart(mbp1);
            //    対象がファイルであり、かつ存在する場合
            if (file.isFile() && file.exists()) {
                mp.addBodyPart(mbp2);
            }
            mimeMessage.setContent(mp);
            mimeMessage.setSentDate(new java.util.Date());
            javax.mail.Transport.send(mimeMessage);
            return;
        } catch (Exception e) {
            throw e;
        }
    }
    public static String getAbsolutePath(String sFileName) throws Exception {
        try {
            File file = new File(sFileName);
            if (file.isFile() && file.exists()) {
                return file.getAbsolutePath();
            } else {
                return "";
            }
        } catch (Exception e) {
            return "";
        }
    }
}

判定部分がファイルの添付をするかどうかだけだから、オーバーロードして書くのはやっぱりアホらしいので却下で。
指定された添付ファイル名が存在して、かつディレクトリではなくファイルであれば添付を行うという形式にしてみた。
つーか、FileクラスのgetAbsolutePath()getCanonicalPath()の違いがいまいちわからん。「API」読んでもわからん。
職場のマシン(Windows XPのSP2とJDK1.3.1_11)で「C:\」にこんなソースを置いて実行してみても、同じ結果が返る。

import java.io.*;
public class PathCheck {
    public static void main(String[] args) {
        try {
            File file = new File("C:\\WINDOWS\\system32\\shell32.dll");
            System.out.println("CanonicalPath = " + file.getCanonicalPath());
            System.out.println("AbsolutePath = " + file.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
C:\>javac PathCheck.java -sourcepath C:\

C:\>java PathCheck
CanonicalPath = C:\WINDOWS\system32\shell32.dll
AbsolutePath = C:\WINDOWS\system32\shell32.dll

結果が同じです。どっちでもいいのか?少し方法を変えて、「C:\java_src」というディレクトリにクラスファイルを置く。
んで、「C:\gzip\GZIPFilter.java」というファイルを参照してパスを出力してみることにする。こんな結果になった。

import java.io.*;
public class PathCheck {
    public static void main(String[] args) {
        try {
            File file = new File("..\\gzip\\GZIPFilter.java");
            System.out.println("CanonicalPath = " + file.getCanonicalPath());
            System.out.println("AbsolutePath = " + file.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
C:\java_src>javac PathCheck.java -sourcepath C:\java_src

C:\java_src>java PathCheck
CanonicalPath = C:\gzip\GZIPFilter.java
AbsolutePath = C:\java_src\..\gzip\GZIPFilter.java

これは面白い。getCanonicalPath()は一般的に言うところの普通のパスを吐き出すのか。getAbsolutePath()が特殊なんだ。
まずは自分自身のクラスファイルの場所まで降りてきて、そこから対象ファイルへのパスを繋げるワケだ。なるほどね。
上記のメール送信を行うソースのsendmailクラスのgetAbsolutePath()は、getCanonicalPath()の方がいいのかな。
どちらも正常にファイルへのパスを持っているけど、一度クラスファイル自身の階層まで降りてくる現状は非効率的か。
しかし、上記の「C:\gzip\GZIPFilter.java」というファイルの参照の仕方を変えると、また同じ結果になってしまう。

import java.io.*;
public class PathCheck {
    public static void main(String[] args) {
        try {
//          File file = new File("..\\gzip\\GZIPFilter.java");
            File file = new File("C:\\gzip\\GZIPFilter.java");
            System.out.println("CanonicalPath = " + file.getCanonicalPath());
            System.out.println("AbsolutePath = " + file.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
C:\java_src>javac PathCheck.java -sourcepath C:\java_src

C:\java_src>java PathCheck
CanonicalPath = C:\gzip\GZIPFilter.java
AbsolutePath = C:\gzip\GZIPFilter.java

どっちが一般的なんですか?階層変更の文字列が入る可能性があるgetAbsolutePath()よりはgetCanonicalPath()か?
常に正しい正規のパスを取得するなら、やはり後者一択だろうか。よし、今後はgetCanonicalPath()に統一していくか。
うーむ、こんな小さなことでも非常に感心してしまう。「API」読んで理解できない場合は実際に試してみなけりゃダメっすね。

2006/04/19 Wed.

4時間も寝たのに眠すぎて頭が回らない。もうだめだー。アプリの性能改善をしようと思ったけど効率がさっぱりだ。

public class SpeedCheck {
    public static void main(String[] args) {
        Utilities util = new Utilities();
        try {
            int s1 = util.getMillis();
            test01();
            int e1 = util.getMillis();
            util.printMessage("test01 : " + (e1 - s1));
            int s2 = util.getMillis();
            test02();
            int e2 = util.getMillis();
            util.printMessage("test02 : " + (e2 - s2));
            int s3 = util.getMillis();
            test03();
            int e3 = util.getMillis();
            util.printMessage("test03 : " + (e3 - s3));
            int s4 = util.getMillis();
            test04();
            int e4 = util.getMillis();
            util.printMessage("test04 : " + (e4 - s4));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void test01() throws Exception {
        try {
            for (int i = 0; i < 1000000000; i++) {
                String str;
            }
        } catch (Exception e) {
            throw e;
        }
    }
    public static void test02() throws Exception {
        try {
            for (int i = 0; i < 1000000000; i++) {
                String str = null;
            }
        } catch (Exception e) {
            throw e;
        }
    }
    public static void test03() throws Exception {
        try {
            for (int i = 0; i < 1000000000; i++) {
                String str = "";
            }
        } catch (Exception e) {
            throw e;
        }
    }
    public static void test04() throws Exception {
        try {
            for (int i = 0; i < 1000000000; i++) {
                String str = new String();
            }
        } catch (Exception e) {
            throw e;
        }
    }
}
C:\>javac SpeedCheck.java -sourcepath C:\

C:\>java SpeedCheck
test01 : 3718
test02 : 3813
test03 : 3859
test04 : 34735

下らない検証をしてみた。文字列変数の初期化性能チェック。Utilitiesクラスについては「このソース」を参照ってことで。
newを使って初期化すると、他と比べてこんなに性能違うもんなの?10億回ループとかいう時点で基本的にありえないが。
test01()からtest04()for文の外にさらに別のfor文で10回ほど回すようにして、100億回のループを試すとこうなった。

C:\>javac SpeedCheck.java -sourcepath C:\

C:\>java SpeedCheck
test01 : 38203
test02 : 37157
test03 : 37109
test04 : 336719

nullか空文字での初期化が一番速いのか?ってか、100億回のループでの結果とか、全然気にしないでもよさそうだな。
100億回で300秒の違いってことは、1億回で3秒の違い。うーむ、こんな部分を性能改善とかいって改修するのはアホだな。
3月8日の雑記で書いたような文字列操作の高速化みたいに、結果が体感できる有効な性能改善の方法は無いだろうか。

2006/04/20 Thu.

死亡フラグが立った。日曜もリリースだが、月曜にもリリースが入った。ゴールデンウィークの最後の日曜も出社確定。

2006/04/21 Fri.

import java.io.*;
import java.util.*;
import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
public class sendmail {
    public static void main(String args[]) {
        try {
            String sAddressTo = new String();
            String sAddressCc = new String();
            String sNameTo = new String();
            String sAddressFrom = new String();
            String sNameFrom = new String();
            String sSubject = new String();
            String sText = new String();
            String sAttachFile = new String();
            String sSMTP_HOST = new String();
            //    sAddressToとsAddressCcはカンマ区切りで複数のアドレスを指定可能
            MailSend(sAddressTo,
                         sAddressCc,
                         sNameTo,
                         sAddressFrom,
                         sNameFrom,
                         sSubject,
                         sText,
                         getCanonicalPath(sAttachFile),
                         sSMTP_HOST);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void MailSend(String sAddressTo,
                                              String sAddressCc,
                                              String sNameTo,
                                              String sAddressFrom,
                                              String sNameFrom,
                                              String sSubject,
                                              String sText,
                                              String sAttachFile,
                                              String sSMTP_HOST) throws Exception {
        try {
            Properties ps = System.getProperties();
            ps.put("mail.smtp.host", sSMTP_HOST);
            Session session = Session.getDefaultInstance(ps, null);
            MimeMessage mimeMessage = new MimeMessage(session);
            MimeBodyPart mbp1 = new MimeBodyPart();
            MimeBodyPart mbp2 = new MimeBodyPart();
            mimeMessage.setFrom(new InternetAddress(sAddressFrom, sNameFrom, "iso-2022-jp"));
            //    送信先Toアドレスの数を取得してアドレスに設定
            StringTokenizer stkTo = new StringTokenizer(sAddressTo, ",");
            InternetAddress[] internetAddressTo = new InternetAddress[stkTo.countTokens()];
            for (int i = 0; stkTo.hasMoreTokens(); i++) {
                //    送信先Toアドレスと送信先名前を設定
                internetAddressTo[i] = new InternetAddress(stkTo.nextToken(), sNameTo, "iso-2022-jp");
            }
            mimeMessage.setRecipients(Message.RecipientType.TO, internetAddressTo);
            //    送信先Ccアドレスの数を取得してアドレスに設定
            StringTokenizer stkCc = new StringTokenizer(sAddressCc, ",");
            InternetAddress[] internetAddressCc = new InternetAddress[stkCc.countTokens()];
            for (int i = 0; stkCc.hasMoreTokens(); i++) {
                //    送信先Ccアドレスと送信先名前を設定
                internetAddressCc[i] = new InternetAddress(stkCc.nextToken(), sNameTo, "iso-2022-jp");
            }
            mimeMessage.setRecipients(Message.RecipientType.CC, internetAddressCc);
            mimeMessage.setSubject(sSubject, "iso-2022-jp");
            mbp1.setText(sText, "iso-2022-jp");
            //    添付ファイル設定用
            FileDataSource fds = null;
            //    ファイル判定用
            File file = new File(sAttachFile);
            boolean isAttachFileCorrect = false;
            //    対象がファイルであり、かつ存在する場合
            if (file.isFile() && file.exists()) {
                //    添付ファイル名を指定
                fds = new FileDataSource(sAttachFile);
                //    マルチパートの領域に添付ファイルをセット
                mbp2.setDataHandler(new DataHandler(fds));
                mbp2.setFileName(MimeUtility.encodeWord(fds.getName()));
                //    フラグを設定
                isAttachFileCorrect = true;
            }
            Multipart mp = new MimeMultipart();
            mp.addBodyPart(mbp1);
            //    対象がファイルであり、かつ存在する場合
            if (isAttachFileCorrect) {
                mp.addBodyPart(mbp2);
            }
            mimeMessage.setContent(mp);
            mimeMessage.setSentDate(new java.util.Date());
            javax.mail.Transport.send(mimeMessage);
            return;
        } catch (Exception e) {
            throw e;
        }
    }
    public static String getCanonicalPath(String sFileName) throws Exception {
        try {
            File file = new File(sFileName);
            if (file.isFile() && file.exists()) {
                return file.getCanonicalPath();
            } else {
                return "";
            }
        } catch (Exception e) {
            return "";
        }
    }
}

業務用アプリとして実行されるメール送信機能とかいうのは、BCCは使われる気配が全く無い。CCは使われまくり。
カンマ区切りでアドレスを複数指定して送信できるように改良してみたのだが、大して違いが感じられないよね。
「j2ee.jar」にパスが通っていないとコンパイルもできないけど、自鯖も立てずに「j2ee.jar」持ってる人っていないっしょ。
添付ファイルも配列にして渡してもいいと思うんだけど、個人的にメール一通に対して添付しまくる人は嫌いなので却下。
つーか、やたらと重いファイル貼り付けてメール送ってくるのがいるけど、マルチメディアファイルじゃなけりゃ圧縮しろよ。
例えば6MBのExcelのファイルをZIPで圧縮してみると500KBくらいになる。メールサーバーへの負荷も違うと思うんだがな。

さて、今後の予定。22日は用事で出かけて、23日にリリースで休日出社。しかも24日もリリース入るとかアホかと。
来週は今まで不要だった仕様書を突然欲しいとか言われたがために、延々と仕様書を書く退屈な週になりそうだし。
んで、ゴールデンウィークの最後の日の日曜にもリリースが入り休日出社。拙者、義務であろうと働きたくないでござる。

2006/04/22 Sat.

風邪引いたのか何なのか知らんけど、頭が動かずに左目も開かない。思考能力が皆無というプログラマにあるまじき状態。
明日は普通に9時出社なのに、何でこういう時に限って体調が悪くなりますかね?今日の予定が無くなってくれて助かった。
絶対に短時間でリリースを終えてやる。思考レベルが落ちてる時に職場の人と話すと、頭悪いと勘違いされそうだ。
そういや明日は飲み会が入った気がするな。しかも昼間にはどっかの誰かと遊びに行くかみたいな話もした気がする。

そういえば先日の雑記でゲーセンで使った金を計算してなかったな。今日使ったことにでもして計上しておくか。