Get started with GraalVM and configure it to run programs written in Java (orother JVM-based languages), JavaScript and Node.js, Ruby, R, or Python. Thispage guides you through downloading and installing GraalVM and adding supportfor additional languages and/or plugins, and shows you how to run simple programs on GraalVM.
Install GraalVM
GraalVM is a standalone Java Development Kit to execute Java or JVM-basedlanguages (e.g. Scala, Kotlin), dynamic languages (e.g. JavaScript, R, Ruby, R,Python), LLVM-based languages (e.g. C and C++) in one shared runtime, andsupports Linux, macOS and Windows platforms on x86 64-bit systems. Please note, the support for Windows platform is experimental.
GraalVM 19.3.0.2 is available as Community Edition (CE) and Enterprise Edition (EE).GraalVM Community Editions are based on OpenJDK version 1.8.0_232 and on OpenJDK version 11.0.5.GraalVM Enterprise Editions are based on Oracle Java version 1.8.0_231 and on Oracle Java version 11.0.5.Proceed to the GraalVM distributions list to see a complete summary or to the Downloads page and make your choice dependingon the operating system and the use case.
In this getting started guide we will focus on working with GraalVMEnterprise Edition based on JDK 8, obtained from the Oracle Technology Network.The base installation includes the JVM, the GraalVM compiler, the LLVM bitcodeinterpreter, and the JavaScript runtime with Node.js support – all in onepackage. GraalVM environment can be extended with:
- GraalVM Native Image – a technology to compile an application ahead-of-time into a binary that runs natively on the system. Warning: GraalVM Native Image isavailable as an Early Adopter technology.
- R, Ruby and Python languages interpreters. Warning: The support for Ruby, R and Python languages is experimental.
- LLVM toolchain – a set of tools and APIs for compiling native programs tobitcode that can be executed with the GraalVM LLVM runtime.
Getting GraalVM installed and ready-to-go should only take a few minutes. Pleasenote, unlike Java HotSpot VM or OpenJDK distributions for macOS that come as a.dmg file, GraalVM does not provide the installation wizard.
- Navigate to Oracle Technology Network Downloads page and accept the license agreement.
- Select and download Oracle GraalVM Enterprise Edition based on JDK8 for macOS (19.3.0.2).
- Extract the archive to your file system. To extract the file to the current directory from the console, type:
$ tar -xvf archive.tar.gz
- There can be multiple JDKs installed on the machine and the next step is to configure the runtime environment.
- Add the GraalVM
bin
folder to thePATH
environment variable:$ export PATH=<path to GraalVM>/Contents/Home/bin:$PATH
. Verify whether you are using GraalVM with the echo command:$ echo $PATH
. - Set the
JAVA_HOME
environment variable to resolve to the GraalVM installation directory:$ export JAVA_HOME=<path to GraalVM>/Contents/Home
. Please also see the notice onjava_home
command.
- Add the GraalVM
- You can also specify GraalVM as the JRE or JDK installation in your Java IDE.Since the executables of all language runtimes in GraalVM emulate thebehavior of the languages’ default runtimes, setting GraalVM on your
PATH
should be enough to run an application with GraalVM.
GraalVM’s /bin
directory is similar to that of a standard JDK, but includes a set of additional launchers:
- js runs a JavaScript console with GraalVM.
- node is a drop-in replacement for Node.js, using GraalVM’s JavaScript engine.
- lli is a high-performance LLVM bitcode interpreter integrated with GraalVM.
- gu (GraalVM Updater) can be used to install language packs for Python, R, and Ruby.
Notably, java runs the JVM with GraalVM’s default compiler.The Ruby, Python, R executables become available only if you install the corresponding languages engines.For more information on installing components please refer to GraalVM Updater documentation.
Once the PATH
environment variable is set properly, check language versions with GraalVM launchers:
$ java -version
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit GraalVM EE 19.3.0.2 (build 25.231-b11-jvmci-19.3-b06, mixed mode)
$ node -v
v12.10.0
$ lli --version
LLVM (GraalVM EE Native 19.3.0.2)
Docker Containers
The official Docker images for GraalVM CE are available from the Docker Hub:https://hub.docker.com/r/oracle/graalvm-ce/.
If you want to use the Docker container with GraalVM CE, use the docker pull
command:
docker pull oracle/graalvm-ce:19.3.0.2
The image is based on Oracle Linux and has GraalVM CE downloaded, unzipped and made available.It means that Java, JavaScript, Node and the LLVM interpreter are available out of the box.
You can start a container and enter the bash
session with the following run command:
docker run -it oracle/graalvm-ce:19.3.0.2 bash
Check that java
, js
and other commands work as expected.
→ docker run -it oracle/graalvm-ce:19.3.0.2 bash
bash-4.2# java -version
openjdk version "1.8.0_232"
OpenJDK Runtime Environment (build 1.8.0_232-20191009173705.graal.jdk8u-src-tar-gz-b07)
OpenJDK 64-Bit GraalVM CE 19.3.0.2 (build 25.232-b07-jvmci-19.3-b06, mixed mode)
bash-4.2# node
> 1 + 1
2
> process.exit()
bash-4.2# lli --version
LLVM (GraalVM CE Native 19.3.0.2)
bash-4.2#
Please note that the image contains only the components immediately available in the GraalVM CE distribution.However, the GraalVM Updater utility is on the PATH
.You can install the support for additional languages like Ruby, R, or Python at will.For example, the following command installs the Ruby support (the output below is truncated for brevity):
docker run -it oracle/graalvm-ce:19.3.0.2 bash
bash-4.2# gu install ruby
Downloading: Component catalog
Processing component archive: Component ruby
Downloading: Component ruby
[###### ]
...
If you want to mount a directory from the host system to have it locally available in the container,use Docker volumes.
Here is a sample command that maps the /absolute/path/to/dir/no/trailing/slash
directory from the host system to the /path/inside/container
inside the container.
docker run -it -v /absolute/path/to/dir/no/trailing/slash:/path/inside/container oracle/graalvm-ce:19.3.0.2 bash
If you want to create docker images that contain GraalVM Ruby, R, or Python implementation, you can use dockerfiles like the example below, which uses oracle/graalvm-ce:19.3.0.2
as the base image, installs Ruby support using the gu
utility, then creates and runs a sample Ruby program.
FROM oracle/graalvm-ce:19.3.0.2
RUN gu install ruby
WORKDIR /workdir
RUN echo 'puts "Hello from Truffleruby!\nVersion: #{RUBY_DESCRIPTION}"' > app.rb
CMD ruby app.rb
If you put the above snippet in the Dockerfile
in the current directory,you can build and run it with the following commands.
docker build -t truffleruby-demo .
...
$ docker run -it --rm truffleruby-demo
Hello from Truffleruby!
Version: truffleruby 19.3.0.2, like ruby 2.6.2, GraalVM CE Native [x86_64-darwin]
Running Applications
Since the executables of all language runtimes in GraalVM emulate the behavior of the languages’ default runtimes, putting GraalVM on your PATH
should be enough to run your applications with GraalVM.
Running Java
Take a look at this typical HelloWorld
class:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Run the following command to compile this class to bytecode and then run it on GraalVM:
$ javac HelloWorld.java
$ java HelloWorld
Hello World!
You can find a collection of larger examples of Java applications you can try running with GraalVM on the examples page.
Running JavaScript
GraalVM can execute plain JavaScript code, both in REPL mode and by executing script files directly.
$ js
> 1 + 2
3
GraalVM also supports running Node.js applications. More than 95,000 npm modulesare tested and are fully compatible with GraalVM, including modules likeexpress, react, async, request, browserify, grunt, mocha, and underscore. Toinstall a Node.js module, use the npm
executable in the /bin
folder of theGraalVM package. The npm
command is equivalent to the default Node.js commandand supports all Node.js APIs.
- Install the
colors
andansispan
modules usingnpm install
:
npm install colors ansispan
After the modules are installed, you can use them from your application.
- Add the following code snippet to a file named
app.js
and save it in the same directory where you installed the Node.js modules:
// RUN-CMD: rm -rf node_modules
// RUN-CMD: npm install ansispan colors
// RUN-CMD: node {file}
// RUN-CMD: rm -r node_modules
// BEGIN-SNIPPET
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); });
// END-SNIPPET
setTimeout(function() { console.log("DONE!"); process.exit(); }, 2000);
- Execute it on GraalVM using the
node
command:
node app.js
More information on compatibility with the Node.js and configuring GraalVM read the reference manual on JavaScript in GraalVM.
Running LLVM Bitcode
The GraalVM LLVM runtime can execute C/C++, Rust, and other programminglanguage that can be compiled to LLVM bitcode. A native program has to becompiled to LLVM bitcode using an LLVM frontend such as clang
. C/C++ code canbe compiled to LLVM bitcode using clang
shipped with GraalVM via a pre-builtLLVM toolchain.
To set up the LLVM toolchain support for GraalVM, execute the following commands:
$ gu install llvm-toolchain
$ export LLVM_TOOLCHAIN=$(lli --print-toolchain-path)
Put this C code example into a file named hello.c
:
#include <stdio.h>
int main() {
printf("Hello from GraalVM!\n");
return 0;
}
Then compile hello.c
to an executable hello
with embedded LLVM bitcode and run it as follows:
$ $LLVM_TOOLCHAIN/clang hello.c -o hello
$ lli hello
More examples and information on running LLVM bitcode with GraalVM can be found in the reference manual for LLVM.
Running Ruby
The Ruby engine is not installed by default, but it can be added using GraalVM Updater:
gu install ruby
The above command will install a community version of a component from GitHub catalog. For GraalVM Enterprise Edition users, a manual component installation is required.Then the Ruby launchers like ruby
, gem
, irb
, rake
, rdoc
and ri
will become available:
$ ruby [options] program.rb
GraalVM Ruby implementation uses thesame options as the standard implementation of Ruby,with some additions.
$ gem install chunky_png
$ ruby -r chunky_png -e "puts ChunkyPNG::Color.to_hex(ChunkyPNG::Color('mintcream @ 0.5'))"
#f5fffa80
Using Bundler
GraalVM implementation of Ruby ships with the Bundler environment.Therefore its installation, gem install bundler
, is not needed.
$ bundle exec ...
More examples and additional information on Ruby support in GraalVM can be found in the reference manual for Ruby.
Running R
The R engine is not installed by default, and can be added using GraalVM Updater:
gu install R
Please note, the installation of the R language component is possible only from catalog.When the R engine is installed, you can execute R scripts and use the R REPL with GraalVM:
$ R
R version 3.6.1 (FastR)
...
> 1 + 1
[1] 2
More examples and additional information on R support in GraalVM can be found in the reference manual for R.
Running Python
GraalVM implementation of Python 3.7 has recently been started.The Python engine is not available by default, but it can be installed using GraalVM Updater:
gu install python
The above command will install a community version of a component from GitHub catalog. For GraalVM Enterprise Edition users, a manual component installation is required.Once the Python engine is installed, GraalVM can execute Python programs:
$ graalpython
...
>>> 1 + 2
3
>>> exit()
More examples and additional information on Python support in GraalVM can be found in the reference manual for Python.
Combine Languages
If enabled, using the —polyglot
flag, scripts executed on GraalVM can use interoperability features to call into other languages and exchange data with them.
For example, running js —jvm —polyglot example.js
executes example.js
in a polyglot context.If the program calls any code in other supported languages, GraalVM executes that code inthe same runtime as the example.js
application. For more information on polyglot applications see the polyglot documentation.
Native Images
GraalVM can compile Java bytecode into native images to achieve faster startup and smaller footprint for your applications.The Native Image functionality is not available by default but can be easily installed.
The HelloWorld
example from above is used here to demonstrate how to compileJava bytecode into a native image:
// HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Run the following to compile the class to bytecode and then build a native image:
$ javac HelloWorld.java
$ native-image HelloWorld
This builds an executable file named helloworld
in the current working directory.Invoking it executes the natively compiled code of the HelloWorld
class as follows:
$ ./helloworld
Hello, World!
Polyglot Capabilities of Native Images
GraalVM Native Image Generator also makes it easy to use polyglot capabilities.Take this example of a JSON pretty-printer using the GraalVM implementation of JavaScript:
// PrettyPrintJSON.java
import java.io.*;
import java.util.stream.*;
import org.graalvm.polyglot.*;
public class PrettyPrintJSON {
public static void main(String[] args) throws java.io.IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String input = reader.lines().collect(Collectors.joining(System.lineSeparator()));
try (Context context = Context.create("js")) {
Value parse = context.eval("js", "JSON.parse");
Value stringify = context.eval("js", "JSON.stringify");
Value result = stringify.execute(parse.execute(input), null, 2);
System.out.println(result.asString());
}
}
}
The —language:js
argument ensures that the JavaScript engine is available in the generated image:
$ javac PrettyPrintJSON.java
$ native-image --language:js --initialize-at-build-time PrettyPrintJSON
The native image generation will take several minutes as it does not just buildthe PrettyPrintJSON
class, but includes building a JavaScript engine(along with the support for partial evaluation). Additionally, the image buildingrequires large amounts of physical memory, especially if you build an image withTruffle Language Implementation Framework included, which is exactly the casehere. Memory requirements and some other limitations of ahead-of-timecompilation with GraalVM are listedhere.
The resulting executable can now perform JSON pretty printing:
$ ./prettyprintjson <<EOF
{"GraalVM":{"description":"Language Abstraction Platform","supports":["combining languages","embedding languages","creating native images"],"languages": ["Java","JavaScript","Node.js", "Python", "Ruby","R","LLVM"]}}
EOF
Here is the JSON output from the native executable:
{
"GraalVM": {
"description": "Language Abstraction Platform",
"supports": [
"combining languages",
"embedding languages",
"creating native images"
],
"languages": [
"Java",
"JavaScript",
"Node.js",
"Python",
"Ruby",
"R",
"LLVM"
]
}
}
The native image is much faster than running the same code on the JVM directly:
$ time bin/java PrettyPrintJSON < test.json > /dev/null
real 0m1.101s
user 0m2.471s
sys 0m0.237s
$ time ./prettyprintjson < test.json > /dev/null
real 0m0.037s
user 0m0.015s
sys 0m0.016s
What to read next?
If you want to learn what GraalVM offers to different types of teams, read the Why GraalVM page. Some of the diverse features of GraalVM are disclosed and supported with examples in Top 10 Things To Do With GraalVM article.Or, you can examine different supported languages in action by looking atexample applications. If you want to learn about the common tools GraalVM enables for the supported languages, proceed to the tools section of the reference manual.And if you are mostly interested in a specific language, more extensive documentation is available in the reference manual as well.