情報科学屋さんを目指す人のメモ

方法・手順・解説を書き残すブログ。私と同じことを繰り返さずに済むように。

Eclipseで「なぜかステップ実行ができない」コードがあるときは

Eclipse (60) Java (38) デバッグ (3)

Eclipseを使ってJavaのコードをステップ実行していて、「なぜかステップ実行されなで飛ばされるメソッドがある」と思ったことはありませんか?

その「なぜか」について解説したいと思います。

「なぜかステップ実行できないクラス」とは

なぜかステップ実行で飛ばされるとしたら、「java.util」などにある、標準ライブラリが多いのではないかと思います。「なぜかステップ実行では標準ライブラリが飛ばされているような」と思う人もいるかと。

ただ原因を特定しようにも、ステップ実行で飛ばされてしまうだけなので、エラーメッセージなどは表示されず、原因が分かりにくいといえます。

そのヒントとなるのが、「なぜかステップ実行できないクラス」は「なぜかBreakpointの設定もできない」という点です。

「なぜかBreakpointを設定できない」理由

「Breakpointが設定できない」場合には、次の「エラーメッセージ」が表示されるので、「なぜかステップ実行で飛ばされてしまう」理由の手がかりになります。

Java Breakpoint

Unable to install breakpoint in java.util.Random due to missing line number attributes. Modify compiler options to generate line number attributes.

Reason: Absent Line Number Information

このエラーに書いてあるとおり、これが表示されてしまうのは、「コンパイル時に行番号に関する情報が埋め込まれてない」のが原因です。平たく言えば「デバッグ情報」が含まれていない場合にBreakpointが設定できないのです。

このようにエラーメッセージが出てくれると分かりやすく、実は「なぜかステップ実行ができない・飛ばされてしまう」理由も、この「行番号に関する情報が埋め込まれていない」のが原因なのです。

対策

では、それらのコードを「ステップ実行できるコード」や「Breakpointが設定できるコード」にするためにはどうすればよいのでしょう。

1.「標準Javaクラスライブラリ」の場合

「標準Javaクラスライブラリ」の場合は、実は行番号情報が「含まれているもの」と「含まれていないもの」の両方が配布されています。前者が「JRE単体として配られているもの」で、後者が「JDKに付属しているもの」です。

したがって、デバッグ実行時に「JDKに付属しているJRE(標準Javaクラスライブラリが含まれている)」を使えばいいのです。

現在利用中のJREを確認する方法

まず、現在の設定を確認します。分かりやすいのは、「Debug」ビューに表示されている「Java仮想マシン」のアイコン横のパスをチェックすることです。「C:\Program Files\Java\jre7\bin\javaw.exe」のように、現在使用しているJRE(Java仮想マシン、javaw.exe)が表示されます。ここから、この場合は「JDK付属のJREではないな」と分かったりします。

設定方法

方針によっていろいろな設定方法があるのですが、そのうちのひとつを紹介します。

まず、あらかじめ「JDK」をダウンロードしておいてください。

次に、「Window>Preferences」の「Java>Installed JREs」を開いて、「Add...」→「Standard VM」→「Next>」でJREの追加画面を開きます。

「JRE home」に、「JDKへのパス(例:C:\Program Files\Java\jdk1.7.0_06)」を入力して、「JRE name」に「jdk1.7.0_05(←例)」と入力されていることを確認してください。また、「Source Attachment」から、「jdk1.7.0_05」フォルダにある「src.zip」へのフルパス(例:C:\Program Files\Java\jdk1.7.0_06\src.zip)が設定済みなのも確認して、「Finish」をクリックしてください。

最後に、「Package Explorer」ビューにある「JRE System Library [JavaSE-1.x]」を右クリックして「Properties」を開いて「Alternate JRE」を選択し、プルダウンの中から先ほど追加した「jdk1.7.0_05」を選択して「OK」をクリックします。

以上で設定が完了です。先ほどの方法で、実行に使うjavaw.exeが変更されていることを確認してみてください。例えば「C:\Program Files\Java\jdk1.7.0_06\bin\javaw.exe」などと表示されているはずです。これにより、問題も解決されていると思います。

2.「Eclipseで編集中のソースコード」の場合

デフォルトなら大丈夫なはずなのですが、「Eclipseで編集中のソースコード」での場合は、Eclipseでのビルド時の設定を確認してください。

「Windows>Preferences」の「Java>Compiler」に「Add line number attributes to generated class files (used by the debugger)」という項目が「ON」になっていることを確認してください。(参考:debugging java hashmap source code using eclipse (IDEs and Version Control forum at JavaRanch)

3.「配布されているライブラリ」の場合

標準Javaライブラリのとき同様に、デバッグ情報込みのバージョンが配布されていないかを確認するか、自分でデバッグ情報を含めるようにビルドしてください。

行番号はjavacのデフォルトで含まれるはずで、全てのデバッグ情報を含めたい場合は「-gオプション」を付けてコンパイルしてください。ちなみに、デバッグ情報を省きたい場合は「-g:noneオプション」です。(参考:javac - Java programming language compiler

「line: not available」もこれが原因

デバッグ実行時のCall Stack表示に「line: not available」と表示され、どの行から呼び出されたのかが分からない場合も、これが原因です。つまり、「行番号に関する情報が無い」ということが、いろいろなところに影響を与えているわけです。

まとめ

今回は、「なぜかステップ実行(Step Into)で無視されて飛ばされるコードがある」「Breakpointを設定できない」「line: not availableと表示されて呼び出し元の行番号が分からない」という現象の原因が「コンパイル時に行番号情報を埋め込まなかった」ことにある、ということを紹介しました。

特にこの現象の対象になりやすいJava標準ライブラリについての対策方法や、自分のコードの対策方法などもあわせて紹介しました

デバッグ中に注意すべきこととしては、標準ライブラリのソースコードのアタッチが良く言われます。この効果は、ソースコードやJava docが見れるようになるという、とても分かりやすいものです。ただし、ちゃんとJDK付属のJREを指定してあげることも重要で、分かりにくいものの、いろいろなところで影響が出るよ、ということが分かってもらえたと思います

コメント(0)

新しいコメントを投稿