On a vu dans un billet précédent comment installer Java sur Debian ou Ubuntu en utilisant le plus possible les paquets fournis par le système, et ce sans avoir recours à d’autres outils ou installeurs qui changent le PATH
de notre système.
On souhaiterait faire de même avec GraalVM, malheureusement Oracle ne fournit pas de dépôt Debian ni Ubuntu pour GraalVM, et il semble qu’AdoptOpenJDK ou Azul ne le fasse pas non plus 🙁 Du moins pas pour l’instant.
1. Installer GraalVM
Les livrables de GraalVM se trouvent sur GitHub dans dépôt graalvm-ce-builds.
On va commencer par télécharger l’archive de GraalVM dans sa dernière version 21.0.0.2:
$ wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0.2/graalvm-ce-java11-linux-amd64-21.0.0.2.tar.gz
Et on va extraire cette archive là où on installe les JDKs du système, à savoir dans /usr/lib/jvm
:
$ sudo tar -xvf graalvm-ce-java11-linux-amd64-21.0.0.2.tar.gz -C /usr/lib/jvm
Ils seront ainsi accessibles par tous les utilisateurs du système.
$ ls -l /usr/lib/jvm/
total 20
drwxr-xr-x 10 root root 4096 mars 20 11:14 graalvm-ce-java11-21.0.0.2
lrwxrwxrwx 1 root root 21 nov. 10 05:18 java-1.11.0-openjdk-amd64 -> java-11-openjdk-amd64
lrwxrwxrwx 1 root root 21 juil. 21 2020 java-1.13.0-openjdk-amd64 -> java-13-openjdk-amd64
drwxr-xr-x 9 root root 4096 févr. 10 17:54 java-11-openjdk-amd64
drwxr-xr-x 9 root root 4096 déc. 16 20:30 java-13-openjdk-amd64
2. Configurer GraalVM
Si on modifie notre variable d’environnement PATH
:
$ export JAVA_HOME=/usr/lib/jvm/graalvm-ce-java11-21.0.0.2
$ export PATH=$JAVA_HOME/bin:$PATH
On utilise bien le binaire java
fourni par GraalVM:
$ java -version
openjdk version "11.0.10" 2021-01-19
OpenJDK Runtime Environment GraalVM CE 21.0.0.2 (build 11.0.10+8-jvmci-21.0-b06)
OpenJDK 64-Bit Server VM GraalVM CE 21.0.0.2 (build 11.0.10+8-jvmci-21.0-b06, mixed mode, sharing)
Il en est de même des autres binaires javac
, etc …
A ce stade GraalVM pour Java 11 est installé. Si vous n’aviez pas encore de JDK 11 installé, vous pouvez tout à fait utiliser cette installation de GraalVM comme JDK 11.
3. Installer native-image
Si l’on souhaite installer GraalVM, c’est en particulier pour pouvoir compiler du code Java
en natif avec l’utilitaire native-image
.
Cet utilitaire n’est pas fourni dans la distribution de GraalVM. On va donc l’installer, ce qui se fait avec l’utilitaire gu
(GraalVM updater) qui lui fait partie de la distribution que l’on vient d’installer:
$ sudo env PATH=$PATH gu install native-image
Downloading: Component catalog from www.graalvm.org
Processing Component: Native Image
Downloading: Component native-image: Native Image from github.com
Installing new component: Native Image (org.graalvm.native-image, version 21.0.0.2)
Vous noterez la façon de passer le PATH
courant à sudo
qui lui n’a pas GraalVM dans son PATH
.
On dispose maintenant de la commande native-image
:
$ native-image --help
GraalVM native-image building tool
This tool can be used to generate an image that contains ahead-of-time compiled Java code.
Usage: native-image [options] class [imagename] [options]
(to build an image for a class)
or native-image [options] -jar jarfile [imagename] [options]
(to build an image for a jar file)
where options include:
...
3.1 Installer les dépendances de native-image
native-image
compile en code natif votre application écrite en Java et a besoin pour cela des dépendances suivantes:
$ sudo apt-get install build-essential libz-dev zlib1g-dev
4. Premier programme Java compilé en natif
On va prendre un exemple très simple de programme Java:
$ cat HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
Le compiler:
$ javac HelloWorld.java
Une fois compilé, on va pouvoir générer une version native de notre programme HelloWorld:
$ native-image HelloWorld HelloWorld.native
Cette dernière opération est très lente, 8 secondes sur ma machine (Core i7).
Voyons maintenant ce qu’on a généré:
$ file HelloWorld.native
HelloWorld.native: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=cee9a397347e78326db66a8bc9ab47186a17001d, for GNU/Linux 3.2.0, with debug_info, not stripped
On a bien un exécutable que l’on pourra lancer comme suit:
$ ./HelloWorld.native
Hello World
Et qui se lance beaucoup plus vite que son homologue Java (0.24s):
$ java HelloWorld
5. Conclusion
On vient de voir comment installer simplement GraalVM, native-image ainsi que les dépendances nécessaires à son utilisation, et ce uniquement avec les commandes wget
, sudo
, tar
et apt-get
. Ensuite on a vu comment transformer un programme Java en code natif.
Nous verrons dans un prochain billet comment utiliser un plugin Maven pour automatiser la génération en code natif dans nos builds.