Emacs で Java アプリケーションをデバッグする
Emacs で Java アプリケーションをソースレベルデバッグするのはいろいろ手を加えないとダメだと思っていたのですが、 Emacs 22.1 の gud.el と gdb-ui.el あたりを注意深く読んでいるとどうもそうでないということが分かり、実際にやってみたところ稚拙ではあるけど一応ソースレベルデバッグっぽいことができたので紹介しておきます。
GUD って何?
GUD (Grand Unified Debugger) は Emacs の統一フロントエンドデバッガで、現在のところ gdb, sdb, dbx, xdb, perldb, pdb, jdb をバックエンドとしてサポートしています。 その中でも gdb に関してはソースレベルデバッガに必要な機能(ブレイクポイントのマークを設置したりする)などが gdb-ui.el に記述されており、ウォッチやローカル変数ウィンドウなど、より豊富な機能が使えるようになっています。
現状では gdb にしかそのような機能が実装されていないので、 Java のデバッガである jdb ではソースレベルデバッグは無理だと思っていたのですが、どうやら next, step in, step over などのアクションに関しては GUD レベルで実装されているらしいので、なんちゃってソースレベルデバッグならできるようです。
普通のアプリケーションのデバッグ
M-x jdb で jdb のコマンドラインの入力を要求されるので、以下のように入力します。l
jdb -sourcepath~/path/to/src/java Main
-sourcepath でソースコードのパスを指定します。これがないとどこにソースファイルがあるか分からないので通常は必須になります。
*gud-Main* というバッファが表示されますが、これはそのまま放置して Main.java を開いて、停止したい位置にポイントを移動して C-x C-a C-b でブレイクポイントを設置します。先述しましたが、 jdb に関してはブレイクポイントのマークの設置が実装されていないので視覚的な効果は全然ありません。そのかわりに GUD バッファで結果を確認することができます。
ブレインクポイント Main:3 を保留しています。 クラスがロードされた後に設定されます。
ブレイクポイントの設定ができたら GUD バッファを表示し run と入力して実行すると、以下のようになります。このまま、 C-x C-a C-s でステップインしたり、 C-x C-a C-f でステップアウトしたり、 C-x C-a C-n で次の行にいったりすることができます。
C-x C-a C-p で現在のポイント付近にある Java の式を評価することができますが、複雑な式を評価したりウォッチする場合は GUD バッファを選択して jdb の生のコマンドを打つ必要があります。
例:
> print x.get(y)
これができるのならブレイクポイントのマークだって GUD で実装できるんじゃないのかと思ってしまいますが、 GUD の抽象度が中途半端なのか gdb-ui.el の作者が GUD いじるの面倒だから gdb だけに対応してしまったのか、真相はよくわかりませんが、ソースを読んだ限りでは両者の中途半端さが絡みあって修正するモチベーションを落とすようなソースになっていました。誰か直してください…
Tomcat アプリケーションのデバッグ
Tomcat 遠隔デバッグ可能モードと jdb の -attach オプションを用いてデバッグを行います。
デバッグしたいアプリケーションをデプロイしてから Tomcat を以下のコマンドで起動します。
$TOMCAT_HOME/bin/catalina.sh jpda start
起動したら、 Emacs で M-x jdb して、
jdb -sourcepath~/path/to/src/java -attach 8000
で起動します。あとは通常通りデバッグできます。
JPDA で起動すると処理が遅かったりメモリをやたら食ったりするので、デバッグしたいときに JPDA で起動することになるのですが、一々 Tomcat を再起動しないといけないあたりはやはり Eclipse より劣ります。 Eclim(*) みたいなことが Emacs でもできたらいいんですがね。
(*) http://eclim.sourceforge.net/
デバッガもいいですけど、デバッグする必要のないようなコードを書いたり、目視でバグを発見できるスキルを培うべきだし、そのためにはやっぱり Emacs がいいと思うんです、うん(冗談です)。
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/debug-java-application-with-emacs/tbping