Log4j、ログのローテートに失敗。原因はlog()メソッド?
プログラマとして社会に踏み出して5年目となる今年、ようやくLog4jを使用するシステムに巡り会えた(※1)。つっても、我々にはLoggerやAppender設計・製造する権限はなく、元請けが昨年製造・全社標準として採択されたjarを使わされるだけの立場なのだが。言われた通りに組み込んで使用していると、不具合発生。ログファイルは1日ごとにローテーションする設定なのだが、日付が変わってもローテーションされず。さらに、出力済みのログファイルの中身を確認したところ、ある時刻までのログが全く出力されていない(その時刻以降は問題無く全て出力されているが)。
で、調べてみたら、以下の記事発見。java-jaの方でしょうかね。前述の通り日付ローテーションと言うことで、まさにこのAppender使っていた。原因はこいつか?別のAppenderに変更して試したところ…状況変わらず、暗礁空域へ…いや、待て。よくよく考えたら、標準ログ以外のログも出力する要件があり、いくつかのLoggerを自作していたのだが、自作の方はDailyだろうが何だろうが、ローテートに失敗したことは一度も無かった。ということで、不具合の原因はコンポーネント側にあると考えるのが順当だ。ということで、提供元に調査依頼を出した。
完全に我が社の責任範囲外の事象だが、そのコンポーネントのソースコードがjarと一緒に提供されていたので、ちょっと覗いてみた。…空のcatchブロックだらけじゃねぇか。例外殺しやがって、こりゃ発見遅れるわけだ、ったく…
正常にローテートされている自作Loggerと異なる部分を探してみる。すると、ログ出力するのに使用しているメソッドに違いが見られた。自作の方はinfo()とかdebug()とかログレベルの名称を冠したものを使用しているのだが、提供されたものはlog()メソッドを使用している。この違いが原因なのか?log()メソッドの部分をinfo()とかに替えて試してみたかったが、何かのクラスが足りなくてコンパイルできず、試行は断念…
Tomcat5.5にて、<jsp:useBean>タグでJasperException発生の原因
…Tomcatは5.0だったかもしれん…過去最悪の仕事環境でのお話。JSP+サーブレットというアーキテクチャのシステム(Struts等のフレームワークは未使用)で、本番環境でのサーブレットコンテナは商用のあまり聞いた事のないやつ。そのサーブレットコンテナは、無償開発版といったものが無いので、皆サーバー環境でデバッグしていたのだが、リンク先記事にある通りコードがグダグダ。ステップ実行とかできないのは厳しすぎるので、ローカルにTomcat環境作ることにした。Javaのバージョンは我が社の案件にしては珍しく5.0だったので、Tomcatは5.5をチョイス。
環境構築して実行してみると…当節見出しの通りの不具合が発生。しかし、全ての<jsp:useBean>の箇所で発生するのではなく、決まったBeanでのみ発生している模様。これらBeanの共通点を探してみると…引数なしコンストラクタが定義されていないことが判明。
次に、JSPから変換されたJavaコードを確認してみた。<jsp:useBean>の箇所は、以下のロジックに変換されていた。
- 引数なしコンストラクタでBeanをインスタンス化
- setter・getterにて値の遣り取り
JavaBeansの必要要件である「publicで引数なしのコンストラクタを実装」を行っていなかったために起こった悲劇であった。
コードレビューってやっぱ必要だよね。
正規表現メモ
範囲指定子の「-」。これ、括弧内([])の先頭か末尾に定義した場合、リテラルとして扱われる…ということを先月知りました。はぁ~…(自分に溜息)*
※1
ちなみにJava5.0に巡り会うのには4年かかった。
「人月計算とExcelとスーツの世界」はホント石橋を叩きすぎだ(それとも我が社の案件が極端なのか?)。