GraalVM for Java

Thushan Fernando
6 min readOct 10, 2021

GraalVM is a high-performance runtime for Java and other JVM languages. It contains a compatible JDK and offers distributions based on Java 8, Java 11, and Java 16. GraalVM comes with multiple compiler optimisations, designed to accelerate Java applications performance while consuming fewer resources. To start using GraalVM, or to migrate from another JDK distribution, you do not have to change any source code. Any application that runs on the Java HotSpot VM will run on GraalVM.

GraalVM provides a high-performance JDK distribution designed to accelerate the execution of applications written in Java and other JVM languages along with support for JavaScript, Ruby, Python, and a number of other popular languages. GraalVM’s polyglot capabilities make it possible to mix multiple programming languages in a single application while eliminating foreign language call costs.

This article will give an architectural overview of GraalVM and its runtime modes, supported platforms, available distributions, functionalities, support levels and installation instructions.

GraalVM Architecture

GraalVM Architecture

GraalVM adds an advanced just-in-time (JIT) optimizing compiler, which is written in Java, to the HotSpot Java Virtual Machine.

In addition to running Java and JVM-based languages, GraalVM’s Truffle language implementation framework makes it possible to run JavaScript, Ruby, Python, and a number of other popular languages on the JVM. With GraalVM Truffle, Java and other supported languages can directly interoperate with each other and pass data back and forth in the same memory space.

Runtime Modes

GraalVM is unique as a runtime environment offering several modes of operation: JVM runtime mode, Native Image, Java on Truffle (the same Java applications can be run on either).

JVM Runtime Mode

When running programs on the HotSpot JVM, GraalVM defaults to the GraalVM compiler as the top-tier JIT compiler. At runtime, an application is loaded and executed normally on the JVM. The JVM passes bytecodes for Java or any other JVM-native language to the compiler, which compiles that to the machine code and returns it to the JVM. Interpreters for supported languages, written on top of the Truffle framework, are themselves Java programs that run on the JVM.

Native Image

Native Image is an innovative technology that compiles Java code into a standalone binary executable or a native shared library. The Java bytecode that is processed during the native image build includes all application classes, dependencies, third party dependent libraries, and any JDK classes that are required. A generated self-contained native executable is specific to each individual operating systems and machine architecture that does not require a JVM

Java on Truffle

Java on Truffle is an implementation of the Java Virtual Machine Specification, built with the Truffle language implementation framework. It is a complete Java VM that includes all core components, implements the same API as the Java Runtime Environment library, and reuses all JARs and native libraries from GraalVM. Java on Trufle is an experimental technology in GraalVM, available as of version 21.0.0.

Available Distributions

GraalVM is available as GraalVM Enterprise and GraalVM Community editions and includes support for Java 8, Java 11 and Java 16. GraalVM Enterprise is based on Oracle JDK while GraalVM Community is based on OpenJDK.

GraalVM is available for Linux, macOS, and Windows platforms on x86 64-bit systems, and for Linux on ARM 64-bit system. The GraalVM distribution based on Oracle JDK 16 is experimental with several known limitations. Depending on the platform, the distributions are shipped as .tar.gz or .zip archives.

Distribution Components List

GraalVM consists of core and additional components. The core components enable using GraalVM as a runtime platform for programs written in JVM-based languages or embeddable polyglot applications.

Core Components

Runtimes

  • Java HotSpot VM
  • JavaScript runtime
  • LLVM runtime

Libraries (JAR files)

  • GraalVM compiler — the top-tier JIT compiler
  • Polyglot API — the APIs for combining programming languages in a shared runtime

Utilities

  • JavaScript REPL with the JavaScript interpreter
  • lli tool to directly execute programs from LLVM bitcode
  • GraalVM Updater to install additional functionalities

Additional Components

GraalVM core installation can be extended with more languages runtimes and utilities.

Tools/Utilities

  • Native Image — a technology to compile an application ahead-of-time into a native executable.
  • LLVM toolchain — a set of tools and APIs for compiling native programs to bitcode that can be executed with on the GraalVM runtime.
  • Java on Truffle — a JVM implementation built upon the Truffle framework to run Java via a Java bytecode interpreter.

Runtimes

  • Node.js — the Node.js 14.16.1 runtime for JavaScript
  • Python — Python 3.8.5 compatible
  • Ruby — Ruby 2.7.3 compatible
  • R — GNU R 4.0.3 compatible
  • GraalWasm — WebAssembly (Wasm)

Licensing and Support

GraalVM Community Edition is open source software built from the sources available on GitHub and distributed under version 2 of the GNU General Public License with the “Classpath” Exception, which are the same terms as for Java. Check the licenses of individual GraalVM components which are generally derivative of the license of a particular language and may differ. GraalVM Community is free to use for any purpose and comes with no strings attached, but also no guarantees or support.

Install GraalVM

Getting GraalVM installed and ready-to-go only takes a few minutes.

  1. Navigate to GraalVM Releases repository on GitHub. Be sure to download the package appropriate for your operating system and the Java version you need (Java 8, 11, or 16)
  2. Unzip the archive to your file system:

on Linux or macOS

tar -xzf <graalvm-archive>.tar.gz

on Windows

unzip <graalvm-archive>.zip

3. Required for macOS only. Move the downloaded package to its proper location, the /Library/Java/JavaVirtualMachines directory. Since it is a system directory, sudo is required:

sudo mv <graalvm> /Library/Java/JavaVirtualMachines

To verify if the move is successful, and to get a list of all installed JDKs, run: /usr/libexec/java_home -V

4. Required for macOS only. If you are using macOS Catalina and later you may need to remove the quarantine attribute from the bits before you can use them. To do tis, run the following:

sudo xattr -r -d com.apple.quarantine /path/to/<graalvm>

5. Configure the environment variables

Set the JAVA_HOME environment variable to resolve to the installation directory:

#Linux
export JAVA_HOME=<graalvm>
#macOS
export JAVA_HOME=/Library/Java/JavaVirtualMachines/<graalvm>/Contents/Home
#Windows
setx /M JAVA_HOME "C:\Progra~1\Java\<graalvm>"

Point the PATH environment variable to the GraalVM bin directory:

#Linux
export PATH=<graalvm>/bin:$PATH
#macOS
export PATH=/Library/Java/JavaVirtualMachines/<graalvm>/Contents/Home/bin:$PATH
#Windows
setx /M PATH "C:\Progra~1\Java\<graalvm>\bin;%PATH%"

6. Restart the Command Prompt/Terminal to reload the environment variables. Then use the following command to check whether the variables were set correctly:

on Linux and macOS

echo $PATH
echo $JAVA_HOME

on Windows

echo %PATH%
echo %JAVA_HOME%

7. Optionally, specify GraalVM as the JRE or JDK installation in your Java IDE

Run Java Applications

GraalVM includes a JDK based on the Java HotSpot VM, and integrates an optimizing just-in-time (JIT) compiler, written in Java. At run time, an application is loaded and executed normally by the JVM.

For demonstration purposes, GraalVM Community based on Java 11 is used.

Check your current Java version:

thushanfernando@MacBook-Pro ~ % java -version
openjdk version "11.0.12" 2021-07-20
OpenJDK Runtime Environment GraalVM CE 21.2.0 (build 11.0.12+6 jvmci-21.2-b08)
OpenJDK 64-Bit Server VM GraalVM CE 21.2.0 (build 11.0.12+6-jvmci-21.2-b08, mixed mode, sharing)

The java launcher runs the JVM with the GraalVM default compiler - the GraalVM compiler. 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 commands to compile the above class to bytecode and then execute it:

javac HelloWorld.java 
java HelloWorld
Hello World!

In this article we discussed about the GraalVM support for Java Application Development.

In the next article, we will discuss the performance benchmarks of GraalVM.

Until then, Happy Compiling :)

--

--

Thushan Fernando

I am a Senior Software Engineer based in Berlin 🇩🇪