1

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?

MABC
  • 576
  • 2
  • 11
  • 29
  • There is a lot to unpack in your question. Generally speaking excluding dependencies which you are certain neither you or another dependency is using should not create any issues at runtime or compile time (the libraries were compiled with your exclusion present and you yourself are not using the library, so of course it compiles). If you use parts of library `A` and then exclude it, it won't compile (of course). In regards to Maven downloading the library: if you add a dependency in your pom Maven will include it, because that's what you are specifying :) – roookeee Aug 13 '21 at 10:14
  • If use parts of library-A that in turn use library-B and library-B is excluded in that dependency but library-C uses library-B too, it will compile and library-A will use library-B though it is excluded because it comes from another dependency? – MABC Aug 13 '21 at 10:20
  • 1
    Excluding a dependency will not **not** stop other dependencies from trying to use classes from that dependency unless these libraries are implemented in a way that the dependency you exclude is optional to them (this is possible). If you use library A that internally uses library B and you exclude library B you will get runtime issues. You might get compilation issues if the APIs of library A leak library Bs classes. Maybe it's a good idea to explain what you want to achive instead of talking on this very theoretical level – roookeee Aug 13 '21 at 10:24
  • 2
    I know excluding a dependency will not stop other dependencies from using it. But if library-A is using library-B and excludes it, but I use also library-C that also uses library-B, will the library-A compile and use library-B (cause library-B is available cause library-C dependency)? I am trying to fix dependency issues and need to know when a dependency is really used or not when excluded.. – MABC Aug 13 '21 at 10:33
  • 1
    Exlcuding a transitive dependency from library A will not stop library C from "bringing" the same dependency in your dependency tree. That way library A will work if library C is providing its transitive dependency B - but only if the version match / are compatible. – roookeee Aug 13 '21 at 10:35
  • This kind of exclusions can get cumbersome real fast if your goal is to fixate a transitive dependency as you have to find out which of your dependencies use the library you are trying to fixate. I would propose to use `` for the library in question instead. – roookeee Aug 13 '21 at 10:37
  • So in the dependency tree I wont see library-A is using library-B (cause I excluded it), project will compile and run and library-A will be really using library-B .. – MABC Aug 13 '21 at 10:38
  • The dependency tree is just showing you dependencies and the dependencies they bring into your dependency tree. If you explicitly exclude a transitive dependency you will not see it in the dependency tree. The dependency tree is just that: showing what dependency depends / includes another dependency - if you modify it by `` it will not be representative of what your dependencies actually depend on / use. – roookeee Aug 13 '21 at 10:41
  • Have you read [_Maven, Introduction to the Dependency Mechanism_](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#introduction-to-the-dependency-mechanism) already? – Gerold Broser Aug 13 '21 at 16:06

1 Answers1

2

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.

J Fabian Meier
  • 33,516
  • 10
  • 64
  • 142