The Maven 2 POM demystified

The evolution of a project model

1 2 3 Page 3
Page 3 of 3
 <project>
  ...
  <reporting>
    <plugins>
      <plugin>
        <artifactId>maven-project-info-reports-plugin</artifactId>
        <reportSets>
          <reportSet></reportSet>
        </reportSets>
      </plugin>
    </plugins>
  </reporting>
  ...
</project>

The reporting element is similar to build. So similar, in fact, that plug-in configuration can be conceptualized as effectively as a subset of build, focused entirely on the site phase. Although I find its existence increases the POM, and hence generates more work to learn for little gain, the Maven 2 team obviously disagreed. It is too early to set up camp on either side. For the time being, however, we must learn and understand both.

Build environment

We now examine how the POM defines and interacts with its environment to finally encompass most aspects of a standard build system. We finish with the lower right block of our POM chart introduced in Figure 1.

Figure 10. Project environment settings

Environment information

Most of the elements here are descriptive of the type of lifestyle in which the project makes itself comfortable. Elements by such names as ciManagement (Continuum, CruiseControl, etc.), issueManagement (Bugzilla, etc.), scm (CVS, Subversion, etc.), and mailingLists (emails and archives) all outline the programs and the settings that this build system has. As great as Maven 2 may be, it does not do everything needed in a project's lifecycle. These elements are concerned with the programs that live in conjunction with Maven to create a healthy environment where our fat little project can grow up big and strong. Think of these programs as Maven's family.

Among these elements, scm is one that deserves a second look. The scm element is connected to a separate subproject named (surprise!) SCM, which seeks to make a common Java interface through which all software configuration management tools may communicate. The SCM project is of particular interest to the scm element because of its use of the SCM URL format. When an scm element is defined in Maven 2, it uses the URL to decode implementation, location, connection, and other information (much like a Java Database Connectivity URL). Its format is: scm:[provider]:[provider_specific], where provider is the type of SCM system. For example, connecting to a CVS repository may look like: scm:cvs:pserver:127.0.0.1:/cvs/root:a. More detailed information on the SCM project may be found from the Maven SCM page.

Maven environment

The remainder of the environment elements are Maven-focused, such as prerequisites for building the POM or the repository elements: repositories and pluginRepositories. These elements define from where a project may download dependency projects, how often it should try, what types of projects it wants (releases or snapshots), as well as all of the same information for downloading plug-ins. On the flip side of the repository is distributionManagement, which specifies how a project may join the ranks of a remote repository. The distribution may define a release and snapshot repository, as well as a location for deploying this project's generated site and, finally, a good place for a deployed project status.

All of the build environment elements we have glanced at are straightforward and simple. In comparison, the profile element has a powerful yet potentially dangerous role to play within the POM. profiles are unique in that they do not define the setup of a project's build environment, but instead tell Maven how to react under different environments. A profile element does this by allowing certain POM elements to be overwritten according to environmental factors. Those profiles may be explicitly activated via the command line, or a settings.xml file, or even activated automatically, such as by the (non)existence of a file or the value of a given property. For example, if we know that our test environments always contain a file called test1.properties under the Java installation directory, then we can activate a test profile as follows:

 

<project>

... <profiles> <profile> <id>

test

</id> <activation> <file> <exists>

${java.home}/test1.properties

</exists> </file> </activation> ... </profile> </profiles> ... </project>

All of the elements that may be set under profiles will now override their POM counterparts whenever this project is built under a test environment. The elements that may be overridden by an active profile are a subset of the build and reporting elements, relationship elements (dependencies, dependencyManagement, and modules), and certain build-and-deployment-related environment elements (repositories, pluginRepositories, and distributionManagement). You can find the exhaustive list on the Maven Model page. Note in particular the missing *Directory elements under build.

Sometimes you may want a POM to flex, but do not want to define profiles within the POM. These situations call for the settings.xml and profiles.xml files. Although beyond the scope of this article, settings.xml is useful for defining properties that should encompass a build system as a whole (or at least an individual user's requirements). The profiles.xml file, on the other hand, proves useful when you wish to add profiles to an individual build, but do not wish to/cannot make modifications to the pom.xml, or where such changes may not be appropriate.

An astute reader may notice that profiles may introduce a point of failure for a build. This is entirely possible. For example, if one of our test servers did not contain the test1.properties file, then the profile would never activate, possibly causing undefined builds. If you begin to notice erratic behaviors in builds involving profiles, you can easily find out which profiles are active by executing the help:active-profiles goal, which will list the active profiles by ID. Believe me, this can save you hours of headaches and spare your walls from head-shaped dents.

Conclusion

As you can see, the Maven 2 POM is big. That is of no doubt. However, its size is also a testament to its versatility. The ability to abstract all aspects of a project into a single artifact is powerful, to say the least. Gone are the days of dozens of disparate build scripts and scattered documentation concerning each individual project. Along with the other stars that make up the Maven 2 galaxy—a well-defined build lifecycle, easy-to-write-and-maintain plug-ins, centralized repositories, system-wide and user-based configurations, and the increasing number of tools to make developers' jobs easier to maintain complex projects—the POM is the large, but bright, center.

Eric Redmond has been an active enthusiast of Maven 2 since its beta—and of Maven 1 before that. Currently, in his position as a senior engineer of a five-man IT department, he is using Maven 2 to coordinate new development with a loosely coupled team of consultants. Redmond holds a bachelor's of science in computer science from Purdue University and is the author of Maven 2 Ruby support.

Learn more about this topic

1 2 3 Page 3
Page 3 of 3