In Maven, dependency is another archive—JAR, ZIP, and so on—which your current project needs in order to compile, build, test, and/or to run. The dependencies are gathered in the
pom.xml
file, inside of a <dependencies> tag.
When you run a build or execute a maven goal, these dependencies are resolved, and are then loaded from the local repository. If they are not present there, then Maven will download them from a remote repository and store them in the local repository. You are allowed to manually install the dependencies as well.
Read More: Local Repository Path
en Dependency Example
Before going further deep inside dependency management, let’s have a quick example having different elements which we will talk in this post.
< 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 > |
If
pom.xml
points to many artifacts of the same groupId
, you should use properties in order to factorize 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 > |
External Dependency
Some times, you will have to refer jar files which are not in maven repository (neither local, central or remote repository). You 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
andartifactId
are both set to the name of the dependency. - The
scope
element value is set tosystem
. - The
systemPath
element refer to the location of the JAR file.
Maven Dependency Tree
Using maven’s
dependency:tree
command, you can view list of all dependencies into your project – transitively. Transitive dependency means that if A depends on B and B depends on C, then A depends on both B and C.
Transitivity brings a very serious problem when different versions of the same artifacts are included by different dependencies. It may cause version mismatch issue in runtime. In this case,
dependency:tree
command is be very useful in dealing with conflicts of JARs.$ mvn dependency:tree
It outputs the dependency information in 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.Maven Dependency Exclusion
Apart from version mismatch issue caused with transitive dependency, there can be version mismatchbetween project artifacts and artifacts from the platform of deployment, 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 classpath and including DBUnit dependency, then you 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 > |
Artifact Version Ranges
While including a dependency, you are free to specify a range of versions for any artifact. To give version range, you can use below symbols:
- Parenthesis signs ( and ) hint an including range
- Brackets signs [ and ] hint an excluding range
- Commas separate subsets
Version range examples
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 only.x == 1.0 |
[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.0 |
[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 that 1.2 or greater than 2.2. Both included. x <= 1.2 or x >= 2.2 |