Maven

How to use Maven for Dependency Management

In this example we are going to see how you can use maven in order to manage your project dependencies.

Maven is a build automation tool used mainly for java projects from apache.

We are going to see some maven capabilities for managing dependencies in our projects.

For this example we use the following technologies:

  • MAC OSX
  • Eclipse Mars.1
  • Maven3
  • JDK 1.8.0_65 64bits

1. Introduction

The maven dependency management mechanism is one of the best features that maven have. You can easily manage all the project dependencies with maven in a easy way, even when you are in a multi-module project with several dependencies, maven can do the task of managing dependencies in a easy way for you.

You can inherit dependencies from a parent project, you can define you own dependencies in a project. You can define dependencies scopes. You can import dependencies, this is specially usefull in large projects once you can only inherit from one pom at most.

Let´s see in details some of the maven capabilities in order to manage dependencies.

2. Transitive dependencies

When you define a dependency in your project, in most cases, that dependency needs its own dependencies too. Since Maven 2 this is made automatically by maven and is know as Transitive dependencies. There is no limit to the number of levels that dependencies can be gathered from.

This only can be a problem if a cyclic dependency is found, that is, a dependency A depends on an artifact B that depends on an artifact C which depends on artifact A.

This mechanism faces some problems, or potential problems, and you can see how it solve them below

  • Multiple version of the same artifact: This capacity is know as dependency meditation. Since maven 2 the dependency meditation is resolved using the nearest definition. Maven will use the closest version that is defined in your dependency tree, until maven 2.0.9 if two versions of the same artifact were in the same depth of dependency tree level, maven will no ensure wich one will choose, after maven 2.0.9, the first one (in dependency declaration order) will be choosen.
  • Dependency management: This allow you to define artifacts version in order to resolve transitive dependencies when no version is defined. You can see more details in the following bullets.
  • Dependency scope: Allow you to specify the way maven have to manage the dependency, or when that dependency has to be used. You can see more details in the following bullets.
  • Excluded dependencies: You can exclude an artifact that is added by the transitive dependencies mechanism if you do not need it, or you are using a different version.
  • Optional dependencies: You can mark a dependency as an optional one, you can see it as a ‘excluded by default’ dependency and only will be added if you add it explicitely

3. Dependency management

If you are 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. In this way you can have all the version in a centralized point, which make easier to mantain the dependencies in your entire project.

If two projects (poms) use the same dependency, you can easily put it in a dependencyManagement tag inside a parent project, extend the two poms with the parent pom and make the two child poms easier.

Let´s see an example

parent_pom:

<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>log4j</groupId>
				<artifactId>log4j</artifactId>
				<version>1.2.17</version>
			</dependency>
		</dependencies>
	</dependencyManagement>
</project>

pom_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>
	<artifactId>java-code-geeks-a</artifactId>
	<version>1.0.1</version>
	<packaging>pom</packaging>
	<parent>
		<groupId>com.java.code.geeks</groupId>
		<version>1.0.1</version>
		<artifactId>aca-parent</artifactId>
	</parent>

	<dependencies>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
		</dependency>
	</dependencies>
	
</project>

pom_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-b</artifactId>
	<version>1.0.1</version>
	<packaging>pom</packaging>
	<parent>
		<groupId>com.java.code.geeks</groupId>
		<version>1.0.1</version>
		<artifactId>aca-parent</artifactId>
	</parent>

	<dependencies>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
		</dependency>
	</dependencies>
	
</project>

As you can see, the parent pom defines some artifacts in a dependencyManagement tag, the pom 1 and 2 inherit from the parent pom and only have to reference the dependency, the version to use will be determined by the transitive dependencies mechanism.

4. Dependency scope

The dependency scope is useful when you want to define in which environment or build phase you want to use an artifact. 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. All of those dependencies are propagated to the dependent projects.
  • provided: Use this when you expect that the JDK or the application server carries with him the dependency. Is only avaiable on compile and test classpath and is not transitive.
  • runtime: Use this scope in order to indicate that the dependency is not required for compile time, but is neccesary for execution. Will be available in test and runtime classpath but not on compile classpath.
  • test: Use this scope to indicate that a dependency is needed in test phase, it will be available on test compilation and execution classpaths only.
  • system: Use this to use a local jar on your filesystem. This will no be searched into any repository.
  • import: Use this inside a dependencyManagement tag. Indicates that the pom have to be replaced with the dependencies that are defined inside that pom.

5. Excluded dependency

Sometime you will have a dependency that depends on another dependencies. Is quite normal that those dependant dependencies get in conflict with another declared or inherited dependency. You can easily exclude a dependency in order to avoid those conficts.

Let´s see an example

exclude_pom:

<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-b</artifactId>
	<version>1.0.1</version>
	<packaging>pom</packaging>
	<parent>
		<groupId>com.java.code.geeks</groupId>
		<version>1.0.1</version>
		<artifactId>aca-parent</artifactId>
	</parent>

	<dependencies>
		<dependency>
			<groupId>com.atomikos</groupId>
			<artifactId>transactions-hibernate3</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<artifactId>hibernate</artifactId>
					<groupId>org.hibernate</groupId>
				</exclusion>
			</exclusions>
		</dependency>
		
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
		</dependency>
	</dependencies>
	
</project>

6. Conclusions

Maven has a very high capacity managing dependencies inside projects as you have seen in this example. All those mechanisms will bring you some powerfull ways in order to manage your projects and its dependencies.

Francisco Hernandez

JEE technologies geek and development engineer. I have over 13 years of experience as software engineer in JEE architectures: Design, development, improvement etc. Currently I work as software architect and consultant. I am mainly involved in projects related to the bank and energy sectors based on Java technologies and Oracle products. I am also very interested in open-source projects
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button