130 votes

Comment exclure un module d'une construction Maven reactor ?

Nous avons un projet Maven 2 avec beaucoup de modules. Par exemple :

<modules>
  <module>common</module>
  <module>foo</module>
  <module>data</module>
  <module>bar</module>
  ... more ...
</module>

Disons que le module "data" prend du temps à construire et que nous voulons l'exclure lorsque le projet est construit par un serveur CI. Actuellement, nous utilisons deux fichiers pom.xml pour y parvenir. L'un contient tous les modules et l'autre contient tous les modules sauf ceux qui peuvent être exclus pour le CI. Mais c'est assez ennuyeux car parfois nous oublions de mettre un nouveau module dans le fichier les deux des fichiers.

Existe-t-il une solution qui ne nécessite pas deux listes de modules distinctes ?

215voto

Yogesh_D Points 452

Avec Maven 3.2.1, vous pouvez désormais utiliser -pl !<module_name>,!<module_name> pour exclure certains modules de la construction du réacteur.

Voir cette demande de fonctionnalité : https://issues.apache.org/jira/browse/MNG-5230

0 votes

Peut-on passer en toute sécurité de la version 3.0.4 à la version 3.2.1 ou y a-t-il des changements plus importants ?

0 votes

J'étais passé de la 3.1 à la 3.2.1 sans aucun problème. Mais pour être honnête, il faudrait faire un build pour s'en rendre compte.

45 votes

N'oubliez pas d'échapper le point d'exclamation sur la ligne de commande du shell. Il a une signification très particulière, voir par exemple unix.stackexchange.com/questions/3747/

91voto

SaM Points 1086

Le plus simple est d'utiliser profiles comme ça :

<project>
  ...
  <modules>
    <module>common</module>
    <module>foo</module>
    <module>bar</module>
  <modules>
  ...
  <profiles>
    <profile>
      <id>expensive-modules-to-build</id>
      <modules>
        <module>data</module>
      </modules>
    </profile>
  </profiles>
</project>

Vous devriez alors consulter comment activer les profils

0 votes

Que feriez-vous si vous aviez besoin que les données arrivent avant le commun ? Dans ce cas, les modules de profil seront placés après les modules par défaut dans l'ordre du réacteur. Existe-t-il un modèle pour forcer l'ordre ?

11 votes

L'ordre des modules n'est PAS l'ordre dans lequel ils apparaîtront dans le réacteur. La seule façon d'affecter l'ordre, est de créer des dépendances entre les modules, c'est-à-dire en utilisant la balise <dependency>. Vous ne pouvez pas vous fier à l'ordre de déclaration pour cela.

7 votes

@SaM En fait, à partir de Maven 3.0.5, le Reactor tiendra compte de l'ordre dans les "modules". bien que l'ordre dicté par les dépendances soit plus prioritaire.

53voto

Jörn Horstmann Points 18118

Les projets à construire peuvent également être spécifiés sur la ligne de commande mvn. Cela supprimerait le besoin d'un pom séparé, mais à la place vous devriez changer la configuration du CI à chaque fois qu'il y a un nouveau module.

-pl,--projects <arg>                Comma-delimited list of specified
                                    reactor projects to build instead
                                    of all projects. A project can be
                                    specified by [groupId]:artifactId
                                    or by its relative path.

Peut-être une combinaison de ce drapeau et --also-make-dependents ou --also-make permettrait de réduire à nouveau cette charge de maintenance.

-am,--also-make                     If project list is specified, also
                                    build projects required by the
                                    list
-amd,--also-make-dependents         If project list is specified, also
                                    build projects that depend on
                                    projects on the list

0 votes

Cela présente les mêmes problèmes que l'utilisation de deux poms séparés. Nous devons placer les modules là où nous les définissons. C'est ce que j'essaie d'éviter.

0 votes

C'est une bonne solution. Il n'est pas nécessaire de mettre à jour le pom. mvn clean install -pl mysubproject

24voto

artbristol Points 17755

Je suppose que vous voulez que le build par défaut construise toujours tout, quelle que soit la vitesse, afin que les nouveaux développeurs puissent démarrer rapidement sans avoir à comprendre beaucoup de choses sur le POM. Vous pouvez utiliser des profils comme ceci :

<modules>
    <module>common</module>
    <module>foo</module>
    <module>bar</module>
  </modules>
  ...
  <profiles>
    <profile>
      <id>expensive-modules-to-build</id>
      <activation>
         <activeByDefault>true</activeByDefault>
      </activation>
      <modules>
        <module>data</module>
      </modules>
    </profile>
  </profiles>
</project>

Le problème, c'est que si un développeur spécifie un autre profil sur la ligne de commande, alors l'option expensive-modules-to-build n'est pas inclus (à moins que le développeur ne le spécifie également). Il est donc compliqué de se rappeler quels profils doivent être inclus.

Voici un moyen détourné de le faire. Les deux profils sont toujours inclus, car le fichier pom.xml existe toujours. Donc pour exclure les modules chers, vous pouvez utiliser -P!full-build sur la ligne de commande.

<profiles>
    <profile>
        <id>full-build</id>
        <activation>
            <file>
                <exists>pom.xml</exists>
            </file>
        </activation>
        <modules>
            <module>data</module>
        </modules>
    </profile>
    <profile>
        <id>short-build</id>
        <activation>
            <file>
                <exists>pom.xml</exists>
            </file>
        </activation>
        <modules>
           <module>common</module>
           <module>foo</module>
           <module>bar</module>
        </modules>
    </profile>
</profiles>

0 votes

Belle réponse. Mais avez-vous vraiment besoin de deux profils dans le deuxième exemple de code ? Le profil unique du premier exemple de code avec un élément d'activation modifié ne fonctionnerait-il pas ?

1 votes

@Arendv.Reinersdorff oui, mais cette réponse fonctionne également avec d'autres profils dans la compilation que vous pouvez vouloir inclure par défaut. Dans l'ensemble, cependant, je pense que l'autre réponse avec -pl !<module_name>,!<module_name> est meilleur que cet ancien

1 votes

Bonne astuce d'activation. Cela m'a résolu les problèmes avec <activeByDefault> qui n'est pas toujours actif !

9voto

Jörn Horstmann Points 18118

Une autre idée : Les modules Reactor peuvent être imbriqués, il devrait donc être possible de regrouper vos modules à construction rapide et lente dans des pom séparés, puis d'ajouter un autre pom agrégateur contenant ces deux-là comme modules. Votre serveur CI ne pourrait alors référencer que le pom contenant les modules de construction rapide.

<artifactId>fast</artifactId>
<modules>
    <module>fast-a</module>
    <module>fast-b</module>
    <module>fast-c</module>
</module>

<artifactId>all</artifactId>
<modules>
    <module>fast</module>
    <module>slow</module>
</module>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X