I. Introduction▲
Né dans les locaux de SUN courant 2008, le très ambitieux projet « Jigsaw » a failli connaître la gloire en 2012. Son objectif est d'aboutir à une plateforme Java modulaire répondant, plus efficacement, aussi bien aux attentes des grandes plateformes Java EE, qu'à celles des architectures plus restreintes comme les mobiles, les tablettes et les micropuces.
Une plateforme Java flexible, légère et performante est plébiscitée, attendue par tous. Or après huit ans de gestation, pourrions-nous continuer à croire à la naissance d'un miracle ?
II. Le début d'un long chemin▲
Dès le début du projet, une partie de la communauté Java s'est opposée assez fermement à l'idée d'un Java SE modulaire. Leur argument, très légitime, était le risque de la perte de stabilité de la plateforme, stabilité qui a contribué grandement à la réputation et au succès de la plateforme Java.
La peur des grands changements était là. Heureusement, elle n'a pas été un frein à l'évolution. C'est elle, malgré la complexité et les risques non négligeables liés à la transition vers une plateforme modulaire, qui a modelé, au fil des discussions entre partenaires, le projet dans sa conformation actuelle. En effet, une fois le projet adopté, sa feuille de route n'a cessé de changer en raison de grosses difficultés techniques et des choix de solutions qui n'ont pas été faciles. Initialement prévu avec Java 7, le projet s'est vu reporté en Java 8, puis finalement en Java 9. Un « staffing » plus étoffé a permis de balayer un nombre important de problèmes, dont quelques-uns sont listés ci-dessous :
- un JDK monolithique et très rigide, entrainant une grande difficulté à isoler des modules cohérents et faiblement couplés ;
- la difficulté de créer des « runtime » par configuration à l'image des modules JDK en raison d'une JRE rigide et monolithique ;
- la présence de dépendances croisées et parfois circulaires (cas du package java.lang.*). Dans un de ces billets, Mark Reinhold, architecte en chef du « Java Platform Group » chez Oracle, dit sans détour que le JDK tel qu'il est, est devenu trop imposant et gourmand en termes de ressources ; que certaines des API sont profondément interconnectées et trainent des dépendances indésirables. Le « plat de spaghetti » (Figure 1), ci-dessous permet d'avoir une petite idée de l'ampleur de la tâche ;
- certains packages internes (sun.*, com.sun.*) sont appelés directement par des API, alors qu'ils ne devraient pas l'être ;
- les bibliothèques et/ou frameworks du marché sont fortement dépendants du rt.jar et/ou tools.jar.
Les efforts consentis ont fini par payer et une version en « early acces : JDK 9 build b80 » semble avoir passé beaucoup de tests avec succès. Le rendez-vous pris aura lieu cette fois-ci comme prévu courant 2016. Mais avant, et pour préparer le terrain, quelques petites graines ont été plantées en Java 8. Ceci a donné naissance aux « Java compacts profiles » ainsi qu'à l'apparition de nouveaux outils d'accompagnement.
Au nombre de trois, ces profils ont été cadrés par la JEP 161 et construits dans un esprit hiérarchique. Chacun d'eux correspond à un sous-ensemble de l'API Java SE 8 globale et inclut les API définies dans le profil sous-jacent. D'un point de vue taille et fonctionnalités, le profil est le plus restreint. Inversement, le profil est le plus important. Il englobe le profil « compact2 » et lui-même est un sous-ensemble de l'API Java SE complète.
Avec « Java SE 8 Embedded », ces profils ont été propulsés pour faciliter et favoriser la création d'applications embarquées. La conquête du marché de l'automobile, des « small devices » et des objets connectés, déjà ciblés, passe à la vitesse supérieure. Une publication Oracle évoque même une future convergence entre Java ME et Java SE.
En java 9, grâce à la modularisation, un nombre plus large d'applications, simples et compliquées, pourront se baser uniquement sur les modules Java qui leur seront nécessaires.
Il est vrai qu'au fil des versions, l'environnement Java a beaucoup mûri en se nourrissant de ce qui se fait de bien autour de lui. Il s'est enrichi en fonctionnalités et en outils. Il a su se simplifier pour une meilleure prise en main et une réelle et bénéfique productivité, tout en garantissant une compatibilité avec les versions antérieures.
Mais tout au long de ce processus, la croissance en termes de fonctionnalités s'est faite par cumul sans sortir de la structure monobloc héritée des premières versions du JDK. L'API globale contient actuellement de nombreuses et variées fonctionnalités or, en général, les applications n'utilisent que quelques fonctionnalités (IO, NIO, NET, UTIL, LANG, etc.) à la fois et n'ont besoin ni de charger tous les modules (AWT, SWING, XML, SQL, MATH, RMI, CORBA, etc.) constituant le JDK, ni de s'appuyer sur un JRE complet garantissant toutes les fonctionnalités. Pour de gros serveurs ou des machines puissantes, ceci parait dérisoire. Or, ceci devient un facteur limitant dès que l'on vise le domaine de « small devices » comme les routeurs, les TV, etc.
Des modules bien identifiés et des JVM adaptées, donc plus légères, répondront plus efficacement aux différents besoins, aussi bien en termes de gestion de ressource que de performance. À titre d'exemple, la « Minimal Hotspot VM - cf. Fig 3 » a été délestée de toutes les fonctionnalités non fondamentales. Entre autres, exit les outils VM Management et les combinaisons GC. Seul le « Serial GC » a été retenu. Sa taille réduite au maximum, cette VM a été optimisée pour les processeurs ARM en particulier.
Avec Java SE 8 embarqué, qui dérive de Java SE 8 et qui en respecte toutes les spécifications, il sera désormais possible de compiler pour un profil donné et de générer le JRE équivalent. Pour accompagner cette « petite » révolution, deux nouveaux outils majeurs ont été élaborés. Le premier se nomme « jdeps ». Il s'agit d'un outil d'analyse des dépendances statiques entre modules. Il pourra être utilisé soit directement soit au travers de son plugin Maven. Le second se nomme « jrecreate ». Disponible seulement sous « Java SE 8 embarquée », il permet de générer un JRE par configuration, autrement dit un « runtime » correspondant au profil utilisé par l'application.
Vous l'avez compris, ces « compacts profils » ont permis de rendre modulaire dans une certaine mesure l'API Java 8. Ils ne sont que les prémices d'un changement plus important et dont les bénéfices escomptés sont nombreux et variés. Les éléments centraux de ce changement sont précisés dans les documents d'amélioration correspondant au JDK 9, les fameux JEP (JDK Enhancement Proposals) :
- JEP 161 et 162 : dont le but est de préparer la transition vers la modularisation. Les axes principaux sont de déprécier les API qui constituent un frein à la modularisation ainsi que d'offrir de nouveaux outils pour faciliter l'utilisation d'une plateforme Java riche et modulaire ;
- JEP 199 : « Smart Java Compilation, Phase Two » ;
- JEP 200 : JDK modulaire, dont le but est de découper le JDK en petits modules indépendants, pouvant être utilisés séparément ou combinés lors des différentes phases d'un projet (compilation, installation et exécution). Différentes configurations deviennent alors possibles allant de la plus complète, comme c'est le cas avec une plateforme JDK 6 ou 7, à une configuration basée sur les « compacts profiles », ou encore, une configuration complètement personnalisée ;
- JEP 201 : source code modulaire pour une meilleure construction et compilation ;
- JEP 220 : Modular Run-Time Images, dont le but est de restructurer le JRE et le JDK. Exit le JDK tel qu'il est connu. Pour simplifier, ce dernier sera une image JRE, les outils de développement en plus ;
- JSR 376 : Java module, dont le but est d'aboutir à un système flexible et évolutif permettant des configurations personnalisées en fonction des fonctionnalités nécessaires à une application cliente.
III. Après la pluie, le beau temps▲
Menée par Mark Reinhold, architecte en chef du « Java Platform Group » chez Oracle, une feuille de route pour Java 9 a été dressée et acceptée par la majorité des partenaires, les « experts groups » (Eclipse Foundation, IBM).
Les premières marches franchies correspondant à :
- la mise en place des profils compacts ;
- l'adaptation du compilateur « javac » et de l'outil jar pour la prise en compte des profils ;
- l'apparition de nouveaux outils comme « jrecreate » et « jdeps » dont le but est d'aider dans la transition vers la modularisation des applications.
Leurs implémentations sont déjà disponibles avec Java 8 (SE et embarqué). Le reste, autrement dit l'essentiel du projet JigSaw suivra dans la « release Java 9 » prévue courant 2016.
À la base, le projet Jigsaw avait pour objectif de définir un système Java modulaire standard associé à une JRE elle-même modulaire ; un système standard dont profiteraient aussi bien les applications, les Frameworks (bibliothèques tierces) que le JDK et le JRE eux-mêmes ; le tout sur un fonds de commerce plébiscitant la légèreté, la sécurité et la performance.
Avec le temps et les discussions, le projet s'est étoffé pour intégrer différents besoins, dont quelques-uns ont été implémentés en Java 9 (SE et embarqué). D'autres ont été cadrés dans des projets à part entière comme « Penrose » traitant de l'interopérabilité avec OSGI.
Un aperçu non exhaustif de ces fonctionnalités est donné ci-dessous :
- encapsulation en modules cohérents gérant leurs dépendances de façon déclarative pour éviter les récurrents problèmes de « CLASSPATH » ;
- gestion fine des dépendances intermodules, un peu à l'image de Maven : les modules devront porter une version et exporter une API.
Extension du langage pour la description de module : naissance des directives « requires », « provides », « exports », « permits », etc., et du module-info.java permettant de définir un module et d'en délimiter le périmètre (cf. figure 4 ci-dessous).
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
module
A @
1.0
{
// Déclaration d'une dépendance (différentes versions, bornes inclusives / exclusives, caractère joker ...).
requires
B @
[1.0
,2.0
);
// Imposer un chargement via le même classloader pour éviter les anciens problèmes de classpath.
requires
local B @
[1.0
, 2.0
);
// Seuls les types " Public " seront exportés donc visibles pour les autres modules : export d'API.
exports
org.x.y.*;
// Contrôle des modules pouvant utiliser A, sinon permis pour tous modules.
permits
C;
// Un module peut indiquer un autre nom comme un alias.
provides
alias_module_A
...
}
- la mise à disposition de nouveaux outils comme « jmod » pour la création de modules et « jpks » pour la création de packages ;
- la suppression de certains outils (hprof et jhat) et l'apparition de nouveaux outils de gestion : création de modules.
IV. L'adoption du JDK 9 va-t-elle se faire dans la douleur ?▲
Quand JDK 9 sera disponible, les développeurs Java pourront donc concevoir et construire des applications et des bibliothèques Java de tailles réduites, basées uniquement sur les modules nécessaires, et non plus sur la plateforme tout entière comme c'est le cas au moment où cet article est écrit. Les bénéfices annoncés sont énormes et on peut déjà en lister quelques-uns ci-dessous :
- une plateforme facilement maintenable et évolutive, car modulaire ;
- un gain en termes de sécurité : en exposant via les modules une API, de facto, on interdit l'accès au reste du code, en particulier l'accès aux classes internes sensibles. La logique qui en découle est simple et efficace : on réduit la surface d'attaque en réduisant le nombre de classes visibles ;
- un gain accru en termes de performance, de temps de chargement et d'exécution ;
- disponibilité de JRE adaptés à différentes configurations (serveur Java EE, application d'entreprise simple et complexe, application mobile et tablette…).
Cependant, de grosses craintes planent sur cette version :
- les développeurs Java devront-ils réapprendre à travailler ?
- la firme Oracle va-t-elle sacrifier la compatibilité avec les versions Java antérieures ?
- quel sera le coût d'une migration pour des applications d'entreprise ?
Certes, les développeurs devront adapter leurs méthodes de travail à la nouvelle plateforme, mais à mon humble avis, ceci n'est qu'une formalité. Ils l'ont prouvé dans le passé et le prouvent tous les jours en adoptant de nouvelles technologies. Avec un peu de chance, la majorité des développeurs ne changeront que peu de choses à leur façon de travailler à condition de passer par la case Java 8. En effet, Java 9 n'introduit que très peu de nouveautés au niveau langage contrairement à Java 8 (Stream, programmation fonctionnelle, etc.). Ce sont ceux qui s'occuperont des processus de construction logicielle (build, installation, déploiement) qui auront fort à faire.
Pour ce qui est de la compatibilité, elle sera parfois bousculée, parfois un peu mal traitée, mais rassurons-nous, elle ne sera pas sacrifiée. Les JEP 199, 200 et 220 sont là pour l'éviter.
Quant à la migration des applications, la dette technique n'est pas une chose nouvelle. Les bonnes chaînes de management l'intègrent déjà dans leurs processus de développement. Elle est inhérente au progrès et, à ce titre, il faut s'en acquitter si l'on veut rester dans le train des nouvelles technologies. Heureusement, avec Java 9, les « experts groups » ont pensé aux outils pour faciliter la vie du développeur. Nous avons déjà abordé « jdeps », « jrecreate », « jmod » et « jpks », d'autres seront à disposition des développeurs comme « jShell » dans un but purement académique, mais aussi pour pouvoir visualiser immédiatement le résultat d'une partie de code sans être obligé de compiler tout son projet.
Bien sûr, certaines applications nécessiteront plus de travail que d'autres, car elles font appel à des API internes de Java (exemple : com.sun.* et sun.*) qui, du fait de la nouvelle réorganisation en modules, ne seront plus directement accessibles, ou alors dépendront de bibliothèques qui font des appels non supportés (dépendances vers les fameux rt.jar et tools.jar). Dans les meilleurs cas, les problèmes disparaitront en passant à des versions de bibliothèques plus récentes.
Il faudra également changer de version d'éditeur ou passer sur un autre supportant Java 9. Mais bonne nouvelle, les ténors du marché NetBean, Eclipse et IntelliJ ont déjà légèrement muté pour accompagner le changement annoncé.
V. Conclusion▲
En se dotant de nouvelles capacités, les prochaines versions du JDK promettent de meilleurs temps de chargement, de déploiement et d'exécution. Confucius a dit : « Si tu veux profiter de ta vie, apprends à profiter de ta simple journée ». Alors, dans l'attente d'une plateforme Java modulaire pleinement opérationnelle, essayons de tirer profit de ce qu'offre déjà la plateforme Java 8.
VI. Remerciements▲
Cet article a été publié avec l'aimable autorisation de la société SoatSoat.
Nous tenons à remercier Claude Leloup pour sa relecture orthographique et Malick SECK pour la mise au gabarit.