You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Running JavaScript on GraalVM supports multithreading.
4
4
Depending on the usage scenario, threads can be used to execute parallel JavaScript code using multiple [`Context`](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Context.html) objects, or multiple [Worker](https://nodejs.org/api/worker_threads.html) threads.
5
5
6
6
## Multithreading with Java and JavaScript
7
7
8
-
GraalVM JavaScript supports multithreading in the context of Java interoperability.
9
-
The basic model of multi-threaded execution supported by GraalVM JavaScript is a "share-nothing" model that should be familiar to any JavaScript developer:
8
+
Multithreading is supported when running JavaScript in the context of Java interoperability.
9
+
The basic model of multi-threaded execution supported by GraalVM is a "share-nothing" model that should be familiar to any JavaScript developer:
10
10
11
-
1. An arbitrary number of JS`Context`s can be created, but they should be used by one thread at a time.
11
+
1. An arbitrary number of JavaScript`Context`s can be created, but they should be used by one thread at a time.
12
12
2. Concurrent access to JavaScript objects is not allowed: any JavaScript object cannot be accessed by more than one thread at a time.
13
13
3. Concurrent access to Java objects is allowed: any Java object can be accessed by any Java or JavaScript thread, concurrently.
14
14
15
-
A JavaScript `Context` cannot be accessed by two or more threads, concurrently.
16
-
It is however possible to access a same `Context` from multiple threads using proper syncronization, to ensure that concurrent access never happens.
15
+
A JavaScript `Context` cannot be accessed by two or more threads, concurrently, but it is possible to access the same `Context` from multiple threads using proper syncronization, to ensure that concurrent access never happens.
17
16
18
-
####Examples
17
+
### Examples
19
18
20
19
The GraalVM JavaScript [unit tests](https://github.com/graalvm/graaljs/tree/master/graal-js/src/com.oracle.truffle.js.test.threading/src/com/oracle/truffle/js/test/threading) contain several examples of multi-threaded Java/JavaScript interactions.
21
20
The most notable ones describe how:
@@ -28,16 +27,16 @@ The most notable ones describe how:
28
27
29
28
## Multithreading with Node.js
30
29
31
-
The basic multi-threading model of GraalVM JavaScript applies to Node.js applications as well.
32
-
In Node.js, a [Worker](https://nodejs.org/api/worker_threads.html#worker_threads_worker_threads) thread can be created to execute JavaScript code in parallel, but JavaScript objects cannot be shared between workers.
33
-
On the contrary, a Java object created with GraalVM Java interoperability (e.g., using `Java.type()`) _can_ be shared between Node.js workers.
30
+
The basic multithreading model of GraalVM JavaScript applies to Node.js applications as well.
31
+
In Node.js, a [Worker](https://nodejs.org/api/worker_threads.html#worker_threads_worker_threads) thread can be created to execute JavaScript code in parallel, but JavaScript objects cannot be shared between Workers.
32
+
On the contrary, a Java object created with GraalVM Java interoperability (e.g., using `Java.type()`) can be shared between Node.js Workers.
34
33
This allows multi-threaded Node.js applications to share Java objects.
35
34
36
-
####Examples
35
+
### Examples
37
36
38
37
The GraalVM Node.js [unit tests](https://github.com/graalvm/graaljs/tree/master/graal-nodejs/test/graal/unit) contain several examples of multi-threaded Node.js applications.
39
38
The most notable examples show how:
40
39
41
40
1.[Node.js worker threads can execute Java code](https://github.com/graalvm/graaljs/blob/master/graal-nodejs/test/graal/unit/worker.js).
42
41
2.[Java objects can be shared between Node.js worker threads](https://github.com/graalvm/graaljs/blob/master/graal-nodejs/test/graal/unit/javaMessages.js).
43
-
3.[JavaScript `Promise` objects can be used to `await` on messages from workers, using Java objects to bind promises to worker messages](https://github.com/graalvm/graaljs/blob/master/graal-nodejs/test/graal/unit/workerInteropPromises.js)
42
+
3.[JavaScript `Promise` objects can be used to `await` on messages from workers, using Java objects to bind promises to worker messages](https://github.com/graalvm/graaljs/blob/master/graal-nodejs/test/graal/unit/workerInteropPromises.js).
GraalVM's Node.js is based on a recent version of Node.js, and runs the GraalVM JavaScript engine instead of Google V8. Thus, some internal features (e.g., VM-internal statistics or configuration, profiling, debugging, etc.) are unsupported, or supported with potentially different behavior.
13
+
GraalVM's Node.js runtime is based on a recent version of Node.js, and runs the
14
+
GraalVM JavaScript engine instead of Google V8. Thus, some internal features (e.g.,
15
+
VM-internal statistics, configuration, profiling, debugging, etc.) are
16
+
unsupported, or supported with potentially different behavior.
14
17
15
-
The `node`executable is largely compatible with Node.js, and features additional GraalVM-specific functionalities (e.g., interoperability with Java and all other GraalVM languages).
18
+
The `node`command is largely compatible with Node.js, and features additional GraalVM-specific functionalities (e.g., interoperability with Java and all other GraalVM languages).
16
19
A list of available options can be obtained with `node --help`.
17
20
18
21
## Installing Packages Using `npm`
19
22
20
-
To install a Node.js package, you can use the `npm`executable in the `$GRAALVM_HOME/bin` folder of GraalVM.
21
-
The `npm`executable is equivalent to the default NPM command, and supports most of its options.
23
+
To install a Node.js package, you can use the `npm`launcher from the GraalVM's `/bin` folder.
24
+
The `npm`command is equivalent to the default NPM command, and supports most of its options.
22
25
23
26
An NPM package can be installed with:
24
-
```
27
+
```shell
25
28
$GRAALVM_HOME/bin/npm install <package>
26
29
```
27
-
As the `npm` executable of GraalVM is largely compatible with NPM, packages will be installed in the `node_modules` folder, as expected.
30
+
31
+
As the `npm` command of GraalVM is largely compatible with NPM, packages will be installed in the `node_modules` folder, as expected.
28
32
29
33
### Installing `npm` Packages Globally
30
34
@@ -33,7 +37,7 @@ By default, `npm` installs global packages in the path where the `node` executab
33
37
In GraalVM, this means that global packages will create files in the GraalVM folder.
34
38
To avoid writing to the GraalVM folder, the default global installation folder of `npm` can be modified by setting the `$PREFIX` environment variable, or by specifying the `--prefix` option when running `npm install`.
35
39
For example, the following command will install global packages in the `/foo/bar` folder:
Copy file name to clipboardExpand all lines: docs/user/NodeJSVSJavaScriptContext.md
+29-37Lines changed: 29 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,11 +1,12 @@
1
1
# Differences Between Node.js and Java Embeddings
2
2
3
-
GraalVM's JavaScript engine is a fully-compliant ECMA2020 language runtime.
4
-
As such, it can run JavaScript code in a variety of embedding scenarios, including the Oracle [RDBMS](https://www.graalvm.org/docs/examples/mle-oracle/), any Java-based application and Node.js.
3
+
GraalVM provides a fully-compliant ECMAScript 2020 JavaScript language runtime.
4
+
As such, it can run JavaScript code in a variety of embedding scenarios, including the Oracle [RDBMS](https://www.graalvm.org/docs/examples/mle-oracle/), any Java-based application, and Node.js.
5
5
6
6
Depending on the GraalVM's JavaScript embedding scenario, applications have access to different built-in capabilities.
7
-
For example, Node.js applications running on GraalVM's JavaScript engine have access to all of Node.js' APIs, including built-in Node.js' modules such as `'fs'`, `'http'`, etc.
8
-
Conversely, JavaScript code embedded in a Java application has access to limited capabilities, as specified through the [Context API](https://www.graalvm.org/reference-manual/embed-languages/#compile-and-run-a-polyglot-application), and do _not_ have access to Node.js built-in modules.
7
+
For example, Node.js applications running on GraalVM's have access to all of Node.js' APIs, including built-in Node.js modules such as `fs` and `http`, etc.
8
+
9
+
Conversely, JavaScript code embedded in a Java application has access to limited capabilities, as specified through the [Context API](https://www.graalvm.org/reference-manual/embed-languages/#compile-and-run-a-polyglot-application), and do not have access to Node.js built-in modules.
9
10
10
11
This guide describes the main differences between a Node.js application and a GraalVM JavaScript application embedded in Java.
11
12
@@ -27,75 +28,70 @@ In this scenario, Java classes can be exposed to the Node.js application by usin
27
28
JavaScript applications can interact with Java classes using the `Java` built-in object.
28
29
The object is not available by default, and can be enabled in the following way:
29
30
30
-
1. In Node.js, start GraalVM using the `bin/node --jvm` command
31
+
1. In Node.js, start GraalVM using the `bin/node --jvm` command.
31
32
2. In Java, create a GraalVM context using the `withHostInterop()` option, e.g.:
32
-
```
33
+
```java
33
34
Context.create("js").withHostInterop()
34
35
```
35
-
More details on the Java interoperability capabilities of GraalVM JavaScript are available in the [Java Interoperability](https://github.com/graalvm/graaljs/blob/master/docs/user/JavaInteroperability.md) guide.
36
+
More details on the Java interoperability capabilities of GraalVM JavaScript are available in [Java Interoperability](https://github.com/graalvm/graaljs/blob/master/docs/user/JavaInteroperability.md).
36
37
37
38
## Multithreading
38
39
39
40
A GraalVM 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.
40
-
In order to leverage parallel execution, multiple contexts have to be created and executed from multiple threads.
41
+
In order to leverage parallel execution, multiple contexts have to be created and executed from multiple threads:
41
42
42
43
1. In Node.js, multiple contexts can be created using Node.js' [Worker threads](https://nodejs.org/api/worker_threads.html) API.
43
-
The worker threads API ensures that no sharing can happen between two parallel contexts.
44
+
The Worker threads API ensures that no sharing can happen between two parallel contexts.
44
45
2. In Java, multiple contexts can be executed from multiple threads.
45
46
As long as a context is not accessed by two threads at the same time, parallel execution happens safely.
46
47
47
48
More details on parallel execution in GraalVM JavaScript are available in [this blog post](https://medium.com/graalvm/multi-threaded-java-javascript-language-interoperability-in-graalvm-2f19c1f9c37b).
48
49
49
-
50
50
## Java Libraries
51
51
52
52
Java libraries can be accessed from JavaScript in GraalVM through the `Java` built-in object.
53
-
In order for a Java library to be accessible from a `Context`, its `jar` files need to be added to the GraalVM class path.
54
-
This can be done in the following way:
53
+
In order for a Java library to be accessible from a `Context`, its `jar` files need to be added to the GraalVM classpath. This can be done in the following way:
55
54
56
55
1. In Node.js, the classpath can be modified using the `--jvm.cp` option.
57
56
2. In Java, the default Java's `-cp` option can be used.
58
57
59
-
More details on GraalVM command line options are available in the [Options](https://github.com/graalvm/graaljs/blob/master/docs/user/Options.md) guide.
58
+
More details on GraalVM command line options are available in [Options](https://github.com/graalvm/graaljs/blob/master/docs/user/Options.md).
60
59
61
60
## JavaScript Modules
62
61
63
62
Many popular JavaScript modules such as those available on the `npm` package registry can be used from Node.js as well as from Java.
64
63
GraalVM JavaScript is compatible with the latest ECMA standard, and supports ECMAScript modules (ECM).
65
64
CommonJS (CJS) modules are supported when running with Node.js.
66
-
CommonJS modules cannot be used _directly_ from Java; to this end, any popular package bundlers (such as Parcel, Browserify or Webpack) can be used.
65
+
CommonJS modules cannot be used _directly_ from Java; to this end, any popular package bundlers (such as Parcel, Browserify, or Webpack) can be used.
67
66
68
67
### ECMAScript Modules (ECM)
69
-
70
68
ECMAScript modules can be loaded in GraalVM JavaScript in the following ways:
71
69
72
70
1. The support of ECMAScript modules in Node.js is still experimental.
73
-
GraalVM supports all features supported by the Node.js version that is compatible with GraalVM.
74
-
To check such version, simply run `bin/node --version`.
71
+
GraalVM Enterprise supports all features supported by the Node.js version that is compatible with GraalVM.
72
+
To check and verify the version, simply run `bin/node --version`.
75
73
2. ECMAScript modules can be loaded in a `Context` simply by evaluating the module sources.
76
74
Currently, GraalVM JavaScript loads ECMAScript modules based on their file extension.
77
75
Therefore, any ECMAScript module must have file name extension `.mjs`.
78
76
This might change in future versions of GraalVM JavaScript.
79
77
80
-
More details about evaluating files using the Context API are available in the [API Javadoc](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Source.html).
78
+
More details about evaluating files using the Context API are available in the [javadoc](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Source.html).
81
79
82
80
### CommonJS Modules (CJS)
83
-
84
81
CommonJS modules can be loaded in GraalVM JavaScript in the following way:
85
82
86
83
1. In Node.js, modules can be loaded using the `require()` built-in function, as expected.
87
84
2. By default, the `Context` API does not support CommonJS modules, and has no built-in `require()` function.
88
-
In order to be loaded and used from a `Context` in Java, a CJS module needs to be _bundled_ into a self-contained JavaScript source file.
89
-
This can be done using one of the many popular open-source bundling tools such as Parcel, Browserify and Webpack.
85
+
In order to be loaded and used from a `Context` in Java, a CommonJS module needs to be _bundled_ into a self-contained JavaScript source file.
86
+
This can be done using one of the many popular open-source bundling tools such as Parcel, Browserify, and Webpack.
90
87
Experimental support for CommonJS modules can be enabled through the `js.commonjs-require` option as described below.
91
88
92
89
#### Experimental support for CommonJS NPM modules in the `Context` API
93
-
94
90
The `js.commonjs-require` option provides a built-in `require()` function that can be used to load NPM-compatible CommonJS modules in a JavaScript `Context`.
95
91
Currently, this is an experimental feature not for production usage.
96
92
97
93
To enable CommonJS support, a JavaScript context can be created in the following way:
98
-
```
94
+
```java
99
95
Map<String, String> options =newHashMap<>();
100
96
// Enable CommonJS experimental support.
101
97
options.put("js.commonjs-require", "true");
@@ -118,43 +114,39 @@ Value module = cx.eval("js", "require('some-module');");
118
114
```
119
115
120
116
##### Differences with Node.js built-in `require()` function
121
-
122
-
The `Context` built-in `require()` function can load regular NPM modules implemented in JavaScript, but cannot load _native_ NPM modules.
123
-
The built-in `require()` relies on the [Truffle FileSystem](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/io/FileSystem.html), therefore I/O access needs to be enabled at context creation time using the [`allowIO` option](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/Context.Builder.html#allowIO-boolean-).
117
+
The `Context` built-in `require()` function can load regular NPM modules implemented in JavaScript, but cannot load native NPM modules.
118
+
The built-in `require()` relies on the [FileSystem](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/io/FileSystem.html), therefore I/O access needs to be enabled at context creation time using the [`allowIO` option](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/Context.Builder.html#allowIO-boolean-).
124
119
The built-in `require()` aims to be largely compatible with Node.js, and we expect it to work with any NPM module that would work in a browser (e.g., created using a package bundler).
125
120
126
121
##### Installing an NPM module to be used via the `Context` API
127
-
128
122
In order to be used from a JavaScript `Context`, an NPM module needs to be installed to a local folder.
129
123
This can be done using GraalVM JavaScript's `npm install` command like one would normally do for Node.js applications.
130
124
At runtime, the option `js.commonjs-require-cwd` can be used to specify the main installation folder for NPM packages.
131
125
The `require()` built-in function will resolve packages according to the default Node.js' [package resolution protocol](https://nodejs.org/api/modules.html#modules_all_together) starting from the directory specified via `js.commonjs-require-cwd`.
132
126
When no directory is provided with the option, the current working directory of the application will be used.
133
127
134
128
##### Node.js core modules mockups
135
-
136
-
Some JavaScript applications or NPM modules might need functionalities that are available in Node.js' built-in modules (e.g., `'fs'`, `'buffer'`, etc.)
129
+
Some JavaScript applications or NPM modules might need functionalities that are available in Node.js' built-in modules (e.g., `'fs'` and `'buffer'`, etc.).
137
130
Such modules are not available in the `Context` API.
138
-
Thankfully, the Node.js community has developed high-quality JavaScript implementations for many Node.js core modules (e.g.,: the ['buffer'](https://www.npmjs.com/package/buffer) module for the browser).
131
+
Thankfully, the Node.js community has developed high-quality JavaScript implementations for many Node.js core modules (e.g., the ['buffer'](https://www.npmjs.com/package/buffer) module for the browser).
139
132
Such alternative module implementations can be exposed to a JavaScript `Context` using the `js.commonjs-core-modules-replacements` option, in the following way:
As the code suggests, the option instructs the GraalVM JavaScript runtime to load a module called `my-buffer-implementation` when an application attempts to load the Node.js `'buffer'` built-in module using `require('buffer')`.
145
138
146
139
##### Global symbols pre-initialization
147
-
148
140
An NPM module or a JavaScript application might expect certain global properties to be defined in the global scope.
149
141
For example, applications or modules might expect the `Buffer` global symbol to be defined in the JavaScript global object.
150
142
The option `js.commonjs-global-properties` can be used to pre-initialize such global symbols using the `Context` API.
0 commit comments