Maven deploy avec 2 profiles

le 27/04/2009 par Bertrand Paquet
Tags: Software Engineering

On a souvent besoin de plusieurs profils lors du développement d'une application. Prenons par exemple une application web qui a besoin de 2 profils : - un profil auth, où l'authentification est activée. C'est la version de production - un profil noauth, où l'authentification est désactivée. C'est la version par défaut, utile pour les développeurs.

L'objectif de cet article est d'illustrer comment gérer cette situation avec Maven. On souhaite donc utiliser Maven pour réussir à :

  • configurer ces 2 profils
  • déployer dans un repository distant les 2 versions
  • générer ces 2 versions lors de la release
  • récuperer ces 2 versions à l'aide de maven

Cela à l'air simple comme cela, mais dans la réalité, c'est loin d'être facile. Après beaucoup d'effort, voici une solution qui fonctionne.

La solution

Il faut

  • utiliser 2 profils
  • utiliser un classifier pour le profil noauth
  • déployer la version noauth sous un autre artifactId, en utilisant le goal deploy-file du plugin deploy

Voici les 2 bouts de configuration pour faire cela :

<plugin>
 <artifactid>maven-war-plugin</artifactid>
 <configuration>
  <classifier>noauth</classifier>
 </configuration>
</plugin>
<plugin>
 <artifactid>maven-deploy-plugin</artifactid>
 <version>2.4</version>
 <configuration>
  <skip>true</skip>
 </configuration>
 <executions>
  <execution>
   <id>deploy-mock</id>
   <goals>
    <goal>deploy-file</goal>
   </goals>
   <phase>deploy</phase>
   <configuration>
    <repositoryid>${project.distributionManagementArtifactRepository.id}</repositoryid>
    <file>${build.directory}/${build.finalName}-noauth.${packaging}</file>
    <url>${project.distributionManagementArtifactRepository.url}</url>
    <artifactid>${artifactId}-noauth</artifactid>
    <groupid>${groupId}</groupid>
    <version>${version}</version>
    <packaging>${packaging}</packaging>
   </configuration>
  </execution>
 </executions>
</plugin>

Release

Pour déployer les 2 versions lors de la release, le plus simple est d'utiliser les commandes suivantes :

mvn release:prepare -P auth
mvn release:perform -P auth
cd target/checkout
mvn clean deploy

Ainsi, la release est effectuée et les 2 versions seront déployées correctement. Note : comme la version de prod est la vesion auth, la release est faite avec ce profil. Note : on peut utiliser l'option --batch-mode pour éviter la saisie des paramètres lors de la commande mvn release:prepare, et automatiser la release dans le serveur d'intégration continue.

Récupération des deux versions

Pour que les autres équipes (qualification, pre prod, prod) puissent récupérer les versions, on utilise le pom suivant :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelversion>4.0.0</modelversion>
 <groupid>com.octo.tools</groupid>
 <artifactid>maven-artifact-getter</artifactid>
 <packaging>pom</packaging>
 <version>0.0.1-SNAPSHOT</version>
 <build>
  <plugins>
   <plugin>
    <artifactid>maven-dependency-plugin</artifactid>
    <configuration>
     <artifactitems>
      <artifactitem>
       <groupid>${artifact.groupId}</groupid>
       <artifactid>${artifact.artifactId}</artifactid>
       <version>${artifact.version}</version>
       <type>${artifact.packaging}</type>
       <destfilename>${artifact.fileName}</destfilename>
      </artifactitem>
     </artifactitems>
    </configuration>
   </plugin>
  </plugins>
 </build>
</project>

Après l'exécution de cette commande, le war demandé se trouve dans target/dependency/monprojet.war. On peut donc le déployer facilement dans un serveur d'application, soit avec maven, soit avec des commandes shell. Il suffit de changer l'artifactId en monprojet-noauth pour récupérer la version noauth. Cela fonctionne pour une version SNAPSHOT ou une version release (Cela s'adapte donc parfaitement dans un job Hudson paramétré).

Pourquoi cela ne marche pas simplement

En vrac, quelques-uns des problèmes rencontrés

  • La version standard du plugin deploy plante sur des artefact avec classifier
  • Pas de timestamp sur l'upload d'une version SNASPHOT sur un artefact avec classifier le plugin deploy 2.4
  • Les metadata.xml du repository ne contiennent des informations que sur le dernier artefact uploadé, et non une info par classifier. Sur une version SNAPSHOT, on ne peut donc récupérer que le dernier artefact uploadé, quelque soit son classifier.
  • Plusieurs issues ici et ici
  • ...