layout | toc_group | link_title | permalink |
---|---|---|---|
docs |
js |
Differences Between Node.js and Java Embeddings |
/reference-manual/js/NodeJSvsJavaScriptContext/ |
GraalVM provides a fully-compliant ECMAScript 2024 JavaScript runtime. As such, it can run JavaScript code in a variety of embedding scenarios, including Oracle Database, any Java-based application, and Node.js.
Depending on the embedding scenario, applications have access to different built-in capabilities.
For example, Node.js applications executed using GraalVM's bin/node
executable have access to all of Node.js' APIs, including built-in Node.js modules such as fs
, http
, and so on.
Conversely, JavaScript code embedded in a Java application has access to limited capabilities, as specified through the Context API, and do not have access to Node.js built-in modules.
This guide describes the main differences between a Node.js application and JavaScript embedded in a Java application.
JavaScript code in GraalVM can be executed using an execution context.
In a Java application, a new context can be created using the Context
API.
New contexts can be configured in multiple ways, and configuration options include exposing access to Java classes, allowing access to IO, and so on.
A list of context creation options can be found in the API documentation.
In this scenario, Java classes can be exposed to JavaScript by using GraalVM's Polyglot Bindings
.
In a Node.js application, the GraalVM Context
executing the application is pre-initialized by the Node.js runtime, and cannot be configured by the user application.
In this scenario, Java classes can be exposed to the Node.js application by using the --vm.cp=
command line option of the bin/node
command, as described below.
JavaScript applications can interact with Java classes using the Java
built-in object.
This object is available by default in the js
and node
launchers, but accessing Java classes is only possible in the JVM standalone (that have -jvm
in the name).
When embedding JavaScript using the Polyglot API, you have to explicitly enable host access in the Context.Builder
(allowHostAccess
, allowHostClassLookup
).
More details on the JavaScript-Java interoperability are available in the Java Interoperability guide.
A polyglot Context
running JavaScript enforces a "share-nothing" model of parallelism: no JavaScript values can be accessed by two concurrent Java threads at the same time.
In order to leverage parallel execution, multiple contexts have to be created and executed from multiple threads:
- In Node.js mode, multiple contexts can be created using Node.js' Worker threads API. The Worker threads API ensures that no sharing can happen between two parallel contexts.
- In Java, multiple contexts can be executed from multiple threads. As long as a context is not accessed by two threads at the same time, parallel execution happens safely.
More details on parallel execution in GraalJS are available in this blog post.
Java libraries can be accessed from GraalJS through the Java
built-in object.
In order for a Java library to be accessible from a Context
, its JAR files need to be added to the class path.
This can be done in the following way:
- In Node.js mode, the class path can be modified using the
--vm.cp
option. - In Java, the default Java's
-cp
option can be used.
Read more in Command-line Options.
Many popular JavaScript modules such as those available on the npm
package registry can be used from Node.js as well as from Java:
- In Node.js mode, JavaScript modules are handled by the Node.js runtime. Therefore, GraalJS supports all modules supported by Node.js (including ES modules, CommonJS modules, and native modules).
- In Java mode, GraalJS can execute any JavaScript module or package that does not depend on native Node.js built-in modules (such as
fs
,http
, and so on). Modules can be loaded using a package bundler, or using the available built-in mechanisms for ES modules. CommonJS modules are supported in Java mode under an experimental option.
More details on JavaScript modules are available in Modules.