mercredi 23 juillet 2008

Migration Maven 2 : 2ème épisode : la procédure

Suite de la migration... Comme je le précisais dans le première épisode dans ce post. J'ai procédé à la migration de gros applicatifs J2EE de maven 1 vers maven 2.

Une fois devant l'écran, un peu comme un écrivain, c'est un peu la page blanche : Par où commencer???

Je vais m'efforcer de vous décrire la procédure que j'ai appliquée:
  • Maitriser et comprendre l'applicatif et le processus de build maven 1 existant :
Avant tout, je pense qu'il faut bien connaître l'applicatif ainsi que le processus de build à migrer, en tous cas d'un point de vue technique. Cette connaissance va permettre de déceler les points sur lesquels il va falloir mettre l'accent plus particulièrement (où ça va coincer :-))
Dans mon cas, il se trouve que quasiment chaque projet java (l'applicatif est composé d'un ensemble de projets java) est muni de son project.xml mais surtout est quasiment toujours accompagné d'un fichier maven.xml. Pas de chance, il y a pas mal de spécificités de build qui ont été mises en œuvre : génération de code source en tout genre, concaténation de fichiers, exécution de tâches ant diverses et variées,...

  • Posséder une plateforme "témoin" :
Un des principales objectifs est de réussir à fournir, avec un processus de build différent, les mêmes livrables j2EE (un ear et plusieurs wars dans mon cas). Je me suis installé l'ensemble de la plateforme de développement et effectué des builds avec le processus de build maven 1 existant. Ce système permet d'avoir un environnement "témoin" permettant d'effectuer des comparaisons entre l'ancien build et le nouveau build. Concrètement, ça revient à récupérer 2 fois les projets de sources sur le poste:
- les projets de sources maven 1 "témoin".
- les projets de sources sur lesquels travailler pour effectuer la migration maven 2.

  • Migrer les dépendances
Dans un premier temps, il faut analyser et lister les dépendances dont le projet a besoin. Un bon vieux tableur facilite le travail. Pour chacune de ces dépendances, il faut vérifier si elle est disponible dans un repository maven 2 sur la toile grâce à ce site par exemple. Pour celles qui n'existent pas, il faut les installer dans le repository maven 2 de l'entreprise (s'il n'y en a pas, c'est un travail à faire... et pourquoi pas aussi mettre en œuvre Archiva , oulaaa, je m'emballe!) :
mvn deploy:deploy-file -Durl=file://C:\m2-repo \
-DrepositoryId=some.id \
-Dfile=your-artifact-1.0.jar \
[-DpomFile=your-pom.xml] \
[-DgroupId=org.some.group] \
[-DartifactId=your-artifact] \
[-Dversion=1.0] \
[-Dpackaging=jar] \
[-Dclassifier=test] \
[-DgeneratePom=true] \
[-DgeneratePom.description="My Project Description"] \
[-DrepositoryLayout=legacy] \
[-DuniqueVersion=false]

  • Mettre en place un premier pom.xml
Dans le cadre d'applicatif j2EE découpé en un ensemble de projets Java/Maven, il est difficile de migrer l'ensemble des POM en une seule fois. Il est important de procéder de façon itérative et de se concentrer sur la migration d'un des projets (simple en terme de build si possible) pour commencer.

  • Capitaliser et centraliser le build
Les possiblités en terme d'héritage et de gestion "multi module" de Maven permettent :
- de réutiliser comportement de Pom en définissant des Pom parent, grand-parent, ...
- de piloter l'ensemble des projets en définissant un Pom multimodule.

En conservant à l'esprit ce type de pratique, j'ai progressivement procédé à des refactorings de Pom au fur et à mesure de la mise en place des Pom des projets. Voici une version simplifiée de mon arborescence de Pom :
pom "base"
pom projet utilitaire
...
pom "webapp"
pom webapp1
pom webapp2
...
pom "ejb"
pom ejb1
pom ejb2
...
  • Migrer les spécificités maven 1 : "exit maven.xml"
Une fois le comportement global du build définit, les spécificités de build maven 1 viennent vite bloquer le processus de migration, notamment en ce qui concerne la génération de code qui a un impact sur la compilation (ça compile si le code a été généré sinon non...).
Voici quelques exemples de spécificités :
- génération des classes techniques ejb avec ejbDoclet de XDoclet : cette génération était pilotée en Maven 1 par le lancement de tâche Ant. Le plugin maven2 antrun a permis de faire la migration.
- génération d'un fichier par concaténation d'un ensemble de fichiers : La concaténation était effectuée en jelly... La seule solution était de mettre en place un plugin maven 2 qui effectue le travail.

  • Rester zen...
Une fois passé le cap du "BUILD SUCCEFULL" (qui , d'ailleurs, fait bien plaisir), le gros du travail est effectué. Le reste correspond a des ajustements mais des ajustements qui font d'ailleurs perdre pas mal de temps. Dans mon cas , le build du projet dans son ensemble prend dans les 10 minutes. Pour tester une modification, une seule solution : reBUILDER! Il faut savoir être patient et se dire que si on devait le faire soi-même on mettrait 3h pour faire un seul build...

  • Comparer les livrables j2EE entre le build maven 1 témoin et le nouveau build maven2
Les principaux ajustements à effectuer pour obtenir des contenus de livrables (ear et wars) identiques concernent les dépendances dans les archives war et ear. Avec maven 2 et la transitivité des dépendances, j'ai dû ajuster les choses en terme de versions et de porter de jars pour finalement obtenir des dossiers de "lib" identiques.

  • Tester les nouveaux livrables
Il faut ensuite déployer les nouveaux livrables pour valider que l'application fonctionne toujours... et procéder à des ajustements en terme de fichiers de conf J2EE notamment ceux propres au serveurs d'applications (ex : weblogic.xml, jboss-web.xml, ...).

Une fois ce cap franchi, on pense avoir quasiment terminé... mais il reste des choses à faire...
Ha, mon build vient de se terminer, la suite dans le prochain épisode...

mardi 15 juillet 2008

Migration Maven 2 : 1ère épisode : Le contexte

Je me suis attelé ses derniers jours (voir mois) chez mon client à entreprendre la migration de gros applicatifs maven 1 vers maven 2. Je vais essayer de vous faire profiter d'un retour d'expérience sur le sujet car je n'ai pas trouvé de méthodes miracles de migration.

Je vais y consacrer un certains nombres de billets. Le dossier est assez touffu...

Pour commencer, voici le contexte des applicatifs qui doivent être migrer :
  • applicatifs j2EE multi module (ear contenant un ensemble d'ejb sessions + mutli war).
  • héritage de projet maven.
  • utilisation du multi-projet.
  • changement du type de packaging (simple jar, ejb-jar ou ejb-jar-client) en fonction de propriétés au moment du build.
  • génération des classes techniques des ejbs avec xdoclet (ejbdoclet).
  • génération de classes techniques type "delegate" pour simplifier l'appel aux ejbs avec xdoclet (template doclet).
  • génération des sites projets.
  • utilisation de l'intégration continue avec continuum.
  • dans les 8000 fichiers au contrôle de source (sources + ressources).
  • une dizaine de minutes à attendre pour faire un build complet.
  • entre 5 et 20 développeurs par applicatifs.
  • déjà en production pour certains applicatifs.
  • application de type stratégiques.

Avant tout on peut se demander pourquoi? Voici les arguments que j'ai pu trouver à part de dire qu'il faut le faire :-) :
  • Pour permettre d’utiliser les nouvelles fonctionnalités de Maven2 (transitivité des dépendances, profile, scope, …).
  • Pour profiter des modifications effectuées sur les fonctionnalités existantes (gestion multiprojet, héritage).
  • Pour profiter des améliorations de performances que propose maven 2 (consommation mémoire pendant le build, temps de build …).
  • De simplifier les scripts de build.

Je détaillerai par la suite la démarche de migration qui a été mise en œuvre dès que j'ai un peu de temps entre 2 builds :-).

La suite dans le prochaine épisode...