I am having a hard time understanding maven dependency management and how dependency exclusion works. What I know is that when some object of class A send messages (invokes method of) to another object of another class B, then class A is coupled to class B (class A needs class B to exist).
I am using Maven in the project and have this dependency in pom:
<dependencies>
<dependency>
<groupId>org.libraries</groupId>
<artifactId>library-A</artifactId>
</dependency>
</dependencies>
Now assuming class A
is from library-A
, and it depends on class B
in library-B
, but I dont use the class A
in my project (I use another class of library-A
not coupled to any class of library-B
). Maven will download and install in local repository the dependency even if not used in my project?
Now assuming a different scenario I use class A
from library-A
in my project, which depends in class-B
of library B
, but I exclude the dependency of library-B
in the pom:
<dependencies>
<dependency>
<groupId>org.libraries</groupId>
<artifactId>library-A</artifactId>
<exclusions>
<exclusion>
<groupId>org.libraries</groupId>
<artifactId>library-B</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
As I dont have any other dependency in pom that depends on library-B
, would the project compile but the execution of the program fails during class loading because the class is not found?
Now assuming I will use class A
from library-A
in my project, which depends in class-B
of library B
, but I exclude the dependency of library-B
in the pom, though I have a dependency of library-C
that depends (like library-A
) on library-B
:
<dependencies>
<dependency>
<groupId>org.libraries</groupId>
<artifactId>library-A</artifactId>
<exclusions>
<exclusion>
<groupId>org.libraries</groupId>
<artifactId>library-B</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.libraries</groupId>
<artifactId>library-C</artifactId>
</dependency>
</dependencies>
Now though I exclude the transitive dependency library-A
has on library-B
, **will the project compile and execute fine and the class A
in library-A
would use library-B
because the transitive dependency library-C
has on library-B
(assuming this library-B
version is compatible with library-A
)?
Last question is, when I exclude a dependency library-A
has on library-B
and use dependency:tree -Dverbose
to see the dependency graph, it wont show in the graph library-A
has a library-B
dependency, although it could be really using that dependency that comes transitively because another dependency am I wrong? If I am not wrong, how I can know that library-A
is using actually that dependency or no?
Let me try to answer you questions more generally:
Maven will not analyse which classes you use (or don't use). It just determines the tree of transitive dependencies.
In the end, Maven creates a classpath. The classpath is flat and it does not matter from which side a given dependency came.
Missing transitive dependencies can cause problems both during compile time and runtime. The former problems are rare, but if e.g. the transitive dependency is used as a super class or in the interface this may occur.