Every project has a lifecycle from project initiation all the way through regular production releases. A typical lifecycle involves at least the basic steps of getting all the resources together, compilation of source-code, unit-tests, integration-tests, packaging to create the custom-format. Maven formalizes this concept into a “default” lifecycle that every project is expected to have.
According to Maven, a lifecycle is made up of a sequence of phases. Each phase has zero or more plugin goals bound to it. Some of the core plugin goals are bound to the core phase steps by default, e.g the compiler plugin’s compile goal is bound to the compile phase. A more clear second example would be the Surefire plugin’s test goal is bound to the unit test phase. However, some phases are free-form and not necessary part of the core of the default lifecycle, they will be activated only when a corresponding plugin goal bound to that phase by default is configured. At the same time, some plugins and their goals are free-form and it is upto the developer to bind them to a particular phase.
Maven site lists all the following goals as part of the default lifecycle for any project regardless of the packaging type. Here are a few examples on what aspects of the project build we can customize by leveraging what plugins.
1.validate - Validates the project is correct and all necessary information is available. The enforcer plugin can be used here to enforce a few environment-specific constraints on the project.
2. initialize - Initialize build state, e.g. set properties or create directories. An example would be to use some programmatic plugins like antrun or groovy to generate custom properties. In the example below, the property ‘buildtime’ was created during build-time and it will be used inside the manifest file to mark the time the jar/war/ear was created. 3.generate-sources - Generate any source code for inclusion in compilation. Projects that use webservices or any of the Java-XML bindings, like JAXB2, XMLBeans, Castor can make use of the corresponding plugins (e.g. axistools:wsdl2java, jaxb2:xjc, xmlbeans:xmlbeans, castor:castor) to generate any source code in this phase. These plugin goals bind by default to this lifecycle phase so that you do not have to explicitly mention it.
4. process-sources - Process the source code, for example to filter any values from within the source code. More on filtering in a later blog.
5. generate-resources - Generate resources for inclusion in the package like WSDLs in a web-services project (e.g axistools:java2wsdl), or Hibernate Configuration XML or hbm.xmls (hibernate3:hbm2cfgxml)
6. process-resources - Copy and process the resources into the destination directory, ready for packaging. This is also a great place to filter any values from within the resources file. More on filtering in a later blog.
7. compile - This is the most obvious phase. Although the compiler plugin is part of the core lifecycle and need not be defined explicitly to be attached to any phase, there is often a need to customize the JDK version to use. Eg
8. process-classes- This phase is used to post-process the generated class files from compilation, for example to do bytecode enhancement on Java classes.
9. generate-test-sources - This is conceptually same as generate-sources phase as above, except that we are generating test source code here.
10. process-test-sources - This phase is used to process test source files, e.g to filter any values, make program variables point to a test DB location instead of production DB location etc.
11. generate-test-resources - This phase is used to create resources for testing. E.g. Let's say your project's tests are off some companydata.dat file which is a part of the companycore.jar. Since your project is interested only in this data file for the purposes of testing, you could use maven-dependency-plugin to unpack the companycore.jar, extracting only that file into your test-resources directory.
12. process-test-resources - This phase is used to copy and process the resources into the test destination directory.
13. test-compile - The compiler plugin compiles the test source code into the test destination directory.
14. process-test-classes - Conceptually same as process-classes to do any byte code enhancement.
15. test - The Surefire plugin runs tests using a suitable unit testing framework. You may need to configure the plugin to skipTests or exclude any particular test class that are causing the build to fail. This may be useful during active development phase.
16. package - Take the compiled code and package it in its distributable format, such as a JAR. You can request Maven to package source files and test source files into respective jars via maven-jar-plugin and maven-source-plugin in addition to the distributable class file jar that it creates.
17. verify- This phase can be used to run any checks to verify the package is valid and meets quality criteria. It is a great place to enforce any source code formatting styles.
So the above list gives a fair idea on how you can leverage Maven plugins to customize your build lifecycle. The above are just brief samples. Any ideas beyond the above usage of plugins in various build phases is more than welcome.
Maven site lists all the following goals as part of the default lifecycle for any project regardless of the packaging type. Here are a few examples on what aspects of the project build we can customize by leveraging what plugins.
1.validate - Validates the project is correct and all necessary information is available. The enforcer plugin can be used here to enforce a few environment-specific constraints on the project.
2. initialize - Initialize build state, e.g. set properties or create directories. An example would be to use some programmatic plugins like antrun or groovy to generate custom properties. In the example below, the property ‘buildtime’ was created during build-time and it will be used inside the manifest file to mark the time the jar/war/ear was created. 3.generate-sources - Generate any source code for inclusion in compilation. Projects that use webservices or any of the Java-XML bindings, like JAXB2, XMLBeans, Castor can make use of the corresponding plugins (e.g. axistools:wsdl2java, jaxb2:xjc, xmlbeans:xmlbeans, castor:castor) to generate any source code in this phase. These plugin goals bind by default to this lifecycle phase so that you do not have to explicitly mention it.
4. process-sources - Process the source code, for example to filter any values from within the source code. More on filtering in a later blog.
5. generate-resources - Generate resources for inclusion in the package like WSDLs in a web-services project (e.g axistools:java2wsdl), or Hibernate Configuration XML or hbm.xmls (hibernate3:hbm2cfgxml)
6. process-resources - Copy and process the resources into the destination directory, ready for packaging. This is also a great place to filter any values from within the resources file. More on filtering in a later blog.
7. compile - This is the most obvious phase. Although the compiler plugin is part of the core lifecycle and need not be defined explicitly to be attached to any phase, there is often a need to customize the JDK version to use. Eg
8. process-classes- This phase is used to post-process the generated class files from compilation, for example to do bytecode enhancement on Java classes.
9. generate-test-sources - This is conceptually same as generate-sources phase as above, except that we are generating test source code here.
10. process-test-sources - This phase is used to process test source files, e.g to filter any values, make program variables point to a test DB location instead of production DB location etc.
11. generate-test-resources - This phase is used to create resources for testing. E.g. Let's say your project's tests are off some companydata.dat file which is a part of the companycore.jar. Since your project is interested only in this data file for the purposes of testing, you could use maven-dependency-plugin to unpack the companycore.jar, extracting only that file into your test-resources directory.
12. process-test-resources - This phase is used to copy and process the resources into the test destination directory.
13. test-compile - The compiler plugin compiles the test source code into the test destination directory.
14. process-test-classes - Conceptually same as process-classes to do any byte code enhancement.
15. test - The Surefire plugin runs tests using a suitable unit testing framework. You may need to configure the plugin to skipTests or exclude any particular test class that are causing the build to fail. This may be useful during active development phase.
16. package - Take the compiled code and package it in its distributable format, such as a JAR. You can request Maven to package source files and test source files into respective jars via maven-jar-plugin and maven-source-plugin in addition to the distributable class file jar that it creates.
17. verify- This phase can be used to run any checks to verify the package is valid and meets quality criteria. It is a great place to enforce any source code formatting styles.
So the above list gives a fair idea on how you can leverage Maven plugins to customize your build lifecycle. The above are just brief samples. Any ideas beyond the above usage of plugins in various build phases is more than welcome.
5 comments:
fanstic post man, a must read for anyone who is learning Maven, bookmarked it.
Thanks
Javin
How HashMap works in Java
I wouldn't mind some more info on how maven expects the integration tests part of the lifecycle to work... Especially in regards to web-apps...
Most of the time I find myself just using "jetty:run" to test things, but I'm sure maven probably has a better way.
Example under 7 compile looks like it is missing the source tags.
Thanks for putting this up, great resource for finding out what phase to put something in.
@intangible - I have not worked with jetty:run. My guess is that you can bind the jetty:run goal to the integration phase of the lifecycle. See http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html as a reference to where integration phase lies in the entire lifecycle.
@Chris Wilkes - Thanks for pointing out the typo.
I am glad that this post is useful to you.
Post a Comment