URL: https://linuxfr.org/news/java-15-est-sorti Title: Java 15 est sorti Authors: barmic bobble bubble, Nonolapéro, Yves Bourguignon, Lawless, Benoît Sibaud, BAud, theojouedubanjo et Ysabeau Date: 2020-09-04T13:08:31+02:00 License: CC By-SA Tags: java Score: 4 Ce 15 septembre 2020 sort Java 15. C’est l’occasion pour cette dépêche de revenir sur les nouveautés entre les _texts blocks_ et autres _garbage collectors_. On en profite pour parler donner quelques informations autour de java (les 25 ans de la plateforme, les nouveaux champions, etc). ---- [OpenJDK 15](https://openjdk.java.net/projects/jdk/15/) [Quarkus 1.5](https://quarkus.io/blog/quarkus-1-5-final-released/) ---- # Java 15 ## Abandons Avec ce nouveau rythme, Java s’autorise à supprimer des parties de la plateforme. Pour cette version : - le système d’exploitation [Solaris](https://fr.wikipedia.org/wiki/Solaris_(syst%C3%A8me_d%27exploitation)) et l’architecture [SPARC](https://fr.wikipedia.org/wiki/Architecture_SPARC), [rendus obsolètes par la dernière version](https://linuxfr.org/news/java-14-tombe-le-masque#toc-les-mises-au-placard-et-lesd%C3%A9parts), ne sont plus pris en charge ([JEP 381](https://openjdk.java.net/jeps/381)) : cocasse quand on connaît les débuts du langage - [Nashorn](https://fr.wikipedia.org/wiki/Nashorn_(moteur_JavaScript)), le moteur JavaScript inclus dans le JDK, a lui aussi été retiré ([JEP 372](https://openjdk.java.net/jeps/372)). Il était considéré comme obsolète depuis la version 11 sortie en septembre 2018. - ce n’est pas encore une suppression, mais RMI Activation (et seulement RMI activation pas tout RMI) est rendu obsolète ([JEP 385](https://openjdk.java.net/jeps/385)) - _biased locking_ n’est plus activé par défaut (il faut ajouter l’option `-XX:+UseBiasedLocking`), elle est du même coup considérée obsolète ([JEP 374](https://openjdk.java.net/jeps/374)) ### Conséquences des retraits #### Cas de la prise en charge SPARC/SOLARIS Le JDK étant plutôt vaste, le retrait de la prise en charge d’une architecture a des conséquences à de très nombreux endroits allant des systèmes de construction, la sécurité, la génération du _bytecode_ ou encore la génération d’IHM. La personne en charge de la JEP a donc fait le tour du propriétaire pour retirer tout ce qui devait l’être comme on peut le voir [sur la liste de diffusion](https://mail.openjdk.java.net/pipermail/jdk-dev/2020-May/004292.html). Les plus curieux pourront suivre les différents liens pour voir le mode de développement du JDK et les spécificités de chaque domaine. Au final, ce sont plus de 127 000 lignes qui ont été supprimées, ce qui ne représente que moins d’un pourcent du nombre total de lignes de code. #### Cas de la gestion du JSON Suite à la suppression du Nashorn JavaScript Engine, il est apparu que le JDK utilisait le javascript et par conséquent le JSON pour certaines fonctionnalités. Se pose alors la question d’une gestion native du JSON ou de laisser cette compétence à des bibliothèques tierces. Actuellement, rien n’est décidé et il y a deux directions possibles : + Oui mais sous quelle forme et quand ? + Non pas pour éviter d’avoir quelque chose de mal foutu comme pour le XML ou encore le logging et se concentrer sur ce qui fait réellement la plus-value du JDK. ## Nouveautés ### Garbage collectors Deux nouveaux [garbage collectors](https://fr.wikipedia.org/wiki/Ramasse-miettes_(informatique)) (gc) sont disponibles en stable avec cette version : **Shenandoah** est un _gc_ qui vise à réduire les temps de pause. Pour atteindre cet objectif, il déplace les objets sans avoir à mettre en pause l’application. Il est aussi capable de mieux paralléliser le déplacement d’objet. Cela ne supprime pas totalement les pauses : elles sont encore nécessaires pour libérer la mémoire. Avec Shenandoah, la vérification des objets en vie et leur déplacement se fait sans pause, mais le nettoyage de la mémoire en réclame une. Comme il fait moins de choses pendant les pauses, elles sont plus courtes. L’activation se fait via l’option `-XX:+UseShenandoahGC`. Ce changement est décrit dans la [JEP 379](https://openjdk.java.net/jeps/379). **ZGC** se donne pour objectif d’avoir des temps de pause faibles, y compris sur de grands tas (_heap_) de l’ordre du téraoctet. Pour cela il est capable de décharger les classes sans arrêter l’exécution. Tous les _gc_ actuels de java effectuent du déchargement de classes, mais ils sont obligés de le faire uniquement durant le _stop the world_. ZGC a travaillé pour pouvoir faire cela en concurrence de l’application. Il semble que cela a eu des effets de bord positifs, notamment le temps de pause n’est dépendant que du nombre de _threads_ de l’application. Il s’agit de l’amélioration majeure, mais il y a eu bien d’autres travaux comme le fait de pouvoir rendre de la mémoire au système d’exploitation, la gestion de tas de 8 Mio jusqu’à 16 Tio. Actuellement seuls Windows, macOS, Linux/x86_64 et Linux/AArch64 sont pris en charge. Pour l’activer c’est l’option `-XX:+UseZGC`. Ce changement est décrit dans la [JEP 377](https://openjdk.java.net/jeps/377). > _C'est très bien mais, du coup, comment choisir entre Shenandoah, ZGC ou rester sur G1 ?_ C’est une question bien complexe qui est évidemment très dépendante de l’application cible. Premièrement G1, malgré le fait qu’il continue d’être amélioré, est très loin derrière ZGC et Shenandoah. Les objectifs de ces derniers sont assez similaires et ils sont tellement efficaces qu’on ne peut pas voir de différence entre eux quand ils sont comparés à G1… De mon avis personnel et de ce que j’en ai lu : - ZGC est fait pour être simple, il est moins configurable - Shenandoah est plus configurable et il offre des temps de pause plus prédictibles que ZGC Néanmoins tout cela peut encore changer d’ici la sortie de Java 17 (en septembre 2021). ### Blocs de texte Les blocs de textes arrivent enfin en version définitive ([JEP 378](https://openjdk.java.net/jeps/378)). Cette fonctionnalité a fait beaucoup parler d’elle depuis son introduction en java13. Il est donc maintenant possible de définir des chaînes de caractères multi-lignes comme ça : ```java String query = """ SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB" WHERE "CITY" = 'INDIANAPOLIS' ORDER BY "EMP_ID", "LAST_NAME"; """; ``` ### Hidden classes Cette nouveauté offre la possibilité aux frameworks de générer des classes pour son propre usage qui ne seront pas accessibles de l’extérieur et ainsi de gérer la tambouille interne sans risque de fuite, notamment en utilisant la réflexion. Java possède des classes internes, qui ne sont pas directement exposées au niveau de l’API, mais qui restent accessibles par réflexion. Ce n’est pas leur nom peu alléchant `Unsafe` qui empêche qu’elles soient largement utilisées par tout un tas de logiciels. Un des objectifs des développeurs du JDK est de faire en sorte que cette pratique cesse. Un article de [java magazine](https://blogs.oracle.com/javamagazine/the-unsafe-class-unsafe-at-any-speed) en parle et il y a bien-sûr la [JEP 371](https://openjdk.java.net/jeps/371) qui décrit cette évolution. C’est donc une étape de plus sur la route de la suppression des classes de `sun.misc.Unsafe`. ### Sous le capot - cette version inclut la prise en charge des signatures EdDSA ([JEP 339](https://openjdk.java.net/jeps/339)). - l’API `DatagramSocket` bénéficie d’une réimplémentation ([JEP 373](https://openjdk.java.net/jeps/373)) ### En vrac + Nouvelles méthodes pour obtenir une valeur absolue : [JDK-8241374](https://bugs.openjdk.java.net/browse/JDK-8241374) + Ajout de Unicode 13 : [JDK-8239383](https://bugs.openjdk.java.net/browse/JDK-8239383) + Mise à jour à la [version 37 de la base unicode CLDR](http://cldr.unicode.org/index/downloads/cldr-37) pour améliorer l’internationnalisation de vos logiciels. + L’AppCDS gère désormais les lambdas ce qui permet [d’accélerer encore un peu](https://twitter.com/gunnarmorling/status/1272454820474085377) le démarrage de la JVM. + Les énumérations peuvent désormais contenir 4103 constantes ! [JDK-8241798](https://bugs.openjdk.java.net/browse/JDK-8241798) ## Preview Les fonctionnalités ci-dessous sont considérées comme _preview_, elles sont sujettes à changement d’une version à l’autre. ### Pattern matching avec instanceof Le _pattern matching_ sur `instanceof` ([JEP 383](https://openjdk.java.net/jeps/383)) permet de discriminer un objet selon sa classe et de récupérer une référence correctement typée. Un exemple possible serait: ```java Object myVar = foo(); if (myVar instanceof String s) { System.out.println(s); } ``` Cela n’est pas encore disponible avec l’instruction `switch`. ### Sealed classes Les _sealed classes_ sont des classes dont on contrôle l’héritage. Cela permet d’avoir une connaissance à la compilation de toutes les classes filles de cette dernière. Le premier gain est de pouvoir s’assurer qu’on a géré tous les cas dans un `switch` qui vérifie le type par `instanceof`. C’est décrit dans la [JEP 360](https://openjdk.java.net/jeps/360). L’écriture est assez différente de ce que l’on trouve en Scala. Ce dernier oblige à ce que toutes les classes filles soient décrites dans le même fichier. Java garde la volonté d’avoir (en principe) une seule classe par fichier. Cela s’écrit donc ainsi : ```java package org.linuxfr; public abstract sealed class Contenu permits org.linuxfr.Depeche, org.linuxfr.Journal, org.linuxfr.Lien { // ... } ``` Il faut voir que cela remet en cause les possibilités d’étendre le code. Ça sert quasi uniquement quand on a besoin de l’_exhaustive checking_ au sein du _pattern matching_. Pour bien décrire l’intérêt, cela permet d’écrire : ```java String foo(Contenu c) { return swicth(c) { case Depeche d -> "plouf"; case Journal j -> "plif"; case Lien l -> "plof"; }; } ``` Sans avoir besoin d’avoir un cas `default`. ### Records Les _records_ (apparus dans la précédente version de Java) sont des classes immuables qui bénéficient d’une syntaxe succincte. Cette mise à jour assure le bon fonctionnement avec les _sealed classes_ et sur l’usage d’annotations, mais la [JEP 384](https://openjdk.java.net/jeps/384) est très complète pour décrire tout leur fonctionnement. Pour ce qui est du code un `Point` en 2 dimensions se déclarera comme ça : ```java record Point(int x, int y) {} ``` Et s’utilise comme n’importe quelle classe. Comme pour le constructeur vide créé par défaut, pour vous ici le langage définit le `equals()`/`hashCode()`, les _getter_ (avec un style _« builder »_, dans l’exemple on a `x()` et `y()`), le constructeur avec le profil que vous avez défini et une méthode `toString()`. Comme pour le constructeur par défaut, il est possible de surcharger les implémentations fournies. Cela devrait réduire l’intérêt de [lombok](https://projectlombok.org/) ou [immutables](https://immutables.github.io/). Cette nouvelle itération apporte diverses évolutions plus ou moins discrète : * Il y a l’interdiction d’utiliser `this` dans le constructeur canonique. C’est la solution trouvée pour éviter aux développeurs peu attentionnés de faire n’importe quoi. * Une modification tardive fait que les attributs des records deviennent réellement finaux et ne peuvent pas être modifiés par réflexion [JDK-8247444](https://bugs.openjdk.java.net/browse/JDK-8247444). * La possibilité de créer des `records` locaux de la même manière que les classes. * Les [mécanismes de sérialisation et de désérialisation](https://inside.java/2020/07/20/serializablerecords/) propre et qui, donc, diffèrent des classes : * la sérialisation est basée seulement sur l’état de l’objet ; * la désérialisation utilise uniquement le constructeur canonique. La version finale sera certainement livrée en version 16. # Écosystème ## fast-jar Le projet [Quarkus](https://en.wikipedia.org/wiki/Quarkus) est un framework Java alternatif à Spring visant l’extrême performance et à être _developer friendly_. Sa version 1.5 propose un nouveau packaging pour les applications Java nommé fast-jar. Un fichier au format JAR est une archive ZIP des applications Java contenant les classes compilées ainsi que quelques fichiers de description et des fichiers de configuration de l’application. Il est possible d’y inclure les bibliothèques utilisées par l’application : c’est ce que l’on appelle un fat-jar ou un uber-jar. C’est un peu comme une compilation statique, cela permet de distribuer l’application avec un unique fichier (il faut « juste » avoir un JDK installé). La simplicité de ces uber-jar leur a fait rencontrer un vif succès, mais l’arrivée de Docker a un peu changé la donne. Le système de layer de Docker (une image Docker dépend d’une précédente image dont on a modifié le contenu) pousse à organiser ses images comme suit : 1. l’image de base contenant le JDK 2. on ajoute les dépendances de l’application dans une couche dédiée 3. on ajoute l’application dans une autre layer 4. si applicable, on ajoute les fichiers de configuration dans une dernière layer L’idée sous-jacente est de découper les couches en fonction de la fréquence de mise à jour : 1. on modifie plus fréquemment sa configuration que l’application 2. on met à jour plus fréquemment l’application que ses dépendances 3. on met à jour plus fréquemment les dépendances que le JDK Cela permet de ne télécharger que les dernièrs layers lors des mises à jour. Lors de leurs tests de performance, les développeurs de Quarkus se sont rendu compte que le temps de démarrage d’une application uber-jar est bien plus court qu’avec les dépendances séparées ([voir ici](https://twitter.com/agoncal/status/1298205802709364737)). Pour pouvoir à la fois avoir un packaging Java efficace et continuer de suivre les bonnes pratiques Docker, ils ont créé fast-jar. Il s’agit simplement d’un JAR éclaté, mais qui possède un index dans le JAR principal qui indique où trouver chaque classe. Le chargeur de classes n’a donc plus à aller chercher dans chaque JAR si la classe qu’il cherche s’y trouve ou non. ## Développement du JDK La version 16 du JDK donnera quelques modifications importantes dans son développement : - passage à C++14 ([JEP 347](https://openjdk.java.net/jeps/347)), actuellement cantonné à C++98 les nouveaux développements seront effectués avec la norme C++14. La JEP décrit ce qui est autorisé ou non d’utiliser - [devnewton en avait parlé dans les liens](https://linuxfr.org/users/devnewton/liens/l-openjdk-abandonne-mercurial-pour-git) : passage de mercurial à git ([JEP 357](https://openjdk.java.net/jeps/357)), cette décision est motivée par la taille de l’historique, l’outillage autour de git et les hébergements dispo pour git. Justement dans la foulée il a été décidé de partir chez github ([JEP 369](https://openjdk.java.net/jeps/369)). Vous trouverez les raisons de ce changement dans la JEP associée : [Why GitHub?](https://openjdk.java.net/jeps/369#Why-GitHub?) ## Java champions Les _Java Champions_ sont un groupe de promoteurs de Java indépendants d’Oracle (ou de Sun à l’époque). Les membres sont élus par leurs pairs (et sont aussi proposés à l’élection de cette façon). Le 5 mai dernier, Audrey Neveu était élue _Java Champion_. Elle travaille chez [Pivotal](https://en.wikipedia.org/wiki/Pivotal_Software) comme développeuse Java/Kotlin/JS et est surtout connue en tant que membre des [Cast Codeurs](https://lescastcodeurs.com/) où elle sensibilise aux enjeux sociétaux que les technologies peuvent poser (les risques liés aux libertés, les problèmes que les GAFAM peuvent induire…). ## 25 ans de Java Le 25 mai dernier Java a soufflé ses 25 bougies. Ça a été l’occasion de créer différents évènements : par exemple, Oracle a mis en ligne [Moved by java](https://www.oracle.com/java/moved-by-java/), et ParisJUG a organisé une soirée rétrospective avec plusieurs champions Java francophones c’est [visible sur youtube](https://www.youtube.com/watch?v=ocQeuV8vejw). On y retrouve pêle-mêle : - [Audrey Neveu](https://twitter.com/audrey_neveu) nouvelle championne - [Antonio Goncalves](https://antoniogoncalves.org/) cofondateur du ParisJUG, de Devoxx France, il travaille pas mal autour de JavaEE - [Emmanuel Bernard](https://emmanuelbernard.com/) développeur Red-Hat sur les projets Hibernate et maintenant Quarkus - [Jean-Michel Doudoux](https://www.jmdoudoux.fr/) il a produit énormément de documentations autour de java, entre autres sur [developpez.com](https://jmdoudoux.developpez.com/cours/developpons/java/), il en publie aussi sur [son propre site](http://www.jmdoudoux.fr/accueil_java.htm) - [Rémi Forax](http://www-igm.univ-mlv.fr/~forax/) enseignant à l’université, il est contributeur OpenJDK depuis très longtemps Il y a aussi un article sympa listant [25 supers applications](https://blogs.oracle.com/javamagazine/the-top-25-greatest-java-apps-ever-written). ## AdoptOpenJDK devient Adoptium AdoptOpenJDK est une distribution de Java très populaire. Elle a rejoint en juin dernier la [fondation Eclipse](https://blog.adoptopenjdk.net/2020/06/adoptopenjdk-to-join-the-eclipse-foundation/). Il peut être compliqué d’un point de vue légal d’utiliser le nom « OpenJDK », il a donc été choisi de renommer le projet [Eclipse Adoptium](https://projects.eclipse.org/projects/adoptium). Cela va permettre au projet de bénéficier de toute l’infrastructure proposée par Eclipse d’un point de vue technique (hébergement par exemple) et organisationnel (la gouvernance n’est pas attachée à une éventuelle entreprise).