Exemple d’une gestion d’un projet muti-modules avec Gradle

Gradle est un système de build complet offrant une gestion avancé d’un projet multi-modules. Prenons la structure de projet suivante :

 resanet   +-- settings.gradle   +-- build.gradle shared   +-- src/main/java/com/zenika/formation/resanet/Operator.java services   +-- src/main/java/com/zenika/formation/resanet/Authenticate.java

Nous avons un projet nommée “resanet” constitué de deux modules (ou sous-projets) “shared” et “services”. Dans notre example, le module “services” va dépendre du module “shared” à la compilation. La première constatation est qu’il n’est pas obligatoire d’avoir un script de build par module. Dans le cas de projet multi-modules, seul le descripteur Gradle racine (build.gradle) est requis. La philosophie de Gradle est d’avoir un script de build uniquement si cela est nécessaire; un répertoire sous la racine du projet définit un module.

Un build Gradle est constitué de trois phases : une phase d’initialisation, une phase de configuration et une phase d’exécution. C’est la phase d’initialisation de Gradle qui permet de déterminer quels projets vont intervenir durant le build. Pour chaque module ou projet de build, un objet Project sera crée. Cette phase d’initialisation s’appuie sur le fichier “settings.gradle” avec le contenu suivant :

  1. include « shared », « services »

Explorons maintenant la définition du fichier de build « build.gradle » :

  1. project.group = ‘com.zenika.formation’
  2. project.version = ‘1.0’
  3. allprojects {
  4. usePlugin(‘java’)
  5. manifest.mainAttributes(provider: ‘gradle’)
  6. sourceCompatibility = 1.5
  7. targetCompatibility = 1.5
  8. }
  9. project(‘:services’){
  10. dependencies{
  11. compile project(‘:shared’)
  12. }
  13. }

Vous remarquez que Gradle permet depuis un script de build d’accéder à n’importe autre script de build grâce à son mécanique d’injection de configuration. Cette fonctionnalité est très puissante comparé à Maven qui ne supporte que l’héritage.
Si vous invoquez la commande de compilation au niveau du projet racine :

 /usr/local/projects/gradle/resanet> gradle compile

vous constaterez que le sous-projet “shared” puis le sous-projet “services” sont compilés
Mais ce qui est important, c’est que si on se place dans le sous-projet “services”, et on invoque la commande de compilation :

 /usr/local/projects/gradle/resanet/services> gradle compile

vous constaterez que le projet “shared” puis le projet “services” sont compilés. Pour ceux qui viennent du monde Maven, Gradle révolutionne le build d’un projet multi-modules. Avec Maven, vous auriez l’aborescence suivante :

 resanet   +-- pom.xml shared   +-- src/main/java/com/zenika/formation/resanet/Operator.java   +-- pom.xml services   +-- src/main/java/com/zenika/formation/resanet/Authenticate.java   +-- pom.xml

Et si vous placez dans le module « services », seul celui-ci est compilé. La librairie shared aurait du être pré-construire et déployé dans un repository Maven (au moins local). En Maven, la compilation simultané du module « shared » et « services » n’est possible que depuis la racine du projet

 /usr/local/projects/maven/resanet> mvn compile

Néanmoins, Gradle est encore un produit jeune et toutes les fonctionnalités ne sont pas encore présentes. En particularité la fonctionnalité de build incrémental. Par défaut, avec Maven ou avec Gradle, si on modifie le projet “shared” et qu’on invoque de nouveau la commande de compilation au niveau du projet racine, seule le projet “shared” est recompilé.
Le module “services” n’est pas recompilé car son code source n’a pas changé. Vous avez alors un projet potentiellement incohérent car le module “services” (qui dépend de “shared”) peut ne pas recompiler.
En pratique, on force une recompilation complète avec la commande qui consiste a détruitre les précédents résultats de compilation, puis à compiler tout le projet multi-modules.

 /usr/local/projects/maven/resanet> mvn clean compile /usr/local/projects/gradle/resanet> gradle clean compile

Dans le cadre de Maven, l’autre possibilité est d’utiliser le plugin Maven maven-incremental-plugin permettant une suppression du répertoire de compilation pour les modules ayant subit une modication et les sous-projets ayant pour dépendances les modules modifiés. Pour Gradle, cette fonctionnalité sera prise en compte très prochainement.

Laisser un commentaire

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

%d blogueurs aiment cette page :