X

An Oracle blog about WebLogic Channel

Java SE 8の新JavaScriptエンジン「Nashorn」が実現する次世代の “JavaScript in Java”環境【Java EEエキスパート・シリーズ】

Guest Author

2013年夏の正式リリースが予定されるJava SE 8では、ラムダ式の導入やJavaFXの統合など、数多くの新機能追加が計画されている。それらの中でも注目を集めていることの1つが、新JavaScriptエンジン「Nashorn(ナスホーン)」の搭載だ。高速化と軽量化を同時に実現するとされるNashornにより、JavaのJavaScript環境はどう変わるのだろうか(編集部)。

「Java EEエキスパート・シリーズ」は、WebLogic ServerユーザーをはじめとするJava EE開発者に対し、Java EEに関する最新の技術情報をお届けする技術解説シリーズです。

JavaでJavaScriptを使う理由


 まず初めに、一部の読者が抱くかもしれない疑問に改めて答えることから始めよう。その疑問とは、「なぜ、Java環境でJavaScriptを使いたいというニーズがあるのか」というものだ。主な理由は次のとおりである。


●Javaに用意された膨大なライブラリやツール・セットをJavaScriptから使いたい

●JavaScriptを使って迅速にプロトタイピングを行いたい

●JavaScriptを利用してビジネス・プロセスを統合したい(BPELでオーケストレーションするのではなく、JavaScriptによってプロセス・フローをセットアップする)

●JavaScriptにより、サービスを組み合わせた開発(コンポジット開発)を行いたい


 また、そもそも数あるスクリプト言語の中で、なぜJavaScriptを使うのかというと、「今日、JavaScriptが最も広く利用されているスクリプト言語だから」という事実のほかに、次のような理由が挙げられる。


●他のスクリプト言語と比べて、実現できる機能が多彩である

●クライアント・サイド(JavaFX)でもサーバ・サイド(CommonJS、Node.js)でも、アプリケーションを書くことができる


 そのうえ、JavaScriptはJavaと構文が似ており、Javaコード内に書かれていても自然で違和感がないということも、Javaコミュニティやオラクルが同言語に注力する理由の1つとなっている。

現状のJavaScriptエンジン「Rhino」の特徴


 Javaは、すでにJava SE 6からJavaScriptをサポートしており、現バージョンのJava SE 7には、Mozillaファウンデーションが開発した「Rhino」というJavaScriptエンジンが搭載されている。そして、2013年にリリース予定のJava SE 8では、そのRhinoが新たなJavaScriptエンジンであるNashornによって置き換えられることになっている。


 それでは、なぜRhinoをNashornに置き換えるのか。Rhinoが抱える問題点の1つは、「エンジンを見つけにくいこと」だ。Java SE 7では、Rhinoを呼び出すのにScripting API(パッケージjavax.script)を使う。つまり、スクリプト・エンジン・マネジャを呼び出し、すべてのエンジンの中から使えるエンジンを検索し、サービス・ローダ機構によってJavaScriptエンジンを探し出す。エンジンが見つかったらスクリプトを渡し、関数evalによって実行値が返される。スクリプトのサイズが大きい場合には、ネットワークではなくファイルシステムからロードすることもできる。

【Java SE 7でRhinoを使うコード】

ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByExtension(“js”);
e.eval(“print('hello')”);
// or using a reader
e.eval(new InputStreamReader(...));


 そのほか、メソッドgetEngineByNameによって直接Rhinoを指定したり、インストール済みのすべてのエンジンをリストアップする方法を使ったりすることもできる。


 また、Rhinoでは、JavaScriptの中にJavaインタフェースをコールバック用に実装することも可能だ。

var runnable = new java.lang.Runnable({
run: function() { console.log('running'); }
});
var executor = java.util.concurrent.Executors.newCachedThreadPool();
executor.submit(runnable);

新JavaScriptエンジンのNashornは“近代的なサイ(Rhino)”


 それでは、Rhinoに代わってJava SEに導入されるNashornでは、何ができるようになるのだろうか。


 Nashornは、オラクルの社内プロジェクトとして2010年10月にスタートし、現在、Java SE 8での導入に向けて開発が進められている。ECMAScript-262に準拠しており、オラクル製のJVM上で動作する。すべてがJavaで書かれているという点は、Nashornの大きな特徴の1つである。なお、この名前はドイツ語の「サイ(Rhino)」に由来しており、「Rhinoをより近代化したもの」という意味も込められている。


 現在、Nashornは次のような要件を満たすことを目標に開発が進められている。


●Javaと同等のパフォーマンスを発揮する

●JavaBeansやCollectionなど、Java開発者が慣れ親しんだAPIをそのまま使える

●Javaのサンドボックスを壊すことなく、JavaScriptをセキュアに実行できる

●「Java-JavaScript」間でシームレスにデバッグできる(ハイブリッドでブレークポイントにも対応)

●JVMの���能を活用し、プロファイルを遠隔で監視可能にする

●エンタープライズのニーズに応える


 また、Nashornの開発にあたり、開発チームでは次の事項を順守するよう心掛けている。


●コンプライアンス:ECMAScript-262 Edition 5に準拠する

●正確性:JavaScriptの互換性検証用テスト・スイート「Test 262」によって検証を行う

●高いパフォーマンス:“より速く”を徹底して追求する


 なお、Nashornには新たなAPIは含まれず、既存のJavaScript APIをRhinoから継承して使うことを想定している。

JavaScriptの呼び出しが、よりスマートかつ高速に


 Nashornに関して開発者が特に注目しているのは、「どのようにしてJavaScriptが実行されるのか」という点だろう。その仕組みは次のようになる。


●JavaScriptを、いったんAST/IR(抽象構文木/中間表現)という中間生成物に変換し、そこからASMを使ってJavaバイトコードを生成する(JavaScriptがJavaバイトコードになる)

●したがって、JavaScriptがネーティブにJVM上で動作する。パフォーマンスにも支障がない

●HotSpot VMがインタープリタとして動作する

●JavaプログラムからJavaScriptを呼び出す際にも、JavaScriptがJavaバイトコードに変換されるので、効率的でセキュアな呼び出しが行える

●動的言語のJVM実装を支援するバイトコードであるInvokeDynamicやMethodHandlerを使うことにより、パフォーマンスの向上が得られる


 なお、NashornにおけるJavaとJavaScriptの各型の対応関係は、次のようになる。































JavaScriptJava
NumberDouble
StringString
BooleanBoolean
未定義 Singleton Object
ArrayWrapper Object+Object[]
ObjectMap



 また、Nashornではオブジェクトを表すScriptObjectがルート・クラスとなり、次の3つのプロパティを持つ。


●Map:オブジェクト・プロパティを格納

●Prototype:未定義のプロパティを委譲

●Spill:動的なプロパティ値を格納


 それでは、JavaScriptからJavaコードが呼び出された際には、どのような流れで動作するのだろうか。Javaコードが呼び出された際、それがNashornオブジェクトでない場合には、Javaオブジェクトとして扱われることになる。したがって、フィールドや配列へのアクセスも透過的に行える。メソッド呼び出しでは、引数が正しいかたちに変換され、メソッド・オーバー・ローディングもサポートされる。get/setメソッドとしては、JavaBeansのgetty/settyメソッドが使われる。


 逆にJava側からJavaScriptを呼び出す際には、NashornオブジェクトはMapオブジェクトとして扱われ、Rhinoと同様にScripting APIを使うことができる。


 セキュリティに関しては、“バイトコードからバイトコードへのアクセス”となるため、別のインタープリタを用意する必要はない。JavaScriptの関数loadを使ってURLを読み込んだとしても、パーミッションを細かく指定できるので、アクセスを拒否するといったことも可能だ。また、JavaScriptのコンテキストは個別のクラスローダでロードされるので、独立性を確保できる。


 以上のような特徴を備えるNashornは、果たしていつごろ使えるようになるのか? OpenJDKプロジェクトの一環としてオープンソースで公開される予定はあるが、その時期はまだ未定だ。開発が順調に進めばJava SE 8にRhinoを置き換えるかたちで同梱され、NetBeansをサポートすることも予定されている。

本記事は、2012年4月に開催されたJavaOne Tokyo 2012における米国オラクル・コーポレーション Java Language and Tools group Principal Member of Technical Staff Akhil Arora氏のセッション「The Future of JavaScript in the JDK」の内容を基に作成しています。

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
Oracle

Integrated Cloud Applications & Platform Services