Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven: How do you deal with dependencies that are both direct and transitive?

Tags:

java

maven-2

I'm trying to determine an approach to the following situation:

There are 3 Maven artifacts: A, B, and C.

B depends on A. (i.e. it uses some of A's code)

C depends on both A and B (i.e. it uses some of A's code and B's code).

Assume I want to use the same version of A for both B and C.

What approach should be used?

1) Declare A as a dependency in C's pom.xml.

Pro: It's clear to the developer that C depends on A. Con: If A's version changes, it needs to be updated in multiple places. (both B and C)

2) Don't declare A as a dependency in C's pom.xml.

Pro/Con: Opposite of option 1.

like image 348
Jin Kim Avatar asked Jan 11 '11 20:01

Jin Kim


People also ask

How does Maven resolve transitive dependencies?

Transitive Dependencies. Maven avoids the need to discover and specify the libraries that your own dependencies require by including transitive dependencies automatically. This feature is facilitated by reading the project files of your dependencies from the remote repositories specified.

What is direct dependency and transitive dependency in Maven?

There are two types of Maven dependencies: Direct: These are dependencies defined in your pom. xml file under the <dependencies/> section. Transitive: These are dependencies that are dependencies of your direct dependencies.

How do you resolve transitive dependencies?

Once you identify your package to be fixed using any of the above methods, to fix the transitive dependency, you must add a dependency to the updated version of the vulnerable package by adding it to the . csproj file. i.e such a vulnerable package needs to be made a direct dependency of your main project.


2 Answers

I think you should have all direct dependencies declared in your pom. Transitive dependencies are just a convenience for automagically resolving your dependencies dependencies.

If you change a version of a direct dependency, the transitive dependencies will likely change along with it, and thus potentially breaking the module. The module should build as an independent unit and thus should have well defined dependencies that will not break due to external changes.

I disagree that this violates the DRY principal, as maven defines things within the confines of a single project and its pom. And within this scope there is no repetition.

Update: The reliance on transitive dependencies existing makes the project frail on it's own, and may also lead to more complex issues like when to include it.

For example, if C has a compile dependency on A, but a runtime dependency on B, then you now have to either add the dependency (since it is no longer in your build path) or declare B as compile even though it isn't. There is a lot to be said for clarity. Explicitly define what your dependencies are and what their scope is, and expect your dependencies to do the same. For the most part, your dependency is a black box, until it causes problems and you have to open it.

like image 100
Robin Avatar answered Sep 28 '22 05:09

Robin


1) Declare A as a dependency in C's pom.xml.

The dependency is readable

Dependency is flexible. If you want to remove A's dependency from B, you do not need to think of the projects that dependend on B.

As suggested in other answer, that it is a good practice to write down direct dependencies in pom.xml and let maven handle it.

2) Don't declare A as a dependency in C's pom.xml.

Mostly, no developer going to see pom.xml. And if they want they can see it by using mvn dependency:tree and it will show transitive dependency.

There will be single point of change when a new version of A is released. If you define dependency at more than one place, you may forget to update all the places. In that case, Maven automatically uses the latest one. But, it does sting sometimes.

Some people prefer this because, mostly, this type of dependency is common knowledge (e.g. MyWebApp -> MyWebAppLib -> MySharedLib and MyWebApp -> MySharedLib) and they want to avoid added step of updating versions at multiple places on each release.

I have written down pros-and-cons, you should evaluate what suits you the best yourself.


Edit#1: tsk! I have switched my comments.
Edit#2: updated the answer after a discussion done on this answer.

like image 34
Nishant Avatar answered Sep 28 '22 05:09

Nishant