Présentation Gradle par Hans Dockter chez Zenika, 25 Juin 2009

Par Grégory Levilain • 29 juin, 2009 • Catégorie: Build, Java, news

J’ai eu l’occasion jeudi dernier d’assister à une présentation de l’outil de build Gradle par Hans Dockter, son fondateur. Cet événement était organisé par la société Zenika.

Dans son discours, Hans explique clairement avoir créé Gradle pour pallier au manque de flexibilité de Maven. Il souligne qu’avec Maven, on ne peut pas interagir avec les plugins, mais seulement les configurer de la façon spécifée. Ainsi, Gradle est un langage de build (et non un framework !) basé sur le principe qu’il est difficile de prévoir tous les scénarios auxquels nous pourrions être confrontés. Indéniablement, la présentation de Hans se déroule comme une partie de bras de fer avec Maven. Il anticipe immédiatement la question que tout le monde se pose : n’est-il pas risqué de s’affranchir des limites posées par Maven, sachant que c’est justement son caractère déclaratif et ses conventions qui en ont fait le succés, comparativement à ANT notamment ? A cette question Hans répond que nous sommes des informaticiens et que nous avons besoin d’outils pointus. “We need sharp tools”, dit-il.

Avec Gradle, les fichiers XML de ANT ou de Maven sont remplacés par des scripts Groovy. Ces scripts sont composés de “tasks” dépendant les unes des autres, comme avec ANT. On retrouve également de nombreuses notions inspirées de Maven, à commencer par la gestion des dépendances. Sur ce point, Gradle s’appuie sur Ivy qui lui confère un fonctionnement analogue à celui de Maven : compatibilité avec les dépôts Maven (repositories), transitivité, etc. La notion de “cycle de vie” de Maven est également présente. L’utilisation du plugin “Java”, par exemple, permet de bénéficier d’un cycle de vie proche de celui de Maven. On pourra ainsi lancer un “gradle clean package”.

Par contre, contrairement à Maven, les plugins fournis nativement font partie intégrante de la distribution Gradle, et évoluent donc au rythme de ses versions. Avantage : inutile de spécifier les versions des plugins pour obtenir un build reproductible. Inconvénients : en cas de bug sur un plugin, il faut attendre la version suivante de Gradle, et en cas de changement de version, les évolutions sur tous les plugins sont imposées. Notez à ce propos que depuis sa version 2.09, Maven fixe une version par défaut pour ses principaux plugins afin d’éviter toute contrainte. Le build n’est plus alourdi inutilement par des déclarations de versions mais il reste possible de surcharger les choix par défaut.

En ce qui concerne l’aspect dynamique du langage, Hans démontre effectivement que Gradle ne manque pas de souplesse. Le descripteur du build étant codé en Groovy, toute l’API Gradle est directement accessible : manipulation des dépendances, modification du comportement des tâches existantes. Il semble que tout soit possible. Les builds multi-projets sont supportés, et Gradle n’impose aucune contrainte quant à la structure des projets.

A l’exécution, Gradle propose un processus ingénieux, en deux phases. Avant l’exécution proprement dite, une phase de configuration est réalisée, sorte de “compilation” destinée à optimiser le déroulement du build. Cela offre également un autre intérêt : procurer aux tâches la capacité de connaître l’avenir, c’est-à-dire d’adapter leur comportement en fonction des tâches ultérieures.

ANT est intégré de façon bidirectionnelle : il est non seulement possible d’invoquer des tâches ANT depuis le script, mais aussi de compléter ou de modifier leur comportement, tout comme pour les tâches Gradle elles-mêmes. C’est Groovy qui rend cela possible en fournissant nativement un accès à son AntBuilder (voir à ce sujet l’article “Practically Groovy: Ant scripting with Groovy“).

Hans souligne qu’il prévoit également une forte intégration avec Maven.

Lors de la séance de questions, l’aspect “debugging” est évoqué. Hans indique qu’un debugger est disponible pour IntelliJ IDEA, l’IDE choisi pour développer Gradle, du fait de son support de Groovy. Le debugger n’est malheureusement pas disponible pour d’autres IDE. La nécessité d’avoir recours à un debugger est significative. Nous sommes bel et bien en présence d’un langage à part entière, et le build lui-même peut être considéré comme “un projet dans le projet”. C’est un inconvénient de ANT souvent cité, qui engendre des builds complexes, hétéroclites, peu maintenables.

La question de la compatibilité ascendante est également soulevée. Gradle étant actuellement en version 0.6.1, qu’adviendra-t-il lors du passage en 1.0 ? Hans répond qu’il y aura forcément des changements mais qu’il ne faut pas s’en inquiéter outre mesure. Avec un nom comme le sien, j’aurais pourtant juré qu’il n’était pas Normand ;)

Vient enfin la question de l’intégration avec Eclipse, et la problématique épineuse de la synchronisation des classpaths. Tout comme Maven, Gradle possède un plugin permettant de générer les fichiers .classpath et .project d’Eclipse. Malheureusement, cette méthode est loin de me convaincre car le véritable besoin dans ce domaine est d’avoir un plugin qui prenne la main sur le système de build natif d’Eclipse au moment de la compilation. L’intégration avec les IDE constitue, à mon sens, l’un des plus gros challenges pour un système de build. Pour l’avoir vécu avec Maven, je suis convaincu que c’est la condition sine qua non pour être en mesure d’utiliser efficacement les mécanismes de déploiement et de test d’Eclipse. En effet, avant l’apparition de plugins Eclipse pour Maven tels que M2Eclipse ou Q4E, il était difficilement envisageable de faire du “hot code replace”, c’est-à-dire de modifier du code à chaud, en phase de debug.
Ces plugins sont également à l’origine d’une réelle intégration de Maven dans Eclipse, autorisant l’usage, de façon transparente, de fonctionnalités telles que le filtrage des ressources. Enfin ils ont apporté un confort considérable en exécutant automatiquement certaines phases du build lors de la modification du POM Maven, et en mettant à jour, par la même occasion, le classpath d’Eclipse.

Quoi qu’il en soit, Gradle apporte sa pierre à l’édifice des problématiques d’assemblage, alors que la communauté Maven est en pleine préparation de sa version 3.0. L’effet ne peut être que positif.

Marqué comme: , , , , ,

3 Réponses »

  1. Merci pour ce compte rendu.

    Juste un détail, dans le cas de l’utilisation du plugin java, la commande Gradle de packaging est “gradle clean libs” et non “gradle clean package”.

    Concernant le mode de packaging des plugins, il est effectivement exact que les plugins sont empaquetés dans le livrable Gradle. Mais au-delà du non-besoin de spécifier les versions des plugins, son avantage est surtout d’avoir un outil tout en un, sans aucune dépendance vers un référentiel extérieur.
    Concernant Maven, c’est exact que depuis la version 2.0.9, il est inutile de spécifier les versions des plugins, mais c’est uniquement pour les plugins core. Pour tous les autres plugins, il est indispensable de spécifier une version fixe afin d’assurer la reproduction de la chaîne de build dans le temps. Mais pour revenir à Gradle sur ce point, le système de plugins actuel risque sûrement d’évoluer car Hans réfléchit à un système basé sur OSGI.

    Concernant l’incorporation de Gradle dans les IDE, je ne suis pas complètement d’accord avec vous mais c’est un débat intéressant. Selon moi, dans le cadre des projets Java/JEE, un système de build ne doit être utilisé que dans un cadre d’intégration (manuel ou continue). Utiliser Gradle pour générer la configuration de son IDE préféré est suffisante. C’est ensuite uniquement les fonctionnalités de son IDE qui doivent permettre de gérer son projet en développement avec des services comme le Hot Code remplacement. Le principe est le même concernant le changement des dépendances dans le descripteur pom.xml pour Maven ou dans le fichier build.gradle pour Gradle. Une personne avec une casquette d’intégrateur change les dépendances, met à disposition le descripteur pour toute son équipe (mise sous SCM), puis chaque développeur relance la commande mvn eclipse:eclipse pour Maven ou la commande gradle eclipse pour Gradle, et c’est OK (si l’équipe utilise IDEA, le descripteur Maven est directement interprété). Une fois cette étape réalisée, il est très rare d’avoir besoin de l’utilisation de son système de build en développement. Pouvez-vous me donner des exemples?
    Les plugins d’incorporation des builders comme Q4e ou m2eclipse pour le support de Maven dans Eclipse, rajoutent une couche supplémentaire, générant souvent des problèmes de performances, et fournissent un support trop spécifique par rapport au contenu de son descripteur de build. Cela entraîne une dépendance complète avec son IDE et ses plugins. Cela va à l’encontre d’un principe de l’intégration continue consistant à avoir une chaîne de build indépendante de son IDE. C’est pourquoi, je pense qu’au contraire, qu’il n’est pas souhaitable que son système de build prenne la main sur le système de build natif de son IDE. A mon avis, le support des builder dans les IDE ne doit permettre que d’avoir une assistance sur l’écriture du script de build avec en particulier la complétion pour les informations de dépendances comme l’entité organisationnelle (groupId), son nom (artifactId) ou sa version.

  2. Gregory, merci pour cette rectification et pour l’information au sujet des perspectives d’évolution de Gradle.
    Concernant l’intégration outils de build / IDE, il s’agit en effet d’un débat intéressant. Voici mon point de vue.

    L’une de mes préoccupations est d’offrir à des équipes de développement des outils qui leur fournissent :
    - une vision continue de l’évolution de leur projet ;
    - le moyen d’atteindre leurs objectifs qualité ;
    - des conditions optimales de confort et de productivité ;
    - un maximum d’autonomie.

    Dans ce contexte, l’équation est relativement simple :

    - l’outil de build assure la qualité : intégration continue, métriques, gestion efficace des dépendances, des releases et des livrables, etc.
    - l’IDE assure le confort et la productivité : compilation automatique, debug et hot code replace, exécution manuelle des tests unitaires, etc.

    La difficulté c’est que les deux outils ont des fonctions antagonistes.

    Par exemple, ils ont des façons différentes de gérer les dépendances. Si je choisis d’utiliser la méthode de mon outil de build, j’estime dommageable d’avoir à gérer en parallèle la méthode de gestion du classpath de mon IDE, que je souhaite au contraire proscrire. Cette double gestion représente un risque d’erreur, de confusion, une perte de temps et de confort.

    J’ai parlé plus haut de compilation automatique, mais on peut également prendre le cas de la gestion des ressources. Mon outil de build me permet de gérer les différences entre mes environnements de production, de recette, de développement et d’intégration continue. Par exemple, les paramètres d’accès à la base de donnée sont généralement différents pour tous ces environnements, et même pour chaque développeur, afin d’exécuter des tests de façon isolée. Mon outil de build peut gérer ce cas de deux façons. Soit en utilisant des fichiers différents en fonction de l’environnement spécifié. Soit en utilisant les mêmes fichiers dans lesquelles certaines informations sont variabilisées (”filtrage des ressources” en terminologie Maven).
    Dans les deux cas, un build est nécessaire pour obtenir la configuration adaptée à l’environnement choisi. Si je souhaite bénéficier de ces fonctionnalités, il me faut :
    - un moyen d’invoquer mon outil de build depuis mon IDE. Ici aussi, une invocation “manuelle” représente une perte de temps et de confort.
    - un moyen d’indiquer à mon IDE qu’il doit utiliser les fichiers résultants du build, et non les fichiers sources, lorsque je déploie mon application pour la tester en debug par exemple.

    “Les plugins d’incorporation des builders comme Q4e ou m2eclipse pour le support de Maven dans Eclipse, rajoutent une couche supplémentaire, générant souvent des problèmes de performances, et fournissent un support trop spécifique par rapport au contenu de son descripteur de build. Cela entraîne une dépendance complète avec son IDE et ses plugins. Cela va à l’encontre d’un principe de l’intégration continue consistant à avoir une chaîne de build indépendante de son IDE.”

    Je ne comprends pas bien cette remarque. Dans la configuration que j’évoque, c’est bien l’IDE qui est configuré pour s’adapter au système de build, et non l’inverse. La chaîne d’assemblage reste totalement indépendante. L’un des principaux intérêts d’un système de build est précisément de faire de l’intégration continue. Vient ensuite la question de l’intégration avec l’IDE.
    Sur ce point, le challenge d’un outil de build est le suivant : autoriser l’utilisation de ses fonctionnalités dans l’IDE, de façon transparente et performante.

  3. Je suis d’accord sur vos préoccupations concernant vos équipes de développement en terme de visibilité du projet, de productivité et d’autonomie.

    Concernant la gestion des ressources, est-ce si important que cela ?
    L’objectif n’est-il pas de produire un livrable indépendant de tout environnement.
    La standardisation des applications Java/JEE avec les mécanismes de JNDI, propriétés systèmes (-Dkey=value), … ne permettent-il pas d’avoir un seul livrable ? Ainsi avec ces techniques, la variabilité n’est pas fournit par le jar, le war ou l’ear mais fournit par l’environnement d’exécution comme un container Web. Ainsi dans ce cas, il n’y a pas le besoin d’un build par environnement car la variabilité est fournit uniquement à l‘exécution. Ainsi, il devient inutile d’invoquer son outil de build depuis son IDE pour ce besoin.

    Concernant la gestion des classpath, j’estime que c’est beaucoup une question de rôle d’un utilisateur.
    Dans une équipe de taille importante, est-il souhaitable qu’un développeur puisse manipuler facilement le classpath des ces projets. Je ne pense que non. Ce travail doit être réservé à l’intégrateur. Un utilisateur ne doit pas gérer manuellement le classpath de son IDE mais s’appuyer sur un outil de build. Pour Eclipse un simple mvn eclipse :eclipse dans le cas de Maven est généralement suffisant sans avoir besoin d’un plugin Eclipse.
    Mais effectivement, dans la situation précédente, c’est le builder qui s’adapte à l ‘IDE alors qu’effectivement, cela devrait être à Eclipse de s’adapter au builder. Dans ce cas, un plugin Eclipse pour Maven est utile.

    Néanmoins, j’estime que ces plugins du support de Maven dans les IDE ne devraient se limiter uniquement à la gestion des classpath. Pour tous le reste, les fonctionnalités natives des IDE doivent suffire.

Laisser un Commentaire