Go to Contents Go to Java Page

JavaOne 2002 in SF Report

 
 

3/29 最終日

 
 
Clean Up
片付けられたレジストレーション

一週間にわたる JavaOne も最終日になりました。このレポートもこれが最終回になります。すでに、レジストレーションの場所は片付けに入っており、祭りの後の雰囲気がそこかしこに漂っています。

今日は Keynote も BOF もなく、朝からテクニカルセッションだけが行われました。それも 15:45 には終わってしまいます。この時間で終われば、その日の内に帰れる人がいるのでしょう。会場でもスーツケースを持ってきている人が結構いました。

そういえば、火曜日に行われた Sun Microsystems vs Apple Computer のアイスホッケーの試合は 5-2 で Sun が勝ったと、JavaOne Today が報じていました。

それでは、本日のレポートです。

 
 

Technical Session

 
 

今日、聴講したのは

  • TS-2423 Java Technology-Based Interactive Streaming Player with Java Technology and the Java Media Framework (JMF) API
  • TS-1311 Using ClassLoaders to Support Better Design, Security and Host Swapping of Component
  • TS-1060 Using java.awt.Robot to Test Performance, Capacity, and Reliability
  • TS-2289 Reflection - Java Technology's Secret Weapon
  • TS-1982 Extreme GUI Testing: A Guide to Using the Project "JFCUnit" and HTTPUnit Extension

なぜかテストに関するセッションが 2 つもあります。また、全てのセッションが特に新しい技術に関するセッションというわけではなく、プログラミングテクニック的なものになってしまいました。

この中から、今日は TS-1311 の ClassLoader と TS-2289 の Reflection、TS-1982 の JFCUnit についてレポートします。

TS-1311 Using ClassLoaders to Support Better Design, Security and Host Swapping of Component

Java を特徴づけているものの中にクラスローダリングがあると思いますが、普通はシステムの ClassLoader を使用するだけの人が多いと思います。このセッションでは ClassLoader 全般に関して解説が行われました。

ClassLoader は JDK1.1 で導入されましたが、そのときはまだ使いづらいものでした。Java 2 になってから使いやすくなりましたし、自分でクラスローダを作るのも簡単になりました。

ClassLoader は次のような特徴をもつクラスです。

  • Resposible for Loading Classes
  • Cand Be Structured As Tree. Class Loader Delegates Request to Parent Class Loader Before Trying to Satisfy It
  • Reads Classes from File System, Network or Gererates Byte Code Dynamically

ツリー構造になっていて、自分がローダリングをできるかどうかを判断する前に親に聞くというのが特徴的です。

Java 2 では ClassLoader クラスは SecureClassLoader という派生クラスをもち、SecureClassLoader の派生クラスとして URLClassLoader が定義されています。

あるクラスを異なる複数の ClassLoader オブジェクトを使用してロードしたときには、2 つのクラスは違うクラスとして扱われます。クラス名は同じだけどパッケージが違うクラスのようなものです。この性質を利用すると異なるバージョンのクラスを同時に使用することもできます。

また、ClassLoader オブジェクトが破棄されるとこのオブジェクトによってロードされたクラスも破棄されます。これを利用することでクラスの Hot Swap が可能になります。

今後は JSR-121 で Application Isolation が策定されており、その中で ClassLoader に関しても議論されているようです。

TS-2289 Reflection - Java Technology's Secret Weapon

Weapon というのは大げさだと思いますが、Reflection はうまく使えば強力な API です。

Reflection は java.lang.reflect.Member インタフェースを親とする Field, Method, Constructor クラスと InvocationHandler インタフェースを親とする Proxy クラス、また Proxy クラスの派生クラスの Array, Modifier クラスが中心になっています。また、java.lang.reflect パッケージではありませんが、java.lang.Class があります。

Class オブジェクトを得るには次の 4 種類の方法があります。

  • Class.forName メソッド
  • Object クラスの class プロパティ (e.g. String.class or int.class)
  • Object.getClass メソッド
  • プリミティブのラッパクラスの TYPE 定数 (e.g. Integer.TYPE)

Field, Method, Construct などはすべて Class オブジェクトから得ることができます。

Reflection を使うときに考慮すべき点には次の 3 点があります。

  • Readable
  • Performance
  • Code Size

Reflection を使うとどうしても Readability が低下します。Readability をすこしでも向上するためにはユーティリティメソッドなどを使用して直接 Reflection をコールする部分をラッパしてしまう方法があります。

次の Performance ですが、J2SE v1.4 以前は Reflection を使用するとかなり Performance が落ちることが知られていました。しかし、J2SE v1.4 では HotSpot の最適化により、直接メソッドをコールした場合と Reflection を使用した場合はそれほど変わらなくなりました。

しかし、Method オブジェクトを得る処理に時間がかかるのは以前も今も変わりません。そこで、一度 Method オブジェクトを得たら、それをキャッシュしておくことで Performance 低下を防ぐことができます。

最後の Code Size ですが、Reflection を使うことでコードのサイズを減らすこともできます。たとえば GUI で多数のボタンが配置されており、それぞれイベントの処理が異なるとします。一般にこのようなときには Inner Class を使用して次のように記述することが多くあります。

    button1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            doSomething1();
        }
    }

このコードだと n 個のボタンがあったときには n 個の Inner Class ができてしまいます。そこで、次のような ActionListener を作成します。

    public class ReflectionActionAdapter implments ActionListener {
        private Method method;
        private Object obj;
 
        public ReflectionActionAdapter(Method method, Object obj) {
            this.method = method;
            this.obj = obj;
        }
 
        public void actionPerformed(ActionEvent event) {
            method.invoke(obj, null);
        }
    }

この方法だと ReflectionActionAdapter クラスが 1 つできるだけで、このクラスのオブジェクトが複数生成されます。したがって、全体的なコードのサイズを減らすことが可能になります。

Reflection がよく使われる場合を次に示します。

  • Factory Method
  • InterPreter
  • Double Dispatch
  • Interposition

最後の Interposition はあるオブジェクトのメソッドコールをフックして他の処理をいれたいときなどに使用します。Servlet 2.3 のフィルターと同じようなことを行うわけです。これには Proxy クラスを使用して Dynamic Proxy を作成することで可能になります。

Reflection を有効に使った例としては

  • Tomcat server.xml を使用した初期化に Reflection を使用
  • jEdit JRE のバージョンをチェックし、処理方法を変化させるために使用

などがあります。

最後に Reflection では型の情報がないため Type Safty を望むのであれば、Reflection は使うべきではないことを付け加えておきます。

TS-1982 Extreme GUI Testing: A Guide to Using the Project "JFCUnit" and HTTPUnit Extension

最近、Extream Programming が浸透してきて、Test First という認識もかなり広まってきています。そこでよく使われるのが xUnit です (x は使用する言語などによって変化します。たとえば Java では JUnit です)。

xUnit は強力なのですが、GUI のテストを行うことはできませんでした。そこで、Web 対応のアプリケーションのテストを行う HTTPUnit と、Swing のテストを行う JFCUnit が提案されています。このセッションではこの 2 つの xUnit ファミリーについて解説します。

HTTPUnit はブラウザーの動きをシミュレートするためのヘルパークラスが提供されています。シミューレトするのはたとえば、フォームのサブミッション、BASIC 認証、クッキーなどです。

また、アプリケーションが処理結果によって生成した Web ページの検証も行うことができます。

サンプルコードを示しておきます。これはフォームに名前を入力すると予約した飛行機の一覧が表示されるアプリケーションです。

    public void testWelcomePage() throws Exception {
        WebConversation convers = new WebConversation();
        WebRequest request = new GetMethodWebRequest(
                                 "http://localhost/httpUnitDemo");
        WebResponse resp = convers.getResponse(request);
        InputStream in = resp.getInputStream();
        InputStreamReader inReader = new InputSteamReader(in);
        BufferedReader br = new BufferedReader(inReader);
        String line = br.readLine();
        line = br.readLine();
        
        assertEquals("<html>", line);
                 .
                 .
                 .


    }
 
    public void testWelcomePageH2() throws Exception {
        WebConversation convers = new WebConversation();
        WebRequest request = new GetMethodWebRequest(
                                "http://localhost/httpUnitDemo");
        WebResponse resp = convers.getResponse(request);
 
        Document welcomeDoc = resp.getDOM();
        NodeList h2NodeList = welcomDoc.getElementsByTagName("h2");
 
        if (h2NodeList.getLength() > 0) {
            Node h2Node = h2NodeList.item(0);
            Node textNode = h2Node.getFirstChild();
            String h2NodeStr = textNode.getNodeValue();
            assertEquals("Airline reservation", h2NodeStr);
        } else {
            fail("Can't find h2 element");
        }
                 .
                 .
                 .
    }
 
    public void testWelcomePageForm() throws Exception {
        WebConversation convers = new WebConversation();
        WebRequest request = new GetMethodWebRequest(
                             "http://localhost/httpUnitDemo");
        WebResponse resp = convers.getResponse(request);
        WebForm form = reponse.getForms()[0];
        request = from.getRequest();
 
        request.setParameter("username", "Tom");
 
        responese = convers.getResponse(request);
        WebTable flightTable = responese.getTables()[0];
 
        TableCell tcell = flightTable.getTableCell(1, 1);
        assertEquals("EWR 3/20/02 10:00", tcell.asText());
                 .
                 .
                 .
    }

JFCUnit はアプリケーションのコンポーネントを検索するための JFCTestHelper が一緒に提供されています。また、AWT のスレッドをコントロールすることもできます。

ただし、JFCUnit では java.awt.Robot を使用したテストは行いません。JFCTestHelper で検索したコンポーネントを直接コールして、結果を検証します。

こちらもサンプルコードを示しておきます。こちらはテキストフィールドが 2 つあり、一方に入力した文字列をコピーボタンを押すと他方にコピーするアプリケーションです。

    public class JFCUnitDemoTester extends JFCTestCase {
        private JFCTestHelper helper;
        private static boolean winCreated = false;
        private Window appWindow;
        private JTabbedPane tabbedPane;
        private JButton copyButton;
        private JTextField fromText;
        private JTabbedPane toText;
 
        public JFCUnitDemoTester(String name) {
            super(name);
            helper = new JFCTestHelper();
            if ("winCreated) {
                String[] stringArray new String[1];
                JFCUnitDemo.main(stringArray);
                winCreated = true;
            }
        }
 
        public JFCUnitDemoTester(String name) {
            awtSleep();
            getFrames();
            tabbedPane.setSelectedIndex(0);
            
            copyButton = (JButton)helper.findButton(
                                "Copy Text", appWindow, 0);
            fromText = (JTextField)helper.findNamedComponent(
                                "field1", appWindow, 0);
            toText = (JTextField)helper.findNamedComponent(
                                "field2", appWindow, 0);
 
            copyButton.onClick();
            assertEquals(fromText.getText(), toText.getText();
        }

        private void getFrames() {
            try {
                appWindow = helper.getWindow("JFCUnitDemo");
                tabbedPane = (JTabbedPane)helper.findComponent(
                                JTabbedPane.class, appWindow, 0);
            } catch (Exception e) {
                e.printStackTrace();
                fail("Unable to get main Window");
            }
                 .
                 .
                 .
    }

コードを見ておわかりの通り、JFCTestHelper はコンポーネントの名前をキーにして検索を行います。このため、アプリケーション側でコンポーネントの名前をなるべくつけるようにしてください。

最後に xUnit を使うときのヒントを示しておきます。

  • All unit test classes should have main method.
  • Meke sure TestCase classes independent.
  • Minimize amout of code in setup/teardown methods.
  • Use fail method instead of assert method to catch test case error.
  • Properly document test code.

参考

 
 

おまけ

 
 

今日は最後なので JavaOne がどのようなところで行われているか紹介します。来年行かれる方の参考にはならないかもしれませんが。

JavaOne の行われている Moscone Center は San Francisco の文化的な施設が集まっている Yerba Buena Gardens の一角にあります。このあたりは SOMA (South of Market) と呼ばれ 10 年ぐらいまでは治安の悪いところだったのですが、Yearba Buena Gardens ができてからは、どんどん治安がよくなってきています。

私がはじめて JavaOne に参加した 5 年前はまだ危ない雰囲気が結構ありましたが、それに比べると今はずいぶん安全になった気がします。それでも、夜になると、大通りから一歩裏通りに入るだけでずいぶん危険な匂いがまだ残っています。

さて、話をもどして Yerba Buena Gardens には Moscone Center 以外にも San Francisco Museum of Modern Art (SF MOMA) や子供のための博物館やちょっとした遊園地のような Zeum などがあります。写真では奥の茶色で丸い屋根のある建物が SF MOMA です。

SF MOMA
SF MOMA
Zeum
Zeum

Moscone Center は道をはさんで Moscone South と Moscone North に分かれています。Moscone South の前に並んでいるバスは Moscone Center とホテルの間を往復するシャトルバスです。朝早くから BOF の終了する夜中まで運行されています。

Center のほとんどの部分は地下にあります。地上の部分は公園になっています。市民の憩いの場になっており、朝は中国系の方たちが太極拳をやっていたり、昼には幼稚園の園児たちが遊びに来たりしています。

下の左側の写真で、奥の方で左手に映っているのが Sony の複合アミューズメント施設の METREON、右手の高い建物が Mariot Hotel です。Mariot は今年は行われませんでしたが、例年 BOF の会場になっていました。

公園にはステージもあって、コンサートが行われたりしています。JavaOne でもここで After Dark Activity としてコンサートを行っていたこともあります。また、ランチをここで食べる方も多いです (私もその 1 人ですが)。

Moscone South
Moscone South
Moscone North
Moscone North
Moscone Park
Moscone South の地上部分
Moscone Park
公園内のステージ

 

さて、それでは Moscone Center に入っていきましょう。Moscone South の入り口から入ると正面にレジストレーションがあります。レジストレーションが終わったら右手にある階段から地下に向かいます。

地下に入ったすぐのところに JavaOne の看板がおかれています。看板の前にあるのは、これも恒例になっている Bean Bag です。参加者はおもいおもいにこれに座ったり、寝たりしてくつろいでいます。

地下におりて左手すぐが Pavilion です。この上がちょうど公園のあたりです。Pavilion はすでにお伝えしたように、大小さまざまなブースが所狭しと並んでいます。

Pavilion の入り口のところでは Duke と記念写真を撮ることができます。結構みなさん並んで待っていました。しかし、JavaOne はどこへいっても行列、行列です。

JavaOne
JavaOne の看板
Pavilion
Pavilion の入り口
Pavilion
Pavilion
Photogenic?
Duke との撮影会

Pavilion から出て、再び JavaOne の看板の前に来ました。このまま行くと Moscone North への通路になります。

通路には Java グッズを販売している Retail Shop や コーヒショップ、疲れた身体をマッサージしてくれる Relaxation があります。

Retail Shop ははやめに行かないと、お目当てのグッズがあっという間に売りきれることもあります。

また、この通路にはとても重要なものがあります。それはコンセントです。ノート PC を使っているとやはり心配なのがパッテリーですが、Moscone Center にはなかなかコンセントがなく、あってもセッション会場の入り口のところなど、充電することができません。この通路が唯一使えそうなコンセントです。あまり、おおっぴらにいってはいけないのかもしれませんが。

さて、Moscone North につきました。ここには 4 つの大きなホールがあります。左から A, B, C となっていますが、A が食堂、B と C を合わせて Keynote セッションの会場になっています。

Hall A に入ってみましょう。左の写真は朝 7 時過ぎに写したもので、まだ閑散としています。10 人がけのテーブルが何個あるか分からないほど広いところで食事をします。食事がサーブされるのは一番奥の方です。右側が昼時の写真です。ほとんど一杯ですね ^^;; これ以外にも外の公園で食べている人も多くいます。

Breakfast
朝の食堂
Lunch
昼の食堂

Keynote の会場は Hall B と C です。暗いので、よく分からないかもしれませんが、写真は会場の一番後ろから写したものです。右側が昨日の Keynote の Pual Saffo がスピーチしている様子です。

Keynote Hall
Keynote 会場
Keynote Session
Keynote セッションの様子

Keynote セッション会場から出ると、目の前に地上に出る階段があるので、あがってみましょう。

この地上部分には参加者の憩いの場になっています。一番広いのが Hacker's Lab と呼ばれるところで、Sun の WS や Ray がずらっと並んでいます。

その他にここにも Bean Bag がおいてあり、いつでも映画が上映されていたりします。今年は Star Wars、猿の惑星、インディアナジョーンズ、トロンなどが上映されていました。また、ゲームもできるようになっています。写真では何台もディスプレイが重なっていますが、それぞれが各自のゲームマシンに繋がっています。

また、James Gosling の Keynote の時に紹介された Java でコントロールされているロボットのデモも行われていました。

Hacker's Lab の右手には Book Store の Digital Guru があります。ここは市価の 15% オフで本を買うことができます。また、いろいろな本の作者たちのサイン会も行われています。

Hacker's Lab
Hacker's Lab
Movie Theater
Movie 上映
Game Center
左はゲーム、右が Movie
Digital Guru
Digital Guru

さて、これでほとんど一通り Moscone Center を回ってきましたが、セッション会場だけは抜かしてしまいました。セッション会場は写真のように 2 台のプロジェクターが設置してあり、真中にステージというのが基本的なセッティングです。

もう一箇所残っていました。2 回以上 JavaOne に参加した人だけが入れる Alumni Club というのがあります。これは Moscone South の地上にある Center of the Art という建物の中にあります。

Session Hall
セッション会場
Alumni Club
Alumni Club

それでは BOF の会場になっている Sheraton Palace Hotel に移動しましょう。Sheraton Palace は古いホテルで風格たっぷりの建物です。中も歴史の香りがするたたずまいです。

BOF は 1 階と 2 階に分かれて行われていますが、1 階の方が広い部屋になります。写真に写っているのが一番広い部屋です。2 階の一番小さい部屋だと 20 人ぐらいで一杯になるぐらいです。

Sheraton Palace
Sheraton Palace
Entrance of Sheraton Palace
Sheraton Palace エントランス
Lobby
BOF の会場に面したロビー
BOF Session
BOF 会場

さて、これで JavaOne の会場を一通り見て回ってみました。仮想 JavaOne ツアーはどうでしたか。えっ、物足りない。そんな人は来年ぜひ JavaOne に参加してみてください。

(2002.3.29)

 
 
Go to Contents Go to Java Page