paint-brush
Gradle est-il vraiment meilleur que Maven ? - Mon verdict finalpar@nfrankel
5,793 lectures
5,793 lectures

Gradle est-il vraiment meilleur que Maven ? - Mon verdict final

par Nicolas Fränkel8m2023/08/09
Read on Terminal Reader

Trop long; Pour lire

Dans cet article, j'aimerais faire la lumière sur Gradle, afin que je puisse y diriger les gens au lieu de démystifier le même "raisonnement" à plusieurs reprises.
featured image - Gradle est-il vraiment meilleur que Maven ? - Mon verdict final
Nicolas Fränkel HackerNoon profile picture
0-item

Je tweete du contenu technique que je considère intéressant, mais les tweets amusants sont ceux qui obtiennent le plus d'engagement. J'ai assisté à la conférence JavaLand en mars, je suis tombé sur le stand Gradle et j'ai trouvé ce joyau :

https://twitter.com/nicolas_frankel/status/1638549568957861889


Bien sûr, à un moment donné, un fanboy a détourné le fil et revendiqué la soi-disant supériorité de Gradle. Dans cet article, j'aimerais faire la lumière sur ma position, afin que je puisse y diriger les gens au lieu de démystifier le même "raisonnement" à plusieurs reprises.


Pour gérer ça, j'ai besoin de remonter dans le temps. Le développement de logiciels est un domaine en évolution rapide, et une grande partie de notre compréhension est basée sur l'expérience personnelle. Alors voici le mien.

Mon premier outil de construction : Fourmi


J'ai commencé à développer en Java en 2002. A l'époque, il n'y avait pas d'outils de build : nous compilions et construisions via l'IDE. Pour mémoire, j'ai d'abord utilisé Visual Age pour Java ; puis, je suis passé à Borland JBuilder.


Construire avec un IDE pose un énorme problème : chaque développeur a des paramètres dédiés, de sorte que la génération d'artefacts dépend de la combinaison développeur-machine.


Les builds non répétables sont un problème séculaire. Ma première expérience avec des builds reproductibles est Apache Ant :


Apache Ant est une bibliothèque Java et un outil de ligne de commande dont la mission est de piloter les processus décrits dans les fichiers de construction en tant que cibles et points d'extension dépendant les uns des autres. La principale utilisation connue d'Ant est la construction d'applications Java. Ant fournit un certain nombre de tâches intégrées permettant de compiler, assembler, tester et exécuter des applications Java. Ant peut également être utilisé efficacement pour créer des applications non Java, par exemple des applications C ou C++. Plus généralement, Ant permet de piloter tout type de processus pouvant être décrit en termes de cibles et de tâches.


-- https://ant.apache.org/


Ant est basé sur trois abstractions principales :


  • Une tâche est une unité de travail atomique, par exemple javac pour compiler des fichiers Java, war pour assembler une archive Web, etc. Ant fournit de nombreuses tâches prêtes à l'emploi mais permet d'en ajouter des personnalisées.
  • Une cible est une liste de tâches.
  • Vous pouvez définir des dépendances entre les tâches, telles que package en fonction de compile . À cet égard, vous pouvez voir Ant comme un moteur d'exécution de flux de travail.


Je suis rapidement devenu « maîtrisant » Ant. En tant que consultant, j'allais d'entreprise en entreprise, de projet en projet. Au départ, j'ai principalement configuré Ant, mais Ant s'est répandu au fil du temps et j'ai rencontré des configurations Ant existantes. J'étais cohérent dans mes projets, mais les autres projets étaient très différents les uns des autres.


Chaque fois, en arrivant sur un nouveau projet, vous deviez lire attentivement la configuration Ant pour comprendre la construction personnalisée. De plus, la structure de chaque projet était différente. Certains placent leurs sources dans src , d'autres dans sources , d'autres dans une structure imbriquée, etc.


Je me souviens d'un fichier de construction générique qui tentait de répondre à l'ensemble des besoins du projet d'une organisation. Il a défini plus de 80 cibles dans plus de 2 000 lignes de XML. Il m'a fallu un temps non négligeable pour comprendre comment l'utiliser avec de l'aide et encore plus de temps pour pouvoir le peaufiner sans casser les projets.

Mon deuxième outil de build : Maven

Le projet ci-dessus m'a beaucoup fait réfléchir. Je voulais améliorer la situation car les mainteneurs avaient déjà repoussé les limites d'Ant. A l'époque, je travaillais avec mon ami Freddy Mallet (du célèbre Sonar). Nous avons parlé, et il m'a indiqué Maven. J'avais déjà construit un projet avec Maven mais je n'avais aucune autre expérience préalable. J'ai étudié la documentation pendant des heures et, à travers des tentatives d'essais et d'erreurs, sous la tutelle de Freddy, j'ai migré l'intégralité du fichier de construction Ant vers un simple POM parent.


Dans Ant, vous devez tout définir dans chaque projet. Par exemple, Ant nécessite la configuration de l'emplacement des fichiers Java pour la compilation ; Maven suppose qu'ils sont sous src/main/java , bien qu'il soit possible de le remplacer. Maven a révolutionné le domaine de la construction Java avec son approche Convention over Configuration . De nos jours, de nombreux logiciels proposent une configuration sensée par défaut.


Pour les développeurs qui vont de projet en projet, comme je l'ai fait, cela signifie qu'il y a beaucoup moins de charge cognitive lorsqu'ils rejoignent un nouveau projet. Je m'attends à ce que les sources Java soient situées sous src/main/java . Les conventions Maven continuent au-delà de la structure du projet. Ils définissent également le cycle de vie du projet, de la compilation au téléchargement de l'artefact dans un registre distant, en passant par les tests unitaires et d'intégration.


Enfin, les développeurs juniors ont tendance à l'ignorer, mais Maven a défini le terme gestion des dépendances . Il a introduit l'idée de registres d'artefacts, où l'on peut télécharger des dépendances immuables et pousser des artefacts vers. Avant cela, chaque projet devait stocker les dépendances dans son référentiel dédié.


Pour mémoire, il y avait quelques dépendances stockées sur le projet mentionné ci-dessus. Lorsque j'ai migré d'Ant vers Maven, j'ai dû trouver la version exacte de la dépendance. Pour la plupart, c'était simple, comme c'était dans le nom du fichier ou le manifeste du JAR. Un, cependant, avait été mis à jour avec des classes supplémentaires.


Voilà pour l'immuabilité.


Maven a eu une profonde influence sur tous les outils de construction ultérieurs : ils se sont définis en référence à Maven.

Aucun outil de construction à moi: Gradle


La principale revendication de Gradle était de corriger les lacunes de Maven, ou du moins ce qu'il percevait comme tel. Bien que Maven ne soit pas exempt de reproches, Gradle a supposé que le problème le plus important était son manque de flexibilité. C'est une hypothèse surprenante car c'est précisément ce que Maven a amélioré par rapport à Ant. Les projets Maven ont des structures similaires et utilisent le même cycle de vie : le principe de moindre surprise en vigueur. Inversement, Gradle permet de personnaliser presque tous les aspects de la construction, y compris le cycle de vie.


Avant d'aborder l'argument de la flexibilité, permettez-moi de reconnaître deux grandes fonctionnalités originales de Gradle que Maven a implémentées par la suite : le démon Gradle et le wrapper Gradle.


Maven et Gradle sont deux applications Java qui s'exécutent sur la JVM. Démarrer une JVM coûte cher en temps et en ressources. L'avantage est que la JVM de longue durée optimisera le code JIT-ed au fil du temps. Pour les tâches de courte durée, le bénéfice est nul voire néfaste si l'on tient compte du temps de démarrage de la JVM. Gradle a créé le démon Gradle. Lorsque vous exécutez Gradle, il recherche un démon en cours d'exécution. Sinon, il en démarrera un nouveau. L'application de ligne de commande déléguera tout au démon. Comme son nom l'indique, le démon ne s'arrête pas lorsque la ligne de commande est terminée. Le démon exploite les avantages de la JVM.


Il y a de fortes chances que votre application survive à vos outils de construction actuels. Que se passe-t-il lorsque vous devez corriger un bogue dans cinq ans, pour constater que l'outil de construction du projet n'est pas disponible en ligne ? L'idée derrière le wrapper de Gradle est de conserver la version exacte de Gradle avec le projet et juste assez de code pour télécharger la version complète sur Internet. Comme effet secondaire, les développeurs n'ont pas besoin d'installer Gradle localement ; utilisent tous la même version, évitant toute divergence.

Démystifier la flexibilité de Gradle

Gradle a apporté les deux fonctionnalités ci-dessus que Maven a intégrées, prouvant que la concurrence est bonne. Malgré cela, je ne trouve toujours aucun avantage à Gradle.


Je vais essayer de repousser le côté émotionnel. À ses débuts, Gradle marketing a essayé de rabaisser Maven à chaque occasion possible, a publié des tableaux de comparaison fous et a généralement été très agressif dans sa communication. Disons que cette phase a duré bien plus qu'il ne serait acceptable pour une jeune entreprise essayant de trouver sa place sur le marché. On pourrait dire que Gradle était très œdipien dans son approche : essayer de tuer son "père" Maven. Enfin, après toutes ces années, il semble qu'il ait compris et maintenant "aime Maven".


N'oubliez pas qu'avant que Maven ne prenne le relais, chaque projet Ant était ad hoc. Maven a mis un terme à cela. Il a apporté la loi au Far West mondial des projets personnalisés. Vous pouvez être en désaccord avec la loi, mais c'est la loi de toute façon, et tout le monde doit s'y tenir. Les normes Maven sont tellement ancrées que même s'il est possible de remplacer certains paramètres, par exemple , l'emplacement de la source, personne ne le fait jamais.


J'ai ressenti deux symptômes de la flexibilité de Gradle. Je soupçonne qu'il en existe beaucoup plus.

Phases de cycle de vie personnalisées

Maven gère les tests d'intégration en quatre phases, exécutées dans l'ordre :


  1. pre-integration-test : configurez tout ce dont les tests ont besoin
  2. integration-test : exécute les tests
  3. post-integration-test : nettoyer les ressources, le cas échéant
  4. verify : agir sur les résultats des tests


Je n'ai jamais utilisé les phases pré et post, car chaque test avait une logique de configuration et de démontage dédiée.


De l'autre côté, Gradle n'a aucune notion de tests d'intégration . Pourtant, les fanboys de Gradle se feront un plaisir de vous expliquer que vous pouvez ajouter les phases que vous souhaitez. En effet, Gradle permet la "personnalisation" du cycle de vie : vous pouvez ajouter autant de phases supplémentaires dans le cycle de vie normal que vous le souhaitez.


C'est la pagaille, car chaque projet devra trouver à la fois le nombre de phases requises et leur nom : integration-test , integration-tests , integration-testing , it (pour les paresseux), etc. Les options sont infinies.

Le syndrome du flocon de neige

Maven traite chaque projet comme un projet standard régulier. Et si vous avez des besoins spécifiques, il est possible d'écrire un plugin pour cela. Écrire un plugin Maven n'est certainement pas amusant ; par conséquent, vous n'en écrivez un que lorsque c'est nécessaire, pas seulement parce que vous avez décidé que la loi ne s'applique pas à vous.


Gradle affirme que le manque de flexibilité est un problème ; par conséquent, il veut le réparer. Je maintiens le contraire : le manque de flexibilité de mon outil de build est une fonctionnalité, pas un bug. Gradle facilite le piratage de la construction. Par conséquent, quiconque pense que son projet est un flocon de neige spécial et mérite une personnalisation le fera avec plaisir. Confrontation à la réalité : c'est rarement le cas ; quand c'est le cas, c'est pour les frameworks, pas pour les projets réguliers. Les partisans de Gradle disent qu'il offre toujours des normes tout en permettant une configuration facile. Le cœur du problème est qu'il ne s'agit pas d'une norme si elle peut être modifiée au gré de quiconque.


Gradle est l'outil de construction de facto pour les projets Android . Dans l'une des entreprises pour lesquelles j'ai travaillé, quelqu'un a écrit du code Groovy personnalisé dans la version Gradle pour exécuter Sonar et envoyer les métriques à l'instance interne de Sonar. Il n'y avait pas de plugin Sonar prêt à l'emploi à l'époque, ou je suppose qu'il ne l'a pas coupé. Jusqu'ici, tout va bien.


Lorsqu'une autre équipe a créé le deuxième projet Android de l'entreprise, elle a copié-collé la structure du premier projet et le fichier de construction. La chose intelligente à faire aurait été, à ce moment-là, de créer un plugin Gradle interne à partir du code spécifique à Sonar. Mais ils ne l'ont pas fait parce que Gradle a facilité le piratage de la construction. Et moi, le Gradle-hater, j'ai pris sur moi de créer le plugin. Cela aurait pu être une meilleure expérience de développeur, c'est le moins qu'on puisse dire. Faute de documentation de qualité et utilisant un langage non typé (Groovy), j'ai utilisé la console pour imprimer la structure des objets pour progresser.

Conclusion

La concurrence est bonne, et Gradle a apporté de nouvelles idées que Maven a intégrées, le wrapper et le démon. Cependant, Gradle est construit sur le principe que la flexibilité est bonne, alors que mon expérience m'a montré le contraire. Ant était très flexible et la charge cognitive pour passer d'un projet à l'autre était élevée.


Nous, développeurs, sommes des êtres humains : nous aimons penser que nos projets sont différents des autres. La plupart du temps, ils ne le sont pas. La personnalisation n'est qu'un moyen de satisfaire notre ego. Des outils de construction flexibles nous permettent de mettre en œuvre une telle personnalisation, qu'elle soit justifiée ou non.


Les personnalisations non pertinentes n'apportent aucun avantage et sont faciles à développer mais coûteuses à entretenir. Si la gestion des actifs logiciels fait partie de mes responsabilités, je choisirai toujours la stabilité plutôt que la flexibilité pour mon outil de construction.


Publié à l'origine sur A Java Geek le 6 août 2023