IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

JDK 18, l'implémentation de référence de Java 18, est désormais disponible,
Elle propose comme Python, Ruby, PHP ou encore Erlang, un mini serveur Web prêt à l'emploi

Le , par Bruno

166PARTAGES

12  0 
Oracle Technologie a annoncé le 22 mars la sortie de la version 18 de JDK, l'implémentation de référence de Java 18, elle arrive avec un serveur web amélioré, une réimplémentation de Core Reflection avec des gestionnaires de méthode, une amélioration du SPI de résolution des adresses Internet et bien plus. « JDK 18, l'implémentation de référence de Java 18, est maintenant en disponibilité general (GA). Nous avons livré la build 36 en tant que première Release Candidate du JDK 18 le 15 février, et aucun bogue n'a été signalé. La build 36 est donc maintenant la build GA, prête à être utilisée en production », a déclaré Mark Reinhold, Architecte en chef, Java Platform au Groupe Oracle.

En fin d’année dernière, l'équipe Java Platform au Groupe Oracle a livré une Preview des nouveautés du JDK 18. Aujourd’hui, Java 18 est livré avec une API pour les vecteurs, un deuxième aperçu de la correspondance des motifs pour les instructions switch, l'UTF-8 comme jeu de caractères par défaut et d'un serveur Web minimal.

Réimplémentation de Core Reflection avec des gestionnaires de méthode

La réflexion de base a deux mécanismes internes pour invoquer les méthodes et les constructeurs. Pour un démarrage rapide, il utilise les méthodes natives de la VM HotSpot pour les premières invocations d'une méthode réflective spécifique ou d'un objet constructeur. Pour une meilleure performance maximale, après un certain nombre d'invocations, il génère du bytecode pour l'opération de réflexion et l'utilise lors des invocations suivantes.


Réimplémente les éléments java.lang.reflect.Method, Constructor et Field sur les gestionnaires de méthode java.lang.invoke. En faisant des gestionnaires de méthodes le mécanisme sous-jacent de la réflexion, les developpeurs reduisent les coûts de maintenance et de développement des API java.lang.reflect et java.lang.invoke.

Pour l'accès aux champs, la réflexion de base utilise l'API interne sun.misc.Unsafe. Avec l'API java.lang.invoke method-handle introduite dans Java 7, il existe en tout trois mécanismes internes différents pour les opérations de réflexion :

  • les méthodes natives VM ;
  • les gestionnaires de méthode ;
  • les stubs de bytecode générés dynamiquement pour Method::invoke et Constructor::newInstance, ainsi que l'accès non sécurisé aux champs pour Field::get et set.

Lorsque java.lang.reflect et java.lang.invoke sont mise à jour pour prendre en charge de nouvelles fonctionnalités du langage, comme celles envisagées dans le projet Valhalla, les trois chemins de code doivent être modifié, ce qui est coûteux. En outre, l'implémentation actuelle repose sur un traitement spécial par la VM du bytecode généré, qui est enveloppé dans des sous-classes de jdk.internal.reflect.MagicAccessorImpl :

  • La vérification est désactivée pour contourner JLS §6.6.2 afin de supporter la réflexion sur Object::clone ;
  • Un chargeur de classe non conforme est utilisé pour contourner certains problèmes de sécurité et de compatibilité ;
  • L'accessibilité est relâchée afin que ces classes puissent accéder aux champs et méthodes inaccessibles d'autres classes.

Description

La nouvelle implémentation effectue des invocations directes des poignées de méthodes pour des objets réfléchissants spécifiques. L’équipe Java Platform du Groupe Oracle utilise le mécanisme de réflexion natif de la VM uniquement au début du démarrage de la VM, avant l'initialisation du mécanisme de gestion des méthodes. Cela se produit peu après System::initPhase1 et avant System::initPhase2, après quoi nous passons à l'utilisation exclusive des method-handle. Cela profite au projet Loom en réduisant l'utilisation de cadres de pile natifs

Réimplémentation de java.lang.reflect sur les method handles en tant que mécanisme réflectif sous-jacent commun de la plate-forme en remplaçant les implémentations génératrices de bytecode de Method::invoke, Constructor::newInstance, Field::get et Field::set.
.
Pour des performances optimales, les instances de Method, Constructor et Field doivent être maintenues dans des champs statiques finaux afin qu'elles puissent être repliées en permanence par le JIT. Lorsque cela est fait, les microbenchmarks montrent que les performances de la nouvelle implémentation sont nettement plus rapides que celles de l'ancienne, de 43 à 57 %.

Lorsque les instances de méthode, de constructeur et de champ sont maintenues dans des champs non constants (par exemple, dans un champ non final ou un élément de tableau), les microbenchmarks montrent une certaine dégradation des performances. La performance des accès aux champs est significativement plus lente que l'ancienne implémentation, de 51-77 %, lorsque les instances Field ne peuvent pas être pliées de manière constante.

Cette dégradation peut toutefois ne pas avoir beaucoup d'effet sur les performances des applications du monde réel. L’équipe Java Platform du Groupe Oracle a effectué plusieurs tests de sérialisation et de désérialisation à l'aide de bibliothèques du monde réel et n’a constaté aucune dégradation des performances.

  • un benchmark de sérialiseur de champ Kryo ;
  • Un benchmark de type convertisseur XStream ;
  • Un benchmark personnalisé de sérialisation et désérialisation JSON utilisant Jackson.


L’équipe Java Platform du Groupe Oracle promet de continuer à explorer les possibilités d'améliorer les performances, par exemple en affinant les formes de bytecode pour l'accès aux champs afin de permettre aux MethodHandles et VarHandles concrets d'être optimisés de manière fiable par le JIT, que le récepteur soit constant ou non. La nouvelle implémentation réduira le coût de la mise à niveau du support de réflexion pour les nouvelles fonctionnalités du langage et, en outre, permettra à l’équipe Java Platform de simplifier la VM HotSpot en supprimant le traitement spécial des sous-classes MagicAccessorImpl.

Risques et hypothèses

Le code qui dépend d'aspects hautement spécifiques et non documentés de l'implémentation existante peut être affecté. Pour atténuer ce risque de compatibilité, les développeurs Java peuvent activer l'ancienne implémentation via -Djdk.reflect.useDirectMethodHandle=false.

Le code qui inspecte les classes de réflexion internes générées (c'est-à-dire les sous-classes de MagicAccessorImpl) ne fonctionnera plus et devra être mis à jour.
L'invocation de Method-handle peut consommer plus de ressources que l'ancienne implémentation de base de la réflexion. Une telle invocation implique l'appel de plusieurs méthodes Java pour s'assurer que la classe déclarante d'un membre est initialisée avant l'accès, et peut donc nécessiter plus d'espace de pile pour les cadres d'exécution nécessaires. Cela peut entraîner une StackOverflowError ou, si une StackOverflowError est lancée lors de l'initialisation d'une classe, une NoClassDefFoundError.

L’équipe Java Platform supprimera l'ancienne implémentation de base de la réflexion dans une prochaine version. La solution de contournement -Djdk.reflect.useDirectMethodHandle=false ne fonctionnera plus à ce moment-là.

SPI de résolution d'adresses Internet

Cette amélioration définit une interface de fournisseur de services (SPI) pour la résolution des noms et adresses d'hôtes, de sorte que java.net.InetAddress puisse utiliser des résolveurs autres que le résolveur intégré à la plateforme. L'API java.net.InetAddress résout les noms d'hôtes en adresses IP (Internet Protocol), et vice versa. L'API utilise actuellement le résolveur natif du système d'exploitation, qui est généralement configuré pour utiliser une combinaison d'un fichier d'hôtes local et du système de noms de domaine (DNS). Les motivations pour définir une interface de fournisseur de services pour la résolution de noms et d'adresses incluent :

  • Projet Loom : une opération de résolution avec l'API InetAddress se bloque actuellement dans un appel du système d'exploitation. C'est un problème pour les threads virtuels en mode utilisateur de Loom, car cela empêche les threads de la plate-forme sous-jacente de servir d'autres threads virtuels en attendant la fin d'une opération de résolution. Un autre résolveur pourrait mettre en œuvre le protocole client DNS directement, sans blocage ;
  • Protocoles réseau émergents : un résolveur SPI permettrait l'intégration transparente de nouveaux protocoles de résolution tels que le DNS sur QUIC, TLS ou HTTPS ;
  • Personnalisation : un résolveur SPI permettrait aux cadres et aux applications d'avoir un contrôle plus fin sur les résultats de résolution, et permettrait aux bibliothèques existantes d'être équipées d'un résolveur personnalisé ;
  • Test : les activités de prototypage et de test nécessitent souvent le contrôle des résultats de la résolution des noms d'hôtes et des adresses, par exemple lors de la simulation de composants qui utilisent l'API InetAddress.

Description

L'API InetAddress définit plusieurs méthodes pour les opérations de consultation :

  • InetAddress::getAllByName effectue une recherche vers l'avant, en associant un nom d'hôte à un ensemble d'adresses IP ;
  • InetAddress::getByName effectue également une recherche avant, en associant un nom d'hôte à la première adresse de son ensemble d'adresses ;
  • InetAddress::getCanonicalHostName effectue une recherche inverse, en faisant correspondre une adresse IP à un nom de domaine entièrement qualifié ;
    Par exemple :
    Code : Sélectionner tout
    1
    2
    3
    var addressBytes = new byte[] { (byte) 192, 0, 43, 7} ;
    var resolvedHostName = InetAddress.getByAddress(addressBytes)
                                      .getCanonicalHostName() ;
  • InetAddress::getHostName effectue également une recherche inverse, si nécessaire.
  • Par défaut, InetAddress utilise le résolveur natif du système d'exploitation pour effectuer les recherches. Le résultat de cette recherche, qu'il soit positif ou négatif, peut être mis en cache afin d'éviter d'autres recherches sur le même hôte.

Interface du fournisseur de services

L'API InetAddress utilise un chargeur de services pour localiser un fournisseur de résolveur. Si aucun fournisseur n'est trouvé, l'implémentation intégrée sera utilisée comme auparavant. Les nouvelles classes du paquet java.net.spi sont :

  • InetAddressResolverProvider : une classe abstraite définissant le service à localiser par java.util.ServiceLoader. Un InetAddressResolverProvider est, essentiellement, une usine pour les résolveurs. Le résolveur instancié sera défini comme le résolveur du système, et InetAddress déléguera toutes les demandes de recherche à ce résolveur ;
  • InetAddressResolver : une interface qui définit les méthodes pour les opérations fondamentales de recherche en avant et en arrière. Une instance de cette interface est obtenue à partir d'une instance de InetAddressResolverProvider ;
  • InetAddressResolver.LookupPolicy : classe dont les instances décrivent les caractéristiques d'une demande de résolution, notamment le type d'adresse demandé et l'ordre dans lequel les adresses doivent être renvoyées ;
  • InetAddressResolverProvider.Configuration : interface décrivant la configuration intégrée de la plate-forme pour les opérations de résolution. Elle permet d'accéder au nom d'hôte local et au résolveur intégré. Elle est utilisée par les fournisseurs de résolveur personnalisés pour amorcer la construction du résolveur ou pour mettre en œuvre la délégation partielle des demandes de résolution au résolveur natif du système d'exploitation.

Alternatives

Sans un SPI tel que celui proposé ici, les applications devront continuer à utiliser les solutions de contournement disponibles aujourd'hui.
Une application peut utiliser l'interface Java Naming and Directory (JNDI) et son fournisseur DNS pour rechercher les noms et adresses du réseau. Cette approche peut être utile pour les applications qui nécessitent un contrôle précis des recherches DNS, mais elle est découplée d'InetAddress et son utilisation avec l'API de mise en réseau de la plateforme nécessite des efforts supplémentaires.

Une application peut utiliser les bibliothèques de résolveurs du système d'exploitation directement via l'interface Java Native (JNI) ou l'API de fonction étrangère du projet Panama. Cependant, comme pour JNDI, cette approche est découplée d'InetAddress et donc plus difficile à utiliser.

Une application peut également utiliser la propriété système jdk.net.hosts.file, non standard et spécifique au JDK, pour configurer InetAddress afin qu'il utilise un fichier spécifique, plutôt que le résolveur natif du système d'exploitation, pour mapper les noms d'hôtes en adresses IP. Cette fonctionnalité est utile pour les tests, mais elle ne constitue pas une solution générale, car la liste complète des noms d'hôtes n'est pas toujours connue à l'avance.

L’équipe Java Platform développe de nouveaux tests pour le SPI résolveur. Elle développe des fournisseurs de résolveurs de preuve de concept pour démontrer et vérifier que le SPI peut être utilisé pour développer et déployer des implémentations alternatives qui sont utilisées de préférence à l'implémentation intégrée du JDK. « Nous mettrons au moins un de ces fournisseurs à disposition pour amorcer le développement d'implémentations plus complètes », déclare l’équipe Java.

Serveur Web simple et prêt à l'emploi

Il fournit un outil en ligne de commande pour démarrer un serveur web minimal qui sert uniquement des fichiers statiques. Aucune fonctionnalité de type CGI ou servlet n'est disponible. Cet outil sera utile pour le prototypage, le codage ad-hoc et les tests, en particulier dans les contextes éducatifs.

  • réduire l'énergie d'activation des développeurs et rendre le JDK plus accessible ;
  • Offrir un serveur de fichiers HTTP statiques prêt à l'emploi avec une configuration facile et une fonctionnalité minimale ;
  • fournir une implémentation par défaut via la ligne de commande ainsi qu'une petite API pour la création et la personnalisation programmatique.

Un rite de passage commun pour les développeurs est de servir un fichier sur le web, probablement un fichier "Hello, world ! un fichier HTML. La plupart des programmes d'enseignement de l'informatique initient les étudiants au développement Web, où des serveurs de test locaux sont couramment utilisés. En général, les développeurs apprennent également l'administration système et les services Web, d'autres domaines où les outils de développement dotés de fonctionnalités serveur de base peuvent s'avérer utiles. Les tâches éducatives et informelles de ce type sont celles pour lesquelles un petit serveur prêt à l'emploi est souhaitable. Les cas d'utilisation comprennent :

  • les tests de développement Web, où un serveur de test local est utilisé pour simuler une configuration client-serveur ;
  • La navigation informelle et le partage de fichiers entre systèmes pour, par exemple, rechercher un répertoire sur un serveur distant depuis votre machine locale ;
  • les tests de services ou d'applications Web, où des fichiers statiques sont utilisés en tant que socles d'API dans une structure de répertoire qui reflète les URL RESTful et contient des données factices.

« Dans tous ces cas, nous pouvons, bien sûr, utiliser un framework de serveur web, mais cette approche a une énergie d'activation élevée : nous devons rechercher des options, en choisir une, la télécharger, la configurer et comprendre comment l'utiliser avant de pouvoir répondre à notre première requête », indique l’équipe Java.

« Ces étapes représentent un certain nombre de cérémonies, ce qui est un inconvénient ; rester bloqué en cours de route peut être frustrant et peut même entraver l'utilisation ultérieure de Java. Un serveur web de base lancé à partir de la ligne de commande ou via quelques lignes de code nous permet d'éviter cette cérémonie et de nous concentrer sur la tâche à accomplir », ajoutent-ils. Python, Ruby, PHP, Erlang et bien d'autres platesformes proposent des serveurs prêts à l'emploi fonctionnant en ligne de commande. Cette variété d'alternatives existantes démontre un besoin reconnu pour ce type d'outil.

Description

Le mini Server Web est un serveur HTTP minimal destiné à servir une seule hiérarchie de répertoires. Il est basé sur l'implémentation du serveur web dans le paquetage com.sun.net.httpserver qui est inclus dans le JDK depuis 2006. Le paquetage est officiellement pris en charge, et l'équipe Java Platform au Groupe Oracle l'étend avec des API pour simplifier la création de serveurs et améliorer le traitement des requêtes. Le mini Serveur Web peut être utilisé via l'outil de ligne de commande dédié jwebserver ou de manière programmatique via son API.

Outil de ligne de commande

La commande suivante démarre le mini server Web :
Code : Sélectionner tout
$ jwebserver
Si le démarrage est réussi, jwebserver imprime un message à System.out listant l'adresse locale et le chemin absolu du répertoire servi. Par exemple
Code : Sélectionner tout
$ jwebserver
Liaison à la boucle par défaut. Pour toutes les interfaces, utilisez -b 0.0.0.0 ou -b : :.
Servir /cwd et ses sous-répertoires sur 127.0.0.1 port 8000
URL : http://127.0.0.1:8000/
Par défaut, le serveur fonctionne en avant-plan et se lie à l'adresse de bouclage et au port 8000. Ceci peut être modifié avec les options -b et -p. Par exemple, pour exécuter le serveur sur le port 9000, utilisez :
Code : Sélectionner tout
$ jwebserver -p 9000
Par exemple, pour lier le serveur à toutes les interfaces :
Code : Sélectionner tout
$ jwebserver -b 0.0.0.0
Service de /cwd et des sous-répertoires sur 0.0.0.0 (toutes les interfaces) port 8000
URL: http://123.456.7.891:8000/
Par défaut, les fichiers sont servis à partir du répertoire courant. Un répertoire différent peut être spécifié avec l'option -d.

Seules les requêtes HEAD et GET idempotentes sont servies. Toute autre demande reçoit une réponse 501 - Not Implemented ou 405 - Not Allowed. Les requêtes GET sont mises en correspondance avec le répertoire servi, comme suit :
  • Si la ressource demandée est un fichier, son contenu est servi.
  • Si la ressource demandée est un répertoire qui contient un fichier d'index, c'est le contenu de ce dernier qui est servi.
  • Sinon, les noms de tous les fichiers et sous-répertoires du répertoire sont listés. Les liens symboliques et les fichiers cachés ne sont pas répertoriés ni servis.


Le mini serveur Web prend en charge le protocole HTTP/1.1 uniquement. Il n'y a pas de support HTTPS. Les types MIME sont configurés automatiquement. Par exemple, les fichiers .html sont servis en tant que text/html et les fichiers .java sont servis en tant que text/plain. Par défaut, chaque requête est enregistrée sur la console. La sortie ressemble à ceci :

127.0.0.1 - - [10/Feb/2021:14:34:11 +0000] "GET /some/subdirectory/ HTTP/1.1" 200 -
La sortie de la journalisation peut être modifiée avec l'option -o. Le paramètre par défaut est info. Le paramètre verbeux inclut en plus les en-têtes de demande et de réponse ainsi que le chemin absolu de la ressource demandée. Une fois lancé avec succès, le serveur fonctionne jusqu'à ce qu'il soit arrêté. Sur les plateformes Unix, le serveur peut être arrêté en lui envoyant un signal SIGINT (Ctrl+C dans une fenêtre de terminal).

L'option -h affiche un message d'aide listant toutes les options, qui suivent les directives de la JEP 293. Une page de manuel jwebserver est également disponible.

Alternatives

l'équipe Java Platform au Groupe Oracle a envisagé une alternative pour l'outil en ligne de commande :
java -m jdk.httpserver : Initialement, le serveur Web simple était exécuté avec la commande java -m jdk.httpserver plutôt qu'avec un outil de ligne de commande dédié. Bien que cela soit toujours possible (en fait, jwebserver utilise la commande java -m ... sous le capot), l'équipe Java Platform a décidé d'introduire un outil dédié pour améliorer la commodité et l'accessibilité.

L'équipe Java Platform au Groupe Oracle a envisagé plusieurs alternatives d'API pendant le prototypage :

Une nouvelle classe DelegatingHandler : regrouper les méthodes de personnalisation dans une classe distincte qui implémente l'interface HttpHandler. L'équipe a écarté cette option car elle implique l'introduction d'un nouveau type sans ajouter de fonctionnalités supplémentaires. Ce nouveau type serait également difficile à découvrir.

La classe HttpHandlers, quant à elle, utilise le modèle de l'externalisation, où les méthodes d'aide statiques ou les usines d'une classe sont regroupées dans une nouvelle classe. Le nom presque identique permet de trouver facilement la classe, facilite la compréhension et l'utilisation des nouveaux points d'API et masque les détails de mise en œuvre de la délégation.

HttpHandler en tant que service : transformez HttpHandler en un service et fournissez une implémentation interne du gestionnaire de serveur de fichiers. Le développeur peut soit fournir un gestionnaire personnalisé, soit utiliser le fournisseur par défaut. L'inconvénient de cette approche est qu'elle est plus difficile à utiliser et plutôt élaborée pour le petit ensemble de fonctionnalités que nous voulons fournir.

Filter instead of HttpHandler : utilisez uniquement des filtres, et non des gestionnaires, pour traiter la demande. Les filtres sont généralement des pré ou post-traitements, ce qui signifie qu'ils accèdent à une requête avant ou après l'appel du gestionnaire, par exemple pour l'authentification ou la journalisation. Cependant, ils n'ont pas été conçus pour remplacer entièrement les gestionnaires. Les utiliser de cette manière serait contre-intuitif et les méthodes seraient plus difficiles à trouver.

UTF-8 par défaut

Les API Java standard pour la lecture et l'écriture de fichiers et pour le traitement du texte permettent de passer un jeu de caractères comme argument. Un jeu de caractères régit la conversion entre les octets bruts et les valeurs chargées sur 16 bits du langage de programmation Java. Les jeux de caractères pris en charge sont, par exemple, US-ASCII, UTF-8 et ISO-8859-1.

JDK 18 Spécifie UTF-8 comme jeu de caractères par défaut des API Java standard. Grâce à ce changement, les API qui dépendent du jeu de caractères par défaut se comporteront de manière cohérente dans toutes les implémentations, systèmes d'exploitation, locales et configurations. Rendre les programmes Java plus prévisibles et portables lorsque leur code dépend du jeu de caractères par défaut. Clarifier les endroits où l'API Java standard utilise le jeu de caractères par défaut.
Standardiser UTF-8 dans toutes les API Java standard, sauf pour les E/S de la console.

Si aucun argument de jeu de caractères n'est fourni, les API Java standard utilisent généralement le jeu de caractères par défaut. Le JDK choisit le jeu de caractères par défaut au démarrage en fonction de l'environnement d'exécution : le système d'exploitation, la locale de l'utilisateur et d'autres facteurs.
Comme le jeu de caractères par défaut n'est pas le même partout, les API qui l'utilisent présentent de nombreux risques non évidents, même pour les développeurs expérimentés.

Prenons l'exemple d'une application qui crée un java.io.FileWriter sans indiquer de jeu de caractères, puis l'utilise pour écrire du texte dans un fichier. Le fichier résultant contiendra une séquence d'octets codés à l'aide du jeu de caractères par défaut du JDK exécutant l'application. Une deuxième application, exécutée sur une machine différente ou par un utilisateur différent sur la même machine, crée un java.io.FileReader sans passer de jeu de caractères et l'utilise pour lire les octets de ce fichier.

Le texte résultant contient une séquence de caractères décodés à l'aide du jeu de caractères par défaut du JDK exécutant la seconde application. Si le jeu de caractères par défaut diffère entre le JDK de la première application et le JDK de la seconde application, le texte résultant peut être silencieusement corrompu ou incomplet, puisque le FileReader ne peut pas dire qu'il a décodé le texte en utilisant le mauvais jeu de caractères par rapport au FileWriter. Voici un exemple de ce risque, où un fichier texte japonais codé en UTF-8 sur macOS est corrompu lorsqu'il est lu sur Windows dans les locales US-English ou Japanese :

java.io.FileReader("hello.txt" -> "こんにちは" (macOS)
java.io.FileReader("hello.txt" -> "ã?“ã‚“ã?«ã?¡ã?" (Windows (en-US))
java.io.FileReader("hello.txt" -> "縺ォ縺。縺ッ" (Windows (ja-JP)

Les développeurs familiarisés avec ces dangers peuvent utiliser les méthodes et les constructeurs qui prennent un argument charset explicitement. Cependant, le fait de devoir passer un argument empêche les méthodes et les constructeurs d'être utilisés via des références de méthode dans les pipelines de flux.
Les développeurs tentent parfois de configurer le jeu de caractères par défaut en définissant la propriété système file.encoding sur la ligne de commande (par exemple, java -Dfile.encoding=...), mais cela n'a jamais été pris en charge. En outre, la tentative de définir la propriété de manière programmatique (c'est-à-dire System.setProperty(...)) après le démarrage du moteur d'exécution Java ne fonctionne pas.

Les API Java standard ne s'en remettent pas toutes au jeu de caractères par défaut choisi par le JDK. Par exemple, les méthodes de java.nio.file.Files qui lisent ou écrivent des fichiers sans argument Charset sont spécifiées pour toujours utiliser UTF-8. Le fait que les API les plus récentes utilisent par défaut UTF-8 alors que les API plus anciennes utilisent le jeu de caractères par défaut constitue un danger pour les applications qui utilisent un mélange d'API.

L'ensemble de l'écosystème Java gagnerait à ce que le jeu de caractères par défaut soit spécifié comme étant le même partout. Les applications qui ne sont pas concernées par la portabilité verront peu d'impact, tandis que les applications qui embrassent la portabilité en passant des arguments de charset ne verront aucun impact. UTF-8 est depuis longtemps le jeu de caractères le plus courant sur le World Wide Web. UTF-8 est standard pour les fichiers XML et JSON traités par un grand nombre de programmes Java, et les propres API de Java favorisent de plus en plus UTF-8, par exemple dans l'API NIO et pour les fichiers de propriétés. Il est donc logique de spécifier UTF-8 comme jeu de caractères par défaut pour toutes les API Java.

JDK 18, l'implémentation de référence de Java 18 apporte également des centaines de petites améliorations et plus d'un millier de corrections de bogues.

Source : Java Team

Et vous ?

Que pensez-vous des nouveautés introduites par le JDK 18 ?

Selon vous, pourquoi l'adoption des versions récentes de Java (JDK) est-elle lente ?

Comment expliquer le fait que beaucoup de développeurs utilisent toujours Java 14, Java 11 et même Java 8 ?

La migration vers les versions récentes de Java est-elle aussi difficile ?

N'y a-t-il pas des risques de continuer à utiliser d'anciennes versions de Java malgré les nouvelles versions LTS ?

Voir aussi :

JDK 18 : les nouvelles fonctionnalités de Java 18 incluent une API pour les vecteurs, un serveur Web minimal et l'adoption d'UTF-8 comme jeu de caractères par défaut

Sondage : quelle édition du JDK (Java Development Kit) utilisez-vous ? Et quelles sont les raisons de votre choix ?

Une erreur dans cette actualité ? Signalez-nous-la !