Eclipseでデバッグ時の「行番号属性が見つからないため」
Eclipseでブレークポイントを入れてデバッグしようとすると以下のようなメッセージが出た。
行番号属性が見つからないため、ブレークポイントをpackage.SomeClassにインストールできません。行番号属性を生成するには、コンパイラー・オプションを変更してください。
Reason:
Absent Line Number Information
ところがPreferencesを覗いてみるとJava>Compilerで確かにAdd line number attributes…はONになっている。
どうやらAntでビルドした.classファイルをデバッグ時にリビルドしてくれていないのが原因だったようで、Antのjavacタスクに属性debug=”true”を追加してビルドしなおすとうまくいった。
Antビルドファイルに手を加えずにEclipse単独でデバッグ可能なリビルドをするには、ProjectメニューからClean…を実行して明示的にクリーンとビルドをする必要があるようだ。
Velocityのログ出力をオフにする
JavaのテンプレートエンジンVelocityは、デフォルトでカレントディレクトリに勝手にログを排出する。ファイル名は「~.log」で、Velocityとは関係のないスタックトレースも何故か勝手に出してくれる。その上アプリを起動するたびに次のようなメッセージがコンソールに出力されてうっとうしい。
2008/01/14 7:16:26 org.apache.velocity.runtime.log.JdkLogChute log
情報: FileResourceLoader : adding path ‘.’
このログ出力を止める方法がすぐには分からなかったのでメモしておく。
結論から言うと
Velocity.setProperty(VelocityEngine.RUNTIME_LOG, "");
でOK。
うそでした。(2008-01-14 16:00修正)
結論から言うと
Velocity.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.NullLogSystem");
でOKです。ソースはCleaning up those velocity.log files。
これぐらいのことはDeveloper’s Guideにサクっと書いておいてほしい。
ちなみにVelocity.setPropertyはVelocityEngine#setPropertyへのショートカット。
それにしてもVelocityは使い勝手も可読性も悪い。どうしてもコードは行数が多くなるしテンプレートはごちゃごちゃする。やっぱりSmartyはよくできていると思う。
Javaの正規表現でドットを改行にマッチさせる
Javaの正規表現において、ドット(.)を改行文字にもマッチさせるにはどうすればいいか。APIドキュメントが分かりにくくてしばし戸惑ったので解決策をメモしておく。
方法1:Pattern.compile時に指定
Pattern.compile("今週のランキング:(.*?)総評", Pattern.DOTALL);
方法2:インラインで指定
Pattern.compile("今週のランキング:((?s).*?)総評");
これがドキュメントにある「埋め込みフラグ」の使い方らしい。ちなみにドットの場合は目的のドットの直前にフラグを書けばいいようだが、他のフラグをどこに書けばいいのかは説明されていない。僕の読み方が甘いのかもしれないが、これぐらい甘い読み方でも理解できるようにドキュメントは書いてほしいものだ。
ぬるぽの記録 HttpURLConnection.getHeaderFieldKey(0)
HttpURLConnectionクラスでHTTP接続をし、そのレスポンスヘッダをハッシュテーブルに格納しようとしてぬるぽが出た。
元のコード:
// レスポンスヘッダを取得 int i=0; String key, value; while ((value = urlconn.getHeaderField(i))!=null){ responseHeaders.put(urlconn.getHeaderFieldKey(i), value); i++; }
原因は、HttpURLConnectionクラスのgetHeaderFieldKey(0)でnullが返ってくること。キーnullに対し200 OKなどのHTTPレスポンスコードとメッセージが返される仕様になっている。そのままハッシュテーブルにキーnullで値を挿入しようとしたためぬるぽが出てしまっていた。
修正後のコード:
// レスポンスヘッダを取得 int i=0; String key, value; while ((value = urlconn.getHeaderField(i))!=null){ if ((key = urlconn.getHeaderFieldKey(i))!=null){ responseHeaders.put(key, value); } i++; }