Tallan's Technology Blog

Tallan's Top Technologists Share Their Thoughts on Today's Technology Challenges

Maven Best Practices

Eric Fitchett

Introduction

Maven is a great build tool that is especially easy to set up and use in simple, standard projects.  When you have very specific needs, it is easy to add a lot of configuration and end up with a confusing POM (Project Object Model) that is hard to maintain.  How can we keep our POM easy to understand, flexible, and maintainable?  These tips may help you do just that.

Use Properties Liberally

User defined properties are a simple way to reduce duplication and make your build more flexible.

One of the more overlooked benefits of properties is that they can easily be overridden at the command line or in profiles.  Think of the values saved in the POM as defaults.  Developers can override properties on a per-build basis.  Property overrides can be specified in scripts for more frequent alterations, or for less command line savvy users.  Additionally, your continuous integration server can be set up to override any properties needed for the environment it builds to.

Using properties for dependency versions may be a good idea – particularly for logical “suites” of dependencies.  For example, when using the Spring Framework, you may find yourself listing dependencies such as spring-webmvc, spring-jdbc, spring-tx, and spring-test.  If you use a single spring.version property as the version of these dependencies, then upgrading your version of Spring is as simple as changing the value of that property.  This can even be done temporarily by overriding the version property, as in the following example:

pom.xml (excerpts):

<properties>
    <spring.version>3.0.0.RELEASE</spring.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
</dependencies>

Command line:

$ mvn install -Dspring.version=3.0.4.RELEASE

If you’re already using the Versions Maven Plugin to keep your dependencies up-to-date, you’ll be glad to know that it works well with version properties.

Consider Using Profiles

A profile is a set of changes to be applied to the POM under certain circumstances.  These “changes” can be property value overrides, additional plugins tied to lifecycle stages, plugin configuration overrides, even additional dependencies.

You can create a profile for running a quick build, which skips anything lengthy and unnecessary; or perhaps a debug build, which might include debug symbols in the compilation step and skip JavaScript and CSS minification.

Profiles can be activated directly on the command line or in the settings.xml file.  Alternatively, they can be active by default, or activated (or deactivated) by a property.  Multiple profiles can be active at the same time, so you can run a quick debug build by activating both profiles as follows:

pom.xml (excerpts):

<profiles>
    <profile>
        <id>quick</id>
        <properties>
            <maven.test.skip>true</maven.test.skip>
        </properties>
    </profile>
    <profile>
        <id>debug</id>
        <!-- TODO: Include debug symbols in compilation -->
        <!-- TODO: Skip JavaScript and CSS minification -->
    </profile>
</profiles>

Command line:

$ mvn install -Pquick -Pdebug

Comment Regularly

We all comment our code to enhance readability, right?  Why not do the same with the Maven POM?

The POM should be simple to understand – one should be able to discern the purpose of every section with a quick glance.  Unfortunately, many things in Maven may require large configuration blocks, making it harder to skim the POM and get the general idea.

It’s easy to fill the POM with obscure sections of plugin configurations, poorly documented properties and dependencies, and profiles whose purpose is not obvious.  All of these can be helped by a little organization and some comments.

As the POM is XML, a comment can be created in the following manner:

<!-- Run the full selenium test suite if enabled -->

Conclusion

Hopefully these tips will help you create a well-documented, flexible POM that is easy to maintain and understand.

WANT TO LEARN MORE?

Additional information about the topics covered here can be found in the freely available book from Sonatype Maven: The Complete Reference.  In particular, the chapters on properties and profiles may be of interest.  These chapters contain examples of defining and using properties, as well as defining profiles.

The Official Maven Website also contains a wealth of information, including the official POM Reference.

2 Comments. Leave new

For anyone reading this who wants to know more about using Maven profiles correctly, I wrote a blog article suggesting some best practices for the use of profiles.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

\\\