Bonnes pratiques Maven
Jithel
Messages postés
843
Date d'inscription
Statut
Membre
Dernière intervention
-
Jithel Messages postés 843 Date d'inscription Statut Membre Dernière intervention -
Jithel Messages postés 843 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
Une petite réflexion à propos de la gestion des dépendances Maven. Selon ce site : https://books.sonatype.com/mvnex-book/reference/multimodule-sect-simple-parent.html, il est intéressant d'utiliser une architecture Maven en multi-module avec une hiérarchie de module.
Ma réflexion est à propos des dépendances vers des librairies tiers comme par exemple JUnit (ou Log4J). Dans ce site, il est suggéré de mettre les librairies "universelles" au niveau du module parent pour que les modules enfants en héritent. Cependant, je vois un inconvénient plus lourd qu'un avantage
Avantage :
- Tous les projets dépendants de cette librairie n'auront pas besoin de la déclarer dans le POM
Inconvénient :
- Une application web, module enfant de ce parent, va hériter de JUnit alors que c'est une dépendance qui n'a rien à voir avec le web.
Ma suggestion consiste à déclarer deux enfants à ce parent : backend et frontend.
Dans backend, on y mets tous les modules en rapport avec Java et dans son pom.xml JUnit et Log4J.
Dans frontend, on y mets tous les modules en rapport avec le langage web et pas de dépendances a priori dans son pom.xml.
Une autre suggestion est de garder la structure actuelle (un parent et les enfants sont web + Java) mais dans ce cas, ne pas déclarer JUnit au niveau du parent mais unitairement dans chaque projet qui en a besoin spécifiquement. Cependant, Maven ira chercher X fois la même dépendance, ce qui n'est pas pratique.
Un avis ? Des pistes pour ma réflexion ?
Une petite réflexion à propos de la gestion des dépendances Maven. Selon ce site : https://books.sonatype.com/mvnex-book/reference/multimodule-sect-simple-parent.html, il est intéressant d'utiliser une architecture Maven en multi-module avec une hiérarchie de module.
Ma réflexion est à propos des dépendances vers des librairies tiers comme par exemple JUnit (ou Log4J). Dans ce site, il est suggéré de mettre les librairies "universelles" au niveau du module parent pour que les modules enfants en héritent. Cependant, je vois un inconvénient plus lourd qu'un avantage
Avantage :
- Tous les projets dépendants de cette librairie n'auront pas besoin de la déclarer dans le POM
Inconvénient :
- Une application web, module enfant de ce parent, va hériter de JUnit alors que c'est une dépendance qui n'a rien à voir avec le web.
Ma suggestion consiste à déclarer deux enfants à ce parent : backend et frontend.
Dans backend, on y mets tous les modules en rapport avec Java et dans son pom.xml JUnit et Log4J.
Dans frontend, on y mets tous les modules en rapport avec le langage web et pas de dépendances a priori dans son pom.xml.
Une autre suggestion est de garder la structure actuelle (un parent et les enfants sont web + Java) mais dans ce cas, ne pas déclarer JUnit au niveau du parent mais unitairement dans chaque projet qui en a besoin spécifiquement. Cependant, Maven ira chercher X fois la même dépendance, ce qui n'est pas pratique.
Un avis ? Des pistes pour ma réflexion ?
A voir également:
- Bonnes pratiques Maven
- Pratiques commerciales déloyales - Guide
- Arnaque aux impôts 2024 : attention aux faux avis de remboursement - Accueil - Arnaque
- Arnaque de la rentrée : ces sites promettent de donner la composition des classes en avance - Accueil - Arnaque
- Meilleures pratiques pour vpn - Guide
- Quelles sont les meilleures pratiques pour trier des données dans excel - Guide
1 réponse
Bonjour,
Dans le Dependency Mechanism, tu n'envisages que les Transitive Dependencies, mais pour ta réflexion il faudrait considérer le Dependency Management et les Dependency Scopes.
JUnit par exemple devrait être défini avec
Remarque : tu pourrais aller plus loin dans la modularisation de ton projet, le back ne doit pas dépendre du front et le front ne devrait pas dépendre du back, cependant ils peuvent manipuler des objets communs, en particulier les interfaces des web services et leurs DTO, qui seraient à mettre dans un module à part.
Tu pourrais également isoler les accès aux base de données, pour faire une ségrégation forte des dépendances et avoir une architecture multi-tiers propre.
Dans le Dependency Mechanism, tu n'envisages que les Transitive Dependencies, mais pour ta réflexion il faudrait considérer le Dependency Management et les Dependency Scopes.
JUnit par exemple devrait être défini avec
<scope>test</scope>afin de n'être utilisé que dans les phases de tests, mais sans être ajouté au livrable de runtime.
Remarque : tu pourrais aller plus loin dans la modularisation de ton projet, le back ne doit pas dépendre du front et le front ne devrait pas dépendre du back, cependant ils peuvent manipuler des objets communs, en particulier les interfaces des web services et leurs DTO, qui seraient à mettre dans un module à part.
Tu pourrais également isoler les accès aux base de données, pour faire une ségrégation forte des dépendances et avoir une architecture multi-tiers propre.
Par exemple, je suis sur un projet côté service. Mon code fait appel à aspectj. Cependant, j'ai déjà importé spring-core qui lui-même rapatrie aspectj. Dois-je déclarer aspectj dans mon pom ou dois-je faire confiance à la transitivité ? Le problème se pose le jour où spring-core pour une raison quelconque décide de ne plus fournir par transitivité aspectj. On se retrouve à devoir faire une mise à jour pour ajouter aspectj dans le pom (qui ne serait pas arrivé si on l'avait fait avant).
Ce problème n'arriverait que si tu décides de mettre à jour spring-core dans une version qui n'utilises plus aspectj, mais l'opération de mise à jour qui t'obligerait à ajouter aspectj est celle qui consiste à modifier spring-core, en aucun cas aspectj ne disparaîtra tout seul si tu ne changes rien à spring-core.
"doit-on faire confiance à un parent pour nous fournir une librairie dont on a besoin ou doit-on déclarer soit même dans notre pom les dépendances dont nous avons besoin"
Je dirai qu'il vaut mieux les déclarer toi même et éviter d'utiliser des bibliothèques qui sont obtenus par transitivité uniquement pour faire fonctionner le code de la dépendance ajoutée, pas celui de ton code.
Attention aux versions ! Exemple (un grand classique avec Spring) :
Tu ajoutes une dépendance A qui ramène transitivement X, puis une dépendance B qui ramène transitivement Y, il peut arriver que X et Y comportent les mêmes classes mais dans des versions différentes et que "aléatoirement" ton programme utilisera tantôt X pour faire fonctionner A et B, tantôt Y pour faire fonctionner A et B, mais tu n'auras pas X qui fait fonctionner A et en même temps Y qui fait fonctionner B.
Remarque : C'est tout l'intérêt des modules introduit par Java 9 qui règlent une partie du problème.
Plusieurs manières d'éviter ce genre de problèmes :
1. Ne pas compter sur une dépendance transitive pour faire fonctionner le code qui en a besoin mais l'importer
2. Importer une bibliothèque transitive peut simplement vouloir dire que j'utilise mal les fonctionnalités de la dépendance directe
Avant de passer le sujet en résolu, tu aurais des bonnes sources externes sur lesquelles je peux m'appuyer ? Livre ? Site ? Vidéo ? Conférence ?