Une citation extensive de la documentation de Maven décrit cela assez clairement :
Les dépendances optionnelles sont utilisées lorsqu'il n'est pas possible (pour une raison quelconque) de diviser un projet en sous-modules. L'idée est que certaines des dépendances ne sont utilisées que pour certaines fonctionnalités du projet et ne seront pas nécessaires si cette fonctionnalité n'est pas utilisée. Idéalement, une telle fonctionnalité serait divisée en un sous-module qui dépend du projet de fonctionnalité de base. Ce nouveau sous-projet n'aurait que des dépendances non optionnelles, car vous en auriez besoin de toutes si vous décidiez d'utiliser la fonctionnalité du sous-projet.
Cependant, comme le projet ne peut pas être divisé (encore une fois, pour une raison quelconque), ces dépendances sont déclarées optionnelles. Si un utilisateur souhaite utiliser une fonctionnalité liée à une dépendance optionnelle, il doit redéclarer cette dépendance optionnelle dans son propre projet. Ce n'est pas la manière la plus claire de gérer cette situation, mais les dépendances optionnelles et les exclusions de dépendances sont des solutions temporaires.
Pourquoi utiliser des dépendances optionnelles ?
Les dépendances optionnelles permettent d'économiser de l'espace et de la mémoire. Elles empêchent les jar problématiques qui violent un accord de licence ou causent des problèmes de chemin de classe d'être regroupés dans un WAR, EAR, fat jar, ou autre.
Comment fonctionnent les dépendances optionnelles ?
Project-A -> Project-B
Le diagramme ci-dessus indique que Project-A dépend de Project-B. Lorsque A déclare B comme une dépendance optionnelle dans son POM, cette relation reste inchangée. C'est comme une construction normale où Project-B sera ajouté dans le chemin de classe de Project-A.
Project-X -> Project-A
Lorsqu'un autre projet (Project-X) déclare Project-A comme une dépendance dans son POM, la nature optionnelle de la dépendance prend effet. Project-B n'est pas inclus dans le chemin de classe de Project-X. Vous devez le déclarer directement dans le POM de Project X pour que B soit inclus dans le chemin de classe de X.
Un exemple pratique : imaginez que vous êtes un développeur d'une bibliothèque/cadre SuperLib
qui est construit en tant qu'un superlib.jar
. Votre bibliothèque propose plusieurs fonctionnalités. Sa principale fonctionnalité (que la plupart des utilisateurs utilisent) est l'injection de dépendances basée sur une bibliothèque tierce di
. Cependant, l'une de vos classes - EmailApi
- offre des fonctionnalités pour envoyer des e-mails, en utilisant une bibliothèque tierce email
. Comme superlib
est un seul artefact, il a besoin à la fois de di
et de email
pour être compilé.
Maintenant, mettez-vous à la place d'un utilisateur qui utilise superlib
. Ils sont intéressés par les fonctionnalités d'injection de dépendances. C'est le rôle principal de votre bibliothèque, donc la dépendance entre superlib
et di
ne serait pas optionnelle.
Cependant, la plupart des utilisateurs ne sont pas intéressés à envoyer des e-mails et peuvent être gênés par le fait d'avoir une bibliothèque email
inutile et ses dépendances ajoutées à leur application (ce qui augmentera la taille de leur application et pourrait provoquer un conflit de versions de dépendances entre les dépendances de email
et celles de l'application de l'utilisateur). Par conséquent, vous marqueriez la dépendance sur email
comme optionnelle
. Tant que l'utilisateur n'utilise pas votre classe EmailApi
, tout se passera bien. Cependant, s'ils utilisent EmailApi
, ils auront besoin de la dépendance email
, sinon l'application échouera à l'exécution avec une ClassNotFoundException pour la classe de email
qui serait référencée dans EmailApi
. L'utilisateur de votre bibliothèque devra ajouter explicitement la dépendance email
dans leur POM.
Voir aussi Quand utiliser true
et quand utiliser provided
.