v0_3_02リリース

エコで低炭素なWebコンテナ「SDLoader」のv0_3_02をリリースしました。


また、スタンドアロン風のSDLoaderDesktopSWTもアップしました。SDLoaderDesktopSWT_v0_0_09が最新です。


http://code.google.com/p/sdloader/


追加機能・不具合修正は以下の通りです。

起動プロセスの高速化

起動プロセスを見直し、起動を速くしました。
JDK1.6.0_13+i7+Vista64bitのDryRun状態で、起動時間が70〜80msぐらいです。


目安として、1Tomcat起動あたり約3SDLoader起動とお考えください。

WebAppContextの機能追加

WebAppContextに、

  • addClassPath()
  • addLibPath()
  • setClassLoaderHandler

の3つのメソッドを追加しました。

addClassPath()とaddLibPath()はメソッド名通りで、デプロイするwebアプリのクラスパスにclassファイルやjarを追加するメソッドです。
プロジェクトがwebアプリのフォルダ構成になっていない場合でも、パス追加でwebアプリを起動することが出来ます。


例えば

MyProject
  |-src  
  |-bin
  |-lib
     |-hoge.jar
  |-webapp
      |-WEB-INF
         |-web.xml

という構成のプロジェクトがあり、MyProjectに手をつけずに起動したい場合に、新規でプロジェクトを作成し、

public class Start{
  public static void main(String[] args){
   SDLoader loader = new SDLoader(8080);
   WebAppContext app = new WebAppContext("/app","../MyProject/webapp");
   app.addClassPath("../MyProject/bin");
   app.addLibPath("../MyProject/lib");
   loader.addWebAppContext(app);
   loader.start();
  }
}

として、MyProjectのとなりにプロジェクトをおき、

StartProject
  |-src
     |-Start.java

MyProject
 |-src
 |-bin
  ......

最後にmainメソッドを実行すると、MyProjectがwebアプリとして起動します。
もちろん同一プロジェクト内のフォルダにもパスが通せるので、開発のときだけ使いたいjarなどがある場合にも使用できます。



またsetClassLoaderHandler()は、webアプリのクラスローダーに介入するための機能です。
引数にはClassLoaderHandlerインターフェースの実装クラスを渡します。このインターフェースは、handleLoadClassとhandleResourcesの2つのメソッドが定義されています。


Webアプリのクラスロードが行われたり、リソースロードが行われる場合に、このクラスがコールバックされます。
例えばテスト時だけ特定のクラスのロードをさせたくない場合や、リソースの中身を変えたい場合、

    app.setClassLoaderHandler(new ClassLoaderHandler() {
      @Override
      public Class<?> handleLoadClass(String fqcn, boolean resolve)
          throws ClassNotFoundException {
        if (fqcn.startsWith("org.yone098")) {
          // ロードさせたくない場合はClassNotFoundExceptionを投げる
          throw new ClassNotFoundException();
        }
        // nullを返すと、通常のロードプロセスが行われる。
        // Classを返すと、返したクラスが使われる
        return null;
      }

      @Override
      public List<URL> handleResources(String resource)
          throws IOException {
        if (resource.equals("log4j.properties")) {
          //テスト時だけテスト用のプロパティファイルを返す
          return Arrays.asList(new File("c:/log4j-test.properties")
              .toURI().toURL());
        }
        //nullを返すと通常のロードプロセス
        //IOExceptionを投げるとロード失敗にできる
        return null;
      }
    });

というようなコードを書くことで、ロードプロセスを制御できます。
特定のクラスやリソースの有り無しで内部の挙動が変わるようなアプリをテストするときに便利です。


連続起動対応

1つのVM上でSDLoaderを連続して起動・停止するようなシチュエーションに対応できるよう、スレッド・ソケット周りを見直しました。
もともとはT2Frameworkのテスト対応ですが、通常のJUnitテストケースにも対応します。


T2Frameworkでは、報告されたIssueのうち、実際にWebコンテナで動作させた方が良いものや、回帰テストが可能なものをテストケースとして実装しています。
テストケース内で、SDLoaderへのデプロイ・起動・テスト・停止の一連のプロセスを実行するイメージです。
Issueを再現できるPageクラスを作ってデプロイし、HTTP通信をおこなった結果をassertしています。
場合によっては、Pageクラス自体にAssert.assertEqualsを書いたりしています。


このため、t2のmavenを動かすとテスト実施中にSDLoaderが20回ほど起動・停止します。
これに対応するため

  • SDLoader#stop()できれいにクリーンナップする
  • 停止したポート番号を保持しておき、bind出来ない場合にSO_REUSE_ADDRを使用して強制的にbindする
  • SDLoaderを止め忘れた場合、次に起動したSDLoaderから停止コマンドを送信して前のSDLoaderを止める


という対応を入れました。


テストケース中でいろいろな条件でアプリをテストしたり、テストをグルグルまわす様なコードを書いても動作するかと思います。

その他

いくつかの不具合修正と、定数クラスの移動などのリファクタリングを行っています。


よろしくお願いします。