About Sonatype

Sonatype in the News

Making the Move to Maven 3

Published: June 02, 2011 09:00

You won't lose any time in upgrading to Maven 3

Most Java programs use either Ant or Maven for the build step. While Ant is infinitely configurable, Maven employs convention instead of configuration. Conventions include location of files, sequence of build steps, etc. For the last few years, Maven 2 has been the standard release. This article discusses Maven 3, which is now available. Java developers who have been relying on Maven 2.x for project build and reporting management may wonder why they should switch to Maven 3. There are many reasons.

Before I get into those, you should know that you won't lose any time in upgrading to Maven 3. It is a drop-in replacement for Maven 2 and fully backwards compatible. So aside from addressing duplicate dependencies and plugin declarations, you don't have to make any changes to your Project Object Models (POM) files, because the command line is fully compatible between Maven 2 and 3.

Performance and Memory Use

Maven 3 is faster and has a smaller memory footprint than Maven 2. While your mileage may vary depending on the specific structure of your project, benchmark testing using a dual-core CPU with 4GB RAM, running Microsoft Windows XP with JDK 1.5 showed the following improvements:

"mvn package" on Maven SCM Trunk (32 modules)

Maven Version Time Max Memory
Maven 2.2.1 3:20 99M
Maven 3.0.2 3:15 51M

"mvn package" on a Corporate Project (11 modules)

Maven Version Time Max Memory
Maven 2.2.1 1:04 48/87M
Maven 3.0.2 0:54 15/35M

This increase in speed is even greater for parallel builds, which is a new feature supported by the Maven 3 core. This feature requires that plugins used during parallel builds declare themselves as thread safe. Here are the benchmark results for parallel builds using Maven 3:

"mvn package" on Maven SCM trunk (32 modules)

Maven Version Time Max Memory
Maven 3.0.2 3:15 27/51M
Maven 3.0.2, 4 threads in parallel 2:26 28/62M

"mvn package" on a Corporate Project (11 modules)

Maven Version Time Max Memory
Maven 3.0.2 0:54 15/35M
Maven 3.0.2, 4 threads in parallel 0:40 16/42M

*Notice also the decrease in memory consumption.

Better POM and Dependency Management

This release of Maven is much stricter than Maven 2 in validating POM files. It quickly complains about obvious errors and omissions. For instance, Maven 3 warns users if they haven’t specified the plugin versions to use or if they have duplicated dependencies that could lead to unpredictable build results. Unlike Maven 2, which made developers entirely responsible for learning and incorporating best practices into builds, Maven 3 provides clear direction regarding what should be happening in the POMs and points developers toward more concise and complete POM configuration.

Maven 3 also separates project dependencies from plugin dependencies, which is particularly helpful in large projects. In Maven 2, plugin dependencies could be retrieved from any Maven repository. Because plugin dependencies could intermingle with regular project dependencies, users managing complex projects were forced to meticulously track hundreds of dependencies. In Maven 3, the project dependencies are retrieved from declared "repositories" while plugin dependencies are retrieved from "pluginRepsitories." This distinction significantly reduces procurement complexity and simplifies repository management.

Integration with Other Products

Maven 3 features new extension points that optimize IDE use, allow for seamless integration with the Hudson CI system as well as support tools, including Polyglot Maven and Maven Shell.

The Maven Shell is embedded in a long-lived shell process that can shorten build times significantly. It caches POMs and eliminates start-up costs associated with repeated use of Maven. The Maven Shell includes a built-in help system and provides Growl support on Mac OS X. It also supports project workflow, and support for Hudson, Tycho, and Polyglot Maven.

No XML: Polyglot Maven

Developers dissatisfied with Maven's original XML format can use Polyglot Maven, which is easily integrated with Maven 3 via an extension point. Polyglot Maven supports dynamic languages, including YAML, and aims to provide first-class POM-mapped Domain-Specific Language (DSL) support for Clojure, Groovy, Ruby, Scala, and Xtext.

Eclipse Support

Embedding changes in Maven 3 significantly improve its performance inside m2eclipse (the first Maven integration plugin for the Eclipse IDE). In fact, while running in this customized plugin environment, Maven 3 is capable of up to a 300% performance boost. M2eclipse provides additional XML metadata in the Maven POM that is recognized by m2eclipse and enables high build performance. M2eclipse also downloads all sources automatically and has a single-click new project creation feature for any of your dependencies. Of course, if you're using m2eclipse now, you are already using Maven 3. Switching to Maven 3 for command line executions will align Maven versions in the tools and add consistency between CLI and your IDE.

Hudson Integration

Maven 3's revamped internals support more efficient embedding. Hudson and Sonatype's multi-year investment in bringing both JSR-330 support and GWT UI integration to Hudson CI has resulted in a continuous integration platform that supports Maven 3 particularly well.

To ensure that Hudson users have the flexibility they need to create quality enterprise builds, Sonatype has taken Maven 3 support in a new direction. In a complex build environment, Maven is often not the only build tool involved in a process. So instead of binding users to a single Maven-specific project type, there is a Maven builder that can be used as part of a larger freestyle build. Maven 3 build processes can contain two separate calls to release:prepare and release:perform to better support real-world Maven builds that need to prepare and perform releases. Developers can also call out to supporting scripts or other build parts that fall outside of the scope of a Maven build.

Fixes to Maven 2

Today, focus has shifted to Maven 3 and few committers are paying attention to Maven 2. While Maven 2.x defects do eventually get fixed, there is no longer a sustained effort to test and push new Maven 2 releases. In contrast, Maven 3 has a six-week release cycle.

Maven 3 has improved artifact/dependency resolution. Previous artifact resolution deficiencies in reactor builds (that is, builds in which a goal is executed on a specific set of modules) led to problems when Maven 2.x users tried to build multi-module projects unless they executed "mvn install." This was caused by the fact that artifacts built by the modules were not resolved properly from the reactor. This defect led to an extra step of configuring the preparationGoals parameter of a maven-release-plugin to "clean install" instead of the default "clean verify." Maven 3 corrects this problem and resolves artifacts within the reactor, which allows you to use the default values of the preparationGoals parameter to streamline the build process.

Maven 3 also responds directly to the request to provide more intelligent class loading for multi-module builds. In Maven 2, the first execution of a plugin determined the classpath for all subsequent executions of that plugin. This often led to complications when a plugin required the use of a different classpath in its second invocation during a build. For example, Maven 2 users who needed to execute the Antrun plugin more than once in a multi-module build with two different classpaths were simply out of luck. This issue was fixed in Maven 3 by making sure that every execution gets its own, isolated classpath.

Interestingly, the Maven 3 codebase is two-thirds the size of the Maven 2 codebase. This is due in part to Maven 3’s use of Google Guice for dependency injection and Sisu to extend Guice’s OSGi capabilities. This release moves the entire dependency resolution mechanism into a standalone product, Sonatype Aether, for which Maven 3 is a client.

Continuous Evolution

Maven 3 is continuously evolving and is currently at version 3.03. Looking ahead, Maven 3.1 will include a security manager with the settings.xml file specifying the default. Maven 3.1 will also introduce POM mixins, which are a type of POM composition that enables parameterized POM fragments to be injected into the current POM with a simple reference. POM mixins make configuration more portable and maintainable, solving the Maven 2 problem where sharing configuration could only be done via inheritance.

Maven 3 is an Apache project and can be downloaded as open-source software http://maven.apache.org here.

Dr. Dobbs