GWTクライアントをChrome上でデバッグする
ここでは、GWTのクライアント側をChrome上でデバッグする方法について説明する。Eclipseを使用することを前提としている。
ちなみに、サーバ側はEclipseのデバッグモードでごく普通にデバッグができるのだが、クライアント側は、当然ながらEclipse側では対応できない。ブラウザの機能を使用してデバッグすることになる。
サンプルプログラム
サンプルとしては単純なものだ。GWT Eclipse Pluginを導入すると、GWTサンプルの作成機能がついてくるが、これを使用するだけである。
作成方法としては、最新Eclipse(2018/1 Oxygen)でGWTサンプルを動かすまでに記述してある。
これを動作させると、ブラウザ側では以下のような画面が表示されるだけだ。
デベロッパーツールを表示する
Chrome上で表示させたら、デベロッパーツールを開く。これは、Ctrl+Shift+Iを押すか、画面を右クリックして「検証」を選択する。
すると、こんな画面になる。
コンソール
まずはコンソールを見てみる。ここには、キャッチされていない例外が表示されるほか、GWTクライアントからのメッセージも表示される。
とは言っても、System.out.println(“”)では表示されない。コンソールに出力するには、GWT.logを使う必要があるのだ。試しに、ボタンをクリックしたら、「clicked!!!」と表示させるには、以下のようにする。
(sampleパッケージのSampleというクラスを作ったという前提で)sample.client.Sampleの以下の部分を変更する。
import com.google.gwt.core.client.*; // これが必要
....
// Create a handler for the sendButton and nameField
class MyHandler implements ClickHandler, KeyUpHandler {
/**
* Fired when the user clicks on the sendButton.
*/
public void onClick(ClickEvent event) {
GWT.log("clicked!!!"); // これを追加
sendNameToServer();
}
ブラウザをリロードして、Sendボタンをクリックしてみると、以下の表示になる。
ソースレベルデバッグ
次にソースレベルデバッグを行ってみる。意外なことなのだが、Chrome上ではクライアントがJavaScriptで動作しているにも関わらず、Javaのソースレベルデバッグができるのである。
以下のようにSourcesタブに移動し、左側のsample下を開いていき、Sample.javaを表示させる。右側にはJavaのソース・ファイルが表示される。先に、変更したように「GWT.log(“clicked!!!”)」のあることがわかる。
このGWT.logのところにブレークポイントを設定してみよう。行番号を右クリックし、Add breakpointを選択する。
背景が青色になり、この行にブレークポイントが設定されたことを示す。
この状態で、Sendボタンをクリックしてみると、以下のようにブレークポイントで停止する。
続行やステップ実行が、左上や下のボタンで選択できる。
このようにして、GWT.logによるトレース出力とソースレベルでのブレークポイントでの停止やステップ実行ができる。
例外発生時のスタックトレース
上記で一通りのデバッグはできるのだが、しかし、思いがけない例外発生時には少々苦労する。
例えば、Sendボタンをクリックしたときに、わざと例外を発生されるため、次のようにコードを変更してみる。この場合はNullPointerExceptionが発生する。
Integer value = null;
// Create a handler for the sendButton and nameField
class MyHandler implements ClickHandler, KeyUpHandler {
/**
* Fired when the user clicks on the sendButton.
*/
public void onClick(ClickEvent event) {
GWT.log("value " + value.intValue());
sendNameToServer();
}
すると、コンソールには次のような表示がされる。
通常のJavaのスタックトレースとは、全く異なるスタックトレースなのである。そして、この例外はSample.javaで起こっているにも関わらず、そのことが全くわからない。
※ちなみに、クライアント側でNullPointerException等が発生すると、「com.google.gwt.event.shared.UmbrellaException」という表示がなされる。NullPointerExceptionという名前も、どこにも現れない。
Debugging in GWT 2.7 Super Dev Mode, stackTrace is missing?に議論がある。これを参考にして、onModuleLoad()を以下のようにしてみる。
import java.util.logging.*;
....
private static Logger LOGGER = Logger.getLogger("TEST");
....
// このメソッドを追加
private void setUncaughtExceptionHandler() {
GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
@Override
public void onUncaughtException(Throwable e) {
Throwable unwrapped = unwrap(e);
LOGGER.log(Level.SEVERE, "onUncaughtException " + e.getMessage(), unwrapped);
}
public Throwable unwrap(Throwable e) {
if (e instanceof UmbrellaException) {
UmbrellaException ue = (UmbrellaException) e;
if (ue.getCauses().size() == 1) {
return unwrap(ue.getCauses().iterator().next());
}
}
return e;
}
});
}
/**
* This is the entry point method.
*/
public void onModuleLoad() {
this.setUncaughtExceptionHandler(); // onModuleLoad()の先頭に追加。
この状態で例外を発生させてみると、以下の表示になる。
先ほどとは異なり、Javaソース・ファイル名と行番号が表示されている。