This project showcases the integration between GraalVM's native image and Java-on-Truffle (Espresso), namely by building a native image of jshell
that executes dynamically generated bytecode on Espresso.
This hybrid mode achieves instant startup, beating the vanilla jshell
in both: time to the first interaction and time to evaluate a simple expression.
It also enables jshell
to run on Java 8.
Requires GraalVM >= 21.0 (11) with Native Image and Java-on-Truffle (Espresso) installed. You can download GraalVM 21.0 (11) here.
To install Native Image and Java on Truffle (Espresso), in the GraalVM 21.0 directory, run:
<graalvm>/bin/gu install native-image espresso
export GRAALVM_HOME="/path/to/graalvm21.0"
sh build-espresso-jshell.sh
It gnerates a native executable: espresso-jshell
.
espresso-jshell [options...]
by default runs on Java 11 with instant startup.
export GRAALVM_HOME="/path/to/graalvm21.0"
export JDK8_HOME="/path/to/jdk8"
sh jshell8.sh [options...]
You can run the following snippets to convince yourself that it runs on the Java 8 mode:
System.getProperty("java.vm.version");
// `jshell -C-source -C8` forbids getModule() access from code,
// but it is still accessible through reflection.
Object.class.getModule();
// In true Java 8 mode, getModule() is not accessible at all,
// not even through reflection.
Class.class.getDeclaredMethod("getModule");
Pass system properties to Espresso with -R-Dkey=value
.
Pass polyglot options to Espresso with -Rjava.InlineFieldAccessors -Rengine.Compilation=false
.
espresso-jshell
behaves similar to jshell -execution local
and should not be directly compared with the default jshell execution engine, e.g., class redefinition is not supported (jshell -execution local
does not support it either).
It does not support execution engines other than -execution espresso
.
It is not fully standalone, it needs the jars/jmods to compile and for Espresso to run.
To run on Java 8, jshell
needs the following bugfix: openjdk/jdk#2097 . Pre-compiled patch for jdk.jshell in jdk.jshell-patch
.