|
||||||
![]() Maven's Strengths and Weaknesses as a Dependency Management System
For many Java teams, switching to Maven will introduce them to formal dependency management. Maven actually does a pretty decent job and is a fantastic system out of the box for informal projects. However, for teams looking to implement rigorous component reuse policies, Maven falls short.
Last month, in our article Chaperoning Promiscuous Software Reuse, we reviewed four elements of a successful strategy for managing components. Briefly, these elements are:
Basic MavenBasic Maven points to a common Maven repository hosted centrally. Various open source projects publish their releases to this repository and a developer can configure her build file to depend on these releases. At build time, the artifacts are automatically pulled down into the workspace and the build can produce a report of what was used.This is actually a pretty good start. If the build script depends on exact versions, the team has some traceability. The Maven repository is an official repository of artifacts (a DSL) used by the team although the team does not control it. Unfortunately, there's little protection against a developer using a rogue component, but it's easier to do the right thing than the wrong thing, and that goes a long way. The major failing here is that the team does not control the repository. Rather, it is an arbitrary resource in the cloud. This eliminates the team's ability to test artifacts prior to including them in the DSL, and there's no guarantee that an artifact used by a production release today will still be available from the repository tomorrow unaltered and intact. Bring the Repository in HouseWhat's needed is to bring the repository in house. While this can be done without special tooling, there are a handful of decent Maven repositories that provide the team more control. Nexus and Artifactory are two of the major choices here. They provide security over who can publish artifacts to the repository as well as more sophisticated storage and indexing than a simple file system.With one of these repositories, the team has it's own DSL they control and can ensure that only approved versions of libraries are made available to the team. Again, as long as the team does not use snapshot dependencies a basic audit trail of what is in a build is available. Impact analysis reports indicating which projects have used a given component version are a little more difficult. Protecting the code-base from a developer checking an arbitrary library into source control is still a manual process, but Maven does discourage the practice by making reuse of a library from the repository more straight-forward. Other Concerns with Maven Dependency ManagementNo ability to depend on the newest version with traceabilityMaven draws a strict line between depending on a released version of a component and depending on the latest built version. Depending on the latest build version is a common practice in multi-component continuous integration. Maven's strict line allows for either approach to be used, but only provides traceability when dependencies are based on releases. In multi-component CI, teams often do not want to release particular components for reuse upstream, but rather consider every successful CI build (with passing unit tests) a mini-release.
Functional tests performed at a system level determine the quality of the entire dependency graph (the application). In these cases, it's only after testers validate a system build, that a release will be pushed out (ideally the binary that was tested) and full traceability to every component is valuable. That Maven discourages mutli-component CI through the arbitrary separation of Releases and Snapshots is unfortunate.
Inability to depend based on statusSometimes, teams don't want to depend on either the latest build of a component nor a specific version. Rather, they want to depend on the latest version that has passed some sort of quality gate. Perhaps a validation from a testing team, or approval from a release manager. Maven has no real concept of statuses on components (version numbers and component names are pretty much it) so status based dependencies are out of the question.Re: Maven's Strengths and Weaknesses as a Dependency Management System
There is a way to depend on status. You would tackle this via setting up a Staging repository.
This is fully supported by the maven release plugin and even has a goal:
mvn release:prepare release:stage -DautoVersionSubmodules=true
This publishes the artifact to a 'staging' repository.
You point your build at your release repository, and set the version to RELEASE, or [1.3, , etc.
<dependency>
<artifactId>artifactId</artifactId>
<groupId>groupId</groupId>
<version>RELEASE</version>
</dependency>
In this circumstance you'll always get your release from your release policy which is your safe, test pasted usable release.
For your unsafe / non-qa'd artifact, simply add your staging repository in under a profile activation (in your parent pom, define the repository under a profile):
mvn install -P staging
When you have test passed, simply finish the release:
mvn release:perform
This will make it into your release policy
Re: Maven's Strengths and Weaknesses as a Dependency Management SystemIf you haven't started with Maven yet, read this first: http://kent.spillner.org/blog/work/2009/11/14/java-build-tools.html. If looking for something less opinionated than Maven to manage dependencies...we are developing (and using in-house) a lightweight dependency mgt. tool we've open-sourced that is in the process of becoming cross-platform: http://github.com/mfoemmel/fig. It's a little rough, but very quick and shows great promise. |