Node.jsとJava埋込みの違い

GraalVMは、完全準拠のECMAScript 2020 JavaScript言語ランタイムです。そのため、Oracle Database、Javaベースのアプリケーション、Node.jsなど、様々な埋込みシナリオでJavaScriptコードを実行できます。

GraalVMのJavaScript埋込みシナリオに応じて、アプリケーションでは様々な組込み機能にアクセスできます。たとえば、GraalVMのbin/node実行可能ファイルを使用して実行されたNode.jsアプリケーションは、fshttpなどの組込みNode.jsモジュールを含むすべてのNode.js APIにアクセスできます。逆に、Javaアプリケーションに埋め込まれたJavaScriptコードは、Context APIを介して指定された制限付きの機能にアクセスでき、Node.js組込みモジュールにはアクセスできません。

このガイドでは、Node.jsアプリケーションとJavaに埋め込まれたGraalVM JavaScriptアプリケーションの主な違いについて説明します。

コンテキストの作成

GraalVMのJavaScriptコードは、GraalVM実行コンテキストを使用して実行できます。

Javaアプリケーションでは、Context APIを使用して新しいコンテキストを作成できます。新しいコンテキストは複数の方法で構成でき、構成オプションにはJavaクラスへのアクセスの公開、IOへのアクセスの許可などが含まれます。コンテキスト作成オプションのリストは、APIドキュメントを参照してください。このシナリオでは、GraalVMのポリグロットBindingsを使用して、JavaクラスをJavaScriptに公開できます。

Node.jsアプリケーションでは、アプリケーションを実行するGraalVM ContextはNode.jsランタイムによって事前に初期化されており、ユーザー・アプリケーションでは構成できません。このシナリオでは、次に説明するように、bin/nodeコマンドの--vm.cp=コマンドライン・オプションを使用して、JavaクラスをNode.jsアプリケーションに公開できます。

Javaの相互運用性

JavaScriptアプリケーションでは、Java組込みオブジェクトを使用してJavaクラスと対話できます。オブジェクトはデフォルトでは使用できず、次の方法で有効にできます:

  1. Node.jsモードで、bin/node --jvmコマンドを使用してGraalVMを起動します。
  2. Javaで、次のようにwithHostInterop()オプションを使用してGraalVMコンテキストを作成します:
    Context.create("js").withHostInterop()
    

    GraalVM JavaScriptのJavaの相互運用性機能の詳細は、「Javaの相互運用性」を参照してください。

マルチスレッド

JavaScriptを実行しているGraalVMコンテキストでは、シェアナッシング型のパラレル実行モデルが適用されます: 2つの同時実行JavaスレッドからJavaScript値に同時にアクセスすることはできません。パラレル実行を利用するには、複数のスレッドから複数のコンテキストを作成して実行する必要があります:

  1. Node.jsモードでは、Node.jsのワーカー・スレッドAPIを使用して複数のコンテキストを作成できます。ワーカー・スレッドAPIを使用して、2つのパラレル・コンテキスト間で共有が行われないようにします。
  2. Javaでは、複数のスレッドから複数のコンテキストを実行できます。2つのスレッドから同時にコンテキストにアクセスしないかぎり、パラレル実行は安全に行われます。

GraalVM JavaScriptでのパラレル実行の詳細は、こちらのブログ投稿を参照してください。

Javaライブラリ

Javaライブラリには、GraalVMのJavaScriptからJava組込みオブジェクトを介してアクセスできます。ContextからJavaライブラリにアクセスできるようにするには、そのjarファイルをGraalVMクラスパスに追加する必要があります。これは次の方法で行うことができます:

  1. Node.jsモードでは、--jvm.cpオプションを使用してクラスパスを変更できます。
  2. Javaでは、デフォルトのJavaの-cpオプションを使用できます。

GraalVMコマンドライン・オプションの詳細は、「オプション」を参照してください。

JavaScriptパッケージおよびモジュール

npmパッケージ・レジストリで使用可能なモジュールなど、多くの一般的なJavaScriptモジュールは、Node.jsおよびJavaの両方から使用できます:

  1. Node.jsモードでは、JavaScriptモジュールはNode.jsランタイムによって処理されます。したがって、GraalVM JavaScriptは、Node.jsでサポートされるすべてのモジュール(ESモジュール、CommonJSモジュールおよびネイティブ・モジュールを含む)をサポートしています。
  2. Javaモードでは、GraalVM JavaScriptはネイティブNode.js組込みモジュール('fs''http'など)に依存しない任意のJavaScriptモジュールまたはパッケージを実行できます。モジュールは、パッケージ・バンドラを使用するか、ESモジュールに使用可能な組込みメカニズムを使用してロードできます。CommonJSモジュールは、Javaモードで試験段階のものとしてサポートされています。

JavaScriptモジュールの詳細は、「モジュール」を参照してください。