This repository contains several useful plugins for developing native and polyglot applications using the Graal compiler. The goal of all plugins is to "just work" whether you are using Hotspot (OpenJDK, OracleJDK, etc.) or GraalVM, so you don't actually need GraalVM to start using the Graal compiler and its polyglot features.
There are three plugins, each focusing on a specific sub-part of Graal functionality:
- Graal Compiler Plugin: Configures the project and its distributions
to use Graal compiler when possible, even on standard Hotspot JVMs. This
provides a significant speed-up when using Graal languages and polyglot
APIs on Hotspot JVMs. Finally, it also allows easy declaration of
Graal language dependencies from standard artefacts (bypassing
gu install
). - Native Image Plugin: Allows declaration of
NativeImage
tasks which use Graal'snative-image
compiler to produce native binaries of Java executables with minimal configuration. Automatically configures aNativeImage
task for application distributions. - Graal Language Plugin: Sets-up the project for development of a custom
Graal&Truffle language. Automatically configures Truffle classpath and
allows creation of packages installable with
gu
.
You can see some basic and advanced examples of how to use the plugins in the demo repository.
Disclaimer: There are currently two other plugins that integrate with
native-image
: org.mikeneck.graalvm-native-image and com.palantir.graal. These have slightly different feature sets than our Native Image Plugin, so feel free to use whatever works best for you.
To start using the Graal Compiler Plugin, add it to your plugin list and configure the desired Graal version:
plugins {
id 'org.graalvm.plugin.compiler' version '$latest'
}
graal {
version '20.1.0'
}
This declared version of the compiler will be used on Hotspot JVMs. GraalVM will use its built-in compiler.
With this setup, any JavaExec
task or a distribution created by the
application
plugin will automatically use the Graal compiler if possible
(only supported from JDK version 11+).
Furthermore, we can declare language dependencies. We differentiate language
and installedLanguage
dependencies. On Hotspot, these essentially correspond
to runtime
dependencies, as Hotspot does not support installation of Graal
languages. On GraalVM, we assume installedLanguage
is already installed using gu
and is thus not loaded explicitly. However, we load any language
dependency
explicitly using truffle.class.path.append
to ensure the language works even
when not installed:
dependencies {
// JavaScript is typically part of GraalVM, so we
// can assume it is installed. We still have to
// include it as a dependency to make it available
// on Hotspot though.
installedLanguage 'org.graalvm.js:js:20.1.0'
// Some custom, domain specific language that may not be
// installed, we thus load it explicitly even on GraalVM.
language 'org.company:my-awesome-language:1.2.3'
}
In the demo repository, you can see how this can be used to run fast Graal JavaScript instead of the deprecated Nashorn engine, or how to consume a custom Graal language as a dependency.
Native image tasks only work when running on GraalVM or when
GRAALVM_HOME
points to a distribution of GraalVM withnative-image
installed.
Start by applying the Native Image Plugin to your project:
plugins {
id 'org.graalvm.plugin.native-image' version '$latest'
}
If you also have the application
plugin applied and configured, you should
immediately see a distNative
task which will run native-image
with the same
configuration as the main application distribution and place it in build/distributions
.
If you need more control, you can declare a custom NativeImage
task. NativeImage
task
can have two types: it is either based on a main class (forMainClass
) or an executable
jar (forJar
). For the jar-based tasks, ideally you should specify a Gradle task of the
type Jar
. However, forJar
will also accept any File
or a string path.
Every NativeImage
task can be then configured with outputDir
(defaults to
$buildDir/nativeImage
), outputName
(defaults to task name), classpath
(defaults
to runtime classpath) and extra cmdArgs
for the native-image
tool:
import com.oracle.truffle.gradle.NativeImage
// A custom NativeImage task based on a main class.
task compileAppFromMainClass(type: NativeImage) {
forMainClass "my.app.Application"
outputDir "$buildDir/bin"
outputName "awesome-app"
// Classpath:
// `appendClasspath` adds extra items to the end of the list;
// `classpath` completely replaces all items.
appendClasspath "libs/extra-dependency-1.jar", "libs/extra-dependency-2.jar"
// Similar to classpath, there is `cmdArgs` and `appendCmdArgs`:
cmdArgs "--extra-cmd-arg"
}
// A custom NativeImage task based on a jar file.
task compileAppFromJar(type: NativeImage) {
forJar customJar
/* ... some configuration ... */
}
task customJar(type: Jar) {
/* ... some configuration ... */
}
In order to develop new Graal languages, you can apply the Graal Language Plugin which will automatically configure your project:
plugins {
id 'org.graalvm.plugin.truffle-language' version '$latest'
}
After this, you have to specify your language name and id:
graal {
version '20.1.0'
languageId 'my.awesome.langauge' // required
langaugeName 'MyLangauge' // defaults to project name
}
This will perform several automatic steps:
- It will apply the compiler plugin so that your language works fast everywhere you want to use it.
- It will extend truffle classpath to include the classpath of the project to load the new language properly.
- It will create a
graalComponent
task, which generatesjar
files which can be installed usinggu
.
At the moment,
graalComponent
creates bundles compatible with the Java 11 versions of the GraalVM, support for the Java 8 variants is coming soon!
A project which has the language plugin applied can be then used as a language
or installedLanguage
dependencies
in any project with the compiler plugin:
plugins {
id 'org.graalvm.plugin.compiler' version '$latest'
}
dependencies {
language ':myAwesomeLanguageProject'
}