Last day @Devoxx
"Devoxx is over!". Directement depuis le train du retour...
Il est traditionnel que la journée du vendredi (la matinée en fait) ne regroupe jamais les sessions les plus attendues. Cette matinée nous a tout de même amené du contenu fort intéressant.
DM Server : from WAR to Web Module
SpringSource a profité de la matinée pour réaliser une présentation d'une heure sur leur nouvellle plateforme DMServer. DMServer a pour objectifs:
- offrir de la modularité. SpringSource considère les war comme quelque chose de monolitique (notamment car l'ensemble des librairies disponibles sont potentiellement en plusieurs exemplaires dans le répertoire WEB-INF/lib) et souhaite pouvoir partager des services communs à plusieurs applications web entre ces applications web.
- faciliter l'intégration des beans Spring dans OSGI avec notamment la "service registry", l'annuaire de services
- faciliter la gestion des librairies avec le "Bundle Repository", le référentiel de Bundle OSGI. A noter que lorsqu'une application utilise un Bundle OSGI, ce dernier est chargé uniquement "on demand" afin bien entendu de limiter l'empreinte mémoire.
OSGI introduit la notion de Bundle, un jar définissant un MANIFEST qui définit quels packages sont visibles de l'extérieur du Bundle. La limite aux bundles dans le cadre d'une application Web reste le déploiement et l'unité de déploiement (classiquement un WAR ou un EAR). pour répondre à cela, SpringSource définit une nouvelle unité de déploiement : le PAR qu'il faut voir comme un jar définissant un MANIFEST qui contient des headers de type Application-* et qui définit quels sont les Bundle OSGI qu'il peut utiliser...Au delà de la pure problématique de déploiement, le PAR doit aussi permettre de gérer le scope des Beans à l'application...Reste que DMServer accepte de déployer de bon vieux WARs.
Il faut avouer que la session était très "par la pratique" et a consisté à transformer un WAR en PAR/WebModule. Donc du code, de l'IDE...
Step 1: d'un WAR aux librairies partagées
Prenez une application web classique regroupant dans son WEB-INF/lib quelques jars. La première étape consiste à rajouter dans le WAR un MANIFEST OSGI qui spécifie les Bundles que l'application va utiliser ainsi que leurs versions. Par exemple
Import-Package:javax.servlet:version="2.5"
Import-Library:org.springframework.spring,version"[2.5.0,3.0.0)"
Résultat des courses, le WEB-INF/lib disparait. Vous me direz qu'on savait déjà mettre des jars dans le classpath du serveur. Ce n'est pas faux mais cela ne permet de gérer qu'une seule version des jars.
Step 2: vers des services partagés entre WAR
L'idée est de pouvoir partager des "services" - concrètement des Beans Spring" - qui seraient communs entre différents WAR. Dans ce cas, l'application se repose sur le Service Registry mis à disposition par DMServer.
Pour faire cela, on extrait du war les classes en question (typiquement les classes des packages "services") puis il faut exposer certains packages au niveau des Bundles réutilisables puis les référencer depuis l'application Web. L'exposition de services/beans est assez simple et ce fait grâce au manifest, à un fichier de configuration spring et un fichier OSGI (et oui, cela se complexifie un peu...).
concernant le manifest donc:
Export-Package:com.octo Import-Package:org.myossproject
La première ligne de cet extrait de manifest offre la possibilité d'exporter les classes présentes dans le package com.octo. La seconde indique que le Bundle utilise le package org.myossproject. Ce fichier manifest doit (ou peut?) être complété par :
- un fichier META-INF/spring/module-context.xml, un classique fichier Spring qui définit le Bean, son nom logique...
- un fichier META-INF/spring/osgi-context.xml qui précise le bean Spring à exposer - via son nom logique -.
<service ref="myService" interface="com.octo.IMyService"/>
Côté WAR et application web, il est nécessaire de modifier le fichier application-context.xml pour référencer le service OSGI
précédemment exposé (vous être toujours là? ;o) ). Le fichier devient donc :
<reference id="myService" interface="com.octo.IMyService" />
Personnellement, à ce moment là je tape les limites suivantes:
- trop de configuration XML avec la nécessité de répéter certaines informations comme l'interface. Il y a certainement une bonne raison mais je dois avouer que je ne l'ai pas saisie.
- les projets se démultiplie. Quelques années auparavant, on créait des artifacts (pour Maven notamment et pour gérer les dépendances de compilation) et donc des projets différents. Personnellement, cela ne me dérange pas mais force est de constater que beaucoup trouve cela trop complexe. Donc, la mode est de tout ramener simplement dans un WAR avec des packages "propres". Et bien là, roll back, le nombre de projet augmente à nouveau.
La session continue avec cet exemple et démontre que l'on peut charger et décharger les bundles de la JVM sans aucun problème. La subtilité vient au moment où on décharge le bundle qui est référencé, utilisé par l'application Web. Tant que cette dernière ne réalise pas d'appels vers les services exposées par ce bundle, tout va bien. Lorsque l'on souhaite utiliser un de ces services, l'application attend jusqu'au timeout...
Là encore je tape une limite. Franchement c'est génial et la démonstration est impressionante mais (ben oui il y a un mais...)
- comment vont faire les équipes d'exploitation pour gérer les bundles utilisés, déployés, non utilisés...certes la console d'administration fournit la liste des bundle et leur version déployées dans le serveur mais est-ce suffisant pour s'assurer qu'après 6 mois d'exploitation, ne seront pas utilisé que 3 des 20 bundles déployés
- peut-on vraiment en production déployer de nouvelles versions des bundles en remplacement des anciennes? Les équipes ont intérêt à être hyper mûres sur les aspects testabilité et non regression de leurs APIs. Enfin il me semble.
- le déploiement des Bundles est ordonné. En effet, si le Bundle B dépend (Import-Package) du Bundle A, il faut que ce dernier soit déployé avant...
Step 3 : La création du Web Module et du PAR
le Web Module est un jar qui contient un répertoire particulier MODULE-INF. Ce répertoire MODULE-INF reprend l'intégralité du répertoire WebContent, c'est à dire les jsp, le WEB-INF...Ce module contient également un manifest
Module-Type:web
Web-ContextPath:myAppContextRoot
Enfin le PAR qui est un artefact d'agrégation. Ce PAR proser un fichier META-INF/MANIFEST qui reprend la liste des Bundles nécessaires à l'application Web. Le bon ordre de chargement des bundles est alors garanti par DMServer.
Bref, j'ai été plutôt prolixe sur cette session qui reste pour moi géniale. J'ai néanmoins cette (première) impression qui est que sur ce coup, les choses sont encore un peu complexes. Après, il s'agit de la première version.
Developing beyond locahost
Lors de cette session, un autre aspect de la productivité à été présenté : comme vérifier rapidement que son code marche correctement sur des OS et des configurations différentes ?
La réponse proposée est d'utiliser des machines virtuelles sur son poste et ainsi pouvoir tester directement les effets d'une modification et son comportement sur les différentes configuration. La démo s'est basée sur l'outil VirtualBox déployé sur OpenSolaris :
- On code notre application
- On switch très rapidement entre les VMs ce qui rend les tests (manuels) très rapides
- La machine utilsée (laptop) n'a pas souffert de lenteurs malgré les 3 VMs
Un outil assez intéressant (désolé le nom m'échappe...) permet d'effectuer des sauvegardes incrémentales (et donc d'en faire une multitude sans prendre trop d'espace). Ces sauvegardes nous permettent de revenir à un état initiale, pour ne plus avoir des cookies ou de cache par exemple, ou encore pour vérifier l'installation ou la montée de version d'une application JavaWebStart.
Devoxx is Over!
Devoxx en général et l'édition 2008 reste un bon moyen de sentir ce qu'il se passe sur les thématiques d'architectures, de développement et même un peu de méthodologie (car on a noté quelques 2 ou 3 sessions taggées "Méthodologie" autour de Java).
- La Modularité. Toujours et partout. Au niveau des serveurs d'applications, au niveau des applications, au niveau du JDK...bref, c'est le régime pour Java et la possibilité du "juste adapté".
- Java et sa JVM comme plateforme d'exécution de "tous" les langages. Force est de constater la poussée toujours plus forte des langages dynamiques (Groovy, Ruby,Python etc...). La retro-compatibilité du lagange et de la plateforme, mise en avant depuis des années, a commencé à être attaqué dans le but de faire tomber les barrières qui limitent l'évolution du langage, l'intégration d'autres langages...La plateforme Java est-elle vouée à devenir une plateforme offrant des services techniques à des applications écrire en N langages, une espèce de machine virtuelle universelle?
- Java s'ouvre à la communauté et cherche à fournir une plateforme plus productive. Les modèles de programmation Spring et JEE se rapprochent et tendent vers du plus simple. Le langage évolue en ce sens également.
- La confirmation de l'avantage des IHMs "vectorielles" (à base de plugin comme par exemple Flex) et des architectures IHM "client-side". Au delà des purs aspects graphiques, ces solutions laissent envisager de nouvelles manières d'interagir avec des machines, bref de nouveaux patterns d'usabilité.
- Le rapprochement Designer/Développeur. Des solutions apparaissent et visent à faciliter voire à rendre transparent ce round trip entre le designer et le développeur, l'objectif étant de s'assurer qu'il n'y a pas de pertes lors des développement.
By Benoit Lafontaine, Olivier Mallassi, Fabrice Robini