はじめに

Eclipseでデバッグ中に任意の式を実行して、戻り値を強制的に決めたり任意の例外を発生させることができる。
任意の式を実行する方法は、表示ビューに式を書いて、式全体を選択し、実行ボタンを押すだけ。

ただ、他に式を実行できる式ビューとの違いや、右クリックメニューの表示と紛らわしいところがあるので、諸々を以下に記載しておく。

Eclipse4.2で動作確認

表示ビュー

実現できること

メソッドの任意の位置で、任意の戻り値を設定できる。

このままメソッドを実行し続ければ例外が発生するが、とりあえず正常終了させたい場合などに便利。

実行方法

※以下の方法を取らなくても、初めから表示ビューを開いて、式を記入してもOK

  1. ブレークポイントで止まったら、「右クリック」あるいは「メニューバーの実行」を選択
  2. 「表示」を選択
  3. 「Ctrl+Shift+D」を押して「表示ビュー」を開く
  4. 表示ビューに任意の式を書いて、式全体を選択
  5. 右クリックして、「実行」を選択(表示ビューの実行ボタンでもOK)
    あるいは右クリックして、「強制リターン」

「実行」と「強制リターン」の使い分けについて説明する。

  • 「実行」: Exceptionを発生させたいとき( throw new Exception(); )や、単純に式を実行して変数の値を変えたいときなど。
  • 「強制リターン」: 式の実行結果を戻り値にして、その場でメソッドを抜けたいとき( return null; )。

例えば、次のようにmethodAの中ほどで例外が発生するが、executeを最後まで終わらせたい場合、methodAの1行目にブレークポイントをつけ、表示ビューで return ""; のように書いてあげる。
そうすれば、ブレークポイント以下のmethodAの処理は実行されず、戻り値を戻すことができる。

public void execute() {
    ...
    String result = methodA();
    ...
    return result;
}
private String methodA() {
    firstMethod();
    ...
    String result = methodThatRaisesException();
    ...
    ...
    return result;
}

ちなみに、表示ビューの式記入場所ではコード補完が使える。
後述する式ビューでは使えないので、表示ビューが式ビューに勝るポイント。

表示

実現できること

選択した式の実行結果を見れる。

実行結果を見るだけでなく実際に実行されるので、実行過程で変数の値が変わるなど副作用が起きるので要注意。
この副作用のため、使いどころはほとんどないと思われる。

表示ビューにも「表示ボタン」や右クリックメニューに「表示」があるが、機能や副作用は同じ。

実行方法

  1. ブレークポイントで止まったら、実行結果を見たい箇所を選択する。
  2. 「右クリック」あるいは「メニューバーの実行」を選択
  3. 「表示」を選択

式ビュー

実現できること

登録した式がステップごとに毎回実行され、実行結果を見ることができる。

以下の注意点を除けば、基本的には表示ビューの機能と同じ。

  • 登録した式がステップごとに実行されることに注意。
  • ステップごとに実行されるため、Exceptionを発生させづらいことに注意。
  • また式ビューと違い、強制リターンがないことに注意。

実行方法

※以下の方法を取らなくても、初めから式ビューを開いて、式を記入してもOK

  1. ブレークポイントで止まったら、登録したい式を選択
  2. 「右クリック」あるいは「メニューバーの実行」を選択
  3. 「監視」を選択
  4. 式ビューに登録される

「ステップごとに実行される」というのは具体的にどういうことか。

次のようなmethodで、int result = 0;にブレークポイントをはり、式ビューには result = 10 と書いていたとする。
resultの初期値をデバッグ中に変えようという意図だったのに、ステップ実行中は常に result = 10 が実行されてしまう。

int method() {
    int result = 0;
    for (int i = 0; i < 10; i++) {
        result += calcMethod(i);
    }
}

一度だけ実行した後は、式ビューから消せば問題ないが、それなら初めから表示ビューで実行したいときだけ実行した方がいい。(今回の例は変数の変更なので、そもそも「変数ビュー」で編集すればいいという点は脇においておく)

ステップごとに実行されるため、Exception発生をさせづらいというのはどういうことか。

ブレークポイントに到達した瞬間に、式ビューに登録された throw new Exception() が実行されるが、もしこの後別の個所でもブレークポイントがあると、また例外が投げられてしまう。
例外のデバッグ中はcatchやfinallyにもブレークポイントをはることが多いので、式ビューで例外発生は実質使い物にならないということ。
この用途では、やはり式ビューよりも表示ビューで実行した方がいい。

もう一つ、ステップごとに実行されるという性質による落とし穴がある。

ServletRequest#getInputStream()のような、一度実行するともう一度実行できないメソッドを式ビューに登録すると、コード中で使用している場所があった時に、使えなくなってしまう。
※一度実行するとServletInputStreamのポインタがEOFになってしまう。
式ビューに書いたままうっかり放置していると、後日別のデバッグ時に原因不明のエラーに悩まされるかもしれない。

では式ビューはどんな時に便利なのか?

式ビューが登録したら消すまでステップ実行中ずっと有効なのに対して、表示ビューは明示的に「実行」等を押した時だけ有効になる、という表示ビューとの違いを考えると、何度実行してもOKな、冪等性のあるコードということになる。
また、表示ビューは明示的に実行しなければいけないので、一度に複数の式を見ることができないし、ステップ実行ごとに式の実行結果が移り変わる様も見れない。副作用のないコードであれば、複数登録して監視することでデバッグが容易になる。

例えば実行したSQLをデバッグ中にEclipseでリアルタイムに見たい場合、実行SQL文字列出力メソッドを式ビューに書いておくと、ログが仕込んでいないところでも、あるいはログが出力される前であってもSQLを見れるので、とても便利。
SQL出力メソッドは単なる表示メソッドなので副作用も通常はないだろうし、あるSQLを実行してから別のSQLを実行するまでという期間の限定はあるものの、何度実行しても出力結果は同じなので、冪等性があると言える。
S2JDBCを使用しているのであれば、式ビューに次の一文を登録しておきたい。

org.seasar.extension.jdbc.SqlLogRegistryLocator.getInstance().getLast().getCompleteSql()

※クラスパスはフルパスで書いてあげないと、デバッグ中のクラスでimport済でない限り、名前解決できずにエラーになる。

まとめ

Eclipseでデバッグ中に任意の式を実行したいときは、表示ビューを使う。
戻り値を強制的に決めたり任意の例外を発生させることまでできるし、任意の式を書くときにはコード補完までしてくれる。

副作用がなかったり、期間限定だったとしても冪等性のあるコードは表示ビューよりも式ビューに登録して、監視した方が楽。
例えば、
・SQLのリアルタイムログ出力
・複数の副作用の無い式を並べて見る
など