18 novembre 2010

Modularisation de la JVM

Cette session présente JigSaw, qui continue son lobbying pour imposer à la JVM une modularisation autre que celle proposée par OSGi ...

A quoi ça sert ?  A sortir du classpath Hell, à accélérer le lancement de la JVM, à alléger le runtime, à approvisionner automatiquement (comme le font les Linux avec apt ou yuml), et à assurer la prédictibilité de l'environnement d'exécution.

La vérification du classpath à l'installation plutôt qu'au runtime, associé à la construction de profils pour une application (liste des classes effectivement chargées lors du premier lancement) doivent nous apporter un gain significatif de fiabilité et de réactivité. La mise en cache des description des classes (i.e. conversion des .class dans un format plus efficace) est aussi une astuce exploitée pour améliorer encore l'environnement d'exécution Java. Toutes ces optimisations sont liées à la possibilité de traiter les problèmes de classpath lors de l'installation, et non au runtime.

Le fichier module-info.java (non qui est en principe invalide pour une classe normale) sert de descripteur à la définition d'un module - à une autre époque on aurait choisi un descripteur XML, les temps changent. Le module permet de définir les requirements de notre module (en gros, les dépendances runtime si vous raisonnez comme moi en langage Maven), y compris avec la notion de requirement optionnel et bien sûr cela implique la gestion de la transitivité - espérons que le modèle choisi pour cela sera compatible avec Maven et OSGi, sinon ça promet...

Avec cette possibilité de définir des modules, il devient facile de découper un gros projet en modules et de les référencer dans un module aggrégateur (tout ce vocabulaire me rappelle bizarrement quelque chose).

A l'usage, le compilateur javac proposera une nouvelle option -modulepath permettant d'indiquer les emplacements de nos modules - en gros, notre localRepository :P. La nouvelle commande jpkg permet alors de construire un livrable selon un nouveau format (oubliez vos jars). La commande jmod quand à elle nous apporte l'approvisionnement des modules pour pouvoir lancer la JVM avec un paramètre -mlib indiquant l'emplacement des modules nécessaires à l'exécution. Et comment fait-elle cet approvisionnement ? Avec un dépôt de modules ! Et bien sûr, le repo maven2 est supporté comme source de modules. Qui a dit "standard de fait" ?

Avec ce mécanisme, une application Java va donc pouvoir démarrer avec une version "allégée" de la JVM, typiquement le lancement d'un batch en ligne de commande ou d'un serveur d'application va s'épargner toute la couche graphique AWT et Swing.

Comment tout ça va s'intégrer au JRE ? Un slide nous présente les dépendances entre packages Java, et on a un magnifique effet spaghetti à l'écran, surtout avec l'ajout des API JavaEE par dessus couleur sauce tomate... Après un gros refactoring, la JRE est descendue à un graphe de 25 noeuds et 97 relations, qui devient raisonnablement affichage dans un slide. Ca a du être un sacré boulot :) En terme de compatibilité, cela suppose néanmoins que les applications existantes ne dépendent que des API publiques et pas de leurs détails d'implémentation.

Et OSGi dans tout ça ?

Au moins on écarte pas le débat lors de cette session... Mark Reinhold répond en un exemple : un module A requiert un module B. Avec la modularité Java, A et B peuvent être packagés en paquet debian et résolus à l'installation. De même, Maven gère sans soucis ce cas d'utilisation. Dans le cas d'OSGi, deux bundles peuvent exporter la même API publique sans définir de moyen de résolution privilégié. Le modèle OSGi est donc implicitement plus complexe, focalisé sur un niveau de granularité package, ce qui est souvent un niveau trop fin pour modulariser du code.

2 commentaires:

pascal leclercq a dit…

Excellent Résumé. Bravo !!! Perso, j'ai pas trouvé très recevable les argument de Mark Reinhold concernant OSGi : tout l'argumentaire tiens sur l'hypothèse que plusieurs modules différents exportent le même paquetag, ce qui est de toute façon incohérent en OSGi (et je pense impossible). Espérons qu'ils ouvrent les yeux....

Bengali a dit…

Oui et il me semble qu'avec OSGi tu peux aussi dépendre d'un bundle (Require-Bundle) plutôt que de packages.