Java 27 : Quoi de neuf ?

Java 27 : Quoi de neuf ?

Maintenant que Java 27 est feature complete (Rampdown Phase One au jour d’écriture de l’article), c’est le moment de faire le tour des fonctionnalités qu’apporte cette nouvelle version pour nous, les développeurs.

Cet article fait partie d’une série d’articles sur les nouveautés des dernières versions de Java, pour ceux qui voudraient les lire, en voici les liens : Java 26, Java 25, Java 24, Java 23, Java 22, Java 21, Java 20, Java 19, Java 18, Java 17, Java 16, Java 15, Java 14, Java 13, Java 12, Java 11, Java 10, et Java 9.

Après Java 26 et ses 10 JEPs, Java 27 arrive avec un petit nombre de JEPs, 9, avec très peu de nouvelles fonctionnalités.

JEP 523 : Make G1 the Default Garbage Collector in All Environments

G1 a été défini comme Garbage Collector par défaut en Java 9. À ce moment-là, des tests ont montré que pour les environnements avec un CPU (ou moins) et moins de 1792 Mo de heap, le Garbage Collector Serial était plus performant. La JVM utilisait donc Serial par défaut dans ces cas-là.

Mais depuis, G1 a été amélioré, et des tests ont montré que G1 équivalait à Serial pour toutes les tailles de heap. Avec les améliorations pour réduire la synchronisation (JEP 522), G1 performe maintenant aussi bien que Serial, même pour un nombre réduit de CPU. Finalement, G1 a aussi vu une baisse de sa consommation de mémoire native, à des niveaux comparables à ceux de Serial.

Logiquement, G1 étant égal ou supérieur à Serial sur tous les critères, même dans des environnements avec peu de CPU et/ou peu de RAM, il est maintenant le défaut dans tous les environnements.

Plus d’informations dans la JEP 523.

JEP 527 : Post-Quantum Hybrid Key Exchange for TLS 1.3

Renforce la sécurité des applications Java nécessitant des communications réseau sécurisées en mettant en œuvre des algorithmes hybrides d’échange de clés pour TLS 1.3. Ces algorithmes permettent de se prémunir contre les futures attaques par informatique quantique en combinant un algorithme résistant à l’informatique quantique avec un algorithme traditionnel.

Un algorithme hybride d’échange de clés combine un algorithme résistant aux attaques quantiques avec un algorithme traditionnel, et reste sûr tant que l’un des deux algorithmes n’est pas cassé. Cette approche permet de se prémunir contre les attaques quantiques tout en reconnaissant que ces nouveaux algorithmes n’ont pas encore bénéficié des années de tests et d’analyses déjà effectués sur les algorithmes traditionnels.

L’implémentation de TLS 1.3 du JDK va prendre en charge trois nouveaux schémas hybrides d’échange de clés post-quantiques, qui combinent le Module-Lattice-Based Key-Encapsulation Mechanism (ML-KEM – ajouté via la JEP 496) avec les algorithmes traditionnels de Diffie-Hellman à courbe elliptique éphémère (ECDHE) :

  • X25519MLKEM768 : schéma hybride combinant ECDHE avec X25519 et ML-KEM-768,
  • SecP256r1MLKEM768 : schéma hybride combinant ECDHE utilisant la courbe secp256r1 avec ML-KEM-768,
  • SecP384r1MLKEM1024 : schéma hybride combinant ECDHE utilisant la courbe secp384r1 avec ML-KEM-1024.

Plus d’informations dans la JEP 527.

JEP 534 : Compact Object Headers by Default

Compact object headers permet à la JVM de stocker le header des objets sur 64 bits au lieu de 128 : 22 bits pour le pointeur de classe, 31 bits pour le hash code, 4 bits réservés pour Valhalla, et les bits restants comme précédemment pour l’âge GC et les flags de la JVM.

Les compact object headers ont été introduits en tant que structure alternative d’en-tête d’objet en preview en Java 24 via la JEP 450, puis sont sortis de preview en Java 25.

Depuis lors, les compact object headers ont prouvé leur stabilité et leurs performances.

Elles ont été testées chez Oracle à l’aide de la suite complète de tests du JDK. Elles ont également été testées chez Amazon et SAP, qui les ont activés par défaut.

Diverses expériences démontrent que l’activation des compact object headers améliore les performances :

  • Le benchmark SPECjbb2015 utilise 22 % d’espace de heap en moins et 8 % de temps CPU en moins.
  • Le nombre de garbage collections effectuées par SPECjbb2015 est réduit de 15 %, tant avec le collecteur G1 qu’avec le collecteur parallèle.
  • Un benchmark de parseur JSON hautement parallèle s’exécute 10 % plus rapidement.

En Java 27, les compact object headers sont activés par défaut. Il est prévu de déprécier l’ancien layout dans une release future.

Plus d’informations dans la JEP 534.

JEP 536 : JFR In-Process Data Redaction

Les fichiers d’enregistrement JFR contiennent les arguments de ligne de commande ainsi que les valeurs des variables d’environnement et des propriétés système, ce qui permet de voir comment le processus a été lancé et configuré. Ces événements peuvent donc contenir des données sensibles, telles que des secrets dans les arguments de ligne de commande, les variables d’environnement et les propriétés système. À l’heure actuelle, ces données apparaissent telles quelles dans les fichiers d’enregistrement, ce qui présente un risque de fuite d’informations sensibles lorsque les enregistrements sont partagés.

JFR va désormais masquer par défaut de nombreux types d’informations sensibles, sans aucune configuration supplémentaire.

Vous pouvez sélectionner explicitement les informations que JFR doit masquer grâce à de nouvelles sous-options de l’option de ligne de commande existante -XX:FlightRecorderOptions. Chaque sous-option spécifie un ou plusieurs filtres qui sélectionnent les arguments de ligne de commande, les variables d’environnement et les propriétés système à masquer.

La sous-option redact-argument spécifie une liste de filtres pour les arguments de ligne de commande, et la sous-option redact-key spécifie une liste de filtres pour les paires clé-valeur sous forme de variables d’environnement et de propriétés système.

Les filtres utilisent des patterns glob, où * et ? sont des caractères génériques. Si un filtre correspond à un argument ou à une clé, l’argument ou la valeur de la clé est enregistré(e) dans l’événement sous la forme [REDACTED]. Les filtres multiples sont séparés par des points-virgules et sont évalués dans l’ordre indiqué. Les différentes sous-options de -XX:FlightRecorderOptions sont séparées par des virgules.

Par exemple, pour masquer toute variable d’environnement ou propriété système nommée « confidential » ou « CONFIDENTIAL », ainsi que tout argument de ligne de commande ressemblant à une URL contenant un nom d’utilisateur et un mot de passe (c’est-à-dire username:password@hostcode>username:password@host</code), utilisez :

java -XX:FlightRecorderOptions:'redact-key=confidential,redact-argument=https://*:*@*' \
       -XX:StartFlightRecording:filename=dump.jfr \
       -Dconfidential=ANOTHER_SECRET \
       -jar application.jar https://john:YET_ANOTHER_SECRET@example.com/login --verbose

Pour vérifier que les informations sensibles ont bien été masquées, utilisez la commande jfr print :

$ jfr print \
      --events InitialSystemProperty,InitialEnvironmentVariable \
      dump.jfr
[...]
jdk.InitialEnvironmentVariable {
  startTime = 17:39:02.244 (2026-02-15)
  key = "CONFIDENTIAL"
  value = "[REDACTED]"
}

Les fonctionnalités qui sortent de preview

Les fonctionnalités suivantes sortent de preview (ou du module incubator) et passent en standard :

Aucune !

C’est assez rare pour le souligner. Une partie des fonctionnalités qui sont en preview depuis longtemps sont bloquées en attente du projet Valhalla.

Les fonctionnalités qui restent en preview

Les fonctionnalités suivantes restent en preview (ou en incubator module) :

  • JEP 531Lazy Constants : troisième preview, nouvelle API permettant de créer des constantes initialisées à la demande. Deux changements : suppression des méthodes de bas niveau isInitialized et orElse, ajout d’une méthode factory Set.ofLazy(...).
  • JEP 532Primitive Types in Patterns, instanceof, and switch : cinquième preview ajoute le support des types primitifs dans les instanceof et les switch, et enrichit le pattern matching pour supporter des patterns de types primitifs : dans les instanceof, dans les cases des switch, et dans la déconstruction d’un record* Aucun changement.
  • JEP 533Structured Concurrency : septième preview, nouvelle API permettant de simplifier l’écriture de code multithreadé en permettant de traiter plusieurs tâches concurrentes comme une unité de traitement unique. Plusieurs changements à l’interface Joiner : la méthode join() admet un troisième argument pour l’exception qu’un StructuredTaskScope peut lever ; awaitAll() a été supprimé au profit de allSuccessfulOrThrow(), anySuccessfulOrThrow(), et awaitAllSuccessfulOrThrow(), qui créent des joiner qui lèvent une ExecutionException en cas d’exception ; onTimeout() a été remplacé par timeout().
  • JEP 537Vector API : douzième incubator API permettant d’exprimer des calculs vectoriels qui se compilent au moment de l’exécution en instructions vectorielles pour les architectures CPU prises en charge. Aucun changement. Il a été acté dans la JEP que la Vector API sera en incubation tant que les fonctionnalités du projet Valhalla ne seront pas disponibles en preview. Ce qui était attendu, car la Vector API pourra alors tirer parti des améliorations de performance et de représentation en mémoire que devrait apporter le projet Valhalla.
  • JEP 538PEM Encodings of Cryptographic Objects : troisième preview, nouvelle API qui apporte le support du format Privacy-Enhanced Mail (PEM) à Java. Ajout de constructeurs qui prennent en entrée des tableaux d’octets encodés en BASE64 à la classe PEM ; DEREncodable a été renommé en BinaryEncodable ; ajout de la méthode EncryptedPrivateKeyInfo.getKeyPair() et ajout d’une exception CryptoException utilisée pour signaler les exceptions cryptographiques.

Pour les détails sur celles-ci, vous pouvez vous référer à mes articles précédents.

Divers

Divers ajouts au JDK :

  • Math.acosh(double) et StrictMath.acosh(double) : renvoie l’inverse du cosinus hyperbolique d’une valeur de type double.
  • Math.asinh(double) et StrictMath.asinh(double) : renvoie l’inverse du sinus hyperbolique d’une valeur de type double.
  • Math.atanh(double) et StrictMath.atanh(double) : renvoie l’inverse de la tangente hyperbolique d’une valeur de type double.
  • String.encodedLength(Charset) : renvoie la longueur, en octets, de cette chaîne de caractères encodée avec le jeu de caractères indiqué.
  • BigDecimal.rootn(int, MathContext) : renvoie une approximation de la racine n-ième de cette valeur, arrondie selon les paramètres de contexte.
  • DateTimeFormatter supporte maintenant les offsets de timezone courts (+01 au lieu de +01:00), voir JDK-8210336.

La totalité des nouvelles API du JDK 27 peut être trouvée dans The Java Version Almanac – New APIs in Java 27.

Des changements internes, de la performance et de la sécurité

Comme toutes les nouvelles versions de Java, OpenJDK 27 contient son lot d’optimisations de performance et d’améliorations de sécurité.

Côté performance, j’ai noté deux améliorations intéressantes :

  • HashMap.putAll() a maintenant un raccourci quand la Map est une HashMap, qui va directement appeler putHashMapEntries(), ce qui amène une amélioration de 66 à 86 % (PR #28243) ;
  • un nouvel intrinsic pour l’architecture AVX2 a été ajouté pour les binary search, ce qui amène une amélioration de 1,5x à 2,35x pour les tableaux au-dessus d’un certain seuil (int=256, long=768, short=512, char=512) (PR #30612).

Côté sécurité, on peut citer :

  • l’ajout du support de la compression des certificats TLS (JDK-8372526) ;
  • l’ajout des certificats WISeKey au truststore de la JVM (JDK-8372351) ;
  • une nouvelle commande jcmd VM.security_properties pour lister les propriétés de sécurité activées (JDK-8364182).

jcmd, la commande de management tout-en-un de la JVM, supporte maintenant la complétion bash (JDK-8357439).

La fonctionnalité expérimentale JVM Compiler Interface (JVMCI) a été supprimée (JDK-8382582). En citant les notes de release :Le JVMCI proposait une API Java interne expérimentale permettant d’écrire en Java un compilateur JIT pouvant être appelé par Hotspot. Après plus d’une décennie d’expérimentation, les coûts liés à sa maintenance et à ses tests au sein du JDK ont fini par l’emporter sur les avantages qu’il apportait au nombre limité de cas d’utilisation en aval auxquels il répondait. Les projets en aval qui dépendent du JVMCI doivent désormais l’intégrer et le maintenir dans leurs propres arborescences de développement, ou rester sur des versions antérieures du JDK. GraalVM était le plus connu de ces projets ; le compilateur Graal ne cite plus JVMCI dans sa documentation, utiliser le compilateur Graal à la place de C2 ne doit plus être supporté.

JFR Events

Voici les nouveaux événements Java Flight Recorder (JFR) de la JVM :

  • ShenandoahPromotionInformation : aucune description.

Vous pouvez retrouver tous les événements JFR supportés dans cette version de Java sur la page JFR Events.

Conclusion

Java 27 est une petite release sans gros changements ni nouvelles fonctionnalités. La bonne nouvelle, c’est que son successeur, Java 28, va très probablement contenir les premières phases du projet Valhalla, car la JEP 401 – Value Objects a déjà un PR ouvert (#31122) !

Pour retrouver tous les changements de Java 27, voir les [release notes](https://jdk.java.net/27/release-notes

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.