◀Table of Contents
Java on Truffle
Using GraalVM, you can run Java applications normally on the JVM, in Native Image, and now on Truffle. Java on Truffle is an implementation of the Java Virtual Machine Specification, Java SE 8 and Java SE 11, built upon GraalVM as a Truffle interpreter. It is a minified Java VM that includes all core components of a VM, implements the same API as the Java Runtime Environment library (libjvm.so), and reuses all JARs and native libraries from GraalVM. See the Implementation Details for more information. The project name behind this implementation is “Espresso”. Its open source version is available on GitHub.
The Java on Truffle execution mode runs Java via a Java bytecode interpreter, implemented with the Truffle framework – an open-source library for writing interpreters for programming languages. Now Java can be executed by the same principle as other languages in the GraalVM ecosystem (JavaScript, Ruby, Python, R), directly interoperate with those languages, and pass data back and forth in the same memory space. Besides complete language interoperability, with Java on Truffle you can:
- run Java bytecodes in a separate context from the host Java VM. It can run either a Java 8 or Java 11 guest or host JVM. In other words, you can embed a Java 8 context in a Java 11 application, by using GraalVM’s Polyglot API.
- leverage the whole stack of tools provided by the Truffle framework, not previously available for Java.
- have an improved isolation of the host Java VM and the Java program running on Truffle, so you can run less trusted guest code.
- run in the context of a native executable while still allowing dynamically-loaded bytecodes.
Java on Trufle is an experimental technology in GraalVM, but already passes the Java Compatibility Kit (JCK or TCK for Java SE). It is available as of version 21.0.0.
Install Java on Truffle
To run Java on Truffle, you need to have GraalVM installed. The Java on Truffle runtime is not available by default, but can be easily added to GraalVM using the GraalVM Updater tool.
For GraalVM Community Edition users, run the following command to install Java on Truffle from the GitHub catalog:
gu install espresso
The installable’s name, espresso
, is the project code-name, it is used to avoid ambiguity with the other ways Java code can run on GraalVM.
For GraalVM Enterprise Edition users, download Java on Truffle from Oracle GraalVM Downloads. Having downloaded the appropriate JAR file in consideration of the operating system and underlying Java SE version, install it with:
gu install -L espresso.jar
It installs the jvm
runtime library under the GRAALVM_HOME/lib/truffle/
location.
Run Java on Truffle
You can run a Java application on Truffle by passing the -truffle
flag to the standard java
launcher.
This is similar to how you used to switch between the -client
and -server
JVMs.
To execute a class file:
java -truffle [options] class
To execute a JAR file:
java -truffle [options] --jar jarfile
Using Java 11 based GraalVM distribution, you can also run a Java application from the main class in a module, or run a single source-file program:
java -truffle [options] -m module[/<mainclass>]
java -truffle [options] sourcefile
By default, Java on Truffle runs within GraalVM by reusing all GraalVM’s JARs and native libraries, but it is possible to “cross-version” and specify a different Java installation directory (java.home
).
It will automatically switch versions regardless of the host JVM.
java -truffle --java.JavaHome=/path/to/java/home -version
Performance Considerations
Java on Trufle is an experimental technology in GraalVM, and peak performance is currently 2-3x slower than HotSpot.
The startup time will not match the speed offered by the regular GraalVM just-in-time (JIT) execution yet, but having created a fully working Java on Truffle runtime, the development team is now focusing on performance.
You can still influence the performance by passing the following options to java -truffle
:
--engine.MultiTier=true
to enable multi-tier compilation;--engine.Inlining=false
in combination with--java.InlineFieldAccessors=true
to make the compilation faster, in exchange for slower performance.
The --vm.XX:
syntax ensures the option is passed to the underlying Native Image VM.
When using the -XX:
syntax, the VM first checks if there is such an option in the Java on Truffle runtime.
If there is none, it will try to apply this option to the underlying Native Image VM.
This might be important for options such as MaxDirectMemorySize
which can be set independently at both levels: -XX:MaxDirectMemorySize=256M
controls how much native memory can be reserved by the Java program running on Truffle (the guest VM), while --vm.XX:MaxDirectMemorySize=256M
controls how much native memory can be reserved by Native Image (the host VM).
Start Running Applications
From Command Line
For the purpose of this guide, GraalVM Enterprise 21.2.0 distribution, based on Java 11 for macOS, is used. To ensure you have successfully installed Java on Truffle, verify its version:
java -truffle -version
java version "11.0.12" 2021-07-20 LTS
Java(TM) SE Runtime Environment GraalVM EE 21.2.0 (build 11.0.12+8-LTS-jvmci-21.2-b06)
Espresso 64-Bit VM GraalVM EE 21.2.0 (build 11-espresso-21.2.0, mixed mode)
Taking this HelloWorld.java
example, compile it and run from the command line:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
<graalvm>/bin/javac HelloWorld.java
<graalvm>/bin/java -truffle HelloWorld
HelloWorld.java!
Taking some real-world applications, try running Spring PetClinic - a sample web application that demonstrates the use of Spring Boot with Spring MVC and Spring Data JPA.
- Clone the project and navigate to the project’s directory:
git clone https://github.com/spring-projects/spring-petclinic.git cd spring-petclinic
- Build a JAR file (Spring PetClinic is built with Maven):
./mvnw package
- Then run it from the command line by selecting the
-truffle
runtime:java -truffle -jar target/spring-petclinic-2.4.2.jar
- When the application starts, access it on localhost:8000.
From IDE
To run a Java project on Truffle from an IDE requires setting the Java on Truffle enabled GraalVM as a project’s default JDK. For exampe, to run the Spring PetClinic project using Intellij IDEA, you need to:
1. Navigate to File -> Project Structure -> Project -> Project SDK. Expand the drop down, press Add SDK -> JDK and open the folder where you installed GraalVM. For macOS users, JDK home path will be /Library/Java/JavaVirtualMachines/{graalvm}/Contents/Home
. Give it a name, and press Apply.
2. Generate sources and update folders for the project. In the Maven sidebar, click on the folder with the spinner icon:
3. Enable the Java on Truffle execution mode. From the main menu select Run -> Run… -> Edit Configurations > Environment. Put the -truffle -XX:+IgnoreUnrecognizedVMOptions
command in the VM options field and press Apply.
It is necessary to specify -XX:+IgnoreUnrecognizedVMOptions
because Intellij automatically adds a -javaagent
argument which is not supported yet.
4. Press Run.
Debugging
You do not have to configure anything special to debug applications running Java on Truffle from your favorite IDE debugger.
For example, starting a debugger session from IntelliJ IDEA is based on the Run Configurations.
To ensure you attach the debugger to your Java application in the same environment, navigate in the main menu to Run -> Debug… -> Edit Configurations, expand Environment, check the JRE value and VM options values.
It should show GraalVM as project’s JRE and VM options should include -truffle -XX:+IgnoreUnrecognizedVMOptions
: -truffle
to run Java on Truffle, and -XX:+IgnoreUnrecognizedVMOptions
as a temporary workaround since the Java on Truffle runtime does not yet support attaching Java agents.
What to Read Next
Java on Truffle enables a seamless Java interoperability with other languages in the GraalVM ecosystem. Check the Interoperability with Truffle Languages guide to learn how to load code written in foreign languages, export and import objects between languages, how to use Java-on-Truffle objects from a foreign language and vice versa to create powerful polyglot programs.
To learn about the implementation approach, project’s current status, and known limitations proceed to Implementation Details.
You can already run some large applications like the Eclipse IDE, Scala or other languages REPLs, etc. in the Java on Truffle execution mode. We recommend having a look at the collection of Demo Applications.
If you have a question, check the available FAQs, or reach us directly over the #espresso channel in GraalVM Slack.