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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

JDK 18, l'implémentation de référence de Java 18, est désormais disponible


Sujet :

Java

  1. #1
    Chroniqueur Actualités

    Homme Profil pro
    Rédacteur technique
    Inscrit en
    juin 2016
    Messages
    2 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Rédacteur technique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : juin 2016
    Messages : 2 392
    Points : 47 241
    Points
    47 241
    Par défaut JDK 18, l'implémentation de référence de Java 18, est désormais disponible
    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

    Le JDK 18 est déjà en cours de développement et l'équipe vient de livrer un aperçu des nouveautés dans cette nouvelle mouture du kit de développement Java, dont la sortie est prévue pour le 22 mars 2022. Java 18 sera 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. Une version préliminaire devrait être disponible en janvier prochain et les versions candidates (RC) sont prévues pour le 10 et 24 février 2022.

    Alors que le JDK 17 était une version de support à long terme (LTS) qui bénéficiera d'au moins huit ans de support de la part d'Oracle, le JDK 18 sera une version de fonctionnalité à court terme qui sera supportée pendant six mois. Les premières versions du JDK 18 sont disponibles pour Linux, Windows et macOS sur java.net. Les propositions spécifiques du JDK 18 sont les suivantes :

    Dépréciation de la finalisation pour une suppression dans une version future

    Selon l'équipe du JDK, Finalizer a des défauts qui causent des problèmes importants dans le monde réel en matière de sécurité, de performance, de fiabilité et de maintenabilité. Il a également un modèle de programmation difficile. La finalisation est activée par défaut pour le moment, mais peut être désactivée pour faciliter les premiers tests. Elle sera désactivée par défaut dans une version de fonctionnalité et supprimée complètement dans une version ultérieure. La proposition prévoit une option de ligne de commande pour désactiver la finalisation et la dépréciation de tous les finaliseurs et méthodes de finalisation dans l'API Java standard.

    Nom : java-18.png
Affichages : 197348
Taille : 3,5 Ko

    Les objectifs de la proposition sont d'aider les développeurs à comprendre les dangers de la finalisation, de les préparer à sa suppression éventuelle et de fournir des outils simples pour aider à détecter la dépendance à la finalisation. Introduite dans Java 1.0, la finalisation avait pour but d'éviter les fuites de ressources. Une classe peut déclarer un finaliseur - la méthode protected void finalize() - dont le corps libère toute ressource sous-jacente. Le ramasseur de déchets planifiera l'appel du finaliseur d'un objet inaccessible avant de récupérer la mémoire de l'objet.

    À son tour, la méthode finalize() peut prendre des mesures telles que l'appel de la fermeture de l'objet. Cela semble être un filet de sécurité efficace pour éviter les fuites de ressources, mais il existe des failles, notamment une latence imprévisible, avec un long délai entre le moment où un objet devient inaccessible et celui où son finaliseur est appelé ; un comportement non contraint, le code du finaliseur pouvant effectuer n'importe quelle action, y compris ressusciter un objet et le rendre à nouveau accessible ; le finaliseur est toujours activé, sans mécanisme d'enregistrement explicite.

    Et les finaliseurs peuvent s'exécuter sur des threads non spécifiés dans un ordre arbitraire. Compte tenu des problèmes posés par la finalisation, il est conseillé aux développeurs d'utiliser des techniques alternatives pour éviter les fuites de ressources, à savoir les instructions try-with-resources et les nettoyeurs.

    Proposition d'un SPI de résolution d'adresse Internet

    La proposition consiste à définir un SPI (service-provider interface) pour la résolution d'adresses d'hôtes et de noms afin que Inet.Address puisse utiliser des résolveurs autres que le résolveur intégré à la plateforme. Les motivations de cet effort comprennent une meilleure mise en œuvre du projet Loom, pour la concurrence et les nouveaux modèles de programmation en Java, ainsi que l'intégration de nouveaux protocoles de réseau, la personnalisation et la possibilité d'effectuer des tests. La proposition n'implique pas le développement d'un autre résolveur pour le JDK.

    Nouvel aperçu de la correspondance des motifs pour switch

    Un deuxième aperçu de la correspondance des motifs, dans lequel le langage Java serait amélioré par la correspondance des motifs pour les expressions et les instructions switch, ainsi que par des extensions au langage des motifs. Ce projet a été présenté en avant-première dans le JDK 17. L'extension de la correspondance des motifs à switch permet de tester une expression par rapport à un certain nombre de motifs, chacun ayant une action spécifique, de sorte que les requêtes complexes orientées données peuvent être exprimées de manière concise et sûre.

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

    Selon l'équipe, la réimplémentation de Core Reflection avec des descripteurs de méthode réimplémenterait lang.reflect.Method, Constructor et Field au-dessus des descripteurs de méthode java.lang.invoke. Le fait que les descripteurs de méthode servent de mécanisme sous-jacent à la réflexion réduira les coûts de maintenance et de développement des API java.lang.reflect et java.lang.invoke.

    Introduction d'un serveur Web minimal

    Avec la proposition de serveur Web simple, un outil en ligne de commande serait fourni pour démarrer un serveur Web minimal qui ne sert que des fichiers statiques. L'équipe a expliqué qu'aucune fonctionnalité de type CGI ou servlet n'est disponible. L'outil sera utile pour le prototypage, le codage ad-hoc et les tests, en particulier dans les contextes éducatifs.

    Les objectifs du plan consistent à offrir un serveur de fichiers HTTP statiques prêt à l'emploi, facile à configurer et doté d'un minimum de fonctionnalités, à réduire l'énergie d'activation des développeurs et à rendre le JDK plus accessible, ainsi qu'à fournir une implémentation par défaut via la ligne de commande et une petite API pour la création et la personnalisation programmatiques. La fourniture d'un serveur riche en fonctionnalités ou de qualité commerciale n'est pas un objectif de la proposition.

    Une API de fonction étrangère et de mémoire (deuxième incubateur)

    Une deuxième incubation d'une fonction étrangère et d'une API de mémoire, dans laquelle une API est introduite par laquelle les programmes Java peuvent interagir avec le code et les données en dehors du runtime Java. En invoquant des fonctions étrangères - code extérieur à la JVM - et en accédant en toute sécurité à la mémoire étrangère - mémoire non gérée par la JVM - l'API permet aux programmes Java d'appeler des bibliothèques natives et de traiter des données natives sans la fragilité et le danger de la JNI (Java Native Interface). L'objectif est de remplacer la JNI par un modèle de développement supérieur, purement Java.

    Cette API a été incubée dans le JDK 17. Pour le JDK 18, des améliorations seraient incorporées, sur la base des commentaires, telles que la prise en charge d'un plus grand nombre de supports tels que Boolean et MemoryAddress dans les descripteurs var d'accès à la mémoire, et une nouvelle API pour copier des tableaux Java vers et depuis des segments de mémoire.

    Proposition d'une API pour exprimer des calculs vectoriels

    L'API vectorielle sera incubée pour la troisième fois dans le JDK 18, après avoir été incubée dans les JDK 16 et JDK 17. Cette proposition exprimerait des calculs vectoriels qui seraient compilés au moment de l'exécution en instructions vectorielles optimales sur les architectures de CPU prises en charge, ce qui permettrait d'obtenir des performances supérieures aux calculs scalaires équivalents. Les opérations vectorielles expriment un degré de parallélisation qui permet d'effectuer plus de travail sur un seul cycle de l'unité centrale, ce qui améliore considérablement les performances.

    L'API vectorielle indépendante de la plateforme vise à fournir un moyen d'écrire des algorithmes complexes en Java, en utilisant l'autovectoriser HotSpot existant, mais avec un modèle utilisateur qui rend la vectorisation plus prévisible. Le JDK 18 ajoutera également la prise en charge de la plateforme ARM Scalar Vector Extension et améliorera les performances des opérations vectorielles qui acceptent des masques sur les architectures qui prennent en charge le masquage dans le matériel.

    Utilisation d'UTF-8 comme jeu de caractères par défaut des API standards

    UTF-8 est un codage de caractères à largeur variable pour la communication électronique et est considéré comme le jeu de caractères standard du Web. Le jeu de caractères est un codage de caractères capable de coder tous les caractères du Web. 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 locales et configurations.

    La proposition ne vise pas à définir de nouvelles API standard Java ou spécifiques au JDK. Les partisans de la proposition s'attendent à ce que les applications dans de nombreux environnements ne voient aucun impact du choix d'UTF-8 par Java, car macOS, de nombreuses distributions Linux et de nombreuses applications serveur prennent déjà en charge UTF-8.

    Cependant, il existe un risque dans d'autres environnements, le plus évident étant que les applications dépendant du jeu de caractères par défaut se comporteront de manière incorrecte lors du traitement de données produites lorsque le jeu de caractères par défaut n'a pas été spécifié. Une corruption des données peut se produire silencieusement. On s'attend à ce que l'impact principal tombe sur les utilisateurs de systèmes Windows dans les localités asiatiques et éventuellement sur certains environnements de serveurs dans les localités asiatiques et autres.

    Source : JDK 18

    Et vous ?

    Quel est votre avis sur le sujet ?
    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

    Oracle annonce la disponibilité de Java 16 : tour d'horizon des nouvelles fonctionnalités et améliorations du JDK

    Sondage : quelle édition du JDK (Java Development Kit) utilisez-vous ? Et quelles sont les raisons de votre choix ?
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  2. #2
    Chroniqueur Actualités
    Avatar de Bruno
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    mai 2019
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Rédacteur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : mai 2019
    Messages : 759
    Points : 10 057
    Points
    10 057
    Par défaut JDK 18, l'implémentation de référence de Java 18, est désormais disponible,
    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

    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.

    Nom : jdkB.png
Affichages : 167424
Taille : 39,6 Ko

    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 - Visualiser dans une fenêtre à part
      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 :
    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
    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 :
    Par exemple, pour lier le serveur à toutes les interfaces :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ 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 ?
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

Discussions similaires

  1. Réponses: 5
    Dernier message: 22/08/2021, 18h13
  2. JDK 14 : un aperçu des nouvelles fonctionnalités de Java 14
    Par Bill Fassinou dans le forum Général Java
    Réponses: 1
    Dernier message: 30/10/2019, 07h11
  3. Oracle présente de nouvelles fonctionnalités de Java 9
    Par Hinault Romaric dans le forum Général Java
    Réponses: 65
    Dernier message: 21/05/2015, 18h25
  4. Réponses: 6
    Dernier message: 29/05/2011, 16h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo