JSR223を使ってJavaからJavaScriptを実行する時にJavaのクラスを利用する

JSR223スクリプト言語サポートでは、JavaScriptなどのスクリプト言語Javaから利用するためのAPIを提供しています。Java6ではJavaScriptRhino)がサポートされており、ライブラリを使えばJRubyJythonなどが利用できます。
利用方法は簡単です。

    public static void eval(String script) throws ScriptException {
        ScriptEngineManager mng = new ScriptEngineManager();
        ScriptEngine engine = mng.getEngineByName("javascript");
        engine.eval(script);
    }

例えばScriptはこんな感じ。

print("Hello World.");

さらに、JavaScriptの中でJavaのクラスを使う事もできます。

var now = new java.util.Date();
print(now);

これを使えばFile IOなども記述できます。

ところが・・・

new java.io.File("hoge").delete();

のようにファイルを削除しようとすると次のような例外がthrowされます。

sun.org.mozilla.javascript.internal.EvaluatorException: missing name after . operator

javascriptではdeleteは予約語なので、deleteメソッドが気にくわないのでしょう。

解決方法はこうでした。

new java.io.File("hoge")["delete"]();

参考:http://www.mail-archive.com/dev-tech-js-engine-rhino@lists.mozilla.org/msg01258.html

40-プロセス間通信とアプリケーションの応答時間の関係

プログラマが知るべき97のこと」の40個目のエピソードは、リモートプロセス間通信に関する話です。近年のアプリケーションでは、ほとんどのパフォーマンス上のボトルネックはリモートプロセス間通信にあると言っても過言ではありません。ウェブアプリケーションであれば、HTTPリクエスト・データベース呼び出し・他のウェブサービス呼び出しがリモートプロセス間通信に相当します。ハードウェアが高性能になった現在では、ネットワークを経由したリモートコールがボトルネックになっているケースが多いのです。
リモートプロセス間通信のボトルネックを解消するには幾つかの方法があります。まず、リモートプロセス間通信のデータ通信量を減らすことで、必要最低限のデータをやりとりする事があげられます。SQLであればselect句の制御により不要なデータを取得しなければデータ量が減るでしょう。HTTPリクエストであればHTMLのタグを減らす・冗長なXMLJSONは避けるなどの手段があるでしょう。シーケンシャルにリモートプロセス間通信を行えば、全ての処理時間の合計になります。可能であれば同時に複数のリモートプロセス間通信を行う事で改善が望めます。リモートプロセス間通信による取得データが頻繁に変更されないようなデータであれば、キャッシュに保存する事で通信回数を劇的に減らせるでしょう。それまで何回かにわけて取得していたデータを1回で取得できるようにできればリモートプロセス間通信は最小限にすることができます。
Google App Engineによる開発では、これらのチューニングが非常に重要なトピックとして知られています。何故ならば、リモートプロセス間通信のデータ量と回数はコストに直結するからです。さらに、プラットフォームの制約でDatastoreに対してSQLのような部分的なselectができないため、必要最低限のデータのみを格納するカインドを別途用意することもあります。これはデータ量は冗長になったとしてもDatastore APIを効率良く消費するための手法です。
アプリケーションの応答時間ユーザビリティに直結します。スケールする事を求められるアプリケーションであれば、コストにも直結する重要な要素です。

プログラマが知るべき97のこと

プログラマが知るべき97のこと