Apache Maven 1.x has reached its end of life, and is no longer supported. For more information, see the announcement. Users are encouraged to migrate to the current version of Apache Maven.

Handling Dependencies

One benefit of Maven is that it can make you much more aware of dependencies your project has on other libraries. This outlines some ways to keep track of your dependencies, and to keep them in sync. This is particularly the case in a multiproject scenario.

Overriding Stated Dependencies

You may find it convenient, or necessary, at times to override the dependencies stated in a given POM. You may wish to use JAR artifacts somewhere in the filesystem or you may wish simply to override the stated version of a given JAR artifact. For this Maven provides an easy way for you to select which artifacts you want to use for building.

In order to use the JAR override feature, you must set the maven.jar.override property to on. Once this property is set you can specify JAR override directives in any of the properties files that Maven processes.

There are two type of JAR override directives. The first form allows you to specify a specific JAR artifact path for a given artifactId; the second allows you to specify a specific version of a JAR artifact that exists in your local repository. The two forms are as follows:

maven.jar.artifactId = [path]
maven.jar.artifactId = [version]

Below is an example of what a properties file might look like that contains JAR override directives:

maven.jar.override = on

# Jars set explicity by path.
maven.jar.a = ${basedir}/lib/a.jar
maven.jar.b = ${basedir}/lib/b.jar

# Jars set explicity by version.
maven.jar.classworlds = 1.0-beta-1

Version Consistency

The version override is of particular assistance when you are attempting to maintain a consistent version across different subprojects, and is a much better alternative to using entities or property interpolation.

The situation is that you have a number of subprojects using similar, but not identical dependencies - but that when a particular dependency is used you want to ensure the version is consistent.

You can use inheritence to set up the structure, but can't put the dependency in the parent POM as all subprojects will inherit that particular dependency whether they want it or not.

The best way to implement it is to put the dependency in each subproject as required, but put the version override in the parent POM. Wherever the dependency appears, that version will be used, but the dependency will not be used unless it is actually declared.

Using SNAPSHOT Dependencies

In Maven versions containing the keyword SNAPSHOT are considered special. They approximate the latest development build of a project that has been deployed to the repository. If a project that you depend on is changing frequently you can state in your POM that you wish to try and keep up with that project by declaring it a SNAPSHOT dependency. So, for example, you may be trying to stay abreast of changes in Jelly so you might put the following in your POM:

<dependency>
  <groupId>commons-jelly</groupId>
  <artifactId>commons-jelly</artifactId>
  <version>SNAPSHOT</version>
</dependency>

Assuming that project is publishing a version called SNAPSHOT (which happens when the jar:deploy-snapshot goal is called), then each time you build, Maven will check the remote repository for changes in that JAR and download it again if a newer SNAPSHOT is available.

Note: It seems to be a common misconception that Maven would replace SNAPSHOT by the most current version of a project that is available in the repository. This is not the case: using a SNAPSHOT dependency requires that the project that you depend on has actually published a SNAPSHOT, and only this SNAPSHOT will get updated automatically.

If you are working offline Maven will warn you that your SNAPSHOT dependencies may be out of date. This is just a warning, and as the remote copy often does not change frequently it can be ignored.

Note: the version need only contain the word SNAPSHOT - it does not need to equal it exactly. It is traditional to append it to a version to indicate "development towards version X". For example, 1.2-SNAPSHOT is the development version between 1.1 and 1.2.

Plugin Dependencies

It is a little known feature that you can include a dependency on a specific version of a plugin in your project.xml, for example:

<dependency>
  <groupId>codeczar-tomcat</group>
  <artifactId>maven-tomcat-plugin</artifactId>
  <type>plugin</type>
  <version>1.1</version>
</dependency>

This causes the plugin to be installed into the local repo, and expanded into the cache, but it will not be installed into the maven plugins directory. In other words, your project will use that particular version of the plugin on the fly, without messing up your Maven installation. You may also force other developers to use the same version of the plugin, even if they have a different version of the same plugin installed.

Keeping Track of Dependencies

Maven provides two site reports that can assist in keeping track of dependencies.

The standard dependency report included in the "Project Info" section of every site lists out the information for each dependency in the project, including those inherited. This is mostly useful to new users of your application or library that wish to see what additional dependencies they will require to use it.

The other report is given by the multiproject plugin, and is called the Dependency Convergence Report. This report will look for matching dependencies with different versions in your multiproject set up, so that you can synchronize those using different versions. The section above on Version Consistency can help automate this.