2022-11-15 06:43 Temps de lecture : 13 min

Quoi de neuf dans Java 17 ?

La version de support à long terme (LTS) de Java 17, tant pour le langage que pour sa plateforme d'exécution, a été officiellement lancée le 14 septembre 2021. Cet article explore les nouveautés de cette version majeure et examine les raisons pour lesquelles une mise à niveau pourrait être bénéfique.

Nombreuses sont les applications qui fonctionnent encore sur des versions antérieures de Java, y compris les précédentes versions LTS telles que Java 11 et Java 8.

Pourquoi une entreprise devrait-elle envisager une migration vers la dernière version de Java ? Le passage à Java 17 implique un certain investissement, mais il permet de profiter pleinement des nouvelles fonctionnalités et améliorations de la machine virtuelle Java (JVM).

Pour faciliter cette transition, de nombreuses organisations se tournent vers Docker et ses images, ce qui permet une mise à niveau vers Java 17 avec un minimum d'effort et de temps. Les développeurs peuvent intégrer leurs pipelines d'intégration et de déploiement continus (CI/CD) et exécuter l'ensemble dans des images Docker. Cette approche permet de ne pas impacter les équipes utilisant d'anciennes versions de Java, qui peuvent continuer à utiliser leurs images Docker existantes.

Nouveautés de Java 17

Amélioration du support pour macOS et AArch64

Une amélioration majeure de la JVM dans cette version est le support renforcé de macOS sur l'architecture AArch64 (JEP 391). Cela inclut la prise en charge des processeurs de la série M1 d'Apple, sortis récemment.

Bien que certains fournisseurs aient déjà proposé des versions du JDK compatibles avec cette architecture, y compris des versions rétrospectives pour Java 8, cette reconnaissance officielle est essentielle pour garantir la maintenance et le support à long terme de la plateforme. A titre de comparaison, le support de Linux/AArch64 a été introduit avec Java 9, et celui de Windows/AArch64 dans Java 16.

Classes scellées

Les classes scellées, introduites dans Java 17, ont achevé leur phase de test et sont désormais une fonctionnalité standard du langage et de la plateforme. Elles permettent au développeur de définir précisément les sous-types autorisés pour un type donné, empêchant ainsi toute extension ou implémentation non désirée.

Grâce aux classes scellées, le compilateur peut détecter et signaler des erreurs au moment de la compilation en cas de tentative de conversion d'un type non scellé en un sous-type non autorisé. Java 17 apporte également un nouveau pipeline de rendu pour les applications AWT/Swing sur macOS, utilisant l'API Apple Metal au lieu d'OpenGL. Enfin, cette version améliore l'API et les fonctionnalités de génération de nombres aléatoires.

Changements, suppressions et restrictions de Java 17

Java 17 apporte des modifications, des suppressions et de nouvelles restrictions.

Encapsulation des composants internes du JDK

La finalisation de l'encapsulation des composants internes du JDK constitue un changement important. Cette initiative, amorcée avec Java 9, générait des avertissements lors de tentatives d'accès aux API internes par réflexion. Des arguments de ligne de commande étaient disponibles pour contrôler ce comportement.

À partir de Java 9, de nouvelles API ont été créées pour remplacer les méthodes d'accès internes aux API. Avec Java 16, l'accès interne est passé d'un avertissement à une exception par défaut. L'utilisation d'arguments en ligne de commande permettait de modifier ce comportement.

Java 17 supprime la possibilité d'utiliser les arguments de ligne de commande, rendant impossible de désactiver cette restriction. Tout accès non autorisé à ces API internes est désormais strictement interdit.

Sémantique des nombres à virgule flottante toujours stricte

Une autre "suppression" notable est le rétablissement de la sémantique stricte des nombres à virgule flottante. Java 1.2 avait introduit une flexibilité permettant à la JVM de privilégier la performance au détriment d'une très faible quantité de précision. Le mot-clé strictfp permettait de spécifier l'utilisation d'une sémantique stricte. Avec l'évolution des processeurs, la sémantique stricte est devenue utilisable sans impact négatif sur les performances.

Java 17 supprime donc la possibilité de choisir, la sémantique à virgule flottante est toujours stricte. Bien que le mot-clé strictfp soit toujours présent, il n'a plus aucun effet et génère un avertissement à la compilation.

Compilation anticipée (AOT)

La compilation anticipée (AOT), introduite comme fonctionnalité expérimentale dans Java 9 utilisant le compilateur Graal, a continué de se développer. Java 10 a intégré le compilateur Graal au sein d'OpenJDK via l'interface JVMCI, permettant son utilisation en tant que compilateur JIT. Le compilateur Graal a fait des progrès considérables et est à la base de la JVM GraalVM.

Suppression de l'activation RMI

L'activation RMI, introduite dans JEP 407, a été supprimée après avoir été retirée de Java 8 puis rendue obsolète dans Java 15. L'activation RMI permettait d'activer des ressources à la demande pour des objets distribués. Cependant, son utilisation était devenue marginale, et des alternatives plus performantes existent aujourd'hui. Cette suppression ne concerne pas le reste du framework RMI.

Suppression de l'API Applet

L'API Applet, retirée dans Java 9 et officialisée pour suppression par JEP 398, permettait d'intégrer des composants Java AWT/Swing au sein d'une page web. Les navigateurs modernes ne supportant plus cette fonctionnalité, les applets sont devenues inaccessibles depuis près d'une décennie.

Gestionnaire de sécurité

La suppression du gestionnaire de sécurité (JEP 411) est une autre suppression importante. Introduit dans Java 1.0, il était conçu pour limiter les actions qu'une application Java pouvait réaliser, comme l'accès au réseau, aux fichiers ou à d'autres ressources locales. Il permettait également de "sandboxer" du code non approuvé.

La suppression du gestionnaire de sécurité a été initiée dans Java 12 avec l'ajout d'un argument de ligne de commande pour le désactiver à l'exécution. Java 17 émet un avertissement à l'exécution en cas de tentative de définition d'un gestionnaire de sécurité.

Fonctionnalités d'incubateur et d'aperçu

Malgré son statut de version LTS, Java 17 propose des fonctionnalités en incubateur et en aperçu.

API Vectorielle

L'API vectorielle (JEP 414) est actuellement en phase d'incubateur. Elle permet aux développeurs de décrire des calculs vectoriels, que le compilateur JIT traduit en instructions vectorielles du processeur (SSE ou AVX par exemple).

Auparavant, les développeurs devaient utiliser des opérations scalaires ou des bibliothèques natives spécifiques à la plateforme. L'implémentation de l'API vectorielle en Java fournit un mécanisme de secours transparent.

La standardisation de l'API vectorielle permet aux classes du JDK de l'exploiter. Des méthodes comme `Arrays.mismatch()` pourraient ainsi être implémentées de façon plus performante en Java.

API Foreign Function & Memory

L'API Foreign Function & Memory (JEP 412) est une autre fonctionnalité en incubateur. Elle combine et fait évoluer deux modules incubateurs de Java 16 : l'API Foreign Linker (JEP 389) et l'API Foreign Memory (JEP 393). Cette API fournit un accès à la mémoire et au code natifs en utilisant une programmation statiquement typée en Java.

Correspondance de motifs pour le `switch`

La correspondance de motifs pour l'instruction `switch` (JEP 406) est une fonctionnalité d'aperçu du langage incluse dans Java 17. Cette fonctionnalité étend la puissance des expressions et instructions `switch` en permettant de faire correspondre des cas en fonction du type, suivant le modèle de la correspondance de motifs (`instanceof`) introduite dans Java 16 (JEP 394).

Auparavant, un code comme celui-ci était nécessaire pour effectuer des actions différentes selon la nature dynamique d'un objet :

String type(Object o) {
  if (o instanceof List) {
    return "Une liste d'éléments.";
  }
  else if (o instanceof Map) {
    return "Une map : clés et valeurs.";
  }
  else if (o instanceof String) {
    return "Ceci est une chaîne.";
  }
  else {
    return "Ceci est autre chose.";
  }
}

Avec la combinaison de l'expression `switch` et de la correspondance de motifs, le code se simplifie comme suit :

String type(Object o) {
  return switch (o) {
    case List l -> "Une liste d'éléments.";
    case Map m -> "Une map : clés et valeurs.";
    case String s -> "Ceci est une chaîne.";
    default -> "Ceci est autre chose.";
  };
}

Comme vous le constatez, la variable est déclarée directement au moment du test. La correspondance de motifs indique que l'objet a été vérifié, transtypé, et est disponible via la variable dans la portée du `case`.

Cette fonctionnalité en aperçu est un pas de plus vers une correspondance de modèles plus riche. L'étape suivante serait l'ajout de la déconstruction de tableaux et d'enregistrements.

Faut-il passer à Java 17 ?

La réponse est oui, il est conseillé de passer à la dernière version, mais pas nécessairement dès le premier jour. Il est possible que les logiciels et bibliothèques que vous utilisez ne soient pas encore compatibles avec Java 17. Il peut être nécessaire d'attendre que les mises à jour nécessaires soient publiées.

Si vous utilisez une version LTS comme Java 8 ou Java 11, Java 17 propose de nombreuses améliorations significatives dans le langage et dans la JVM qui justifient une mise à niveau. Puisqu'il s'agit d'une version de maintenance à long terme, il est très probable que vos environnements de production migreront eux aussi vers Java 17.

Si vous démarrez un nouveau projet ou si votre projet est préparé pour Java 17, une mise à niveau précoce est probablement le choix le plus efficace afin de réduire les coûts de migration. Cela permet également aux développeurs de profiter des dernières fonctionnalités et des améliorations côté opérationnel.

Enfin, cette mise à niveau vous permettra de bénéficier des nombreuses améliorations de ces dernières années, comme l'amélioration du support des conteneurs exécutant des applications Java et de nouvelles implémentations de collecteurs de mémoire à faible latence.

Auteur
France

Rédacteur tech, guides pratiques et astuces numériques.