今では、開発の様々なシーンでオープンソースのライブラリを使うことが多くなってきています。
そんなライブラリを使用する際に、想定しない動きをしたり、うまく動かないんだけど、中で何が行われているかわかりにくいこと、ありますよね。
自分で作成したクラスやアプリならEclipseのデバッグ機能を使えば、変数に何が入っているかなどを逐次実行できますが、オープンソースのスタンド・アロンアプリやWebサーバ上のWebアプリだと、そうは行きません。
そんなときに役立つTipsをご紹介します。
Eclipseで実行できないなら、実行中のJVMにつないで覗いてみる
その方法は、JVMに、リモートから接続してデバッグするというものです。
Javaのアプリやサーバはバーチャルマシン(JVM)上で実行されているというのはご存知ですよね。JVMにはもともと、デバッグ機能を外部に公開する仕様が備わっており、それを利用すると、Eclipseなど、他のJavaアプリから接続して、デバッグを行えるようになります。
外部からそのJVMに接続してデバッグを出来るようにするためには、JVMの起動時に、下記のようなオプションを渡す必要があります。
アプリやサーバの起動バッチファイルの中でJVMオプションを指定している部分があればそこに、なければ、Javaの実行時に以下の引数を指定します。(最後の「-jar remotedebugtest.jar」は実行するjarファイルの指定ですので、お使いの環境に合わせて変更してください。その前までの引数が重要です。)
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=y -jar remotedebugtest.jar
それぞれの意味を解説すると、
- -Xdebug・・・このJVMでデバッグを行うという意味になります。
- -Xrunjdwp:・・・これ以降が、デバッグの詳細な振る舞いを指定するオプションです。
- transport=dt_socket・・・接続をソケット形式で行う指定になります。他に共有メモリーも使用できますが、多くの場合はソケット形式でしょう。
- server=y・・・デバッグ情報をどこで生成するかの指定です。yだと、接続先のJVMで行うことになります。
- address=8000・・・Eclipseとのデバッグクライアントからの接続をそのポート受け付けるかのポート番号です。8000番台等、他のサーバと重ならない、適当なポート番号を指定します。
- suspend=y・・・これは、少し癖があります。「y」だと、デバッグクライアントから接続するまで、アプリが実行されずに待ったままになります。すぐに実行して終わってしまうアプリは「y」の方がよいでしょう。逆に指定しないと待たずに実行されます。サーバ上に配備されるWebアプリは、指定しないほうが良いと思います。
上記オプションでアプリを起動したら、今度は、Eclipse側の設定を行って接続しましょう。
はじめに、適当なプロジェクトを作成します。
次に「実行」⇒「デバッグの構成」を開くと、上記のような設定画面が開きます。ここで、「リモートJavaアプリケーション」を右クリックすると、新規に構成が追加できます。
追加する構成の設定で、接続プロパティーにサーバのアドレス(ホストの部分)、ポートを入力します。
上記の起動時の引数だと、JVM側は、8000番で待ち受けているのですよね。
さて、こここからも結構重要なポイントです。
どうやってステップ実行するかということです。ステップ実行するためには、上記で作成したプロジェクトのクラスパスに、デバッグする対象のクラスが含まれている必要があります。
イメージでいうと、リモートJVMで実行しているクラスファイルと、クライアントのEclipse側のプロジェクトのクラスファイルを指紋のように比較して、同じ形があれば、そこが実行されているとみなす感じでデバックしていくからです。
また、同じ形があったら、そのソースを表示するので、jarに、ソースをアタッチする設定を行っておきましょう。
ソースの無いjarであれば、jad等を利用して、Eclipseでデコンパイルしたソースを作ってプロジェクトに含めておくと、どんなアプリでもデバッグできます。