Régler les conflits entre Eclipse et le plugin Resources de Maven

Le plugin maven-resources-plugin permet d'adapter les fichiers de configuration du projet à un environnement cible en remplaçant des expressions de type ${...} par des valeurs présentes dans un fichier de propriétés correspondant à cet environnement cible.

Cependant, Eclipse ne connaît pas le plugin maven-resources-plugin de Maven et peut écraser les fichiers générés par Maven.

Ceci peut conduire à des conflits et à des problèmes de synchronisation au niveau des fichiers qui sont traités à la fois par le plugin maven-resources-plugin et par Eclipse.

L'objectif de ce post est de vous expliquer comment résoudre ces conflits.

Exemple de filtrage par le plugin resources de Maven

Dans cet exemple, nous souhaitons avoir un niveau de log différent suivant l'environnement cible.
Il sera ainsi en DEBUG en développement, en INFO en intégration et en ERROR en production.

Le fichier de configuration de la log log4j.xml a besoin d'être adapté pour que nous définissions le niveau de log approprié.

   <root>
       <level value="${log_level}"/>
   </root>

Le plugin maven-resources-plugin est utilisé pour remplacer l'expression ${log_level} par le niveau de log indiqué dans le fichier de propriétés correspondant à l'environnement cible.

Cet environnement cible est spécifié par le profil Maven et pointe vers le fichier de propriétés correspondant qui contient le bon niveau de log.

Par exemple, pour l'environnement d'intégration, nous avons le fichier de propriétés filter-integration.properties suivant :

   log_level=INFO

Nous lançons le filtrage du fichier log4j.xml par le plugin maven-resources-plugin pour l'environnement d'intégration à l'aide de la commande Maven :

   mvn resources:resources -P integration

Nous obtenons alors le fichier log4j.xml suivant :

   <root>
       <level value="INFO"/>
   </root>

Ce fichier est ainsi généré par Maven dans le répertoire de travail de Maven :

Il s'agit du répertoire target/classes à la racine du projet.

Ainsi, à chaque lancement de la commande mvn resources:resources, Maven génère un nouveau fichier log4j.xml dans le répertoire target/classes.

Attention, Eclipse travaille en compagnie de Maven sans le savoir

Cependant, ce répertoire traget/classes est également le répertoire de travail d'eclipse. C'est à dire qu'Eclipse y génère les fichiers .class de l'application et y recopie tous les fichiers de ressources du projet nécessaires au fonctionnement de l'application.

Comme Eclipse n'a pas connaissance qu'un fichier a été généré par Maven, il va reprendre bêtement le fichier original et écraser celui généré par Maven.

Eclipse utilise les fichiers présents dans le répertoire target/eclipse pour le lancement de l'application, notamment pour le déploiement sur le serveur Tomcat via le WTP.

Ceci implique que l'application déployée par le WTP va contenir le fichier log4j.xml original avec l'expression ${log_level} au lieu de DEBUG, ce qui provoquera une erreur au démarrage de l'application.

Comment empêcher les conflits avec Eclipse ?

Pour éviter qu'Eclipse écrase les fichiers générés par le plugin ressources de Maven, il faut indiquer à Eclipse de ne pas copier les fichiers qui sont également générés par Maven, mais uniquement les autres fichiers.

Ainsi dans le Build Path du projet, pour les répertoires des sources, nous indiquons à Eclipse d'exclure tous les fichiers filtrés par Maven (dans notre exemple, il s'agit de log4j.xml) et de copier uniquement les autres fichiers de ressources.

Nous avons ainsi à configurer les deux répertoires suivants :

  • src/main/resources
  • src/test/resources

Configuration du Build Path

Pour chaque répertoire, nous avons les propriétés suivantes :

  • Output folder désigne le répertoire où seront copiés les fichiers.
    Il peut s'agir soit de target/classes, soit de target/test-classes pour les tests.
  • Included: Fichiers du répertoire qui sont recopiés à chaque compilation du projet par Eclipse dans le répertoire Output folder.
  • Excluded: Fichiers du répertoire qui ne sont pas recopiés par Eclipse.

Pour éviter les conflits entre Maven et Eclipse, la configuration pour un répertoire de ressources consiste à définir les valeurs suivantes :

  • Included: N'indiquer aucun fichier afin que tous les fichiers soient recopiés par défaut par Eclipse lors du Build du projet
  • Excluded: Lister les fichiers qu'Eclipse ne doit pas recopier. Ces fichiers seront traités et recopiés par le plugin resources de Maven. Eclipse n'écrasera pas ainsi les fichiers générés par Maven par leurs originaux.

Ce qui correspond à l'écran d'édition des fichiers à inclure et à exclure :

Configuration des fichiers du répertoire de sources

  • Inclusion patterns: Cette liste de fichiers doit rester vide.
  • Exclusion patterns: Cette liste contient tous les fichiers du répertoire qui seront générés par le plugin resources de Maven et qui ne sont pas gérés par Eclipse.

Dans notre exemple, le fichier log4j.xml est traité par le plugin resources de Maven et se retrouve donc dans la liste des fichiers exclus par Eclipse.

Lancement de la commande Maven depuis Eclipse

Autre astuce, pour faciliter l'actualisation des fichiers dans Eclipse après l'exécution de la commande Maven, nous pouvons ajouter la commande suivante :

Dans Eclipse > External Tools Configurations > Program > New > Ajouter la configuration Maven suivante :
Maven Resources - External Tools Configuration

Puis, dans l'onglet Refresh, activer le rafraîchissement des fichiers dans Eclipse après chaque lancement de cette commande Maven :
Maven Resources - Refresh

Ceci permet à Eclipse de prendre en compte les fichiers générés par Maven.

Comment utiliser cette configuration ?

Une fois le projet configuré correctement dans Eclipse, les conflits entre Eclipse et Maven disparaissent.

Il reste cependant à suivre les règles suivantes selon si le fichier modifié est filtré par Maven ou non :

Le fichier n'est pas filtré par Maven

Dans le cas où nous éditons un fichier non filtré par Maven et qui est géré par Eclipse, sa modification est alors prise en compte automatiquement par Eclipse lors du Build automatique.

Résultat: nous n'avons rien à faire dans ce cas-là 🙂

Le fichier est filtré par Maven

Dans le cas où le fichier modifié est à filtrer par le plugin resources de Maven, nous avons à lancer la commande Maven mvn resources:resources via l'External Tools que nous venons de créer. Eclipse se charge alors lui-même de rafraîchir les fichiers du projet et prend ainsi en compte le fichier filtré par Maven

Bénéfices : dorénavant nous n'avons à lancer la commande Maven qu'une seule fois après la modification du fichier. En effet, le fichier généré ne sera plus écrasé par Eclipse et ne posera plus de problème de rafraîchissement.

Conclusion

La solution présentée ici permet l'utilisation du plugin maven-resources-plugin dans Eclipse en évitant les problèmes de rafraîchissements et de synchronisation dans l'IDE.

Bien sûr ce type de solution ne devrait pas avoir à exister : c'est à l'IDE de se charger de ce genre d'opérations.

Cependant Maven n'est pas supporté nativement par Eclipse ce qui implique l'utilisation de plugins comme m2eclipse pour gérer ce type de problèmes.

Références :

2 commentaires

  1. Je croyais que le plugin m2Eclipse permettait de gérer ce type de conflit. Je me trompe ?

  2. Merci pour ce commentaire.

    Je présenterai effectivement dans un second post comment installer et configurer son projet avec m2eclipse pour justement résoudre ce type de problèmes.

    Je détaillerai aussi les nouvelles fonctionnalités apportées par m2eclipse au niveau de la gestion des POM.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.