J’ai rencontré Jean-Laurent de Morlhon de Valtech, venu passer une journée chez Reuters pour entre autre parler de Maven. A cette occasion, j’ai commencé à regarder et envisager la possibilité de migrer nos scripts ANT et notre système de release vers Maven.
Notre équipe développe un framework j2ee qui est ensuite relivré à 4 équipes différentes. La mise en place de Maven nous permettrait de gérer les versions ainsi que l’intégration avec les autres produits plus facilement. Chaque version de notre framework serait installé dans un repository local commun aux 4 équipes. Notre framework sera packagé comme un dépendance parent pour leur projet.
Après avoir téléchargé et installer Maven, j’ai commencé à écrire mon premier POM… Via le blog de jean-laurent j’ai trouvé un très bon livre en anglais au format PDF de Vincent Massol et Jason van Zyl qui est disponible gratuitement après vous être enregistré sur le site de l’éditeur Mergere Inc.
Pour revenir à notre projet, celui-ci est composé de plusieurs jar, ejb, d’une application web et enfin le tout packagé dans un ear. La première étape a été de réorganiser les sources. Merci à Subversion, il est possible de faire cela tout en conservant l’historique. En effet, Subversion contrairement à CVS ou VSS, versionne les répertoires. Il est facile de renommer un répertoire ou de le déplacer tout en conservant l’historique de vos fichiers. Pensez-y si vous devez choisir entre CVS et SVN. Pour revenir à Maven je me suis donc lancé dans un chantier de déménagement pour tout d’abord mettre en place mon arborescence.
Ensuite l’étape suivante est de placer un fichier pom (project object model) par module du projet. J’ai ainsi rangé mes ejbs d’un côté, les jars de l’autre. Parmis les modules nous avons aussi un connecteur JCA. Maven2 est aussi capable de génerer un RAR pour ce connecteur.
La gestion des dépendances et des librairies est le premier intérêt majeur de Maven. J’ai ajouté en quelques lignes toutes les librairies que nous utilisons (Log4J, Castor, Commons-fileupload, Xerces, Xalan-J…). J’ai regroupé à la racine de mon projet dans le POM de départ mes dépendances. En fait il semble que si des modules fils soient les seuls à se servir de certaines librairies, il vaut mieux les déclarer dans le pom de ce module uniquement et pas à la racine. A vérifier…
J’ai ensuite regardé comment récuperer tous nos tests JUnit. Et bien c’est facile ! Il suffit de relocaliser les tests dans un répertoire src/test/java et hop, Maven les compile et les execute alors aussi.
Après quelques heures, j’avais la quinzaine de module de notre projet qui compilait. La partie Web est cliente des EJB. Pour charger les dépendances comme des EJB client, il suffit d’utiliser la balise type dans la balise dependency:
<dependency> <groupId>com.reuters.karma</groupId> <artifactId>wfProfiling</artifactId> <version>1.0-SNAPSHOT</version> <type>ejb</type> </dependency>
Le packaging de l’EAR n’est pas plus compliqué. Le connecteur JCA est packagé sous la forme d’un JAR dans la balise packaging de son POM mais il sera ensuite packagé comme un rar dans l’EAR via la configuration suivante:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ear-plugin</artifactId> <configuration> <displayName>Karma Framework</displayName> <description>Karma Framework Maven</description> <version>1.4</version> <modules> <rarModule> <groupId>com.reuters.karma</groupId> <artifactId>wfBLSetransport</artifactId> <bundleFileName>wfBLSetransport.rar</bundleFileName> </rarModule> <webModule> <groupId>com.reuters.karma</groupId> <artifactId>karma-war</artifactId> <contextRoot>/karma</contextRoot> </webModule> </modules> </configuration> </plugin> </plugins> </build>
Maven est un framework de compilation qui permet aussi via des plugins de faire des choses assez sympathique comme installer et deployer un JBoss AS 4.0 automatiquement via l’API Cargo. Cargo est une API qui permet de gérer les conteneurs J2EE comme JBoss, Geronimo ou BEA WebLogic en proposant des méthodes pour démarrer, arrêter et déployer des applications. En intégrant cela dans Maven, il devient alors possible d’automatiser l’installation d’un serveur J2EE dans l’environnement d’un développeur. Le déploiement sera fait aussi automatiquement. Cela vous evitera d’installer plusieurs fois JBoss sur différentes machines. Maven s’en chargera pour vous. Le support de BEA WebLogic est aussi un gros point positif. J’avoue que c’est assez bluffant.
Bien entendu, ceci ne s’applique qu’à la partie Production. Il n’est pas question des clients finaux, mais plutôt des développeurs et de l’installation de leur environnement de travail.
Derniers tests réalisés avec Maven, la gestion qualité du projet. J’ai rajouté quelques lignes dans le POM de départ pour que Maven génère des rapports HTML sur la qualité du code source: tests unitaires, PMD, Checkstyle le tout avec JXRef pour accéder au code source. Et bien je dois dire que cela marche. Le seule souci pour l’instant, c’est que j’ai rencontré une erreur avec Maven. En effet, j’utilise des dépendances systèmes afin de charger des librairies Reuters (que nous ne pouvons pas distribuer) pour les données du marchés. Or il semble qu’il y ait un bug entre la gestion de ces dépendances systèmes et la dernière version de Maven.
Lorsque je lance la commande mvn site voici l’exception génerée:
java.lang.NullPointerException
at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:82)
at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:63)
at org.apache.maven.project.DefaultMavenProjectBuilder.findModelFromRepository(DefaultMavenProjectBuilder.java:467)
at org.apache.maven.project.DefaultMavenProjectBuilder.buildFromRepository(DefaultMavenProjectBuilder.java:225)
Le POM du projet qui génere cette erreur a une dépendance système :
<!-- Special dependency for Reuters Report Server API --> <dependency> <groupId>internal</groupId> <artifactId>reportserverapi</artifactId> <version>1.0.0</version> <systemPath>${basedir}/../libs/internal/reportserver/reportserverapi-1.0.0.jar</systemPath> <scope>system</scope> </dependency>
Donc voilà où j’en suis aujourd’hui. Je vais aller voir sur le site de Maven2 si je peux ajouter un bug, quoique je doute d’être le premier avec ce problème.
Le premier bilan est très positif. En migrant sous Maven nous pourrions tout d’abord accélerer le temps de compilation du projet. En effet, avec ANT la compilation complète du projet prend dans les 5mn30. Avec Maven la compilation complète prend autour de 3mn. La compilation après modification d’un fichier seulement est par contre beaucoup plus rapide. Je pense que la gestion des dépendances dans notre projet entre les JAR et les EJB est mieux fait avec Maven.
Autre astuce intéressante: la génération d’un projet IDEA IntelliJ automatiquement. Je rassure mes colluegues, utilisateur d’Eclipse, il est aussi possible de générer un projet Eclipse automatiquement. Là encore un gain de temps. Maven fait gagner du temps en évitant de laisser les développeurs gérer la plomberie d’un projet, que ce soit la compilation, l’intégration, le packaging, la mise en production sur un serveur de test ou même la mise en place du projet dans Eclipse ou IntelliJ… Cela achève de me convaincre qu’on devrait migrer vers Maven afin de ne plus perdre de temps à gérer tout cela