Sortie de Java 17, quoi de neuf ?

Oracle a annoncé la sortie et la disponibilité de Java 17, le 14 septembre dernier. C’est une release majeure, du fait qu’elle soit une LTS. Le support est garanti pour une période de 8 années. Pour rappel la dernière version LTS est Java 11, qui est sortie il y a de cela 3 ans. Dans cet article, nous faisons le tour des JEPs (fonctionnalités) ajoutées depuis la version 16.

JEP 306: Restore Always-Strict Floating-Point Semantics

Les opérations en virgules flottantes seront strict par défaut, cela veut dire que les résultats des opérations en virgules flottantes seront les mêmes, quelle que soit l’architecture matérielle sous-jacente. Depuis la version 1.2 de Java, pour s’assurer que les opérations en virgules flottantes soient déterministes sur les différentes architectures matérielles, il fallait utiliser strictfp. Dorénavant, strictfp est la sémantique par défaut dans les opérations à virgule flottante.

JEP 356: Enhanced Pseudo-Random Number Generators

Cette JEP améliore l’API des générateurs de nombre pseudo-aléatoires. Elle y ajoute d’abord une nouvelle interface RandomGenerators qui uniformise l’API des nombres pseudo-aléatoires et introduit les streams via l’interface StreamableGenerator. Ensuite, un refactoring a été réalisé les classe de l’API pour une meilleure maintenance et évolutivité, accompagné d’une amélioration de la robustesse des algorithmes utilisés.

JEP 382: New macOS Rendering Pipeline

Nouvelle implémentation du pipeline de rendu Java 2D pour MacOS, utilisant Apple Metal API, comme alternative au pipeline existant qui utilise l’API Apple OpenGL, qui elle est dépréciée.

JEP 391: macOS/AArch64 Port

Un port de la JDK sur macOS / AArch64 (processeurs ARM). Ceci est la conséquence de l’annonce d’Apple en 2020 du passage des processeurs Intel vers les processeurs ARM.

JEP 398: Deprecate the Applet API for Removal

L’API Applet a déjà été dépréciée depuis Java 9, mais pas pour une suppression. Cette JEP déprécie l’API applet pour une future suppression.

JEP 403: Strongly Encapsulate JDK Internals

Le but de cette JEP est de supprimer l’accès à certains packages / classes internes à la JDK. En effet ces éléments qui ne sont pas sensés être utilisés, sont massivement utilisés par les librairies et les frameworks. Cette JEP encourage les librairies utilisant ces éléments internes à migrer vers les API standards. Les librairies qui utilisent ces éléments ne pourront tout simplement pas fonctionner. A titre d’exemple la très populaire lib Lombock.

Cette restriction a été introduite dans Java 16, mais il y avait une manière de contourner en utilisant le flag −−illegal-access.A partir de JDK 17, ce flag n’aura aucun effet.

JEP 406: Pattern Matching for switch (Preview)

Fonctionnalité en preview. Suite à l’introduction du pattern matching pourinstance of, il est paru naturel aussi d’ajouter le pattern matching pour le switch. Ainsi, le code suivant à base de if/else:

static String formatter(Object o) {
    String formatted = "unknown";
    if (o instanceof Integer i) {
        formatted = String.format("int %d", i);
    } else if (o instanceof Long l) {
        formatted = String.format("long %d", l);
    } else if (o instanceof Double d) {
        formatted = String.format("double %f", d);
    } else if (o instanceof String s) {
        formatted = String.format("String %s", s);
    }
    return formatted;
}

Peut être réécrit avec le switch Java 17, en utilisant la nouvelle syntaxe introduite dans Java 16 et le pattern matching :

static String formatterPatternSwitch(Object o) {
    return switch (o) {
        case Integer i - > String.format("int %d", i);
        case Long 1 - > String.format("long %d", 1);
        case Double d - > String.format("double %f", d);
        case String s - > String.format("String %s", s);
        default - > o.toString();
    };
}

JEP 407: Remove RMI Activation

C’est un mécanisme introduit dans le JDK 7, qui permet de s’assurer que les services sont disponibles (crash recovery, persistent references, on demand). Avec l’évolution des web services, des containers et des orchestrateurs, ce mécanisme est jugé obsolète. RMI Activation est donc déprécié à partir de la JDK 15, pour être supprimé dans le JDK 17. Il faut noter que cela ne modifie en rien le reste de RMI et ce n’est point une dépréciation de RMI.

JEP 409: Sealed Classes

Introduites dans Java 15 en preview, les Sealed Classes sont définitivement adoptées dans Java 17. Le but est de pouvoir définir une classe ou une interface comme étant scellée, en contrôlant quelles classes ou interfaces peuvent en hériter.

Attention: ce n’est en aucun cas un remplacement des access modifiers ou un remplacement du mot clé “final”.

Le mot clé utilisé est sealed. En voici un exemple :

public abstract sealed class Shape permits Circle
{

    public abstract Point getCenter();public non-sealed

    class Circle extends Shape {
        private Point center;

        public Circle() {
            this.center = new Point(0, 0);
        }

        public Circle(int x, int y) {
            this.center = new Point(x, y);
        }

        @Override
        public Point getCenter() {
            return center;
        }
    }
}

Les sous-classes d’une classe Sealed, doivent utiliser l’un des modifiers suivants : sealed, non-sealed ou final. Le mot clé non-sealed permet d’ouvrir les parties déclarées de cette classe aux sous-classes.

JEP 410: Remove the Experimental AOT and JIT Compiler

Suppression du compilateur AOT (Ahead-Of-Time) / JIT (Just-In-Time) expérimental, introduit dans JDK 9 et JDK 10. Le compilateur AOT jaotc a été introduit dans le JDK 9, il utilise le compilateur Graal. Ce dernier est également utilisé à titre expérimental comme compilateur JIT dans le JDK 10. Cette suppression intervient car ces fonctionnalités expérimentales sont très peu utilisées.

JEP 411: Deprecate the Security Manager for Removal

Dépréciation du Security Manager. Très peu utilisé dans la sécurisation du code serveur, il a surtout été conçu pour sécuriser le code client (Applets). Cette dernière API sera supprimée dans le futur, et avec le Security Manager.

JEP 412: Foreign Function & Memory API (Incubator)

Cette JEP introduit une nouvelle manière d’interagir avec du code et des données en dehors de la JVM. Cette API permet d’appeler des fonctions externes à la JVM, et d’accéder de façon sécurisée à des espaces mémoire en dehors de la JVM. Cela donne la possibilité à des programmes Java d’utiliser des librairies natives, en évitant les dangers et la fragilité de JNI.

JEP 414: Vector API (Second Incubator)

Nouvellement introduite dans la JDK 17, cette API offre la possibilité d’effectuer des opérations vectorielles (plusieurs opérations en même temps. Par exemple l’addition de deux tableaux). Cela permet de profiter des instructions vectorielles sur les CPU qui en sont équipés. Les programmes ainsi écrits en utilisant des instructions vectorielles atteignent des niveaux de performances beaucoup plus élevées que leurs équivalents scalaires. Cette fonctionnalité est en incubation, elle devrait être améliorée dans les prochaines versions.

JEP 415: Context-Specific Deserialization Filters

La désérialisation des objets est une opération dangereuse. Dans la JEP 290 introduite dans le JDK 9, il était possible de créer des filtres de désérialisation statiques, afin de renforcer la sécurité et la robustesse du code et des lib utilisées. Avec la JEP 290, il est par exemple possible d’autoriser ou de bannir les classes dé-sérialisables, le niveau de profondeur maximum autorisé pour les objets … Par contre, ces filtres sont spécifiés comme paramètre en ligne de commande, donc statiquement, mais surtout pour toutes les opérations de dé-sérialisation sur l’ensemble de la JVM. Dans le JDK 17, avec la JEP 415, il est possible de créer et de mettre en place ces filtres dynamiquement dans le code et par contexte.

Software Engineer & CEO @TechInstinct