GraalVM JavaScriptの実装
GraalVMは、JavaScriptおよびNode.jsアプリケーションを実行するためのECMAScript準拠のランタイムです。完全に標準に準拠しており、アプリケーションを高いパフォーマンスで実行できます。また、言語の相互運用性や共通ツールなど、GraalVMスタックのすべての利点を享受できます。このリファレンス・ドキュメントでは、使用可能なJavaScriptエンジン構成、Node.jsランタイム、javax.script.ScriptEngine
実装、マルチスレッド・サポートの詳細、考えられる埋込みシナリオなどについて説明します。これまでNashornエンジンまたはRhinoエンジンにターゲット指定していたコードを移行できるように、移行ガイドが用意されています。
JavaScriptの実行
GraalVM 22.2以降、JavaScriptサポートは別個のGraalVMコンポーネント内にパッケージ化されています。これはGraalVMアップデータを使用してインストールできます:
$JAVA_HOME/bin/gu install js
または、次のように、JavaScriptランタイム・コンポーネントをダウンロードし、ファイルからインストールすることもできます:
$JAVA_HOME/bin/gu install --file ~/Downloads/js-...-.jar
これにより、$JAVA_HOME/bin
ディレクトリにjs
がインストールされます。JavaScriptコンポーネントがインストールされている場合、GraalVMでは、プレーンJavaScript (ECMAScript)コードを実行できます:
$JAVA_HOME/bin/js [options] [filename...] -- [args]
GraalVM JavaScriptと既存の標準およびエンジンとの互換性の詳細は、「JavaScriptの互換性」を参照してください。
Node.jsの実行
GraalVMは、変更されていないNode.jsアプリケーションを実行できます。アプリケーションでは、npmモジュール(ネイティブ・モジュールを含む)をインポートできます。GraalVM 21.1以降、Node.jsサポートは別個のGraalVMコンポーネント内にパッケージ化されています。これはGraalVMアップデータを使用してインストールできます:
$JAVA_HOME/bin/gu install nodejs
または、次のように、Node.jsランタイム・コンポーネントをダウンロードし、ファイルからインストールすることもできます:
$JAVA_HOME/bin/gu install --file ~/Downloads/nodejs-installable-...-.jar
これにより、node
およびnpm
ランチャが$JAVA_HOME/bin
ディレクトリにインストールされます。node
ユーティリティを使用して、Node.jsアプリケーションを実行します:
node [options] [filename] [args]
Node.jsパッケージをインストールするには、$JAVA_HOME/bin
のnpm
ランチャを使用します。npm
コマンドは、デフォルトのNode.jsコマンドと同等で、すべてのNode.js APIをサポートします。
- 次のように、
npm install
を使用してcolors
およびansispan
パッケージをインストールします:npm install colors ansispan
インストールしたパッケージは、アプリケーションから使用できます。
- 次のコード・スニペットを
app.js
という名前のファイルに追加し、Node.jsパッケージをインストールしたディレクトリに保存します:const http = require("http"); const span = require("ansispan"); require("colors"); http.createServer(function (request, response) { response.writeHead(200, {"Content-Type": "text/html"}); response.end(span("Hello Graal.js!".green)); }).listen(8000, function() { console.log("Graal.js server running at http://127.0.0.1:8000/".red); }); setTimeout(function() { console.log("DONE!"); process.exit(); }, 2000);
- 次のように、GraalVMで
node
コマンドを使用して実行します:node app.js
Node.jsの実行の詳細は、「Node.jsランタイム」を参照してください。Node.js機能は、アプリケーションがnode
バイナリ・ランチャから起動されたときに使用できます。Node.jsアプリケーションの起動時またはJavaコンテキストからのnpmパッケージへのアクセス時には、特定の制限が適用されます。Node.jsとJavaスクリプト・コンテキストの違いを参照してください。
相互運用性
GraalVMは、Ruby、R、Python、LLVMなどの他のいくつかのプログラミング言語をサポートしています。GraalVMはNode.jsおよびJavaScriptアプリケーションを実行するように設計されていますが、これらの言語間の相互運用性にも対応し、GraalVMポリグロットAPIを使用すればこれらのうち任意の言語でコードを実行したり、メソッドをコールできます。
Node.jsまたはJavaScriptと他の言語との相互運用性を有効にするには、--jvm
および--polyglot
オプションを渡します。たとえば:
node --jvm --polyglot
Welcome to Node.js v16.14.2.
Type ".help" for more information.
> var array = Polyglot.eval("python", "[1,2,42,4]")
> console.log(array[2]);
42
> console.log(Polyglot.eval('R', 'runif(100)')[0]);
0.8198353068437427
他のプログラミング言語との相互運用性の詳細は、「ポリグロット・プログラミング」を参照してください。
Javaとの相互運用性
JavaScriptからJavaにアクセスするには、次の例のようにJava.type
を使用します:
node --jvm
> var BigInteger = Java.type('java.math.BigInteger');
> console.log(BigInteger.valueOf(2).pow(100).toString(16));
10000000000000000000000000
その逆に、JavaからJavaScriptを実行するには、JavaScriptコンテキストをJavaプログラムに埋め込みます:
import org.graalvm.polyglot.*;
import org.graalvm.polyglot.proxy.*;
public class HelloPolyglot {
static String JS_CODE = "(function myFun(param){console.log('hello '+param);})";
public static void main(String[] args) {
System.out.println("Hello Java!");
try (Context context = Context.create()) {
Value value = context.eval("js", JS_CODE);
value.execute(args[0]);
}
}
}
関数定義をラップすると(()
)、関数がすぐに返されます。ソース・コード単位は、例に示すように文字列で表したり、ファイル、URLからの読取りおよびその他の方法を通じて表すことができます。
前述のJavaプログラムを実行します:
javac HelloPolyglot.java
java HelloPolyglot JavaScript
これにより、Javaに埋め込まれたJavaScriptコンテキストを評価できますが、Javaコードから直接関数をコールしたり、関数のパラメータを設定することはできません。Node.jsランタイムはJVMに埋め込むことはできず、別のプロセスとして起動する必要があります。
たとえば、次のコードをapp.jsという名前で保存します:
var HelloPolyglot = Java.type("HelloPolyglot");
HelloPolyglot.main(["from node.js"]);
console.log("done");
次に、--jvm
オプションを指定してnode
を起動し、Javaとの相互運用性を有効にします:
node --jvm --vm.cp=. app.js
Hello Java!
hello from node.js
done
クラスパスを設定することで、JVMが適切に起動するようにnode
に指示します。Node.jsとJVMの両方が同じプロセスで実行され、相互運用性は前述と同じValue
クラスを使用して機能します。
言語の相互運用性の詳細は、「Javaの相互運用性」ガイドを参照してください。
その他のドキュメント
詳細は、GraalVM JavaScriptに関する特定のトピックのドキュメント・ページを参照してください:
GraalVM JavaScriptの使用:
レガシー環境:
Node.jsサポート: