VT2020-GraalVM-Fiche

=Rappels sur l'architecture de la plateforme Java=

L'architecture de GraalVM se basant sur celle d'un Java Development Toolkit, un rappel sur le fonctionnement de la plateforme Java peut s'avérer utile.

Tout d'abord, le Java a la particularité d'être un langage à la fois compilé et interprété. Les tâches de compilation et d'interprétation sont distinctes et réalisées par des composants différents. Comme on peut le voir sur le schéma ci-dessous, le code Java est d'abord compilé en bytecode par un Java Compiler pour ensuite être interprété et exécuté par une Java Virtual Machine.



Il faut donc distinguer dans cette architecture :
 * La Java Virtual Machine (JVM), qui interprète et exécute le code.
 * Le Java Runtime Environment (JRE), qui est un environnement d'exécution contenant des librairies et la JVM.
 * Le Java Development Toolkit (JDK), qui est composé de librairies en Java, du JRE et du Java Compiler.

=GraalVM=

Abstract
"GraalVM is a high-performance multilingual runtime. It is designed to accelerate the execution of applications written in Java and other JVM languages while also providing runtimes for JavaScript, Ruby, Python, and a number of other popular languages. GraalVM’s polyglot capabilities make it possible to mix multiple programming languages in a single application while eliminating any foreign language call costs."

Documentation officielle de GraalVM

Constats
Malgré son apparente popularité, le langage Java est sur le déclin. A l'origine, ce langage conçue par Sun Microsystems et dit "JVM" (comme Kotlin ou Scala) avait été conçu avec l'idée de pouvoir être exécuté sur n'importe quelle plateforme ayant une JVM, affranchissant ainsi le développeur des spécifités d'exécution de la plateforme (d'où le slogan "Write Once Run Anywere"). Cependant, à cause la surcouche logicielle induite par la JVM, le langage Java a essuyé des critiques sur sa performance et sur sa verbosité.

S'ajoute à cela un regain de popularité des langages natifs dans les années 2010, notamment grâce à Apple et son développement mobile iOS en Objective-C qui contraste avec Java ou Kotlin (étant tous deux des langages JVM) en terme de performance.

Pour répondre à ces problématiques, l'entreprise Oracle se doit d'adapter constamment Java afin de rester compétitive, et sa JVM avec.

Ce qui existait déjà
Evidemment, Java fonctionnait bien avant l'arrivée de GraalVM, ce qui signifie qu'il existait donc déjà des machines virtuelles. La plus utilisée d'entre elles est HotSpot, écrites en C++. Elle a été créé par Sun et appartient aujourd'hui à Oracle depuis le rachat de Sun. Notez que toutes les JVM (ou autres composants de la plateforme Java), ne sont pas forcément propriété d'Oracle : par exemple, OpenJ9 est une JVM dont la propriété revient à IBM et à la fondation Eclipse. Ces composants doivent ceci dit respecter des spécifications dictées par Sun (https://docs.oracle.com/javase/specs/).

La première version de Hotspot n'était qu'un interpréteur, puis elle a été améliorée avec un ajout de la compilation à la volée (Just-In-Time). Ensuite elle a été capable de détecter les portions de code les plus fréquemment utilisés et de les optimiser.

Ceci dit, GraalVM trouve ses racines dans le projet Maxine (dévelopé par Sun Microsystems Laboratories en 2005), dont l'objectif était d'écrire une JVM en langage Java pour s'affranchir des problèmes de développement liés au C++, plus particulièrement la gestion de la mémoire. Le projet s'est avéré trop ambitieux à l'époque mais a servi de point de départ pour GraalVM presque 15 ans plus tard.

Solution
Les objectifs ayant mené à la création de GraalVM sont multiples :
 * Avoir un environnement qui accélère l'exécution des applications écrites en Java ou d'autres langages JVM afin de rivaliser avec les langages natifs
 * Fournir un environnement d'exécution qui supporte plusieurs langages de programmation, supprimant ainsi l'isolation entre eux et établissant une véritable inter-opérabilité.

La solution développée est GraalVM, une machine virtuelle haute performance (d'après les dires d'Oracle) qui prend en fait la forme d'un JDK dont la partie VM a été grandement améliorée.

Fonctionnalités
Les principaux atouts de GraalVM sont:
 * Graal Compiler, un nouveau compilateur JIT (Just-In-Time) pour Java
 * GraalVM Native Image, permettant la compilation AOT (Ahead-Of-Time) pour les applications Java
 * Truffle Language Implementation framework et GraalVM SDK, fournissant des runtimes pour d'autres langages de programmation
 * LLVM Runtime et JavaScript Runtime

Architecture


GraalVM réutilise l'architecture d'OpenJDK (qui est sans grande surprise un JDK), mais avec quelques particularités au niveau de la JVM :
 * Il réutilise la VM Hotspot, mais de laquelle on a retiré le JIT Complier.
 * Il bénéficie d'un nouveau compilateur JIT, Graal Compiler, écrit en Java et en dehors de Hotspot. Il a pour mission de transformer du bytecode en code machine (ne pas confondre avec le Java Compiler, plus haut niveau).
 * Pour permettre à la JVM Hotspot d'utiliser un compilateur écrit en Java, une couche intermédiaire est nécessaire : la JVM Compiler Interface.
 * Tout ce qui doit arriver au compilateur JIT doit être du bytecode. C'est pourquoi les langages non-JVM ne peuvent pas être directement pris en entrée de Graal Compiler. La couche Truffle framework répond à cette problématique. Truffle est un framework open-source qui sert à définir nos propres langages de programmation à travers un AST (Abstract Syntax Tree) et à construire des interpréteurs pour ce dernier. Il est réutilisé dans GraalVM pour définir des implémentations Truffle de Python, Ruby ou encore Javascript.
 * La couche Truffle suffisait pour les langages interprétés puisque Truffle construit des interpréteurs. Mais pour les langages LLVM (Low Level Virtual Machine) comme le C, le C++ ou le Fortran, une surcouche est nécessaire. Sulong est une LLVM qui permet de produire du bitcode en s'appuyant sur les fonctionnalités de Truffle.

Installation
GraalVM est très simple à installer.

java -version
 * Naviguez sur le git de GraalVM (https://github.com/graalvm/graalvm-ce-builds/releases) et téléchargez la version de GraalVM compatible avec notre version de Java/OpenJDK, que l'on peut connaître avec la commande :

tar -xzf .tar.gz
 * Dézippez l'archive à l'endroit de votre choix.

export PATH= /bin:$PATH Si vous souhaitez remplacer votre JDK par GraalVM pour toutes vos applications utilisant Java, vous pouvez changer la variable d'environnement JAVA_HOME. export JAVA_HOME= Si vous ne souhaitez pas modifier votre JAVA_HOME, vous pouvez définir une variable d'environnement GRAAL_HOME qui vous sera utile pour ne pas avoir à réécrire le chemin complet de Graal. Notez également que vous pouvez rendre les commandes au-dessus permanentes en les ajoutant à votre fichier .bashrc ou .zshrc.
 * Configurez votre variable d'environnement PATH:

Exécution
Le dossier /bin est similaire à un JDK standard, mais contient des launchers additionnels (en plus de javac pour le Java): En d'autres termes, GraalVM ne comprend que le Java, Node.js (grâce au Javascript Runtime) et les langages LLVM (grâce au LLVM Runtime). Cependant, d'autres launchers peuvent être installés avec la commande : gu install 
 * js, un launcher JavaScript
 * node, un launcher Node.js
 * lli, un launcher LLVM

Par ligne de commande
En règle générale, les commandes d'exécution sont de la forme :   Par exemple : node app.js Les programmes LLVM doivent êtres compilés avant avec l'outil LLVM Toolchain car le launcher lli ne comprend que du bitcode : gu install llvm-toolchain export LLVM_TOOLCHAIN=$(lli --print-toolchain-path) $LLVM_TOOLCHAIN/clang hello.c -o hello lli hello

Dans un IDE
Dans l'IDE, il suffit de remplacer le path du JRE ou du JDK par le path de GraalVM. Sous eclipse par exemple, cela peut se faire en allant dans Window/Preferences/Java/Installed JREs.



Limites
Même si les promesses de GraalVM, à savoir l'amélioration des performances à l'exécution des langages JVM et le polyglottisme, sont respectées, l'outil d'Oracle rencontre quand même quelques limites :


 * On peut regretter que les langages les plus bas niveaux comme le C soient paradoxalement ceux qui traversent le plus de couches logicielles dans l'architecture de GraalVM. Leur interêt en termes de performance est donc extrêmement diminué puisqu'ils nécessitent de nombreuses opérations pour être transformé en bytecode, bytecode qui est logé à la même enseigne que le bytecode issu de code Java au yeux du compilateur.


 * En règle générale, les performances hors langages JVM sont tout de même loins d'être extraordinaires. L'inter-opérabilité entre langages est fonctionnelles mais coûteuse en ressources.


 * Les langages compris par GraalVM étant en fait des implémentations Truffle de langages et pas les langages en eux-mêmes, il manque les librairies utiles à chaque langage. Il est donc impossible par exemple, d'utiliser matplolib dans un programme Python. Les programmes en sont plus ou moins réduit à de l'algorithmie selon les capacités natives du langage.

Demonstration
=Sources=
 * 1) GraalVM Official documentation: Getting Started
 * 2) GraalVM Official documentation: Introduction
 * 3) Wikipedia: GraalVM
 * 4) Elvadas Nono : A la découverte de GraalVM (2020)
 * 5) ServerSide: Definition of GraalVM
 * 6) Wikipedia: Machine Virtuelle Java
 * 7) Wikipedia: Environnement d'exécution Java
 * 8) Wikipedia: Hotspot
 * 9) Wikipedia: Maxine
 * 10) Wikipedia: Java Development Toolkit
 * 11) Wikipedia: Environnement d'exécution Java
 * 12) Abdul Fousan: GraalVM Polyglot Virtual Machine
 * 13) Mike Hearn: GraalVM and Truffle
 * 14) Truffle Official documentation: GraalVM and Truffle

=Veille Technologique 2020=
 * Année : VT2021
 * Sujet : GraalVM
 * Slides : [[Media:GraalVM.pdf|Slides]]
 * Auteurs : User:Alexis.Rollin