Maven 2 life cycles, phases, plug-ins, and mojos
Maven accomplishes most of its build tasks through the action of plug-ins. You can think of the Maven engine as an orchestrator of plug-in actions.
Plug-ins are software modules written to fit into Maven's plug-in framework. Currently, custom plug-ins can be created using Java, Ant, or Beanshell. Each task within a plug-in is called a mojo. Sometimes, plug-ins are viewed as a set of related mojos. Creating custom Maven 2 plug-ins is beyond this tutorial's scope; see Resources for more information.
Maven 2 comes prepackaged to download and work with many frequently used plug-ins. Most typical development tasks do not require the use of additional plug-ins.
Before you set out to write your own plug-ins, you should first consult the popular Maven 2 plug-in listing Web sites (see Resources) to see if the plug-in you need is already available. Figure 5 shows the Maven Plugin Matrix (see Resources), which provides compatibility information for many available plug-ins:
Figure 5. Maven Plugin Matrix
A mojo (build task) within a plug-in is executed when the Maven engine executes the corresponding phase on the build life cycle. The association between a plug-in's mojo and a phase of the life cycle is called a binding. Plug-in developers can flexibly associate one or more life-cycle phases with a plug-in.
Maven's built-in understanding of a build life cycle consists of many distinct phases. Table 1 provides a brief description of each phase:
Table 1. Maven 2 default life-cycle phases
|validate||Ensures that the current configuration and the content of the POM is valid. This includes validation of the tree of pom.xml files.|
|initialize||A chance to carry out any initialization prior to the main tasks in a build cycle.|
|generate-sources||A chance for code generators to start generating source code that can be processed or compiled in the later phases.|
|process-sources||Provided for the parsing, modification, and transformation of the source. Both regular and generated source code can be processed here.|
|generate-resources||A chance to generate non-source-code resources. This typically includes metadata files and configuration files.|
|process-resources||Handles the processing of the non-source-code resources. Modifications, transformation, and relocation of resources can occur during this phase.|
|compile||Compiles the source code. The compiled classes are placed into a target directory tree.|
|process-classes||Handles any class file transformation and enhancement steps. Bytecode weavers and instrumentation tools often operate during this phase.|
|generate-test-sources||A chance for mojos that generate unit-test code to operate.|
|process-test-sources||Executes any processing necessary on the test source code prior to compilation. Source code can be modified, transformed, or copied during this phase.|
|generate-test-resources||Allows for the generation of test-related (non-source-code) resources.|
|process-test-resources||Enables processing, transformation, and relocation of test-related resources.|
|test-compile||Compiles the source code of the unit tests.|
|test||Runs the compiled unit tests and tallies the results.|
|package||Bundles the executable binaries into a distribution archive, such as a JAR or WAR.|
|pre-integration-test||Prepares for integration testing. Integration testing in this case refers to testing of the code in (a controlled clone) of the actual deployment environment. This step can deploy the archive to a server for execution.|
|integration-test||Carries out actual integration tests.|
|post-integration-test||Unprepares for integration testing. This can involve reset or reinitialization of the testing environment.|
|verify||Verifies the validity and integrity of the deployable archive. After this phase, the archive will be installed.|
|install||Adds the archive to the local Maven directory. This makes it available for any other modules that may depend on it.|
|deploy||Adds the archive to a remote Maven directory. This can make the artifact available to a larger audience.|
Maven captures more than a decade of project build management experience from the open source community. You will be hard-pressed to find a software project whose build cycle cannot fit into the life-cycle phases in Table 1.
When you start Maven 2's engine, it marches in order through each phase in Table 1 and executes any mojo that may be bound to that phase. Each mojo in turn can use Maven 2's rich POM support, dependency management, and access to build-state information in performing its dedicated task.
When you invoke the Maven 2 engine, you can specify a life-cycle phase as a command-line argument. The engine works through all the phases up to and including the specified phase. All mojos in the included phases are triggered.
This, in a nutshell, is how Maven 2 operates. You will see the operation first-hand in the next section. With a background understanding of Maven's operation, its dependency management model, and its POM, you'll find working hands-on with Maven 2 to be a straightforward exercise.