雑記帳 2009年 5月第4週

2009/05/17 Sun.

undefined.

2009/05/18 Mon.

蕨だの品川だの新橋だの川崎だの、一体何がどうなってやがる。あげくの果てには関内だとか。もう知らんわ。

今日はLogger関連と「JUnit」関連のコーディング。汎用のLoggerを作るのは、思っていた以上に難しいモンだな。
自作したライブラリを「JUnit」で試験してみているんだが、何か上手いやり方でも無いかな。「JUnit」は仕様変更に弱いし。
テスティングフレームワークは色々あるんだろうけど、一体どれを導入したらいいモンか。試験関連の書籍を漁ってみよう。

2009/05/19 Tue.

今日は「POI」と「JExcelAPI」を色々と触ったり、過去のプロジェクトのロギング関連のソースを調べてたり。
ロギングに関しては非常にいい勉強になった。「Java ロギング」の「Java Logging API vs Log4j」というページが面白い。
つーか、まずは標準APIからしっかり勉強していかんといけないな。バッチ系では結構な確率で必須になってくるだろうし。
POI」については「「POI」でExcelファイルを操る - ITアーキテクト」を、「JExcelAPI」は「いがぴょんの日記v2」を参考にしました。
前にいたプロジェクトでは、Excelのテーブル定義からDDLやJavaのソースを吐いていたりして、それが面白いなと思ってて。

帰り際に携帯のプランというかオプションを変更。「Wホワイト」と「コンテンツ得パック」を切りました。後は何を切るか。
来月中旬くらいには「基本オプションパック」も切るかな。そもそも携帯無くさないし、遠隔ロックとか普通要らないっしょ。

2009/05/20 Wed.

今日は延々とロギングについて。お決まりということで、log4j-1.2.15.jarを「Apache Logging Service Project」より入手。
Log4jの設定ファイルについては「ココ」を参考にした。最初は気づかなくてShift_JISでファイルを作成したのはご愛嬌で。
ログの出力フォーマットやら出力レベルやら出力対象パッケージやらを調べてると、今度はCommons Loggingが目に付く。
JDK標準APIとLog4jのロギングの切り替えができるらしい。commons-logging-1.1.1.jarを「Commons Logging」より入手。
難しく考えないで「Log」でログを吐こうとすると、何故だか以下のようなエラーが標準エラー出力に出てきた。

log4j:WARN No appenders could be found for logger
log4j:WARN Please initialize the log4j system properly.

Log4jを使っていないのに、何でこんなエラーが出るのかと。調べると、「commons-loggingリファレンス」というページを発見。
なるほど、ロギングに関する設定のcommons-logging.propertiesは無いし、環境変数にも特に設定されているワケではない。
で、クラスパスにはLog4jがあるから、それを使うような設定になるということか。面白い仕組みになってんだなー。
要するに、最初からCommons Loggingでログを仕込んでおくと、commons-logging.propertiesでいくらでも設定変えられるんだ。
634 - Commons Logging - 初期設定」というページがわかりやすかった。インターフェースだけを提供するってワケかな。
色々見てると、最近はどうやらCommons LoggingとLog4jのセットではなく、slf4jとLogbackというセットが流行らしい。
一気にあれこれ見始めると、結局何も覚えられなさそうだし、とりあえずはCommons LoggingとLog4jをモノにしよう。
他に参考にしたサイトは「Log4J徹底解説」、「634 - Jakarta Commons」、「JavaでHello World - ログ機能編」とか。
プロパティ関連だと「J2SE 5.0 Tiger 虎の穴 Properties」、ロガー別出力レベル対応表は「java.util.loggingリファレンス」とか。

そういや、Log4jは出力対象にパッケージ別、クラス別って指定できたけど、JDK標準APIの方ってどうなんだっけ。
以前に水天宮でやってたプロジェクトで使ったのはJDK標準APIの方だけど、クラス別設定ができなかった気がする。
設定の仕方の問題だったのかな。この辺は明日にでも試そう。さて、明日の課題は何にしようかなー。

イクラちゃんってBoolean型だよな

1 :仕様書無しさん 投稿日:2008/12/08(月) 15:47:21
ハーイ:true
バブー:false
6 :仕様書無しさん 投稿日:2008/12/08(月) 18:44:47
ちゃーん
7 :仕様書無しさん 投稿日:2008/12/08(月) 19:56:04
ちゃーん=null
11 :仕様書無しさん 投稿日:2008/12/08(月) 21:06:14
extends SeaFoodだろ
14 :仕様書無しさん 投稿日:2008/12/08(月) 21:46:15
スーパークラスはノリ助
47 :仕様書無しさん 投稿日:2009/05/04(月) 21:38:27
ちゃーん=null
ワロタ

こんなしょうもないスレで笑うことになろうとは……。スレタイだけでも中身の推測は容易だったはずなのに……。

2009/05/21 Thu.

JDK標準APIでのロギングは、レベルにクラス名をパッケージを含めて記述することで個別に制御できた。
以前のプロジェクトで使用したJDK標準APIを拡張したロギングは、パッケージのみでの指定しかできなかった。
出力レベル判定にはパッケージを含むクラス名を書くのが普通だと思われるが、多分レベル判定処理にバグがあったんだろう。
isOutputEnabled(Object obj, int level)という形でレベル判定を行っていたけど、objの扱い方がマズかったんだな。
実際にはobjの部分には自インスタンスを指すthisを渡していたけど、Logger#getLogger()のパラメータにパッケージ名を渡してる。
これじゃあ出力制御がパッケージレベルでしか行われないのも当然だ。つーか、あれで本当に良かったのだろうか?
まあ今後はCommons LoggingやLog4jを使っていくだろうから問題無いか。slf4jとLogbackは気が向いたらにしよう。

で、log4j.xmlをプロパティ形式に書き換える方法がよくわからん。いや、ある程度までは形にはできて動くんだけど。
appenderの設定とかはいいんだけど、パッケージに対する出力レベルの設定がわからん。設定一つ見ても難しいな。
逆にプロパティで記述するlog4j.debug=trueをlog4j.xmlに落とす書き方もわからん。どこにどう書けばいいんだ?
とりあえず多少のロギングの知識は覚えただろうから、これでよしとしておこうかな。ゼロから環境作る機会も少ないだろうし。

お次は何を手につけようかと思ったけど、恥ずかしながら自分はAntがわかってない。build.xmlを書けと言われても書けない。
まずは「Apache Ant」からapache-ant-1.7.1-bin.zipを入手。解凍してから環境変数ANT_HOMEとPathにパスを通す。
ちなみに参考にしたのは「Ant徹底活用:第1回:はじめてのAnt」というトコ。ド素人の自分にとってはありがたいページだ。
さて、環境ができたところでbuild.xmlで何か書いてみようかと思ったけど、特に何もネタが思いつかなかったり。
Eclipseでタスクを組むにしても、別にエディタとコンパイラ以外の使い方をしてないし、タスクが思いつかん。
何も思いつかないからと言って何もしなかったら、結局何も覚えなさそうなので、簡単なタスクを作っておこう。
と言っても、単にクラスファイル出力先のディレクトリを消して再作成して、そこに再コンパイルしたクラスファイルを吐かせるのみ。

そもそもAntで何ができるのかってトコから始めた方が良さそうな気がするので、「Apache Ant User Manual」に軽く目を通す。
使用バージョンは1.7.1だけど、該当バージョンのドキュメントが見当たらない。バージョンによって結構違うモノなのかな。
何となく覚えられればいいんで、別に古いドキュメントでも気にする必要は無いだろう。基本どころは変わらないだろうし。

つーか、そもそもAntで何ができるんだ?特定の処理を一連化して実行できるという認識って間違ってたりする?
Apache Ant User Manual」でタスクの一覧を眺めていると、どうやらJUnitの実行までもが可能らしい。これは面白そうだ。
junit.framework.TestCaseを継承した試験クラスを作成して、とりあえず試験ケースを15コほど書いてみる。
build.xmlにJUnitのタスクを追加して、早速実行してみると、何故かAntがClassNotFoundExceptionで落ちてしまう。
EclipseのAntの設定で、コンパイル時に必要になるjarの一覧をクラスパスのグローバル項目に突っ込んでみる。
再確認してみるも、今度は試験クラスそのものが見つからないといってClassNotFoundExceptionで落ちる現象が。
いまいちよくわからんが、今度はクラスファイル出力先ディレクトリをクラスパスのグローバル項目に突っ込む。
ここまでやって、ようやくまともに15コの試験が動いてくれた。試験結果をテキストで吐いてみたけど味気無いな。
試しにXMLで吐いてみると、今度は見る気もしないようなファイルになった。まあ動いたからOKとしておこう。
ちょっと気になったのが、試験クラスを個別指定していた点。これを*で設定したら、パッケージ内のが全部動くのか?
出力ファイル名を指定しない場合、パッケージとクラス名がファイル名として使われるので、別途出力ファイル名を指定。
これで試験クラスをパッケージ名と*で指定したところ、*というクラスが無いという内容のClassNotFoundExceptionが出た。
……何だかよくわからなくなってきたな。batchtestって記述を使わないと、複数クラスの一括指定はできないってこと?
filesetとincludeを使ってbatchtestの記述を書いてみたけど、試験クラスはxx.classと拡張子まで書かないと動いてくれん。
あくまでもbatchtestは対象ファイルを記述、testの方は対象クラスを記述ってことか?本当に合ってんだろうな……。

最後にオマケってことで、jarを作成するタスクを作成。前にソースを貼った、GUIでMySQLに繋いでデータを取るヤツです。
jarの作成自体は簡単だったけど、メインクラスを起動してMySQLに繋ぎにいくとClassNotFoundExceptionが出る。
あ、一応manifestファイルを手動で作成して、-jarで起動可能なjarにしてみました。しかし、この例外は一体何なんだ。
引っかかる箇所はClass#forName()の部分。実行時に-classpathでMySQLのライブラリを指定しているんだけどなあ。
調べてみると「こんなページ」が。何だか色々とメンドくさそうだ。まあこの辺も保留にして終わらせちゃいますか。
-jarでの起動は無しにして、普通にパッケージ指定でメインクラスのmain()を呼んで起動確認完了。こんなモンでいいか。
起動可能のjarってクラスパス関連がメンドいんだな。自作jarの中にサードパーティ製ライブラリを入れるのも問題だし。
やっぱり別々にしておいて、別途起動用のバッチを提供した方がいいんだろうね。色々と勉強になる一日でした。

2009/05/22 Fri.

昨日でJUnitをAntから動かせることはわかったので、今日はJUnitの試験結果XMLからJUnitReportを作成してみた。
レポート作成のネタとなるXMLの試験結果を指定して、適当なディレクトリに出力してみる。おお、簡単にできたな。
Antはbuild.xmlとタスクを指定すればバッチからも動かせるので、この手法で夜間自動試験をしてレポート出力するんだろうな。
んで、JUnitのjarが古かったので最新版に差し替えてみた。ちゃんと試験もレポートも完了したので、とりあえずこれはOKだ。
試験対象を指定する際って、クラスファイルとソースファイルのどっちを選択するのが正しいんだろう?どっちでも動くみたい。
クラス指定でワイルドカード指定をすると、インナークラスが対象になる可能性もあるし、ソースを指定するのが正しいのか?

JUnitで自動試験するのはいいんだけど、DB操作クラスとかの試験はどう行うべきか悩む。で、「DBUnit」ってのを発見。
なるほど、試験前や試験後のDB情報をExcelなりXMLで持っておいて、それを使って試験を行えるってことですな。
早速ライブラリを手に入れて、junit.framework.TestCaseを継承したDB試験クラスを書いてみる。が、ここで問題が。

public class CommonDBCtrl {
    private static final String DRIVER_NAME = "com.mysql.jdbc.Driver";
    private static final String DB_URL = "jdbc:mysql://localhost:3306/test_db";
    private static final String DB_USER = "tester";
    private static final String DB_PASSWORD = "******";
    private Connection connection = null;
    public CommonDBCtrl() throws CommonException {
        try {
            Class.forName(DRIVER_NAME);
            this.connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            this.connection.setAutoCommit(false);
        } catch (ClassNotFoundException clsEx) {
            throw new CommonException(clsEx);
        } catch (SQLException sqlEx) {
            throw new CommonException(sqlEx);
        }
    }
    // 他のメソッドは省略
}

いつも自分はDB操作クラスのConnectionってprivateで書いてて、外から触らせたくないのでアクセサは作りません。
あ、上のソースは手抜き版です。ユーザ名やパスワードをベタで持たせるはずがないので。importとかは省略してます。
んで、事前に用意したExcelデータをTestCaseからオーバーライドしたsetUp()で投入させようとして、実は無理だった。
DBUnitでデータ投入する際、「DatabaseConnection」を作る必要があるけど、コンストラクタに「java.sql.Connection」が要る。
そりゃDB操作クラスがprivateで持ってたらどうしようもないわ。しょうがないので、試験用のDB操作クラスを別途作成。
よし、今度こそデータ投入だと思ったのに、「DatabaseOperation」のCLEAN_INSERTでNoClassDefFoundErrorが出やがる。
何事だと思ってログを見たら、「slf4j」が無いとか言ってます。えええ、Commons Loggingで我慢してくれよー。メンドくせーな。
やはり時代の流れはCommons LoggingとLog4jから、slf4jとLogbackへと移っているのか?来週あたりにslf4jを調べるかな。

帰りに携帯の932SHの保護シートを350円で買ってみた。光線透過率92%らしい。貼ってみたけど、確かに違いはわからん。

2009/05/23 Sat.

さて、今日は932SHで再生できる動画を作ってみようかと。とりあえず「携帯動画変換君」とかいうのが簡単らしい。
サイトの説明を読んでいると、恐ろしいことに「QuickTime」のコンポーネントが必要らしい。諦めて入れるとしましょう。
で、肝心の「携帯動画変換君」を起動すると、出力ファイルのフォーマットをどうするかの設定が可能。QVGAばっかじゃんか。
Transcoding.iniという設定ファイルがあるので、中身を見てみると何やら出力ファイルの情報を色々とパラメータ設定してる。
試しに新しい設定を追加して、-sで渡している出力動画サイズを640x480に変えて変換してみる。おお、ちゃんと変換できた。
fpsは-rで渡している箇所か?あまりfps云々は詳しくないので、ここは放置。VGA出力できるだけで十分だろうし。
とりあえずQVGAとVGA、標準画質と高画質の組み合わせで4つほど作った。音声は全てモノラルでも別に問題無いだろう。
ちなみに、調べたら「携帯動画変換君の設定」なんてページがあった。あれこれ試行せず、最初からここを見てりゃよかった。

動画がしっかり再生できるとわかれば、932SH用のイヤホンセットを買ってもいいかもしれない。いくらするんだろう。
ジャックの部分が平べったい形のヤツなんだけど、何て名称なんだ。少なくともステレオミニとかであるはずはない。
そうそう、携帯用に変換した3gp形式動画の再生には、Media Player Classic ver 6.4.9.1を使用してます。これ便利だよなー。

んで、「ニコニコ動画」から適当にflvを落としてきて、試しに変換してみるとエラーが出る。調べると「こんなページ」を発見。
まずは「ここ」からAviSynth 2.5.8を落として入れる。その後の「ffdshow」は既に入れてある。設定の変更も必要なし。
最後にcoresの中のAVS_Skelton.avsを更新して、3GP_Converter.iniの拡張子設定にflvを追加。よし、変換できたみたいだ。
暇つぶし用コンテンツを大量に突っ込んでおきたいが、使用しているmicroSDが2GBだから困る。SDHCで16GBでも買うか。