Maven Dependency Management

In this Maven tutorial,  learn about Maven dependency management, including external dependency, transitive dependency tree, excluding dependencies and version ranges.

1. What is Maven Dependency?

In Maven, a dependency is just another archive—JAR, ZIP, and so on—which our current project needs in order to compile, build, test, and/or run. These project dependencies are collectively specified in the pom.xml file, inside of a <dependencies> tag.

When we run a maven build or execute a maven goal, these dependencies are resolved and then loaded from the local repository.

If these dependencies are not present in the local repository, then Maven will download them from a remote repository and cache them in the local repository.

We are allowed to manually install the dependencies as well.

2. Maven Dependency Example

Before going further deep inside dependency management, let’s have a quick example of the dependency section in pom.xml.

<dependencies>
 
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
     
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.3.5.RELEASE</version>
    </dependency>
     
</dependencies>

We can use properties section in order to refactorize the code for easy maintenance.

<properties>
  <junit.version>4.12</junit.version>
  <spring.version>4.3.5.RELEASE</spring.version>
</properties>
 
    <dependencies>
     
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
         
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
         
    </dependencies>

3. Configuring External Dependencies

Sometimes, we will have to refer to jar files that are not in the maven repository (neither local, central or remote repository).

We can use these jars by placing them in project’s lib folder and configure the external dependency like this:

<dependency>
  <groupId>extDependency</groupId>
  <artifactId>extDependency</artifactId>
  <scope>system</scope>
  <version>1.0</version>
  <systemPath>${basedir}\war\WEB-INF\lib\extDependency.jar</systemPath>
</dependency>
  • The groupId and artifactId are both set to the name of the dependency.
  • The scope element value is set to system.
  • The systemPath element refer to the location of the JAR file.

4. Maven Dependency Tree

Using maven’s dependency:tree command, we can view the list of all transitive dependencies in our project.

Transitive dependency means that if A depends on B and B depends on C, then A depends on both B and C.

Sometimes, transitivity brings a very serious problem when different versions of the same artifacts are included by different dependencies. It may cause version mismatch issues in runtime.

In this case, dependency:tree command is very useful in dealing with conflicts of JARs.

$ mvn dependency:tree

It outputs the dependency information in the given format:

[INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ MavenExamples ---
[INFO] com.howtodoinjava.demo:MavenExamples:jar:0.0.1-SNAPSHOT
[INFO] +- junit:junit:jar:3.8.1:test
[INFO] \- org.springframework:spring-core:jar:4.3.5.RELEASE:compile
[INFO]    \- commons-logging:commons-logging:jar:1.2:compile

See how it inform about spring having dependency on commons-logging. Similarly, you can get whole transitive dependencies information using this command.

5. Excluding the Dependencies

Apart from the version mismatch issue caused by transitive dependency, there can be version mismatch issues between the project artifacts and artifacts from the platform of deployments, such as Tomcat or another server.

To resolve such version mismatch issues, maven provides <exclusion> tag, in order to break the transitive dependency.

For example, when you have JUnit 4.12 in the classpath and include DBUnit dependency, then we will need to remove JUnit 3.8.2 dependency. It can be done with exclusion tag.

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.dbunit</groupId>
    <artifactId>dbunit</artifactId>
    <version>${dbunit.version}</version>
    <scope>test</scope>
    <exclusions>
        <!--Exclude transitive dependency to JUnit-3.8.2 -->
        <exclusion>
            <artifactId>junit</artifactId>
            <groupId>junit</groupId>
         </exclusion>
    </exclusions>
</dependency>

6. Dependency Version Ranges

While including a dependency, we are free to specify a range of versions for any artifact. To give version range, we can use the below symbols:

  • Parenthesis signs ( and ) hint an excluding range
  • Brackets signs [ and ] hint an including range
  • Commas separate subsets

Let’s few examples to understand better about specifying version range.

Range
Meaning
1.2
Version equals to 1.2 or is starting with 1.2
(,1.2]
Any version less than 1.2. Version 1.2 included. x <= 1.2
(,1.2)
Any version less than 1.2. Version 1.2 excluded. x < 1.2
[1.2]
Only version 1.2. x == 1.2
[1.2,)
Any version greater than 1.2. Version 1.2 included. x >= 1.2
(1.2,)
Any version greater than 1.2. Version 1.2 excluded. x > 1.2
(1.2,2.2)
Version between 1.2 and 2.2. Both excluded. 1.0 < x < 2.2
[1.2,2.2]
Version between 1.2 and 2.2. Both included. 1.2 <= x <= 2.2
(,1.2],[2.2,)
Version either less than 1.2 or greater than 2.2. Both included. x <= 1.2 or x >= 2.2

Happy Learning !!

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

2 thoughts on “Maven Dependency Management”

  1. I tried specifying version range in import packages.
    I am unable to specify [9,) due to the below exception:

    java.lang.IllegalArgumentException: illegal version range syntax too many commas
    at org.apache.felix.utils.version.VersionRange.(VersionRange.java:143)
    at org.apache.felix.utils.version.VersionRange.(VersionRange.java:99)

    POM Changes

    com.google.common.base;version=”\”[16.0,17)\””,
    javax.swing,javax.swing.border,
    javax.swing.text,
    org.lorainelab.igb.menu.api;version=”[8,)”,
    org.lorainelab.igb.menu.api.model;version=”[8,)”,
    org.slf4j;version=”\”[1.7,2)\””

    Kindly suggest.

    Reply
  2. is there a way to provide the version number (for a dependency) after/while creating a project from my custom archetype?

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.