Bonnes pratiques pour gérer les dépendances Java
26 août 2022
0 minutes de lectureCréer des applications Java est passionnant, et les ressources ne manquent pas. Pour accélérer le développement, beaucoup utilisent des frameworks et des bibliothèques qui prennent en charge une partie du travail. Les applications Java modernes contiennent presque toutes des dépendances issues de bibliothèques développées par des tiers.
Les dépendances représentent environ 80 à 90 % du binaire : il est donc essentiel d’en prendre soin lors de la création d’un projet Java. Dans cet article, je vous donne des conseils et des bonnes pratiques pour gérer les dépendances Java de votre projet.
Pourquoi mieux connaître vos dépendances Java
Pour gérer les contributions au code, nous faisons généralement appel à un processus tel que les revues de code afin d’effectuer un premier contrôle qualité avant de fusionner le nouveau code dans notre branche principale. Consultez notre guide des outils de revue de code Java pour en savoir plus. La programmation en binôme est une autre façon d’assurer ce contrôle qualité.
Cependant, nous ne traitons pas les dépendances comme notre propre code. Souvent, elles sont utilisées sans aucune validation. De plus, les dépendances directes entraînent fréquemment des dépendances transitives, parfois imbriquées sur plusieurs niveaux. Par exemple, une application Spring de 200 lignes avec cinq dépendances directes peut finir par en utiliser 60 au total, soit près d’un demi-million de lignes de code déployées en production.
La mise à jour des dépendances Java dans les projets existants peut être difficile. Si elles sont obsolètes, vous risquez un effet domino de problèmes de compatibilité ; mettre à jour une seule bibliothèque peut en nécessiter plusieurs autres à cause d’un bug ou d’un problème de sécurité. Si l’API de ces dépendances Java change, vous devrez peut-être réécrire entièrement votre application.
De plus, dans de nombreuses grandes applications d’entreprise, les dépendances restent dans le fichier manifeste même si elles ne sont plus utilisées dans le code. Ces dépendances inutilisées restent accessibles dans votre programme.
Tout cela peut entraîner :
Des binaires plus volumineux, qui consomment davantage de ressources ou mettent plus de temps à démarrer
Des conflits potentiels entre bibliothèques lors de l’ajout de nouvelles dépendances.
Des bibliothèques obsolètes contenant des bugs ou des problèmes de sécurité
Des problèmes de compatibilité lors de la mise à jour des bibliothèques
Et bien plus encore
Gérer les dépendances Java
L’une des bonnes pratiques pour utiliser efficacement des dépôts tels que Maven Central consiste à mettre en place votre propre gestionnaire de dépôts. Il s’agit d’un serveur proxy dédié, situé entre votre environnement de développement interne et les dépôts publics. Il accélère et fiabilise vos builds, tout en vous permettant de définir des règles pour les packages Java. Vous pouvez, par exemple, bloquer certaines versions afin qu’elles ne puissent pas être téléchargées ni utilisées dans vos applications.
Pour en savoir plus sur les gestionnaires de dépôts et découvrir une liste de produits possibles, consultez la documentation Maven.
Ajouter de nouvelles dépendances à votre projet Java
Lorsque vous devez résoudre un problème et qu’une bibliothèque existe pour cela, vous voudrez probablement l’ajouter aux fichiers manifestes des dépendances Java. Avant de le faire, posez-vous les questions suivantes :
Cette bibliothèque résout-elle le problème ?
La principale raison d’importer un package est de résoudre votre problème. La dépendance choisie peut-elle le faire ? Résout-elle l’ensemble du problème sans en créer de nouveaux ? Si ce n’est pas le cas, il existe peut-être de meilleures solutions.
Ai-je besoin de tout le package ?
Est-il pertinent d’importer une dépendance volumineuse, avec de nombreuses fonctions et types de données, si vous n’avez besoin que d’une seule fonction ? Il peut parfois être plus simple et plus facile à gérer de l’écrire vous-même. Par exemple, est-il judicieux d’inclure toute la bibliothèque Eclipse Collections si vous ne voulez utiliser que le type de données Tuple ? Probablement pas.
Un rapide coup d’œil à mvnrepository.com m’indique que ce package pèse environ 10 Mo

Vérifiez également si les dépendances dont vous disposez déjà peuvent répondre à vos besoins. Certaines fonctions ou certains types de données similaires sont peut-être déjà disponibles. D’un autre côté, l’ajout d’une nouvelle bibliothèque complète peut vous aider à résoudre plusieurs problèmes à la fois : tout dépend de la situation.
Combien de contributeurs y a-t-il ?
Le facteur bus est assez faible si la dépendance Java utilisée ne compte qu’un seul responsable, ou quelques-uns. Que se passera-t-il si la personne qui la maintient décide d’arrêter ou n’a pas le temps de corriger un bug ? Vous pouvez aussi choisir de contribuer vous-même au projet, pour le rendre plus sûr pour toutes les personnes concernées.
Avant d’ajouter une dépendance à votre projet, vérifiez le dépôt principal et le nombre de responsables actifs.

Est-elle toujours maintenue ?
Si un package n’est plus maintenu, mieux vaut ne pas en dépendre. Avant de l’intégrer, vérifiez s’il y a eu de nouveaux commits sur son dépôt GitHub et consultez son cycle de publication. Cela vous donnera une idée de la qualité de sa maintenance.

Quelle est la dernière version du package ?
Les exemples de code peuvent vous donner de précieuses indications sur une dépendance Java. Toutefois, ils sont parfois obsolètes et le package concerné a peut-être déjà été mis à jour. Envisagez d’utiliser la dernière version stable. Pour Eclipse Collections, mvnpackage.com indique que la dernière version stable est la 11.1.0, publiée le 5 juillet 2022. Envisagez d’utiliser cette version.
Notez que la version 11.1.0.M2 figure également dans cette image. Il s’agit clairement d’une préversion. Dans votre application de production, n’incluez que des versions stables, sauf si vous êtes absolument certain de votre choix. En règle générale, évitez les versions comportant un qualificatif tel que :
alpha ou a
beta ou b
milestone ou m
rc ou cr
snapshot
Si une dépendance Java porte le qualificatif GA ou final, vous pouvez généralement la considérer comme une version stable.

Existe-t-il des vulnérabilités de sécurité ?
Avant de vous appuyer activement sur un package Java, veillez à rechercher les vulnérabilités connues. Snyk CLI est un excellent outil pour analyser votre fichier Maven ou Gradle. Si votre bibliothèque présente une vulnérabilité de sécurité, vous pouvez envisager d’utiliser un autre package.
Mettre à jour vos dépendances Java
Existe-t-il des versions plus récentes ?
Vous ne voulez pas vérifier manuellement chacune de vos dépendances Java pour savoir si une version plus récente est disponible. Heureusement, il existe des méthodes plus simples. Les plugins de votre gestionnaire de packages peuvent vérifier automatiquement vos dépendances aussi souvent que vous le souhaitez, par exemple à chaque build.
Attention : vos outils peuvent vous proposer des versions bêta ou des préversions. Il est fortement recommandé d’utiliser uniquement les versions stables d’une bibliothèque.
Exemple avec Maven
Avec Maven, vous pouvez utiliser le plugin versions comme ci-dessous. Il n’est pas nécessaire d’ajouter quoi que ce soit de particulier à votre pom.xml.

Exemple avec Gradle
Avec Gradle, vous devez inclure un plugin, par exemple le plugin versions de ben-manes.
Vous pouvez ensuite exécuter une commande similaire pour afficher les versions plus récentes de vos bibliothèques.

IntelliJ IDEA
Si vous utilisez IntelliJ IDEA, les dépendances pouvant être mises à jour seront soulignées. Cela fonctionne avec les projets Maven et Gradle.

Snyk
En connectant votre dépôt GitHub à votre compte Snyk, nous pouvons vous recommander des correctifs ou des mises à jour à chaque pull request. Ces recommandations, associées à nos conseils de sécurité complets, vous aident à maintenir vos dépendances Java à jour.

Les packages que vous utilisez sont-ils toujours maintenus ?
Il est judicieux de consulter à nouveau le dépôt GitHub ou mvnpackage.com pour rechercher les mises à jour et commits récents. Si un package ne semble plus correctement maintenu, vous pouvez choisir de le maintenir vous-même ou de migrer vers une autre bibliothèque mieux tenue à jour.
Toutefois, si vous rencontrez un problème avec une dépendance essentielle à votre application, envisagez de le résoudre vous-même et de contribuer ce correctif au projet open source. Votre contribution sera très appréciée et permettra souvent d’aller plus vite que le dépôt d’un ticket et l’attente d’un correctif de la part de la personne qui maintient le projet.
Mes dépendances Java présentent-elles des problèmes de sécurité ?
Même si votre application est actuellement exempte de vulnérabilités, rien ne garantit que cela restera le cas. De nouvelles vulnérabilités et de nouveaux exploits sont découverts et divulgués chaque jour. Vous devez donc réanalyser régulièrement vos bibliothèques pour vérifier qu’elles ne présentent toujours aucune vulnérabilité.
Snyk vous propose plusieurs façons d’intégrer l’analyse des dépendances à votre cycle de développement. Sur votre machine, vous pouvez utiliser Snyk CLI ou les intégrations pour IntelliJ, Eclipse et VS Code afin de rechercher des vulnérabilités. Vous pouvez également effectuer des analyses pendant vos builds avec les plugins Maven et Gradle (non officiels), ou choisir l’une des intégrations de pipelines CI. Autre possibilité : ajouter votre dépôt Git à Snyk pour que nous analysions et mettions à jour vos projets quotidiennement.

Supprimer les dépendances Java de votre projet
Le package est-il toujours utilisé ?
Si une dépendance Java n’est plus utilisée, supprimez-la de votre fichier manifeste. Chaque package qui y figure fait partie de votre binaire et est accessible dans le classpath. La suppression des dépendances inutilisées réduit la taille de votre binaire et accélère le démarrage et les téléchargements, tout en renforçant la sécurité. Limiter les dépendances dans votre classpath est essentiel pour vous protéger contre des attaques telles que les chaînes de gadgets de désérialisation.
Il est toujours fortement conseillé de garder son bureau propre — ou, dans ce cas, de garder son application propre. Heureusement, vos gestionnaires de packages peuvent vous aider à repérer les dépendances Java inutilisées.
Exemple avec Maven
Avec Maven, je peux utiliser le plugin dependency pour analyser mes dépendances. Ce plugin vérifie si les dépendances Java déclarées sont également utilisées dans mon code.
Dans ce cas, je ne veux pas être alerté au sujet des dépendances fournies ou de test ; j’utilise donc l’option ignoreNonCompile.

Exemple avec Gradle
Avec Gradle, nous devons ajouter un autre plugin pour analyser les dépendances. Nous allons utiliser ici le plugin nebula.lint. Ce linter Gradle peut analyser les dépendances Java que vous avez incluses et repérer celles qui ne sont pas utilisées.
Je dois configurer le plugin en conséquence pour définir les gradleLint.rules. Vous pouvez le faire dans votre fichier Gradle ou en passant un paramètre de ligne de commande. Dans l’exemple ci-dessous, je choisis cette dernière option. Consultez la documentation du plugin pour savoir comment le configurer pour votre application.

Élaborez une stratégie solide de gestion des dépendances pour vos applications Java
Lors du développement d’applications Java utilisant des dépendances telles que des bibliothèques ou des frameworks, il est judicieux de définir une stratégie de gestion. Savoir sélectionner, mettre à jour et supprimer les dépendances Java de votre application est essentiel pour sa sécurité. Une stratégie claire vous évitera les mauvaises surprises lorsqu’un problème de sécurité prioritaire vous obligera à mettre un package à jour.
Consultez cet article pour en savoir plus sur la gestion des dépendances open source.
Lancez-vous dans les compétitions Capture The Flag
Apprenez à résoudre des défis de capture du drapeau en regardant à la demande notre atelier virtuel d’initiation.



