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.
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
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.
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.
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.
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.