[DevoxxFR 2014] Gradle ne fait pas que remplacer Maven

double_xx_texte gradle_logo

Gérer le build d’un projet logiciel a toujours été une tache plus ou moins ingrate dans la vie d’un développeur. Les plus anciens d’entre vous peuvent en témoigner, le chemin a été long depuis l’époque des makefile, des scripts shell et des scripts Ant. Néanmoins l’arrivée de Maven en 2004 a permis une nette amélioration des choses pour les projets Java. Dix ans après son lancement Maven est devenu le standard pour la majorité des développements mais pourtant…

N’avez-vous jamais pesté contre la gestion des exclusions et les obscures dépendances transitives ? N’avez-vous jamais détourné le fonctionnement d’un plugin pour arriver à vos fins ? Ne vous êtes vous jamais sentis frustrés par l’outil ? Si c’est le cas c’est que vous êtes probablement mûrs pour essayer Gradle.

Cet article trouve son origine dans une conférence donnée au Devoxx France 2014. L’orateur du jour, Cédric Champeau (@CedricChampeau), est un fervent partisan de Groovy le langage sur lequel Gradle repose. Pendant une petite heure ce dernier nous a exposé pourquoi il était temps de trouver un successeur à Maven et en quoi Gradle pouvait reprendre le flambeau et aller plus loin.

Structurer le build

Au-delà de la gestion des dépendances pour laquelle il est connu Maven se veut avant tout un structurateur de build grâce au principe du “convention over configuration”.

Ce rôle de structurateur passe aussi par l’idée que le processus de build comporte un ensemble d’étapes récurrentes et prédéfinies afin d’obtenir l’artéfact final.

Ces conventions permettent d’uniformiser la structure d’un projet et sont des hypothèses fortes sur comment vous devriez organiser votre code. Mais justement ces dernières ne seraient-elles pas trop fortes ?

Au secours mon projet sort de l’ordinaire !!

Dans le cadre d’un projet en phase de démarrage il est facile de se conformer à ces conventions. Mais quid de mes projets historiques ? Que faire si la structure de mon projet s’éloigne trop de celle imaginée par les concepteurs de Maven ?

Beaucoup de développeurs se mettront en quête d’un plugin tiers (s’il existe) ou spécifiquement développé pour l’occasion. Or la multitude de plugins créés pour pallier à ces situations est une preuve indirecte du manque de flexibilité de l’outil. Il suffit pour s’en convaincre de parcourir la liste des plugins officiels sur codehaus.org. Chacun a été développé dans le but de pallier à une situation précise qui n’était pas obligatoirement prise en compte dans le cycle de vie habituel de Maven. Et c’est justement là où réside le plus gros problème de Maven actuellement.

Objectivement parlant, adapter le cycle de vie en rajoutant une étape et / ou une tache spécifique n’est pas réalisable de manière simple. La seule alternative reste de se raccrocher à l’étape qui semble la plus proche. Maven se comporte donc ici comme une boîte noire avec en entrée du code et un artéfact en sortie. Entre ces deux étapes le développeur ne garde pas la main sur les opérations réalisées.

Certes Gradle utilise aussi le concept de “convention over configuration” associé à un cycle de vie par défaut mais, contrairement à son prédécesseur, la modification de la mécanique de build reste possible. Voyons comment.

Ouvrir la boîte noire

La base du processus du build est le fichier build.gradle. Ce fichier rédigé en Groovy sert tout d’abord à définir les propriétés de votre build. Commençons par définir nos entrepôts d’artéfacts.

Gestion des entrepôts d’artéfacts

Avec Maven, travailler avec un entrepôt d’artéfacts se limite très rapidement aux entrepôts ne contenant QUE des artéfacts Maven. Gradle, au contraire, supporte plusieurs types d’entrepôts (entrepôts locaux ou distants, artéfacts Maven, Ivy ou simples jar). La déclaration se fait de manière relativement aisée comme nous le montre les exemples suivants.

    repositories {
    mavenCentral()
    }
    
    repositories {
    mavenLocal()
    }
    
    repositories {
    flatDir {
    dirs 'lib', 'myLib'
    }
    }
    

Do you speak Java ? Sprechen Sie Groovy ? ¿Hablas Scala ?

Idéologiquement parlant Maven reste un outil orienté Java. Pour autant est-ce que le processus de build d’un artéfact est fonction du langage dans lequel il est codé ? Évidemment non. C’est donc dans cette optique que Gradle supporte le polyglottisme. Le passage d’un langage à un autre se fait très simplement par le seul changement du plugin appelé.

    apply plugin: 'java'
    
    apply plugin: 'groovy'
    

Prédictibilité du build et de l’artéfact

Vous l’aurez probablement remarqué un descripteur de build Maven ne pose pas de pré-conditions sur l’exécution du build. La seule condition à respecter est que le descripteur soit syntaxiquement correct pour la version de Maven que vous utilisez.

Imaginez à présent qu’un autre développeur récupère votre pom.xml mais l’utilise avec une autre version Maven ? Pire encore et si c’était votre serveur d’intégration continue qui ne disposait pas de la même version ? La compatibilité descendante est certes souvent assurée mais rien n’est moins sûr pour la compatibilité ascendante.

Pour contrer cela Gradle dispose d’un système de wrapper. Grâce au wrapper vous êtes assuré que votre build sera exécuté avec la version spécifiée et ce même si la machine réalisant le build ne dispose pas de cette version.

L’intérêt de ce wrapper est évidente pour les équipes de développement et notamment pour éviter le fameux “je ne comprends pas ça compilait chez moi”.

    task wrapper(type: Wrapper) {
    gradleVersion = '1.4'
    }
    

Groovy à la rescousse

Comme évoqué précédemment, le fichier build.gradle utilise le langage Groovy. Ce choix permet tout d’abord de remplacer une syntaxe XML verbeuse et monolithique nuisant à la lisibilité du descripteur. Mais ce n’est pas tout.

L’utilisation d’un tel langage permet surtout d’enrichir directement le processus de build car le descripteur dispose d’une API donnant accès à la mécanique interne de Gradle. Une analogie simple serait de dire que le descripteur n’est rien d’autre qu’une classe héritant du descripteur par défaut et qu’à ce titre il peut redéfinir, surcharger ou enrichir tout ou partie du comportement de Gradle.

On parle alors de “conventions over configuration” dans le sens que, en plus des conventions par défaut, vous pouvez définir vos propres conventions si un besoin spécifique se faire sentir.

Un très bon exemple d’enrichissement du descripteur de build est disponible au sein du projet Android tools qui a récemment adopté Gradle. En effet, malgré l’arrivée des profils, Maven reste campé sur sa position du “1 pom.xml = 1 artéfact” ce qui rend difficile la customisation du processus de build en fonction de la plateforme ciblée.

Or dans le cas des applications Android il convient de pouvoir gérer simultanément les éléments suivants :

  • La plateforme matérielle (x86, ARM, Mips…)
  • Le format (smartphone, tablette, phablet…)
  • La fragmentation de l’OS (Froyo, JellyBean, KitKat…)
  • Les déclinaisons gratuites ou payantes

Décrire la manière dont cette gestion est réalisée serait fastidieux. Je vous invite donc plutôt à lire directement la documentation du projet ADT ici et .

Néanmoins l’existence de ce projet et sa capacité à produire des artéfacts en fonction de la plateforme ciblée prouve toute la flexibilité du DSL de Gradle. Avec cette syntaxe on accède non seulement à un descripteur de build mais aussi à une API complète de customisation du processus. Et c’est justement cela qu’il faut retenir de Gradle à savoir qu’il va au delà de ce que propose Maven actuellement.

En conclusion

Le but de cet article n’est pas de tirer un boulet rouge sur Maven, loin de là. Il a rendu des services inestimables à un moment où les processus de build durent être rationalisés. Il continuera certainement d’être utilisé dans de nombreux projets grâce à ses nombreux avantages. Néanmoins en sortant de la conférence de Cédric Champeau il faut se demander si le changement ce n’est pas maintenant. Maven a amorcé le mouvement des structurateurs de build mais il est aujourd’hui temps de se projeter un peu plus dans l’avenir et de lui trouver un remplaçant. Et à mon sens Gradle est bien parti pour.

Pour aller plus loin

Nombre de vue : 911

AJOUTER UN COMMENTAIRE