« Enum<?>にキャストしようとするとコンパイルエラー"変換できない型"が発生する | トップページ | [読書]「科学者になる方法」 科学技術振興機構(JST)プレスルーム編 »

2009/11/05

FEST-Swingを利用する(6) 非EDTでのSwingアクセスを検証する

Swingのスレッドポリシーに記載されている通り、Swingコンポーネント及び関連クラスはイベントディスパッチスレッド(EDT)で実行する必要がある。

スタンドアロンなプログラムを作成している場合には、上記リンク先に記載されているとおり、あまり意識する必要がない。しかし、クライアント/サーバ間で非同期通信を行うプログラムなどでは、よく誤ったコーディングを見かける。

本エントリでは、上記問題の簡単な実例と、それに対するFEST-Swingでの検証方法について記述する。

 

サンプルの説明

今回のサンプルコードはこちらになる。本サンプルコードは、GUIを持つクライアント(client.Client)とサーバ(server.Server)が登場する。

クライアントは、サーバに要求を行い、サーバからその結果を受けた際に、画面に結果を表示する機能を持つ。

サーバは、クライアントからの要求を受け付けた後、非同期で処理を行い結果を通知する機能を持つ。

cs_sequence

(余談。JUDE/Community 改め astash* community、最近のバージョンでは、印刷やコピー時に、上図のような透かしが入るようになったようだ。あくまで試用版、という色合いが濃くなったということか。JUDEは2009年末までダウンロード提供、とのこと。)

 

注目すべき箇所

結果を表示するラベル(resultLabel)に文字列を設定している2箇所に注目する。

1箇所目はclient/Client.javaの106行目requestButtonActionPerformed メソッド中になる。要求ボタンを押した際に実行される。

   1: private void requestButtonActionPerformed(java.awt.event.ActionEvent evt) {                                              
   2:     resultLabel.setText("要求中...");
   3:     server.request();
   4: }

2箇所目は同ファイル134行目 listen メソッド中になる。サーバからの通知を受けた際に実行される。

   1: public void listen(String str) {
   2:     resultLabel.setText(str);
   3: }

どちらも同じようにイベントハンドラの中でラベルに文字列を書いており、実行してみても通常問題は発生しないため、このような実装が行われているのをよく見かける。

しかし実際は、一方は問題ないが、もう一方は冒頭記述のSwingスレッドポリシーに反している。

1点目のメソッドはJButton#addActionListenerメソッドで登録したハンドラであり、これは、ボタンが押された場合にEDTで実行されることが保証されている。

一方、2点目のメソッドはサーバ側のタイミングで実行される(今回の場合はサーバスレッドが実行する)。従って非EDTで実行されてしまっている。

 

FEST-Swingを用いた検出

FEST-Swingでは、上記のようなコーディング誤りを検知する方法を提供している。FailOnThreadViolationRepaintManagerというクラスがこれに当たる。

利用するには、JUnitのテストクラスの@BeforeClassで以下の1行を追加すればよい。

   1: @BeforeClass
   2: public static void setUpClass() throws Exception {
   3:     FailOnThreadViolationRepaintManager.install();
   4: }

サンプルコードのテストケースを実行してみると、例外EdtViolationExceptionが発生し

Exception in thread "Server Thread" org.fest.swing.exception.EdtViolationException: EDT violation detected

から始まる例外スタックトレースによって、前述2点目のハンドラに問題があることが検知できる。

ただし、JUnit自体は正常終了している。これは、前回記載した事項と同様で、JUnitを失敗させるためには、JUnitスレッドで例外を送出する必要がある。

実際のプログラムでは、あらゆるスレッドやプロセス(通常、クライアントとサーバは別VMだろう)で発生した例外をJUnitスレッドに集約することはできないだろう。ただし、ユニットテスト時、このようなテストにはモックオブジェクトを使用するのが通例だと考える。従って、モックオブジェクトのスレッドで発生した例外を、前回のようにJUnitスレッドに教えるコードを追加すれば正しく問題を検知できるテストコードが作成できると考える。

FailOnThreadViolationRepaintManagerを用いた検証は完璧ではない(これについては次回記載予定)のだが、十分役に立つのではないだろうか。

« Enum<?>にキャストしようとするとコンパイルエラー"変換できない型"が発生する | トップページ | [読書]「科学者になる方法」 科学技術振興機構(JST)プレスルーム編 »

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: FEST-Swingを利用する(6) 非EDTでのSwingアクセスを検証する:

» FEST-Swingを利用する(7) EDTで発生した例外をJUnitで検知するの追補 [雪羽の発火後忘失]
EDTで発生した例外のハンドラをカスタム化するにはsun.awt.exception.handlerプロパティを使用する、と以前記載した。 先日リリースされたFEST-Swing 1.2a4では、カスタム化するためのクラスAWTExceptionHandlerInstallerが用意されたようだ。こちらを使用する方が良いかもしれない。ただし、実装上は、内部で上記プロパティを利用しているので差異は無... [続きを読む]

» FEST-Swingを利用する(8) 視覚の威力 [雪羽の発火後忘失]
期間があいた割にネタが用意できていないので、今回は総集編、回想回です… 過去FEST-Swingに関して記述したエントリを以下に示します。 FESTを使用してJava GUI (Swing)のテストを実行してみる FEST-Swingの紹介。FEST-Swingの機能概要を、簡単なサンプルをもとにして実行してみます。 NetBeansでFEST-Swingを利用する その1 インストール 実際にF... [続きを読む]

« Enum<?>にキャストしようとするとコンパイルエラー"変換できない型"が発生する | トップページ | [読書]「科学者になる方法」 科学技術振興機構(JST)プレスルーム編 »

other sites

  • follow us in feedly
  • github
  • stackoverflow

ソフトウェアエンジニアとして影響を受けた書籍

  • Christain Bauer: HIBERNATE イン アクション

    Christain Bauer: HIBERNATE イン アクション
    理論と実践が双方とも素晴らしい製品であるHibernate。本書はそのプロダクトを書名に冠していますが、Hibernateを使うつもりがなく、ORマッピングの解説書として読むにしても十分な良書です。Second EditionとしてJava Persistence With Hibernateという書籍も出版されていますが、残念ながら現在のところ 和訳はされていません。-インアクションは2.xの、Java Persistence-は3.1の頃のものなので、最新版とはちょっと違うところもあることに注意。 (★★★★★)

  • アンドリュー・S・タネンバウム: 分散システム 原理とパラダイム 第2版

    アンドリュー・S・タネンバウム: 分散システム 原理とパラダイム 第2版
    クライアント/サーバシステムを構築する上で必要となる知識が総論されてます。Web技術者も、フレームワーク部分を開発するのであれば必読。 (★★★★★)

  • Joel Spolsky∥著: ジョエル・オン・ソフトウェア

    Joel Spolsky∥著: ジョエル・オン・ソフトウェア
    前述の書籍「ソフトウエア開発プロフェッショナル」をより砕いたもの、という感じでしょうか。 前書きではプログラマでなくSE向けの本のように書かれているが、プログラマが読んでも面白い本であると思われます。 SEになった新人(あるいはそういう会社に入る/入りたての人)にとっては、これからどういったことが仕事を遂行していく上で起こりえるのか、どのように考えて行なっていけばいいのか決定する助けになると思います。 元は″Joel on Software″というブログの記事で、web上でも一部日本語で読めます。 http://japanese.joelonsoftware.com/ (★★★)

  • ドナルド・C・ゴース,ジェラルド・M・ワインバーグ: ライト、ついてますか

    ドナルド・C・ゴース,ジェラルド・M・ワインバーグ: ライト、ついてますか
    問題解決(一昔前のの流行語で言うところの『ソリューション』)能力は、システムエンジニアのスキルとして備えるべきもののうちのひとつです。しかし、これは難しい。学校で出されるテストと違い、唯一の、(問題提出者が想定している)解を求めるだけが「問題解決」では無いからです。そもそも、何が問題なのか、それは本当に問題なのか、それは本当に解決すべき問題なのか、その問題解決方法は正しいのか、などを解決しなければ、「その解は正しいのか」に辿りつくことができません。この本の最も良いところのひとつは、本があまり厚くないこと。すぐに読めるし、何回も読み返す気になるでしょう。 (★★★★★)

  • スティーブ・マコネル: ソフトウエア開発プロフェッショナル

    スティーブ・マコネル: ソフトウエア開発プロフェッショナル
    コードコンプリートで有名なスティーブマコネルの著書。新人SEに読んで欲しい。個人として業界の中でどうあるべきか、組織としてどうあるべきか、SEのプロ意識とは?SEの心構え概論、といったところでしょうか。また、業界における資格の重要性についても説かれています。この業界では資格が特に軽んじられる傾向がありますが、この傾向はどんな弊害をもたらすのか、将来的にこの業界は資格に対してどのような姿勢で臨んでいくべきなのか。日経BP社では(他の出版社もだが)最近、似たような類いのあまり面白くない書籍が乱出版されていますが、この本は別格だと思うので安心して購入して欲しいと思います。 (★★★★★)

無料ブログはココログ