Java s'est longtemps présenté comme le langage qui fonctionne partout, sur des milliards d'appareils, des vêtements de cuisine aux écosystèmes d'entreprise complexes. Le même programme écrit une fois, pourrait fonctionner partout. Mais, à l'ère du cloud natif, les coûts inhérents (énorme empreinte mémoire, temps de démarrage lents) liés à sa nature dynamique deviennent des obstacles sur la voie de l'évolution.
Les nouveaux frameworks conçus pour les applications cloud natives, telles que Quarkus ou Micronaut, misent sur Static Java pour des temps améliorés et une empreinte plus légère.
L'implication de Dan Heidinga avec Static Java est née de la reconnaissance de la nécessité pour Java d'évoluer pour répondre aux changements dans l'écosystème porté par les nouvelles pratiques liées au cloud. Outre son implication actuelle avec CRiU (point de contrôle/restauration dans l'espace utilisateur) à la fois dans les projets CRaC et CRiU d'OpenJ9 et sa contribution à la JVM OpenJ9, Java Lambdas, apportant les MethodHandles à Java et actuellement avec le projet Valhalla, il est aux premières loges du voyage vers Static Java. InfoQ a contacté Dan Heidinga pour comprendre à quel point nous sommes loin d'une large adoption.
InfoQ : Bonjour Dan. Merci d'avoir pris le temps de répondre à quelques questions pour nos lecteurs. Pouvez-vous s'il vous plaît nous donner une brève présentation de vous-même, en indiquant vos responsabilités quotidiennes et votre implication avec Static Java ?
Dan Heidinga : Je suis un développeur sur la JVM et un utilisateur de Java de longue date. Mes responsabilités quotidiennes consistent à travailler sur la JVM Hotspot (également chef de projet pour la JVM OpenJ9) et sur le projet qbicc : un compilateur statique expérimental pour les programmes Java, qui sert de terrain de jeu pour essayer différentes approches de Static Java afin d'explorer l'espace de conception complet en préparation du projet Leyden d'OpenJDK.
Je suis également activement impliqué dans les investigations CRiU (point de contrôle/restauration dans l'espace utilisateur) dans le projet CRaC d'OpenJDK et le projet CRiU d'OpenJ9, car je voie beaucoup de chevauchement entre les besoins de point de contrôle/restauration et Static Java.
InfoQ : Quels sont les avantages de Static Java ? Quels sont les cas d'utilisation les mieux adaptés ?
Dan Heidinga : Static Java produit un exécutable natif compilé de manière statique ciblant un démarrage rapide et un faible encombrement mémoire, à la fois sur le disque et avec une faible surcharge de métadonnées lors de l'exécution. Même si les scénarios potentiels où il pourrait être utilisé sont nombreux, les microservices, les applications CLI et les déploiements serverless sont les meilleurs candidats.
Il est composé d'un petit nombre de fonctionnalités :
- Compilez nativement tout le code Java qui compose votre application.
- La possibilité de "fermer le monde (close the world)" et d'empêcher le chargement de classes supplémentaires. Cela permet d'éliminer le code mort pour supprimer les méthodes et les champs inutilisés, ce qui donne un binaire plus petit.
- La possibilité d'initialiser des parties de l'application au moment de la création pour permettre une optimisation plus poussée et éviter les tâches redondantes lors des démarrages ultérieurs.
Le principal avantage est un démarrage plus rapide à partir d'un petit package de déploiement exécutable unique. Le démarrage plus rapide vient de la possibilité d'éviter les comportements dynamiques de Java tels que le chargement et la vérification des classes et la résolution de chaque champ et méthode lors de la première utilisation. Et de l'utilisation de l'initialisation au moment de la construction pour déplacer des opérations - telles que l'initialisation de classe - de l'exécution au moment de la construction.
Les améliorations de l'empreinte au moment de l'exécution sont plus évidentes pour les applications avec de petits tas, car sinon, la taille du tas domine complètement la plus petite quantité de mémoire nécessaire pour les métadonnées de classe.
InfoQ : Que faut-il aux développeurs pour migrer du modèle classique de "VM dynamique" de Java vers Static Java ?
Dan Heidinga : même si des guides et des outils sont disponibles, les développeurs doivent s'attendre à consacrer pas mal d'efforts à relever les défis pour transformer leur application en une application statique.
Static Java, comme son nom l'indique, est beaucoup moins dynamique que le Java standard. Par conséquent, l'utilisation de nombreuses fonctionnalités dynamiques de Java, telles que la réflexion, les MethodHandles, le chargement de classe, la génération de bytecode et les agents JVMTI, peut entraîner des problèmes. Un bon point de départ est l'agent de traçage (tracing agent) de GraalVM pour créer les fichiers de configuration requis pour prendre en charge l'utilisation de ces fonctionnalités dynamiques. L'une des exigences de Static Java - que les capacités dynamiques deviennent plus limitées et doivent être explicitement activées au moment de la construction.
Choisir un framework qui utilise Static Java (par exemple, Quarkus, Micronaut) vous permettra de profiter de ses avantages sans les obstacles à l'adoption.
InfoQ : Est-ce que Static Java est déjà utilisé dans les systèmes de production ?
Dan Heidinga : Les premiers utilisateurs l'utilisent en production mais, principalement sur des projets entièrement nouveaux ou des cas d'utilisation non critiques pour leur permettre de renforcer leur confiance et leurs connaissances. Je m'attends à ce que la standardisation du modèle par OpenJDK via le project Leyden facilite l'adoption. À l'heure actuelle, Static Java, mis à part les frameworks qui ont facilité le chemin d'adoption, est encore difficile à démarrer.
Bien que je m'attende à ce que l'adoption continue de croître à mesure que les pratiques cloud continuent de prendre le dessus sur l'industrie et que les utilisateurs deviennent plus soucieux des coûts avec leurs déploiements cloud, la croissance sera lente car il y a beaucoup de logiciels qui ne pourront jamais s'adapter aux exigences de Static Java (et c'est OK !). Les utilisateurs qui ont besoin de ses caractéristiques commencent à peine à réaliser à quel point ces fonctionnalités sont importantes pour leurs déploiements.
Pour vraiment favoriser l'adoption par le grand public, Java doit prendre conscience des changements de phase (temps de construction vs temps d'exécution et point de contrôle vs restauration) et donner aux développeurs des outils pour dire ce qu'ils veulent dans le langage. Je pense que cela va arriver mais, étant donné les délais des projets OpenJDK existants, c'est probablement dans plus d'un an.
Avec le mouvement perpétuel vers le cloud et le besoin de temps de démarrage plus rapides et d'empreintes réduites, Static Java n'en est qu'au début de son voyage, selon Dan Heidinga. Mais la mise en œuvre du project Leyden pourrait accélérer son adoption. Néanmoins, à ce stade, il recommande de l'expérimenter, en indiquant les expériences menées par Andrew Dinn, distinguished engineer chez Red Hat. Dan Heidinga soutient également qu'il est difficile de dire à quel point le projet Leyden a progressé depuis son approbation en 2020, mais :
De nombreuses recherches et explorations sont en cours dans OpenJDK et les communautés environnantes, et j'espère que nous verrons cela se concrétiser dans le projet Leyden dans un avenir proche
Plusieurs projets ont des chevauchements avec l'espace de problèmes de Leyden, comme le projet CRaC, en particulier en ce qui concerne "comment exposer les différentes phases du modèle de programmation Java". De plus, la communauté GraalVM a continué à améliorer SubstrateVM pendant cette période.
Pour ceux qui rencontrent des problèmes insurmontables en adoptant Static Java, ou qui ne veulent tout simplement pas adapter leur conception dynamique existante, il y a encore de l'espoir pour un démarrage plus rapide : les efforts liés à CRiU, tels que le project CRaC, pour explorer un autre point sur le spectre entre Java statique et dynamique.