mercredi 30 avril 2008

Mise en place de Maven sur des plugins Eclipse RCP



On n'a plus besoin de vanter les mérite de l'utilisation de maven et de l'intégration continue car ils ont fait leur preuves sur des applicatifs conséquents et cela commence être intéressant de les mettre en place même sur des "petits" projets.

Il est maintenant possible de gérer des projets type plugins Eclipse RCP avec Maven 2 et quelques plugins tierces. Certains diront "Et alors, on pouvait pas avant ?" Eh bien NON ! Enfin, pas depuis bien longtemps...

Environnement technique : Maven 2.0.9, Eclipse 3.3, utilisation d'une target platform, plugin Maven pour Eclipse 0.9.5

Alors tout n'est pas encore parfait mais ça vaut le détours !

Prenons un plugins Eclipse RCP et ajoutons lui des dépendances vers des projets type Maven 2. Par exemple, si votre plugin Eclipse RCP est le client pour un serveur applicatif distant et si des classes java doivent être communes au client et au serveur, alors il est possible d'ajouter certains projets comme dépendances du plugin RCP au sein du fichier pom.xml comme on le ferait pour un projet Maven 2 "normal".

Le fait d'ajouter ces projets en dépendance permet d'utiliser ses classes dans le plugin mais un soucis persiste lors de l'exécution du plugin, les jars dépendants ne se trouvent pas dans le classpath. Heureusement une commande maven existe pour y remédier: mvn eclipse:eclipse mais celle ci fonctionnera uniquement si le fichier pom.xml aura été modifié en ajoutant l'équivalent des balises suivantes:

<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-sources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${basedir}
</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>
false
</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<includeScope>compile</includeScope>
<excludeTypes>pom</excludeTypes>
<!--
<classifier>sources</classifier>
<failOnMissingClassifierArtifact>
false
</failOnMissingClassifierArtifact>
-->
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
<filesets>
<fileset>
<directory>${basedir}</directory>
<includes>
<include>*.jar</include>
</includes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<pde>true</pde>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>pde-maven-plugin</artifactId>
<version>1.0-alpha-2-SNAPSHOT</version>
<extensions>true</extensions>
<!-- Custom lifecycle configuration -->
<configuration>
<eclipseInstall>C:/eclipse</eclipseInstall>
<pdeProductFilename>avecMaven.product</pdeProductFilename>
<pdeBuildVersion>3.3.2.R331_v20071019</pdeBuildVersion>
<buildProperties>
<base>C:</base>
<baseLocation>C:/target</baseLocation>
<buildDirectory>target/build.directory</buildDirectory>
</buildProperties>
</configuration>
<!-- Also bind to mvn clean -->
<executions>
<execution>
<id>clean-pde</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

Pour que cette version 1.0-alpha-2-SNAPSHOT du pde-maven-plugin soit trouvée, il vous faudra ajouter un pluginrepository dans votre settings.xml :

<pluginRepository>
<id>codehausSnapshots</id>
<name>Codehaus Snapshots</name>
<releases>
<enabled>false</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://snapshots.maven.codehaus.org/maven2</url>
<layout>default</layout>
</pluginRepository>

Ou bien ajouter ce repository directement dans votre pom.xml...

Cette version du plugin a le mérite de fonctionner avec eclipse 3.2 et 3.3 mais si seul Eclipse 3.2 vous intéresse, utilisez la version 1.0-alpha-1-SNAPSHOT et ce repository est alors inutile.

Pour réussir à construire le projet par Maven, il faut ajouter un répertoire buildConfiguration à la racine du projet. Puis dans ce répertoire, copier coller le fichier build.properties du répertoire eclipse/plugins/org.eclipse.pde.build_*/template/headless-build
Une fois ce fichier copier, il faut modifier certaines de ces propriétés :

product=avecMaven.product
archivePrefix=avecMaven
configs=win32,win32,x86
buildDirectory=target/eclipse.build
buildId=withMaven
base=C:/target
baseLocation=C:/target/eclipse
pluginPath=.

Ce fichier permet de spécifier comment faire le build headless, comment générer l'application en somme.

Il est important d'être sensibilisé à l'utilisation d'une target platform dans Eclipse: http://help.eclipse.org/stable/index.jsp?topic=/org.eclipse.pde.doc.user/guide/tools/preference_pages/target_platform.htm
Très pratique pour builder ses plugins dans des versions différentes de la platforme eclipse de développement utilisée ou pour paramétrer les plugins utilisés.

Ajouter le fichier customBuildCallbacks.xml à la racine du projet, fichier que l'on peut trouver ici dans le répertoire
eclipse\plugins\org.eclipse.pde.build_*\templates\plugins

Ajouter customBuildCallbacks=customBuildCallbacks.xml au fichier build.properties à la racine du projet (ne pas confondre avec le build.properties de buildConfiguration)

Modifier le fichier customBuildCallbacks.xml comme suit:

<target name="post.gather.bin.parts">
<copy todir="${target.folder}">
<fileset dir=".">
<include name="*.jar"/>
</fileset>
</copy>
</target>

Le but de cette modification étant de permettre l'export (la génération) du product dans Eclipse via l'assistant. Si cette étape est n'est pas effectuée, l'export ne fonctionnera plus. Cele permet de recopier l'ensemble des jars à la racine du projet dans le répertoire de travail de la génération, à la racine également. Ainsi les dépendances seront présentes au runtime... Cela évite de devoir réaliser une build de l'application via maven (mvn install) à chaque fois que l'on souhaite générer l'application... tout reste possible dans Eclipse.


A noter:
-Le projet plugin doit être dans un répertoire "plugins" et non directement dans le workspace pour des raisons assez obscures quu ne seront pas détaillées ici.
-Il reste des points noirs dans l'utilisation de maven avec des plugin RCP (product) et ce même après être passé sur Eclipse 3.3, m2eclipse 0.9.5 et maven 2.0.9 ! Par exemple, si un projet en dépendance maven est modifié (ajout de classe, de méthode...), le plugin sera incapable de voir ces modifications automatiquement, il faudra builder le projet modifié (mvn install) et relancer la commande mvn eclipse:eclipse sur le plugin... assez rébarbatif non ?

Sources: http://aspsp.blogspot.com/2008/02/maven-eclipse-rcp-product-build-at-last.html