Exécuter une tâche Ant automatiquement à la compilation via Eclipse

  • warning: array_map(): Argument #2 should be an array in /var/www/titouille.ch/www/modules/system/system.module on line 1050.
  • warning: array_keys() expects parameter 1 to be array, null given in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
  • warning: Invalid argument supplied for foreach() in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
Portrait de titouille

Dans le projet sur lequel je travaille actuellement, nous sommes une équipe et utilisons différentes technologies.

Tout d'abord LCDS / Hibernate, en relation avec Java côté serveur, et Flex côté client. Dans l'optique de monter un projet de manière correcte, nous avons également mis en place, côté serveur et côté client, des tests unitaires. Les tests unitaires sont fait via FlexUnit pour la partie Flex, et via JUnit pour la partie Java.

La compilation du projet java via Eclipse pose néanmoins un problème... Lorsque je travaille sur la partie Java, j'ai 2 parties distinctes :

premièrement, les fichiers sources java, accompagnés de leur fichier hbm respectifs (mappings hibernate). Ces fichiers vont se retrouver, après compilation du projet, dans le répertoire jrun4\servers\default\flex\WEB-INF\classes\{package(s)}.

deuxièmement, LCDS requiert deux fichiers de configuration. Le premier se nomme hibernate.cfg.xml, et décrit l'accès à la base de données ainsi que les fichiers de mapping à prendre en compte. Le second se nomme data-management-config.xml, et décrit les "destinations" utilisées par Flex pour récupérer les données. Les destinations sont liées directement aux assembleurs Java / hibernates et décrivent les méthodes d'accès au serveur.

Le premier fichier ne cause pas de problèmes, car il doit être situé à la racine des classes, donc dans le répertoire de base qui va contenir les classes finales : jrun4\servers\default\flex\WEB-INF\classes. C'est au niveau du second fichier, data-management-config.xml, que ça se corse. Ce dernier est situé dans un répertoire différent des classes finales : jrun4\servers\default\flex\WEB-INF\flex.

La compilation Eclipse ne peut donc malheureusement pas aller placer ce second fichier dans le bon répertoire. Il est nécessaire de le placer manuellement, et cette action peut souvent causer des soucis, car on oublie vite cette action manuelle.

Pour palier ce problème, il y a un moyen très efficace : utiliser une tache Ant. Ant est un outil qui permet d'exécuter plusieurs actions, dans un ordre précis. Dans notre cas, Ant va nous permettre de faire une copie du fichier data-management-config.xml, puis de placer les fichiers de mapping hibernate dans les répertoires finaux.

La configuration du projet change donc quelque peu, pour permettre d'effectuer ces 2 actions à la suite, et permettre ainsi d'avoir un projet compilé proprement.

Pour mettre en place un script Ant, il suffit de créer un fichier nommé "build.xml". Ce fichier va contenir une structure XML qui va décrire les actions à faire. La première chose est donc de créer ce fichier, à la racine du projet. Nous allons ensuite y placer la structure XML suivante :

<?xml version="1.0"?>
<project name="lcds_java" default="compile">
 
	<!-- 
		webinf directory
	-->	
	<property name="jrun4.webinf" value="${jrun4.path}/servers/default/flex/WEB-INF/"/>
 
	<!--
		source and target directory for the java / hbm.xml files
	-->
	<property name="project.src" value = "${basedir}/src"/>
	<property name="project.bin" value = "${jrun4.webinf}/classes"/>
 
	<!--
		name, source and target directory for the data-management-config.xml file
	-->
	<property name="config.name" value="data-management-config.xml"/>
	<property name="config.src" value="${basedir}/config"/>
	<property name="config.bin" value = "${jrun4.webinf}/flex"/>
 
	<!-- 
		copy data-management-config.xml file into the {configOutputPath} directory
	-->
	<target name="copyConfig">
		<copy file="${config.src}/${config.name}" 
			tofile="${config.bin}/${config.name}"/>
	</target>
 
	<!-- 
		copy all xml files into the classes directory on the server, depends on the hierarchy
	-->
	<target name="copyHbm" depends="copyConfig">
		<copy todir="${project.bin}">
 			<fileset dir="${project.src}" includes="**/*.xml"/>
		</copy>
  	</target>
 
	<!--
		execute all tasks
	-->
	<target name="compile" depends="copyHbm">
	</target>
 
</project>

A y regarder de plus près, le système est simple. Après la déclaration de projet qui va spécifier le nom de projet et l'action par défaut, je déclare d'abord quelques variables (balise property) qui définissent les chemins et noms de mes fichiers :

  1. src : le répertoire des sources java
  2. bin : le répertoire ou seront placés les classes java compilées
  3. configName : le nom de mon fichier de configuration des destinations
  4. configPath : le chemin "source" de mon fichier de configuration des destinations
  5. configOutputPath : le chemin final vers lequel devra être copié le fichier de configuration des destinations

J'ai ensuite 3 balises "target" qui vont définir des actions à effectuer. La première balise "target" nommée "copyConfig" défini très simplement la copie du fichier de configuration des destinations à partir du fichier source dans le fichier final que j'ai cité auparavant.

La seconde balise "target", nommée "copyHbm" défini une copie plus large. Petite explication. FlexBuilder3, lors de la compilation, me copiait automatiquement les fichiers de mappings hibernates (*.hbm.xml et hibernate.cfg.xml) dans les répertoires de destination des classes. Néanmoins, il est préférable de s'assurer que ces fichiers sont placés correctement dans les répertoires finaux. Il est donc nécessaire d'indiquer à Ant qu'il doit copier tous les fichiers ayant une extension "xml" dans les répertoires finaux. Cette cible est là pour ça. Cette cible possède un attribut "depends" qui établi une dépendance avec une autres cible. Cette dépendance implique que lorsque cette cible est exécutée, il est obligatoire que la cible dépendante ait été exécuté auparavant. Elle est dépendante de la cible "copyConfig". Si on suit la hiérarchie, la copie des fichiers xml de mapping est dépendante de la copie du fichier des destinations hibernates.

Enfin, la dernière cible, "compile", n'a aucune action spécialisée, si ce n'est de dépendre de la cible "copyHbm". Ce qui implique que lorsqu'on lance l'exécution de la tache "compile", toutes les autres actions sont effectuées, dans l'ordre de leur dépendance respective.

Il reste encore un point légèrement ambigüe... D'où sort donc la variable "jrun4.path" qui est utilisée dans le script ? Cette variable est une variable dite "globale" au script, qui spécifie le chemin vers le serveur JRun. Nous allons l'intégrer dans la configuration dans la suite de cette explication.

Le fin du fin, maintenant, est de spécifier à Eclipse que lorsque nous désirons compiler notre application, il déclenche également le script que nous avons créé pour la copie des fichiers.

Pour ce faire, il suffit d'aller dans les propriétés du projet, sous "Générateurs". Clickez sur "Nouveau...", sélectionnez "Ant Builder", nommez ce nouveau générateur "Générateur Ant", et dans "Fichier de génération", cliquez sur "Parcourir l'espace de travail" pour sélectionner le fichier build.xml. Une fois ceci fait, passez sur l'onglet "propriétés". C'est ici que nous allons rajouter notre variable globale "jrun4.path" citée plus haut : décocher la case à cocher "Utiliser les propriétés globales..." puis cliquez sur "Ajouter une propriété". Spécifiez comme nom "jrun4.path" et comme valeur le chemin d'accès à votre serveur JRun4. Validez avec OK, vous verrez la variable apparaitre dans la liste des prpriétés. Validez maintenant la configuration via le bouton Ok au fond du panneau. Enfin, cochez votre nouveau générateur et laissez coché le générateur par défaut, la compilation via Eclipse.

Dorénavant, à chaque fois qu'une compilation est effectuée via Eclipse, le script Ant sera également exécuté.