Java開発の問題解決を助ける(1)
デバッグでのプレークポイント活用

ブレークポイントを設定し問題個所を絞り込む

 今回のサンプルは大まかに分けると、(1)ファイルからの読み込み、(2)変数への格納、(3)標準出力への出力の3つの部分で構成されています。

 (1) ファイルからの読み込みはプログラム 82行目でファイルから読み込んでいますので、その次の83行目にブレークポイントを設定します。XMLを解析した時点でデータが壊れていないかどうかを調査します。

76:    public void load(String filename) {
77:        setArticle(new Article());
78:        
79:        try {
80:            DocumentBuilderFactory dbf =
               DocumentBuilderFactory.newInstance();
81:            DocumentBuilder db = dbf.newDocumentBuilder();
82:            Document d = db.parse(new File(filename));
83:            
84:            load(d);
85:        } catch (Exception e) {
86:            e.printStackTrace();
87:            setArticle(null);
88:        }
89:    }

 (2) 変数への格納。読み込んだXML構造から変数に格納する際に誤ったデータを格納していないかどうかを調査します。変数への格納はloadAuthorメソッド中の117行目で行っていますので、その処理が終わった次の118行にブレークポイントを設定します。

115: private void loadAuthor(Element e) {
116: Element author = getSingleElement(e, "authr");
117: article.setAuthor(getNodeText(author));
118: }

 (3) 標準出力への出力は mainメソッド中の183行目で行っています。

170: public static void main(String[] args) {
171: if (args.length == 0) {
172: System.out.println("java Sample01 [filename..]");
173: System.exit(0);
174: }
175: for (int i = 0; i < args.length; i++) {
176: Sample01 sl = new Sample01();
177: 
178: sl.load(args[i]);
179: 
180: Article s = sl.getArticle();
181: 
182: System.out.println("title : " + s.getTitle());
183: System.out.println("author : " + s.getAuthor());
184: }
185: }

 では、それぞれの部分でブレークポイントを設定してみましょう。ブレークポイントを設定するには、メニューの[デバッグ]から[新規ブレークポイント]を選択するか、該当の行にカーソルを合わせグレーの部分をクリックします。ブレークポイントに設定されると設定された行が赤色で表示されます。

 ブレークポイントの設定が完了したらデバッグ実行を行います。メニューの[デバッグ]から[セッションを開始]にある[デバッガ内で実行]を選択します。

  1. 82行目で一時停止したらXMLの内容が解析されて保存されている変数 dに着目します。ローカル変数ツールを使って内容を確認することができます。この時点では、下図のように qName(タグ名)が“article”となっている構造体以下の qNameが“author”となっている項目にある内容は正しく 'T', 'a', 'k', 'a'……と読み込まれていることが分かります。


  2. 次に、メニューの[デバッグ]から[継続]を選んで次のブレークポイントまで実行します。ここで author変数の内容を確認すると、この時点で内容が間違っていることが分かります。つまり問題は(2)変数への格納の部分で生じていることが分かりました。

ステップ実行による問題個所の特定

 問題が発生していたのは、変数へ格納している部分であることが分かりました。では、問題の起こった周辺をステップ実行を使って詳細に調べ問題個所を特定しましょう。loadAuthorメソッドの入り口である115行目にブレークポイントを設定し再度実行することにします。

115:    private void loadAuthor(Element e) {
116:        Element author = getSingleElement(e, "authr");
117:        article.setAuthor(getNodeText(author));
118:    }

 再度実行するにはまずメニューの[デバッグ]から[セッションを終了]を選んでセッションを終了した後に、メニューの[デバッグ]から[セッションを開始]にある[デバッガ内で実行]を選択します。

 ブレークポイントまで実行されて一時停止したら、変数の内容を確認しながらステップ実行を行います。ステップ実行はメニューの[デバッグ]から[ステップイン]を選ぶか[F7]キーを押します。これにより1行ずつプログラムが実行されますので、変数の内容をチェックしながらステップ実行を繰り返します。しばらくステップ実行を繰り返し、116行目の処理が終わった時点で変数authorを確認すると、この変数がnullとなっていて読み込みに失敗していることが分かります。よく見ると getSingleElementメソッドの第2引数は“author”であるべきものが“authr”となっていることに気付きます。

デバッガを使うと効率的な場合とそうでない場合

 このようにデバッガのブレークポイントやステップ実行を使用しながら変数の内容をチェックすることによって、問題個所の絞り込みや特定をすることが非常に容易になります。これによって、プログラムの至るところにトレースのためのデバッグ出力を埋め込んだりしなくても効率的にデバッグを行うことができます。しかしながら、デバッガツールも万能のものではなく効率的にデバッグが行えないような場合もあります。

 デバッガは一度の実行で非常に多くの情報を取得することができるため、実行のための準備が非常に大変なプログラムや、プログラムが小規模またはある程度問題の範囲が絞り込めている場合には有効な手段です。しかしながら、広範囲の調査を行うには多くの時間が必要であり、あまり効率的とはならない場合もあります。そのような場合は、モジュール間のデータの受け渡しの内容をログに出力しながらチェックすることで、問題がありそうなモジュールを特定していく必要があります。

 問題解決を効率的に行うためにはデバッガツールを実際によく使い込んで、問題解決までにどの程度の時間がかかるかを知っておく必要があります。そのような準備をしておくことによって、実際に問題が発生した際にデバッガツールを使うのが効率的か、それともほかの方法で問題個所の絞り込みをした方が効率的かを判断することができます。世の中にはさまざまなツールが存在しますが、デバッガはプログラムの問題解決を行ううえで最も基本的なものとなりますので、手を動かしながらしっかりマスターしてください。

 次回はメモリリークやパフォーマンスボトルネックなどの問題を解決する方法をご紹介します。どうぞお楽しみに。

3/3  

 INDEX

第1回 Java開発の問題解決を助ける
  Page1
問題はどんなところに潜んでいるのか
問題のタイプと解決の視点
ツールを活用する
 

Page2
デバッガを使ってみよう

  Page3
ブレークポイントを設定し問題個所を絞り込む









Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間