How maven dependency exclusion works for this scenarios

1.4k views Asked by At

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?

1

There are 1 answers

0
J Fabian Meier On

Let me try to answer you questions more generally:

  1. Maven will not analyse which classes you use (or don't use). It just determines the tree of transitive dependencies.

  2. In the end, Maven creates a classpath. The classpath is flat and it does not matter from which side a given dependency came.

  3. 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.