Maven is an extreme example of the principle of “inversion of control.” The key to success with Maven is to work with it, not against it. This is best achieved by avoiding trying to change how Maven does things. Rather, it is best to find out the way Maven intends to do the sort of thing you want and then provide input to that process.
All of the action in Maven happens on top of the backbone of the build lifecycle. All of the work done by Maven during a build is done by plugins executing at specific phases during the build lifecycle. Each specific thing that a plugin does is called a “goal.” Plugins typically declare in which lifecycle phases their goals are designed to execute. There are actually three lifecycles that are used in Maven, called clean, default, and site. Every invocation of mvn will use at least one of these three lifecycles. When analyzing its command-line arguments, Maven determines which of the three lifecycles to run and the end phase for each one, based on the order in which the arguments are specified. The clean and site lifecycles deal with running the clean and site goals. Clean resets the project to its nonbuilt state, usually just deleting the target directory. Site generates reports, such as code coverage and unit test results. The default lifecycle is the most interesting and is where most of the work is done by Maven and its many plugins. Hudson jobs that invoke Maven will usually have cause to use all of these different lifecycles in one way or another.
Each of the three lifecycles consists of several different phases, each with a name and purpose and executed in sequence by Maven. Maven always executes at least one of the three lifecycles, and when it does, it always executes them from the start phase until the user-specified end phase. You can think of the execution of the lifecycle phases as a journey on a non-express train from the starting station through multiple stations. When traveling on a such a train from the starting station, you can get off at any station, but no stations can be skipped.
The previous chapter introduced Hudson and explained the process of setting up a working Hudson instance and creating a simple job. One thing that is immediately apparent after completing that first job is the unique nature of Hudson: it’s a product that is only useful in combination with other products. For this reason, skill in using Hudson is only valuable when combined with skill in using the other products with which Hudson integrates. This chapter introduces the tools most commonly used with Hudson, and introduces the software development concepts in which Hudson can play a central role. It is beyond the scope of this book to provide full coverage of all these tools, but references are provided where full coverage can be found.
Hudson in the Software Development Lifecycle
It is difficult to understate the importance of software in history and in today’s economy. Even though software is an extremely recent development in history, it is only the fifth knowledge storage medium in history. Philip G. Armour, in his 2003 book The Laws of Software Process, identifies five knowledge storage media in history: DNA, brains, tools, printed media, and software. The pervasiveness of software and its impact on everyone’s life means that software should be as high quality as possible. To achieve high-quality software, the processes for creating, testing, documenting, delivering, and maintaining software should be as good as possible. This is the purpose of the software development lifecycle.
Though the sole purpose of the software development lifecycle is to make software, many ways have been devised over the years to partition the required tasks, with various names such as “waterfall,” “spiral,” and “agile.” Such topics are well beyond the scope of this book, but all of these approaches are made more successful when automation can be brought to bear in their execution. This is where Hudson comes in. Regardless of the process used for software development, or the number of people involved, Hudson can be used to achieve higher-quality software.