Un vrai build incremental dans Maven

Maven contient une bizarrerie, que certains qualifieront à juste titre de bug. Sans le plugin maven-incremental-plugin, le build dans Maven ne peut pas être executé de manière incrementale car le résultat peut dans certaines situations se reveler incorrect.

Description du problème 

Considerons le projet suivant :

module-parent

   |--- module-api

   |--- module-impl

Le module module-parent contient 2 sous-modules : module-api et module-impl.

Le module module-impl contient une classe ProcessImpl qui implemente l’interface Process définie dans module-api.

Nous lancons la commande "mvn install" sur le projet parent. Tout marche parfaitement. Nous modifions la signature de l’interface Process dans module-api sans répercuter les changements sur ProcessImpl de module-impl.

Nous re-lançons une installation du projet sur module-parent avec la commande "mvn install".

...
[INFO] ------------------------------------------------------------------------
[INFO] Building module-api
[INFO]    task-segment: [install]
[INFO] ------------------------------------------------------------------------
...
[INFO] [compiler:compile]
[INFO] Compiling 1 source file to C:\devs\poc-inc\module-parent\module-api\target\classes
...
[INFO] [jar:jar]
[INFO] Building jar: C:\devs\poc-inc\module-parent\module-api\target\module-api-1.0_SNAPSHOT.jar
[INFO] [install:install]
...
[INFO] ------------------------------------------------------------------------
[INFO] Building module-impl
[INFO]    task-segment: [install]
[INFO] ------------------------------------------------------------------------
...
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date ...
[INFO] [jar:jar]
[INFO] [install:install]
...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] module-parent ......................................... SUCCESS [3.828s]
[INFO] module-api ............................................ SUCCESS [2.875s]
[INFO] module-impl ........................................... SUCCESS [0.047s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------

Le build se déroule correctement et les livrables module-api.jar et module-impl.jar sont installés dans le repository Maven. Comme les sources de module-impl n’ont pas été éditées, Maven ne le recompile pas, bien qu’il dépende d’un module modifié : module-api. L’état du projet est donc invalide dans le repository maven car au runtime, le problème d’implémentation de Process par ProcessImpl lèvera une exception.

Ce problème peut être résolu en forçant le "clean" avant chaque "install". Le build n’est alors plus incremental et pour la modification d’une simple classe, le rebuild est total. Dans de gros projets utilisant l’intégration continue, le coût d’un rebuild total est trop élevé.

Utilisation de maven-incremental-build

Le plugin maven-incremental-build permet d’obtenir un vrai build incremental en ne recompilant que les projets qui doivent l’être.

Il s’exécute automatiquement lors de la toute première phase (validate) du cycle de build Maven et vérifie que ni les sources ni les dépendances n’ont été modifiées depuis le dernier build. Dans le cas contraire, il force la recompilation en effectuant un clean du projet.

Pour l’activer, il suffit d’éditer le pom parent pour ajouter :

     ...
    <pluginRepositories>
        <pluginRepository>
            <id>maven2-repository.dev.java.net</id>
            <name>Java.net Repository for Maven</name>
            <url>http://download.java.net/maven/2/</url>
            <layout>default</layout>
        </pluginRepository>
    </pluginRepositories>

    <build>
        ...
        <plugins>
            ...
            <plugin>
                <groupId>org.jvnet.maven.incrementalbuild</groupId>
                <artifactId>incremental-build-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>incremental-build</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    ... 

Avec le plugin activé, si ProcessImpl n’est pas modifié en accord avec Process, le build sera en échec. 

[INFO] ------------------------------------------------------------------------
[INFO] Building module-api
[INFO]    task-segment: [install]
[INFO] ------------------------------------------------------------------------
[INFO] [incremental-build:incremental-build {execution: default}]
[INFO] Verifying module descriptor ...
[INFO] Pom descriptor modification detected.
[INFO] C:\devs\poc-inc\module-parent\module-api\target deleted
[INFO] [compiler:compile]
[INFO] Compiling 1 source file to C:\devs\poc-inc\module-parent\module-api\target\classes
...
[INFO] [jar:jar]
[INFO] Building jar: C:\devs\poc-inc\module-parent\module-api\target\module-api-1.0_SNAPSHOT.jar
[INFO] [install:install] 
...
[INFO] ------------------------------------------------------------------------
[INFO] Building module-impl
[INFO]    task-segment: [install]
[INFO] ------------------------------------------------------------------------
[INFO] [incremental-build:incremental-build {execution: default}]
[INFO] Verifying module descriptor ...
[INFO] Pom descriptor modification detected.
[INFO] C:\devs\poc-inc\module-parent\module-impl\target deleted
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 1 source file to C:\devs\poc-inc\module-parent\module-impl\target\classes
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure
C:\devs\poc-inc\module-parent\module-impl\src\main\java\fr\ippon\vbe\ProcessImpl.java:[3,7] fr.ippon.vbe.ProcessImpl is not abstract and does not override abstract method method(java.lang.String,int,boolean) in fr.ippon.vbe.Process

Grâce au plugin maven-incremental-build, le projet est forcément dans un état valide en n’effectuant des cleans que lorsque cela s’avère nécessaire.

Liens :

Site du plugin : http://maven-incremental-build.dev.java.net/

Discussion sur le build incremental dans Maven : http://markmail.org/message/kdij7s7jlm2crlip

Tweet about this on TwitterShare on FacebookGoogle+Share on LinkedIn

5 réflexions au sujet de « Un vrai build incremental dans Maven »

  1. Salut,

      On m’a parlé de votre plugin il y a peu. Je ne le connaissais pas et j’avoue que je suis formaté au clean/install quand nécessaire. Le problème est réel et je me demande si Maven 3 ne pourrai pas apporter une réponse plus propre et surtout native. Il serait bon d’en parler sur nos mailing listes pour voir ce qu’en pense la communauté aujourd’hui. Le thread mentionné est de 2007 et tout le monde a déjà du l’oublier (pour peu que quelqu’un l’ai lu car il n’y a pas eu beaucoup de developpeurs qui ont répondu). Un petit mail sur la liste dev ne serait pas mal à mon goût

    A++

    Arnaud

    PS : Non je ne pousserai pas personnellement ce sujet car je n’aurai pas le temps par contre je suis prêt à vous épauler si besoin est 🙂

  2. Commmetn vas tu ?

    Je vois que notre illustre collegue maitient son plugin.

    Remarque depuis 1 an rien n'a changé au niveau de Maven pour régler ce problème.

Laisser un commentaire

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


*