Universal Reuse Through Maven Plugins

The core of Maven is pretty dumb; it doesn’t know how to do much beyond parsing a few XML documents and keeping track of a lifecycle and a few plugins. Maven has been designed to delegate most responsibility to a set of Maven plugins that can affect the Maven lifecycle and offer access to goals. Most of the action in Maven happens in plugin goals that take care of things like compiling source, packaging bytecode, publishing sites, and any other task that needs to happen in a build. The Maven you download from Apache doesn’t know much about packaging a WAR file or running JUnit tests; most of Maven’s intelligence is implemented in the plugins, and the plugins are retrieved from the Maven repository. In fact, the first time you run something like mvn install with a brand new Maven installation, it retrieves most of the core Maven plugins from the central Maven repository. This is more than just a trick to minimize the download size of the Maven distribution; this is behavior that allows you to upgrade a plugin to add capability to your project’s build. The fact that Maven retrieves both dependencies and plugins from the remote repository allows for universal reuse of build logic.

The Maven Surefire plugin is responsible for running unit tests. At some point between version 1.0 and the version that is in wide use today, someone decided to add support for the TestNG unit testing framework in addition to the support for JUnit. This happened in a way that didn’t break backward compatibility—if you were using the Surefire plugin to compile and execute JUnit 3 unit tests, and you upgraded to the most recent version of the Surefire plugin, your tests continued to execute without fail. You also gained new functionality, so if you wanted to execute unit tests in TestNG, you now had that ability, thanks to the efforts of the maintainers of the Surefire plugin. You also gained the ability to run annotated JUnit 4 unit tests. You gained all of these capabilities without having to upgrade your Maven installation or install new software. Most importantly, nothing about your project had to change aside from a version number for a plugin in a POM.

It is this mechanism that affects much more than the Surefire plugin: projects are compiled with a Compiler plugin, projects are turned into JAR files with a Jar plugin, and there are plugins for running reports, plugins for executing JRuby and Groovy code, as well as plugins to publish sites to remote servers. Maven has abstracted common build tasks into plugins that are maintained centrally and shared universally. If the state of the art changes in any area of the build, if some new unit testing framework is released or if some new tool is made available, you don’t have to be the one to hack your project’s custom build system to support it. You benefit from the fact that plugins are downloaded from a remote repository and maintained centrally. This is what is meant by universal reuse through Maven plugins.

Get Maven: The Definitive Guide now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.