SDLoaderがめちゃ便利な件


SDLoaderというWebコンテナをT2メンバでもある、id:c9katayamaがリーダーで作っています。
このWebコンテナがかなり便利で、テストを書くとき、プロトタイプを書くときなどにとても重宝しています。

便利なシチュエーション1 サンプルに簡単なブートストラップをつける


サンプルを書いて誰かに提供するときに、できるだけその敷居は下げたいものです。
たとえばEclipseプラグインを入れてくださいといっても、忘れる人が多いのは事実。
なので、できるだけ簡単にブートストラップできることが僕としては開発時のWebコンテナに望むことです。


そこでSDLoaderですよっと。
こんな感じでさくっとブートストラップを書けます。Eclipseプラグインとか全く必要ありません。

public class SampleServerStart {
	/**
	 * サーバを起動し、ブラウザを立ち上げます.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		SDLoader loader = new SDLoader(true);

		WebAppContext webAppContext = new WebAppContext("/t2-samples",
				"src/main/webapp");
		loader.addWebAppContext(webAppContext);
		loader.setPort(8080);

		loader.start();

		Browser.open("http://localhost:" + loader.getPort()
				+ "/t2-samples/index.jsp");

	}

}


ブラウザまで開いて表示するので、らくちんらくちん。

便利なシチュエーション2 Flex開発が超楽


個人的にはかなり感動したのがFlex開発がすごい楽にできる点です。
SDLoaderはルートコンテキストに割り当てるディレクトリを複数選ぶことが出来ます。
どういうことかというと、コンテキストルート/hogeに/java_rootと/flex_binを両方選ぶことが出来ます。


たとえば、こんな感じ。

public class Bootstrap {

	public static void main(String[] args) {
		SDLoader loader = new SDLoader(8080);
		loader.setUseNoCacheMode(true);
		loader.setUseOutSidePort(true);
		WebAppContext context = new WebAppContext("/t2amf-internal-test",
				"WebContent", "bin-debug");
		loader.addWebAppContext(context);
		loader.start();
		String startUrl = "http://localhost:" + loader.getPort()
				+ context.getContextPath() + "/main.html";
		Browser.open(startUrl);
	}
}

これはどんなメリットがあるかというと、FlexJavaの開発が非常に簡単にできるところです。
従来だと、Flexで出力されるswfとかの出力先をJavaのコンテキストルート内のどこかに指定しなくてはいけなかったのですんげー面倒でした。
SDLoaderを使えば、Webコンテナ側でみてくれるディレクトリを複数指定できるので、java側のコンテキストルートとswfの出力先が全く別でも
あたかも一つであるかのように見てくれます。これで今まで以上に何も気兼ねなくFlexプロジェクトを始められるようになりました。

便利なシチュエーション3 ITが超楽


T2のようなURLとのマッピングがコア機能なフレームワークはITによるデグレ防止が欠かせません。
ユーザからの要望やバグ報告をきちんと形にしておき、毎回実行されてチェックされるようになってないとダメです。

というわけで、ここでもSDLoaderを使っています。
特にT2はURLマッピングがウリの一つなのでここはきちんと仕様にのっとりテストしておきたいところ。
T2では普通のテストの中にSDLoaderをブートしてURLパターンをチェックするテストが入っています。


こんな感じで。

public class CheckUrlPatternTest extends AbstractItTestCase {

	public void test1() throws Exception {
		String baseUrl = "http://localhost:" + loader.getPort()
				+ context.getContextPath() + "/check";
		{
			assertEquals("default", getRequestContent(baseUrl, "GET"));
			assertEquals("a1", getRequestContent(baseUrl + "/a1", "POST"));
			assertEquals("a2", getRequestContent(baseUrl + "/a1", "GET"));
			assertEquals("a3", getRequestContent(baseUrl + "/a1/b1", "GET"));
			assertEquals("a4:b1b1", getRequestContent(baseUrl + "/a1/b1b1",
					"GET"));
			assertEquals("a5:bbbbbb", getRequestContent(baseUrl + "/a1bbbbbb",
					"GET"));
			assertEquals("default", getRequestContent(baseUrl + "/b1bbbbbb",
					"GET"));
		}

		baseUrl = "http://localhost:" + loader.getPort()
				+ context.getContextPath() + "/check2/hoge";
		{
			assertEquals("a1:hoge", getRequestContent(baseUrl, "GET"));
			assertEquals("a2:hoge", getRequestContent(baseUrl, "POST"));
			assertEquals("a3:hoge", getRequestContent(baseUrl + "/a3", "GET"));
			assertEquals("a4:hoge", getRequestContent(baseUrl + "/a4", "POST"));
		}

		baseUrl = "http://localhost:" + loader.getPort()
				+ context.getContextPath()
				+ "/check3/checkurl3_should_be_invoked";
		{
			assertEquals("CheckUrlPattern3", getRequestContent(baseUrl, "GET"));
		}

		baseUrl = "http://localhost:" + loader.getPort()
				+ context.getContextPath() + "/check3/fuga";
		{
			assertEquals("CheckUrlPattern4", getRequestContent(baseUrl, "GET"));
			assertEquals("CheckUrlPattern3", getRequestContent(
					baseUrl + "fuga", "GET"));
		}

	}

}


ちなみにささっと書いたAbstractItTestCaseはこんな感じ。

public abstract class AbstractItTestCase extends TestCase {

	SDLoader loader;

	WebAppContext context;

	@Override
	public void runBare() throws Throwable {
		this.loader = new SDLoader();
		loader.setAutoPortDetect(true);
		loader.setUseNoCacheMode(true);
		this.context = new WebAppContext("/it", "webapp");
		context.addClassPath("target/classes");
		context.addClassPath("target/test-classes");
		context.addLibDirPath("webapp/WEB-INF/lib");
		loader.addWebAppContext(context);
		try {
			loader.start();
			super.runBare();
		} finally {
			loader.stop();
		}
	}
......


ちなみにもっと言えば、今のSDLoaderならweb.xmlを書く必要もありません。
プログラマチックにweb.xmlを組み立ててSDLoaderにロードすることも可能です。



というわけで、普段あんまり言ったこと無いけど、はっきり明言しておきましょう。
Viva SDLoader!