26 août 2016

La migration vers Java 9

Design & Code

Marouane

Salim

26 août 2016

La migration vers Java 9

Design & Code

Marouane

Salim

26 août 2016

La migration vers Java 9

Design & Code

Marouane

Salim

Pour bénéficier de toutes les nouveautés apportées par les dernières versions de Java et embarquer dans le release train proposé par Oracle à partir de Java 9, il va falloir se confronter à un incontournable : la migration vers Java 9. Ce sera la plus complexe puisqu’elle amène la modularisation et que les releases suivantes seront beaucoup moins espacées et donc avec moins de fonctionnalités. Mais… pas de panique ! Dans cet article, nous vous proposons une feuille de route à suivre pour ne pas vous perdre en chemin.

 

État des lieux avant migration

Avant la migration il est primordial de faire un état des lieux qui permettra de recenser les différents points à prendre en compte. Il faut cartographier les dépendances pour :

  • Vérifier pour chaque dépendance si une version modulaire existe,

  • Nettoyer les dépendances,

  • Prévoir les montées de version des dépendances.

Vous pourrez utiliser l’outil « jdeps » pour collecter des informations. Il est fourni dans le JDK depuis Java 8 et il a été amélioré en Java 9. Cet outil analyse le bytecode et pourra vous aider à :

  • Choisir la stratégie de migration,

  • Avoir une meilleure visibilité sur l’ampleur de la tâche,

  • Connaitre les dépendances,

  • Connaitre les split packages,

  • Les API du JDK qui ne sont plus accessibles, proposent une solution alternative si déjà existante.

Il existe différents formats de restitution du rapport, notamment le format .dot qui peut être utilisé par des outils tels que « GraphViz » pour créer une image des dépendances qui sera plus parlante.

De nombreuses options sont disponibles sur « jdeps », il est possible de les lister en utilisant l’option -h, en voici quelques-unes :

jdeps

 

Migration vers Java 9 : les stratégies

Voyons ici les différentes stratégies que vous pourrez mettre en place.

  • Pas de migration ?

Il existe encore de rares applications qui tournent en Java 4/5 qui date de 2004, un peu plus d’applications en Java 6 et beaucoup en Java 7.

La solution serait de ne pas faire de migration et de rester en Java 8 mais le problème est qu’il n’y aura plus de support gratuit d’Oracle à partir de 2019. Il faudra donc y faire attention car il n’y aura plus de mises à jour gratuites du JRE, qui englobent tous les correctifs et les nouvelles fonctionnalités de la JVM mais aussi celles relatives à la sécurité et la performance.

  • Migrer ?

Deux stratégies sont possibles :

  • La conversion en module d’un jar

Il faudra ajouter un fichier module-info qui permet de fixer le nom du module et les dépendances. Cela permettra son utilisation dans le module-path et donc de le déclarer comme dépendance d’un autre module. Son utilisation sera toujours possible via le classpath.

  • Sans conversion en module

Il faudra figer le nom du module avec l’attribut « Automatic-Module-Name » dans le fichier MANIFEST.MF (sinon le nom du module est déterminé à partir du nom du jar).

 

Les difficultés

  • L’identifiant _ n’est plus valide.

  • Certaines fonctionnalités de la JVM ont été retirées avec les modules :

- Les fichiers rt.jar et tools.jar,

- Le mécanisme d’extension,

- Le mécanisme endorsed.

  • L’alignement de la structure du JDK et du JRE.*

  • Les API internes sont désormais encapsulées et ne sont donc plus accessibles. Ces API sont non standards / non supportées et elles n’auraient jamais dû être utilisées et accessibles, certaines sont remplacées (ex : sun.misc.BASE64Decoder). Pour vérifier l’utilisation d’API internes, il est possible d’utiliser jdeps avec l’option –jdkinternals qui va lister les API internes utilisées sur les classes et proposer une méthode alternative si elle existe.

  • Les Split packages :

Les split packages sont les packages présents dans plusieurs jars. C’était possible et assez courant avec l’utilisation du classpath mais Java 9 les interdit et ce, pour assurer une certaine fiabilité de la configuration.

Pour l’instant cela ne s’applique qu’aux modules et non pas au unnamed module ce qui permet tout de même une compatibilité.

  • Le(s) nouveau(x) format(s) de version :

La version est parfois utilisée pour de mauvaises raisons (si telle version, telle action est faite…), ce qui rend la migration difficile.

Son format va changer avec Java 9 : il n’y a plus de 1.XX, dorénavant elle sera sous la forme 9.XX.

Il sera donc difficile de rechercher l’utilisation dans le code du numéro de version car il n’existe aujourd’hui aucune API standard qui fasse une recherche dans le code source pour extraire toutes les utilisations de l’ancien format de version.

Le format va encore évoluer en Java 10 mais restera globalement compatible avec le format utilisé en Java 9. Il faut désormais passer par l’API  Runtime.Version pour connaitre la version de Java utilisée.

 

Conclusion

Comme vous avez pu le voir la migration vers Java 9 n’est pas aussi simple que celle d’une application de Java 7 vers la version 8. Malgré les problèmes que cette migration risque de poser, elle va permettre de beaucoup mieux contrôler nos applications et de mieux gérer toutes les dépendances et librairies. De plus ce sera une étape obligatoire pour profiter de toutes les nouveautés des versions suivantes. Vous pourrez en avoir un aperçu dans notre prochain article : Les Nouveautés de Java 10.

 

Liens utiles

Guide migration Java 9 par Oracle : https://docs.oracle.com/javase/9/migrate/toc.htm#JSMIG-GUID-7744EF96-5899-4FB2-B34E-86D49B2E89B6 Conférence Devoxx liée à l’article : https://www.youtube.com/watch?v=dYubeLiObqY