Mustangに簡易HTTPサーバが含まれる可能性があるとのこと。
スレッドプールを備え、マルチスレッドで動作し、SSL通信、フィルターなどもサポートしており大抵の要件に間に合う。
これが最終リリースに含まれる可能性は低いように思えるがどうなのだろう。
これをRhinoから動作を確認してみた。
importPackage( java.io );
var server = Packages.com.sun.net.httpserver.HttpServer.create(
new java.net.InetSocketAddress(8000), 5);
var context = server.createContext("/", function(exchange){
// 以下を設定しない場合、ストリームクローズ時にNullPointerExceptionが発生する
exchange.setStreams(exchange.requestBody, exchange.responseBody);
exchange.responseHeaders.set("Content-Type", "text/plain;charset=utf-8");
// responseLengthに0を指定すると、Transfer-encodingがchunkedとなる
exchange.sendResponseHeaders(200, 0);
var response = new PrintWriter(new OutputStreamWriter(exchange.responseBody, "UTF-8"));
var requestHeaders = jmap(exchange.requestHeaders);
for(var key in requestHeaders){
response.println(key + ": " + requestHeaders[key]);
}
response.close();
}
);
// 以下を設定しない場合、サーバーはシングルスレッドで動作する
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
server.start();
// 分岐したスレッドを残しスクリプト実行環境が終わってしまうためカレントスレッドをサスペンドする
java.lang.Thread.currentThread().suspend()
動作の流れは、以下。
フィルタは以下のようにコンテキストへ追加する。
var filter = new Packages.com.sun.net.httpserver.Filter({
destroy : function(context){},
init : function(context){},
description : function(context){},
doFilter : function(exchange, chain){
print("PRE-PROCESS");
chain.doFilter(exchange);
print("POST-PROCESS");
}
});
context.filters.add(filter);
しかし、Mustang添付のスクリプト補助クラスJavaAdapteにバグがあり、抽象クラスを継承して無名クラスを作ることができない。
java.awt.event.ActionListenerなど、インターフェイスの実装クラスは問題なく生成できる。
RhinoのJavaAdapteに比べてコードが極端に短いため、開発途中かまたは代替手段が提供されるのかもしれない。
当然だが、今の時点でMustangを使うのは手間がかかる。
現段階では、逆にJSAdapterなどのMustangの便利なものをRhinoへ持ち返り、一般に手に入るHTTPサーバープロダクトなどと組み合わせるのが現実的なように感じた。
ということで、引き続きサーバーシリーズ、Tiny Java Web Server、MINA、Jettyなどを調べようと思う。
蛇足。
J2SE 5.0から導入されたConcurrency Utilitiesの利用方法を以下の書籍で確認した。
セマフォ、カウントダウンラッチ、サイクリックバリア、エクスチェンジャなどのマルチスレッドパターンが、わかりやすい例えを基に記述され大変わかりやすく、勉強になった。
進化するJava J2SE5.0 (エクスメディアライブラリ)