GraalVM JavaScriptおよびNode.jsランタイム

GraalVMは、JavaScriptおよびNode.jsアプリケーションを実行するためのECMAScript準拠のランタイムです。完全に標準に準拠しており、アプリケーションを高いパフォーマンスで実行できます。また、言語の相互運用性や共通ツールなど、GraalVMスタックのすべての利点を享受できます。このリファレンス・ドキュメントでは、使用可能なJavaScriptエンジン構成、Node.jsランタイム、ScriptEngine実装、マルチスレッド・サポートの詳細、考えられる埋込みシナリオなどについて説明します。これまでNashornエンジンまたはRhinoエンジンにターゲット指定していたコードを移行できるように、移行ガイドが用意されています

スタート・ガイド

GraalVM for JDK 21では、JavaScript (GraalJS)およびNode.jsランタイムはスタンドアロン・ディストリビューションとして使用できます。Oracle GraalVMとGraalVM Community Editionの両方で、ネイティブ・イメージ・コンパイル済ネイティブ・ランチャまたはJVMベースのランタイム(付属)の2つのスタンドアロン言語ランタイム・オプションを使用できます。これらを区別できるよう、GraalVM Community Editionバージョンの名前には、graaljs-community-<version>-<os>-<arch>.tar.gzgraalnodejs-community-<version>-<os>-<arch>.tar.gzのように、接尾辞-communityが付いています。JVMに付属するスタンドアロンの名前には、-jvm接尾辞が付いています。

  1. GitHubリリースに移動し、オペレーティング・システムに適したスタンドアロンを選択します。

  2. アーカイブを解凍します:

    ノート: macOS Catalina以降を使用している場合は、最初に隔離属性を削除します。

     sudo xattr -r -d com.apple.quarantine <archive>.tar.gz
    

    解凍:

     tar -xzf <archive>.tar.gz
    

    または、ファインダでファイルを開きます。

  3. バージョンをチェックして、ランタイムがアクティブかどうかを確認します。

     ./path/to/bin/js --version
    
     ./path/to/bin/node --version
    

JavaScriptの実行

jsランチャを使用して、プレーンJavaScript (ECMAScript)コードを実行します。

js [options] [filename...] -- [args]

Node.jsの実行

Node.jsスタンドアロンでは、nodeおよびnpmランチャが提供されます。

nodeユーティリティを使用して、Node.jsアプリケーションを実行します:

node [options] [filename] [args]

npmコマンドは、デフォルトのNode.jsコマンドと同等で、すべてのNode.js APIをサポートします。

  1. 次のように、npm installを使用してcolorsおよびansispanパッケージをインストールします:
     npm install colors ansispan
    

    インストールしたパッケージは、アプリケーションから使用できます。

  2. 次のコード・スニペットを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);
    
  3. 次のように、GraalVMでnodeコマンドを使用して実行します:
     node app.js
    

Node.jsの実行の詳細は、「Node.jsランタイム」を参照してください。Node.js機能は、アプリケーションがnodeバイナリ・ランチャから起動されたときに使用できます。Node.jsアプリケーションの起動時またはJavaコンテキストからのNPMパッケージへのアクセス時には、特定の制限が適用されます。Node.jsとJavaスクリプト・コンテキストの違いを参照してください。

Javaとの相互運用性

JavaScriptをJavaホスト・アプリケーションに埋め込むには、プロジェクトの依存関係として追加することでJavaScriptを有効にします。JavaScript埋込みのMaven構成を次に示します。

<dependency>
    <groupId>org.graalvm.polyglot</groupId>
    <artifactId>polyglot</artifactId>
    <version>${graalvm.version}</version>
</dependency>
<dependency>
    <groupId>org.graalvm.polyglot</groupId>
    <artifactId>js</artifactId>
    <version>${graalvm.version}</version>
    <type>pom</type>
</dependency>

Oracle GraalVMのJavaScriptランタイムをデフォルトで有効にします。GraalVM Community Editionの上に構築されたアーティファクトが必要な場合は、js-communityを使用します。

JavaScriptからJavaにアクセスするには、次の例のようにJava.typeを使用します:

node
> 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に埋め込まれたJavaScriptコンテキストを評価できますが、Javaコードから直接関数をコールしたり、関数のパラメータを設定することはできません。

Node.jsランタイムはJVMに埋め込むことはできず、別のプロセスとして起動する必要があります。

たとえば、次のコードをapp.jsという名前で保存します:

var HelloPolyglot = Java.type("HelloPolyglot");

HelloPolyglot.main(["from node.js"]);

console.log("done");

その後、実行します。

node --vm.cp=. app.js
Hello Java!
hello from node.js
done

Node.jsとJVMの両方が同じプロセスで実行され、相互運用性は前述と同じValueクラスを使用して機能します。

言語の相互運用性の詳細は、「Javaの相互運用性」ガイドを参照してください。

その他のドキュメント

追加情報については、次のドキュメントを参照してください。

GraalVM JavaScriptの使用:

レガシー環境:

Node.jsサポート: