Node.js 與 Java 嵌入之間的差異

GraalVM 提供完全符合 ECMAScript 2024 標準的 JavaScript 執行階段。因此,它可以在各種嵌入情境中執行 JavaScript 程式碼,包括 Oracle 資料庫、任何基於 Java 的應用程式,以及 Node.js。

根據嵌入情境,應用程式可以存取不同的內建功能。例如,使用 GraalVM 的 bin/node 可執行檔執行的 Node.js 應用程式可以存取所有 Node.js 的 API,包括 fshttp 等內建 Node.js 模組。相反地,嵌入在 Java 應用程式中的 JavaScript 程式碼只能存取有限的功能,這些功能透過 Context API 指定,並且無法存取 Node.js 內建模組。

本指南描述 Node.js 應用程式與嵌入在 Java 應用程式中的 JavaScript 之間的主要差異。

內容建立 #

在 GraalVM 中,可以使用執行內容來執行 JavaScript 程式碼。

在 Java 應用程式中,可以使用 Context API 建立新的內容。可以透過多種方式設定新的內容,設定選項包括公開對 Java 類別的存取、允許存取 IO 等等。可以在 API 文件中找到內容建立選項的列表。在這種情況下,可以使用 GraalVM 的 Polyglot Bindings 將 Java 類別公開給 JavaScript。

在 Node.js 應用程式中,執行應用程式的 GraalVM Context 由 Node.js 執行階段預先初始化,並且無法由使用者應用程式設定。在這種情況下,可以使用 bin/node 命令的 --vm.cp= 命令列選項,將 Java 類別公開給 Node.js 應用程式,如下所述。

Java 互通性 #

JavaScript 應用程式可以使用 Java 內建物件與 Java 類別互動。這個物件在 jsnode 啟動器中預設可用,但僅在 JVM 獨立執行個體(名稱中帶有 -jvm)中可以存取 Java 類別。

使用 Polyglot API 嵌入 JavaScript 時,必須在 Context.Builder (allowHostAccessallowHostClassLookup) 中明確啟用主機存取。有關 JavaScript-Java 互通性的更多詳細資訊,請參閱Java 互通性指南

多執行緒 #

執行 JavaScript 的多語言 Context 強制執行「無共享」平行處理模型:沒有 JavaScript 值可以同時被兩個並行的 Java 執行緒存取。為了利用平行執行,必須從多個執行緒建立和執行多個內容。

  1. 在 Node.js 模式中,可以使用 Node.js 的 Worker 執行緒 API 建立多個內容。Worker 執行緒 API 可確保兩個平行內容之間不會發生共享。
  2. 在 Java 中,可以從多個執行緒執行多個內容。只要兩個執行緒不同時存取內容,就會安全地進行平行執行。

有關 GraalJS 中平行執行的更多詳細資訊,請參閱 這篇部落格文章

Java 程式庫 #

可以透過 Java 內建物件從 GraalJS 存取 Java 程式庫。為了使 Java 程式庫可以從 Context 存取,必須將其 JAR 檔案新增到類別路徑中。可以透過以下方式完成

  1. 在 Node.js 模式中,可以使用 --vm.cp 選項修改類別路徑。
  2. 在 Java 中,可以使用預設的 Java -cp 選項。

請參閱 命令列選項,以了解更多資訊。

JavaScript 套件和模組 #

許多流行的 JavaScript 模組,例如在 npm 套件註冊表中提供的那些模組,可以從 Node.js 以及 Java 中使用。

  1. 在 Node.js 模式中,JavaScript 模組由 Node.js 執行階段處理。因此,GraalJS 支援 Node.js 支援的所有模組(包括 ES 模組、CommonJS 模組和原生模組)。
  2. 在 Java 模式中,GraalJS 可以執行任何不依賴於原生 Node.js 內建模組(例如 fshttp 等)的 JavaScript 模組或套件。可以使用套件捆綁器或使用可用的內建 ES 模組機制來載入模組。在 Java 模式下,實驗性選項支援 CommonJS 模組。

有關 JavaScript 模組的更多詳細資訊,請參閱 模組

與我們聯繫