Discover how to install it
Play around with Graal native images
Explore (barely) the polyglot goodness
"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."
https://www.graalvm.org/docs/introduction/
virtual machine execution engine
drop-in replacement for Oracle Java 8/11
as well as drop-ins for other languages/runtimes
ahead-of-time compiler for Java
create standalone binaries
polyglot virtual machine
language implementation framework (Truffle)
Java (JVM), JavaScript/NodeJS, Python, Ruby, R, WASM, LLVM
custom language/DSL implementations
Which Java do you want?
Java8-compatible
Java11-compatible
(experimental) Java16-compatible
Which license do you want?
Community Edition (CE)
Enterprise Edition
Drop-in for a number of virtual machine environments
Java/JVM
Web Assembly (GraalWASM)
Python
Ruby ("TruffleRuby")
R ("FastR")
Various stages of support
Many/most are "experimental"
Online repository
gu
: Graal updater tool
available
: List all available
install
: Download/install
list
: Display locally-installed
upgrade
: Upgrade locally-installed
remove
: Delete locally-installed
Installed by default with GraalVM
All the SDK tools
javac, jar, jarsigner, javadoc, javap
jdb, jshell, jmod
All the runtime engine tools
java, jstat, jps, jmap
rmiregistry, serialver
Script engine support
js, jrunscript
gu install native-image
Provides
native-image
: AOT image generator for JVM
Node.js 14.16.1 runtime
gu install nodejs
Provides
node
: Runs NodeJS code
npm
: NodeJS package manager
npx
: NPM-manifest-execute
LLVM 10.0.0
gu install llvm-toolchain
Provides
lli
: Runs LLVM bitcode
lld
: LLVM debugger
llvm-ar
, llvm-nm
: LLVM linker, "name" tool
c++
, cc
, clang
, clang++
, g++
, gcc
graalvm
-prefixed set of tools
Python 3.8.5
gu install python
Requires llvm-toolchain
Provides
graalpython
instead of python3
WebAssembly 1.0
gu install wasm
Provides
wasm
: WebAssembly interpreter
GNU R 4.0.3
gu install R
Provides
R
: Console R environment
Rscript
: alternative front end for use in #! scripts
Compile Java ahead-of-time to native executable
includes classes
dependencies
runtime library
statically linked native code
Resulting app does not run on the JVM
instead runs on the "Substrate JVM"
like the deoptimizer, garbage collector, thread scheduling, ...
faster startup time and lower runtime memory overhead compared to a JVM
All the benefits/drawbacks of native apps
Specific to CPU
Faster startup
Less overhead
Depends on glibc-devel
, zlib-devel
, gcc
packages
possibly more, depending on OS distribution
Ubuntu: sudo apt-get install build-essential libz-dev zlib1g-dev
To build around class file in current directory:
native-image [options] class [imagename] [options]
To build around JAR file:
native-image [options] -jar jarfile [imagename] [options]
Any .class/JAR-based codebase works
Java, Kotlin, Scala, Groovy
... so long as all dependencies are available
... or you're OK with "falling back" to a JDK
... or you're willing to risk runtime errors
Example
public class Example { public static void main(String[] args) { String str = "Native Image is awesome"; String reversed = reverseString(str); System.out.println("The reversed string is: " + reversed); } public static String reverseString(String str) { if (str.isEmpty()) return str; return reverseString(str.substring(1)) + str.charAt(0); } }
build.sh
echo GraalVM Home is "$GRAALVM_HOME" echo Compiling Java... javac $1.java echo Converting to native binary... $GRAALVM_HOME/bin/native-image $*
First, make sure native-image
is installed
gu available
(verify native-image is listed)
gu install native-image
Point native-image
at the main
-containing class
native-image Example
(generates example
)
native-image Example myapp
Creates both executable and "build_artifacts.txt"
Standard JVM options (-classpath, etc) available
-jar {jarfile}
: Generate from JAR instead
--verbose
: (Exactly what you think it means)
-g
: Generate debug information
--shared
: Build shared library
--static
: Build statically-linked executable
--target
: compilation target; -
Graal is doing deep static code analysis
Loading the code; loading declared and static dependencies
"Running" code to determine heap differentials
Region analysis for memory pressure insights
Converting Java bytecode to native executable code
Very similar to what happens in a JIT compiler
Adding a barebones runtime as part of the executable
Three different flavors (--gc
)
serial
(default) optimized for low memory footprint, small heap sizes
g1
(EE only) multi-threaded GC optimized to reduce latency
epsilon
no-op collector good for short-running/fast-lived apps
JVM is a dynamic environment
Class.forName()
for example
... which is why native-image does an iterative analysis
"Points-to" analysis
Runs initializations
Snapshots the heap
... until it reaches a fixed point
Code goes into the TEXT section
Heap image goes into the DATA section
Some wins
Startup speed
Memory footprint
Packaging size
Some losses
Peak throughput
Max latency
GraalVM Native-Image docs
https://www.graalvm.org/reference-manual/native-image/
Note that native-image is still (as of Oct 2021) "experimental"
that said, it seems to be pretty reliable...
Production-Ready
Java
Scala, Groovy, Kotlin
JavaScript, NodeJS, Native Image
Experimental
Ruby
R
LLVM Toolchain
"Visionary"
Python
Webassembly
LLVM Backend
As a polyglot host/glue/binding layer between languages
As an implementation framework for new languages
(Really, those are the same thing, but from different perspectives)
Build must reference Truffle Polyglot JARs
MavenCentral package org.graalvm.js:js:+
As of this writing 21.2.0 is the latest; do due diligence
Should make org.graalvm.polyglot
package available
If not, diagnose and fix
Happy path
Create a Context
Build a Source
around the code
build()
the Source
eval()
the Source
within the Context
Straight-source evaluation (no optimizations)
Create Context
eval()
the raw source code
Pass parameters, harvest results via Value
Hello, JavaScript
package com.newardassociates.graalpolyglot; import org.graalvm.polyglot.*; import org.graalvm.polyglot.proxy.*; public class App { static String JS_CODE = "(function myFun(param){return 'hello '+param;})"; public String getGreeting() { try (Context context = Context.create()) { Value value = context.eval("js", JS_CODE); return value.execute("World").asString(); } } public static void main(String[] args) { System.out.println(new App().getGreeting()); } }
Hello, Java!
var BigInteger = Java.type('java.math.BigInteger'); console.log(BigInteger.valueOf(2).pow(100).toString(16));
Run with (GraalVM) node
$ node --jvm app.js 10000000000000000000000000
GraalVM GitHub ships with an example
"Simple Language"
https://www.graalvm.org/graalvm-as-a-platform/implement-language/
https://github.com/graalvm/simplelanguage.git
From the SLLanguage.java comment header:
"SL is a simple language to demonstrate and showcase features of Truffle. The implementation is as simple and clean as possible in order to help understanding the ideas and concepts of Truffle. The language has first class functions, and objects are key-value stores."
From the SLLanguage.java comment header:
"SL is dynamically typed, i.e., there are no type names specified by the programmer. SL is strongly typed, i.e., there is no automatic conversion between types. If an operation is not available for the types encountered at run time, a type error is reported and execution is stopped. For example, {@code 4 - "2"} results in a type error because subtraction is only defined for numbers."
Hello, SimpleLanguage
function main() { println("Hello World!"); }
Objects in SimpleLanguage
function main() { obj3 = new(); obj3.fn = mkobj; println(obj3.fn().z); // prints "zzz" } function mkobj() { newobj = new(); newobj.z = "zzz"; return newobj; }
SL uses ANTLR for parsing
src/main/java/com/oracle/truffle/sl/SimpleLanguage.g4
AST is converted to SL "nodes"
as in, nodes in an execution tree
src/main/java/com/oracle/truffle/sl/nodes/*
Truffle annotations are everywhere
Truffle processing uses these for hints and optimizations
Includes the need to build "instruments"
debuggers
profilers
other runtime instrumentation tools
Similar to JVMPI/JVMDI/JVMTI interfaces
A minimalistic code-coverage tool
No tutorial (yet)
https://github.com/graalvm/simpletool
Start with looking at TruffleInstrument
Between the standard JVM API...
... and the Truffle library for polyglot support
Not to mention that it "speaks" a number of important languages
... I can't see how it WON'T be the future for Java
Explore it!
Embrace it!
Graal website
https://www.graalvm.org/
Graal docs
https://www.graalvm.org/docs/introduction/
"Ten Things You Can Do With GraalVM"
https://chrisseaton.com/truffleruby/codeone18/ten-things-graal.pdf
(Old) presentation by Chris Seaton
GraalVM Publications
https://www.graalvm.org/community/publications/
"Supercharge Your Applications with GraalVM"
A B Vijay Kumar (Packt)
GraalVM videos list
https://www.graalvm.org/community/video-library/
Who is this guy?
Architect, Engineering Manager/Leader, "force multiplier"
Principal -- Neward & Associates
http://www.newardassociates.com
Educative (http://educative.io) Author
Performance Management for Engineering Managers
Author
Professional F# 2.0 (w/Erickson, et al; Wrox, 2010)
Effective Enterprise Java (Addison-Wesley, 2004)
SSCLI Essentials (w/Stutz, et al; OReilly, 2003)
Server-Based Java Programming (Manning, 2000)