JAVA 9

Par :
benigne.thierry
ven, 20/01/2017 - 11:50
Niveau :
Facile

Une nouvelle version : Java 9 :

Après le déploiement de Java 8 en avril 2014, Oracle commence le projet Java 9. La Bêta finale de Java 9 sortira en Mars 2017 et la version finale sera disponible en cours d’année 2017.

Cette nouvelle version de Java est importante car elle apportera un environnement modulaire et plus performant.

JIGSAW, le projet Java 9 :

  • JSR 376 :

La Java Platform Module System (JPMS) est la plus grande partie de Java 9. Ses principaux objectifs sont :

  • Configuration fiable
  • Encapsulation forte

Tout repose sur le projet Jigsaw. De plus le nouveau JDK est maintenant entièrement modulaire. Voici un exemple qui utilise les requires et les exports :

module com.foo.bar {

     requires org.baz.qux ;

     exports com.foo.bar.alpha ;

     exports com.foot.bar.beta ;

}

Initialement prévu pour Java 8, le projet Jigsaw arrive avec Java 9. Les principaux objectifs de Jigsaw est de rendre la plateforme Java plus modulaire Il va également améliorer la sécurité des implémentations Java et plus particulièrement des JDK. La construction et la maintenabilité des bibliothèques seront facilitées pour les développeurs. Les performances des applications vont également être améliorées. Jigsaw est destiné aussi bien pour les grandes plateformes Java EE qu’aux architectures plus petites comme les mobiles, les tablettes et les micros puce. Le projet Jigsaw ont en entend parler depuis Java 7 mais celui-ci fut repousser pour Java 8 puis maintenant c’est pour Java 9 que Jigsaw va surement réellement voir le jour. Ce projet à rencontrer plusieurs difficultés techniques mais aussi des choix de solutions qui n’ont pas été facile à prendre, c’est pour cela que son retard est si important. Grace à Jigsaw et sa découpe de bibliothèque d’exécution de base en différent modules, les machines virtuelles Java (JVM) pourront fonctionner sans le support de certains packages de base.

Pour mettre en place ces modifications, ORACLE propose un système de modules standard pour l’appliquer directement à sa plateforme et au JDK. Le système de module sera alors utilisé avec Java 9 ce qui remplacera les fichiers .jar par des modules.

Jigsaw est composé de plusieurs JEP ( 200, 201, 220, 260, 261, 282) et du JSR 376.

Il sera disponible sur différents systèmes d’exploitations tels que :

  • Windows
  • MacOS
  • Linux

Java 9 sera compatible avec plusieurs IDE tels que : Eclipse Oxygen (v4.7), NetBeans ou encore IntelliJ

Les principales nouvelles fonctionnalités :

Cette nouvelle version proposée par Oracle apporte deux nouvelles interfaces. La première assure le support de HTTP 2.0 et des web sockets (HHTP 2 Client API) et la seconde permet une meilleure intégration des processus non-Java (Process API Updates).

  • JEP 110 : HTTP 2 Client :

Cette API permet principalement de remplacer l’héritage HttpURLConnection car celui-ci comportait trop de problèmes (il fonctionnait uniquement en mode blocage donc un thread par requête/réponse, il était difficile à utiliser et fonctionnait uniquement en mode blocage) et sera livré avec JDK 9.

HHTP 2 sera aussi plus performant et consommera moins de mémoire que HTTP 1.x

Cette API comprend donc :

  • Demandes et réponses distinctes, telles que l’API serveur Servlet et HTTP
  • Notification asynchrone (erreur de réponse, push du serveur, réponses reçus)
  • HTTPS via SSLEngine
  • Proxying
  • Cookies
  • Authentification

Voici un exemple afin de créer et gérer une simple requête http :

HttpResponse response = HttpRequest
     .create(new URI(http://www.google.com))
     .body(noBody())
     .GET().send();

int responseCode = response.responseCode();
String responseBody = response.body(asString());

System.out.println(responseBody);

Voici un autre exemple qui effectue un appel asynchrone avec la nouvelle API :

HttpRequest req = HttpRequest
     .create(new URI(http://www.google.com))
     .body(noBody())
     .GET();

CompletableFuture<HttpResponse> aResp = req.sendAsync();
Thread.sleep(10);

If (!aResp.isDone()) {
     aResp.cancel(true);
     System.out.println("Failed to reply in 10 seconds…");
     return;

  • JEP 102 : Process API Updates :

Cette API est améliorée afin de mieux contrôler et gérer les processus du système d’exploitation en question. Cette amélioration permet l’accès aux informations sur les processus (telles que l’heure de début du processus, la durée d’utilisation du processus, l’ID du processus) mais aussi de mieux les contrôler.

La conception de cette API doit permettre un déploiement possible différents modèles d'OS. La nouvelle classe ProcessHandle facilite l'interaction avec les processus et les arbres de processus.

Par exemple pour obtenir l’ID du processus :

private static int getOwnProcessID() {
     return ProcessHandle.current().getPid() ;
}

Lister tous les processus :

ProcessHandle.allProcesses().forEach(h -> printInfo(h)) ;

public void printInfo(ProcessHandle pHandle) {
     System.out.println("PID :" + pHandle.info().getPid();
     System.out.println("Path :" + pHandle.info().command().orElse("-");
}

Le principal risque de cette nouvelle API est la différence entre les systèmes d’exploitation et tout particulièrement avec Windows. 

  • JEP 143 : Improve Contended Locking :

Cette amélioration va permettre d’améliorer les performances entre les threads.

Les performances dans les domaines suivants seront améliorées :

  • Réorganisation des champs et alignement des lignes de cache
  • Accélérer PlatformEvent ::unpark()
  • Opérations d’entrées plus rapides
  • Opérations de sorties plus rapides
  • Les méthodes notify et notifyAll seront plus rapides

Il y aura donc moins de conflits entre les threads.

  • JEP 197 : Segmented Code Cache :

Grâce à cette nouveauté au lieu d’avoir un seul segment de code, le cache du code est segmenté en plusieurs code distincts : cela permet de séparer le code avec des propriétés différentes. Il existe trois types de code compilé :

  • Code JVM interne (non-méthode)
  • Code profilé
  • Code non-profilé

Cela apporte de nombreux avantages. En effet le temps de balayage sera plus court car le code non-méthode sera ignoré , le temps d’exécution de certaines compilations sera réduit , la fragmentation du code hautement optimisé est réduit et enfin il y a une réduction du nombre d’erreurs iTLB et iCache.

  • JEP 199 : Smart Java Compilation, Phase Two :

Dans les versions précédentes de Java, sjavac n’était pas utilisé par défaut dans les scripts JDK. L’objectif principal de ce JEP est d’améliorer la qualité de sjavac afin qu’il soit capable de compiler de grands projets Java et qu’il soit disponible par défaut dans le nouveau JDK.

Ce JEP repose principalement sur le développement du JEP 139 qui consiste à améliorer javac et ainsi d’améliorer la vitesse de construction.

  • JEP 201 : Modular Source Code : mettre ca avant le jigsaw

Ce JEP est la première étape du projet Jigsaw. Il vise à concevoir et mettre en œuvre un système de module standard pour la plate-forme Java SE et d’appliquer ce système à la plate-forme elle-même et le JDK. Ses principaux objectifs sont de rendre les implémentations de la plate-forme plus facilement évolutives jusqu’à de petits périphériques, d’améliorer la sécurité et la maintenabilité, d’améliorer les performances des applications et de fournir aux développeurs de meilleurs outils de programmation.

Les motivations pour réorganiser le code source à ce stade précoce sont les suivantes :

  1. Donner aux développeurs JDK la possibilité de se familiariser avec la structure modulaire du système ;
  2. Préserver cette structure en appliquant les limites des modules dans la construction, même avant l’introduction d’un système de module.
  3. Permettre le développement ultérieur de projet Jigsaw pour procéder sans toujours avoir à «shuffle» le code source actuel.
  • JEP 222 : The Java Shell :

L'API et l'outil Java Shell fourniront un moyen d'évaluer de manière interactive les déclarations, les instructions et les expressions du langage de programmation Java dans l'état JShell. L'état JShell comprend un code évolutif et un état d'exécution. Pour faciliter l'investigation et le codage rapides, les énoncés et les expressions ne doivent pas apparaître dans une méthode, les expressions n'ont pas besoin d'effets secondaires, les variables ne doivent pas apparaître dans une classe et les méthodes ne doivent pas apparaître dans une classe ou une interface.

L’outil jshell sera un outil de ligne de commande avec des fonctionnalités pour faciliter l’interaction, y compris : l’ajout de tabulation, l’ajout automatique des points-virgules, les importations et les définitions prédéfinies configurables.

  • JEP 251 : Multi-Resolution Images API :

L'objectif est de définir une API d'images multi-résolution afin que les images avec des variantes de résolution puissent être facilement manipulées et affichées par les développeurs.

Opérations de base sur une image multi-résolution :

  • Récupérer une variante d'image spécifique à la résolution en fonction d'une métrique DPI donnée et d'un ensemble de transformations d'image
  • Récupérer toutes les variantes de l'image

Voici un exemple :

package java.awt.image ;

public interface MultiResolutionImage {
     Image getResolutionVariant (float destImageWidth, float destImageHeight) ;
     public List<image> getResolutionVariants();
}

  • JEP 264 : Plateform Logging API and Service :

Cette API utilisera une plate-forme afin d’enregistrer des messages, ainsi qu'une interface de service pour les consommateurs de ces messages. Une bibliothèque ou une application peut fournir une implémentation de ce service afin d'acheminer les messages de journal de plate-forme vers la structure de journalisation de son choix. Si aucune mise en œuvre est fourni, une implémentation par défaut : java.util.logging sera utilisée. 

  • JEP 267 : Unicode 8.0 :                                                                                         

Les API de plateforme vont être mise à niveau car il va falloir prendre en charge la version d’Unicode 8.0. Les caractères et les chaine de caractère seront désormais dans le package java.lang. Pour les autres changements il y aura aussi NumericShaper dans le package java.awt.font et Bidi, Breklterator et Normalizer seront dans le package java.text. Unicode est très utiliser dans l’industrie c’est pour cela que Java doit suivre l’évolution et rester à jour par rapport à ces utilisateurs.

Unicode 8.0 possède 8000 caractères, 10 blocs et également 6 scripts supplémentaire par rapport à la version précédente.

  • JEP 272 : Plateform-Specific Desktop Features :

Cette nouvelle API permet d’accéder aux fonctionnalités du bureau spécifiques au système d’exploitation concerné telles que :

  • Connexion/Deconnexion et verouiillage d’écran.
  • Interactions avec la barre de tâches : Informations sur la progression de la tâche, raccourcis d’actions disponibles.

Cette API sera disponible grâce à la classe java.awt.Desktop. Les systèmes d’exploitation concernés sont Mac OS, Windows et Linux.

  • JEP 290 : Filter Incoming Serialization Data :

Le but de cette nouveauté est de permettre aux flux entrants de données de sérialisation d'objet d’être filtrer afin d'améliorer à la fois la sécurité et la robustesse. Voici un exemple d’utilisation de ObjectInputFilter :

interface ObjectInputFilter {
     Status checkInput(Class< ?> clazz,
          long size, long nRefs, long depth, long streamBytes);    

     enum Status {UNDECIDED, ALLOWED, REJECTED;}
}

Les méthodes d'interface de filtrage sont appelées pendant le processus de désérialisation pour valider les classes en cours de désérialisation, les tailles des tableaux en cours de création et les métriques décrivant la longueur du flux, la profondeur du flux et le nombre de références lorsque le flux est décodé. Le filtre renvoie un état pour accepter, rejeter ou laisser le statut indécis.

Pour chaque nouvel objet du flux, le filtre est appelé, avec la classe de l'objet, avant que l'objet ne soit instancié et désérialisé. Pour chaque tableau, qu'il s'agisse d'un tableau de primitives, d'un tableau de chaînes ou d'un tableau d'objets, le filtre est appelé avec la classe array et la longueur du tableau. Pour chaque référence à un objet déjà lu dans le flux, le filtre est appelé pour qu'il puisse vérifier la profondeur, le nombre de références et la longueur du flux. Si l’enregistrement est activé, les actions de filtrage sont enregistrées dans le journalisateur 'java.io.serialization'. 

  • JEP 268 : XML Catalogs :

Il faut savoir que cette API prend en charge la norme OASIS XML Catalogues v1.1. Les catalogues XML sont utiles pour résoudre des références externes dans XML/XSD/XSL, supprimant ainsi la nécessité de récupérer des ressources externes de manière répétitive. Dans certains cas, un catalogue XML est nécessaire pour garantir que les applications fonctionnent correctement dans les environnements locaux où la source de la ressource XML importée est différente de l'original. Les catalogues XML peuvent également améliorer la sécurité des applications en orientant des références externes distantes vers un catalogue local puis en interdisant la récupération de ressources externes.

Cette API implémentera les interfaces EntityResolver et URIResolver :

  • CatalogManager va gérer la création de XML Catalogues ainsi que de CatalogResolver
  • CatalogResolver s’occupera d’implémenter les deux interfaces énoncées précédemment

 

  • JEP 236 : Parser API for Nashorn :

Il faut savoir que Nashorn est un moteur JavaScript développé en Java par Oracle. Il permet de mettre en œuvre un runtime JavaScript léger et performant avec une JVM native.

Cette API permettra l’analyse de code ECMAScript (ensemble de normes concernant les langages de programmation de type script, standardisé par Ecma) par des programmes tels que les IDE (comme NetBeans) et les Framework coté serveur sans que ces programmes doivent dépendre des classes internes de Nashorn.

Le nouveau fichier javadoc contient la documentation des interfaces et des classes du nouveau package jdk.nashorn.api.tree. Les principales classes de cette API sont ParserFactory et ParserFactoryImpl.

  • JEP 213 : Milling Project Coin :

Cette API concerne quelques modifications au niveau du langage de programmation Java comme :

  • L’annotation @SafeVarargs ne peut être appliquée à des méthodes qui ne peuvent pas être surchargées, y compris les méthodes statiques et les méthodes d'instance finaux.
  • Les variables « effectively-final » sont utilisées comme ressources dans les déclarations « try-with-ressources » :

void doSomethingWith(Connection connection) throws Exception {
     try(connection) {
          connection.doSomething();
     }

  • Les soulignement (« _ ») généraient un avertissement sous Java SE 8 et sous Java SE 9 cela devient une erreur.
  • Les interfaces auront des méthodes privées.
  • JEP 289 : Deprecate the Applet API :

L’API Applet n’est plus utile car les navigateurs web ne prennent plus en charge les plug-in Java. Cependant elle n’est pas supprimée mais seulement obsolète.

L’annotation @Deprecated est ajoutée aux classes suivantes :

  • Java.applet.AppletStub
  • Java.applet.Applet
  • Java.applet.AudioClip
  • Java.applet.AppletContext
  • Javax.swing.JApplet

Pourquoi faut-il se préparer dès maintenant à l’arrivée de Java 9 ?

Normalement le passage à Java 9 sera moins douloureux que pour Java 8 car il y aura moins de nouveautés au niveau du langage. Ce sont les personnes qui s’occupent des processus de construction logicielle qui auront beaucoup à faire (build, installation et déploiement). Un processus de développement est prévu pour migrer son application d’une version java à l’autre. Mais comme nous le savons on rencontre souvent quelques problèmes lors de ces migrations. Bien entendu certaines applications rencontreront plus de problèmes que d’autre lors de la migration vers Java 9, comme celles qui font appel à des API internes de java (exemple : com.sun.* ou sun.* ) à cause de la nouvelle organisation sous forme de modules. Il faudra certainement passer à des versions de bibliothèques plus récentes pour résoudre ce genre de problème. Les différents IDE tel que NetBeans, Ecplipse ou IntelliJ ont déjà commencé à modifier leurs plateformes pour accompagner le passage vers Java 9, cela simplifiera les migrations des applications. Comme autre problème pour la migration de Java 8 à 9 il y a la compatibilité. Pour commencer il faudra faire attention aux APIs internes mais aussi au JDK. Grâce à Jdeps, qui un nouvel outil qui permet de lister les dépendances par package d’un .jar, cela va permettre d’identifier l’utilisation des API et JDK en internes. Il faudra également faire attention aux propriétés système pour qu’elles restent cohérentes (java.version, java.runtime. version, java.vm.version, java.specification.version et java.vm.specification.version). Il faudra utiliser un underscore comme unique caractère de nommage.

Le projet mobile prévu avec le JDK 9 :

Oracle souhaite se concentrer sur le portage du JDK pour les plates-formes mobiles populaires tels que iOS, Android et Windows. L'objectif à court terme de ce projet est de soutenir les améliorations suivantes et de se préparer à les intégrer dans une future version de JDK 9.

  • Supporte au minimum l'équivalent du profil JDK 8 compact2 (sous forme de module)
  • IOS x64 et arm64 (arm64 sera fourni via l'interpréteur Zero)
  • Android x86 et arm (arm sera fourni via l'interpréteur Zero)
  • Applications pour tablette sous Windows 10
  • Interface d'aide JavaLauncher pour simplifier le processus d'inclusion de Java dans les applications mobiles
  • Exemple d'applications HelloWorld et / ou modèles de projets pour chaque plate-forme

Bénigne THIERRY et Julien ROYER
Ecole supérieure Esaip de Dijon