How to Use Maven For Dependency Management
In this example, we will see how to use Maven for dependency management. Maven is a build manager tool and mostly used in java projects. Maven was built on a central concept of project object model (POM). Maven addresses two steps for any project – first how a project is built and second how the dependencies are described.
1. Environment
- Windows 7 SP 1
- Eclipse Kepler 4.3
- Maven 3.0.4
- Java version 7
2. Maven for Dependency Management
Maven is used in large projects for one of its major feature and that is dependency management. Maven just not supports dependencies for a single project, but it easily manages multi-module projects. In such projects, maven helps in maintaining a high degree of control and stability.
3. Transitive Dependency
This feature of Transitive Dependency allows to avoid needing to discover and specify libraries that your own dependencies require, and what that means is that if your project is dependent on some libraries and those libraries are dependent on other libraries, you only specify your project’s dependencies and this feature takes care of other dependencies. There is no limit to levels that dependencies can be gathered from, and will only cause a problem if cyclic dependency is discovered. If your project depends on A
and A
depends on C
and C
depends on B
and B
depends on A
.
Following features help to limit the graph of included libraries using transitive dependencies’ feature:
- Dependency Mediation – This feature determines what version of a dependency will be used when multiple versions of an artifact are encountered. You can always guarantee a version by declaring it explicitly in project’s POM. If two dependency versions are at the same depth in the dependency tree, the order in the declaration that counts, the first declaration wins.
- Dependency Management – With this feature, you can specify versions of artifacts to be used when they are encountered in transitive dependencies.
- Dependency Score – This allows you to only include dependencies appropriate for the current stage of the build.
- Excluded Dependencies – If project X depends on project Y, and project Y depends on project Z, the project X can explicitly exclude project Z as a dependency using the
exclusion
element. - Optional Dependencies – If project Y depends on project Z, and the owner of Project Y can mark project Z as optional dependency, using the
optional
element. When project X depends on project Y, X will depend only on Y and not on Y’s optional dependency Z.
4. Dependency Scope
Dependency scope is used to restrict the transitivity of a dependency, and also to affect the classpath
used for various build. There are 6 scopes available:
- Compile – This is the default scope if any is indicated. The dependencies are available in all classpaths of a project.
- provided – This is used when JDK or a web container is going to provide a dependency at runtime.
- runtime – This scope indicates that the dependency is not required for compilation, but for runtime.
- test – This scope indicates the dependency is required during test compilation and execution phases.
- system – This scope is similar to
provided
except that you have to provide JAR which contains in explicitly. - import – This is used inside a
dependencymanagement
tag. It indicates that the specified POM should be replaced with the dependencies in that POM’sdependencymanagement
section.
5. Dependency Management
Dependency management is a mechanism to centralize the dependency information. In a multi-module project, you can specify in a parent project all the artifact version and it will be inherited by the child projects.
Below we will see an example where there are two POMs which extend the same parent.
project A
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javacodegeeks.example</groupId> <artifactId>java-code-geeks-parent-A</artifactId> <version>1.0.1</version> <packaging>pom</packaging> <dependencies> <dependency> <groupId>group-a</groupId> <artifactId>artifact-a</artifactId> <version>1.0</version> <exclusions> <exclusion> <groupId> group-c </groupId> <artifactId>excluded-artifact</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>group-a</groupId> <artifactId>artifact-b</artifactId> <version>1.0</version> <type>bar</type> <scope>runtime</scope> </dependency> </dependencies> </project>
project B
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>java-code-geeks-parent-B</artifactId> <version>1.0.1</version> <packaging>pom</packaging> <dependencies> <dependency> <groupId>group-c</groupId> <artifactId>artifact-b</artifactId> <version>1.0</version> <type>war</type> <scope>runtime</scope> </dependency> <dependency> <groupId>group-a</groupId> <artifactId>artifact-b</artifactId> <version>1.0</version> <type>bar</type> <scope>runtime</scope> </dependency> </dependencies> </project>
These two POMs share a common dependency and each has one non-trivial dependency. Now parent POM will look like below
Parent Project
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.java.code.geeks</groupId> <artifactId>java-code-geeks-parent</artifactId> <version>1.0.1</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>group-a</groupId> <artifactId>artifact-a</artifactId> <version>1.0</version> <exclusions> <exclusion> <groupId>group-c</groupId> <artifactId>excluded-artifact</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>group-c</groupId> <artifactId>artifact-b</artifactId> <version>1.0</version> <type>war</type> <scope>runtime</scope> </dependency> <dependency> <groupId>group-a</groupId> <artifactId>artifact-b</artifactId> <version>1.0</version> <type>bar</type> <scope>runtime</scope> </dependency> </dependencies> </dependencyManagement> </project>
And two child POMs will be like below
Child A
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javacodegeeks.example</groupId> <artifactId>java-code-geeks-child-A</artifactId> <version>1.0.1</version> <packaging>pom</packaging> <dependencies> <dependency> <groupId>group-a</groupId> <artifactId>artifact-a</artifactId> </dependency> <dependency> <groupId>group-a</groupId> <artifactId>artifact-b</artifactId> <type>bar</type> </dependency> </dependencies> </project>
Child B
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.java.code.geeks</groupId> <artifactId>java-code-geeks-child-B</artifactId> <version>1.0.1</version> <packaging>pom</packaging> <dependencies> <dependency> <groupId>group-c</groupId> <artifactId>artifact-b</artifactId> <type>war</type> </dependency> <dependency> <groupId>group-a</groupId> <artifactId>artifact-b</artifactId> <type>bar</type> </dependency> </dependencies> </project>
6. System Dependencies
System
dependencies are specified with systemPath
under system scope and they are always available and are not looked up in repository. They tell Maven about dependencies which are provided by JDK or VM. A simple example as below shows that of JDBC extension:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javacodegeeks.example</groupId> <artifactId>java-code-geeks-jdbcexample</artifactId> <version>1.0.1</version> <packaging>pom</packaging> <dependencies> <dependency> <groupId>javax.sql</groupId> <artifactId>jdbc-stdext</artifactId> <version>2.0</version> <scope>system</scope> <systemPath>${java.home}/lib/rt.jar</systemPath> </dependency> </dependencies> </project>
7. Conclusion
Maven has provided a powerful capabilities to developer to manage their multi-projects under one roof. In this example, we saw how to use Maven for dependency management.