Oracle Labs announced that Java libraries will replace the GraalVM Updater (gu
) starting with GraalVM on JDK 21. The updater enabled the installation and management of GraalVM language runtimes and utilities. Libraries are available for their other supported languages such as JavaScript, Node.js, Python, WebAssembly and Ruby.
gu
was last supported in GraalVM on JDK 20. It was used to install packages, most notably Native Image and JavaScript, for example, gu install native-image
and gu install js
, respectively. From GraalVM on JDK 21 moving forward, the gu
utility has been removed and similar functionality is provided by several Java libraries.
The polyglot APIs are backward compatible and this new release won’t require code changes in existing projects.
The GraalVM team provided several reasons for the change: the first is that in order to upgrade a language with gu
, the JDK should also be upgraded, which complicates the upgrade process; the second is that installed applications and runtimes should be immutable, however gu
changed the installation, which makes it difficult to use for system and package managers that require immutability; and third is that language launchers for languages such as Python inside the JDK bin
directory are relatively confusing for users; and lastly, due to gu
it wasn't possible for a Java application to indicate a dependency on another language such as Python.
With this change, the Truffle framework, which allows running programming languages on GraalVM, is now loosely coupled and no longer tied to the JDK. This means all the language runtimes are available as libraries via Maven Central. Future language runtimes are backward compatible with the latest Long Term Support (LTS) release. Standalone language downloads are now available to replace the standalone language launchers in the JDK. GraalVM for JDK 21 is required for Runtime Optimization Support.
GraalVM should be installed in order to use the new libraries. GraalVM binaries are available for Linux, macOS and Windows. Alternatively, the community edition binaries may be used with a less restrictive license.
The example application integrates JavaScript inside a Java application and requires the following Maven dependencies:
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<version>23.1.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js-community</artifactId>
<version>23.10</version>
<type>pom</type>
</dependency>
Alternatively, Gradle dependencies might be used:
dependencies {
implementation("org.graalvm.polyglot:polyglot:23.1.0")
implementation("org.graalvm.polyglot:js:23.1.0")
}
The default libraries are licensed through the GraalVM Free Terms and Conditions (GFTC). Alternatively, libraries with a -community suffix are available with an open-source license.
The libraries allow the interoperability between Java and JavaScript; Java code might be used from JavaScript and JavaScript may be embedded in a Java program. The following example calls a JavaScript function from a Java application:
static String JAVASCRIPT_CODE = "(function myFirstFunction(language) { console.log('Hello world from ' + language); } )";
public static void main(String[] args) {
System.out.println("Hello world from Java!");
try (Context context = Context.create()) {
Value value = context.eval("js", JAVASCRIPT_CODE);
value.execute("JavaScript!");
}
}
Running the application results in the following output:
Hello world from Java!
Hello world from JavaScript!
The reference manual provides more information on the interoperability between JavaScript and Java, but also for languages such as Python, R and Ruby, WebAssembly and LLVM.
More information on the recent changes may be found in the Truffle Unchained blog post written by Christian Humer, consulting researcher at Oracle.