----- Maven Lifecycle Phases ----- The Maven Team ----- Maven Lifecycle Phases * generate sources [modello, antlr, javacc] * process sources [qdox, xdoclet, jam] * generate resources [modello -> persistence mappings] * process resources [process persistence mappings] * compile [plexus component or something else] * process classes [eg JDO, coverage] * generate test sources [generating junit tests] * process test sources * generate test resources [plexus component or something else] * process test resources * test compile * process test classes * test [surefire, testNG, dbunit ...] * package [jar or making a dist] * package tests which required the entire app/assembly to be finished [integration and more] * install * deploy Mojos only know what they need as input and what phase they contribute to perform their task. They don't know anything about Maven specifically because Maven controls how they are executed in the lifecycle using the lifecycle configuration which looks like the following: +-----+ %{snippet|id=lifecycle|url=http://cvs.apache.org/viewcvs.cgi/*checkout*/maven-components/maven-core/src/main/resources/META-INF/plexus/components.xml} +-----+ You can see that we use the mojo id to indicate what mojo we want to execute at a particular place in the lifecycle to protected against any package refactoring and generally protects against any changes that might occur with naming. An example of something commonly done is Maven is to compile the sources of your project: +-----+ m2 compile +-----+ This would invoke the lifecycle up to, and including, the compile phase. What about mojos that fall outside of this standard lifecycle? Things like <<>>, <<>>, and <<>>? These mojos can be executed by invoking Maven as such. +-----+ m2 : +-----+ These mojos that execute can be thought of as stand-alone tools, they may require dependency resolution but aside from that they do not interact with any other mojos Adding Mojos into the lifecycle Here we are using antlr and it is known to maven that this plugin contributes to the generate-sources phase. In m1 the antlr plugin, in fact, worked by magic i.e. if there was a grammar present antlr would try to fire. This is a little too tricky and it would make sense to allow users to specify what they want fired as part of their build process. +-----+ ... antlr src/grammars/confluence.g ... +-----+ So here the user specifies the use of the antlr mojo that takes a grammar and generates sources and maven knows that this mojo contributes to the <<>> phase and so executes the antlr mojo inside the the <<>> phase. In cases where there is a possible domination problem we can state that the order in which the the configurations are listed is the dominant order. I think in most cases there will no be any domination ordering problems but when there could be you have to be able to explicity state what the order would be. notes to finish copying: -> mojos will contain @tags for parameters and the phase they contribute to, a mojo will be limited to contributing to one phase in the lifecycle. -> goal resolution within phases -> file dependency timestamp checking (mhw) -> strict use of artifact handlers for things like package/install/deploy this again would be a mapping so a handler could delegate to another utility for packaging -> how users decorate or completely override the lifecycle, but most of this should be alleviated by a mojo having a defined place in the lifecycle by telling maven what phase it contributes too. in this way maven can probably assemble the entire execution chain by looking at the mojos the user has specified for use in the build process. [Added, jdcasey/2005-01-23] Notes for discussion: - What about enabling goals only for certain enviornments (introduce the concept of a target "environment", like CI/dev/QA/production/etc.) We can't enforce a vocabulary of environments IMO, since different teams will have different needs, and shouldn't be forced to adapt. What about something like: +---+ . . . test dev surefire:test . . . +---+ With an invocation style similar to <<>> - In keeping with the concept of providing tons of flexibility but providing a comprehensive set of sensible defaults, the default phase-goal bindings will probably be provided in the implied root POM. That said, how do we allow users to those phase-goal bindings? How do we allow users to specify a new binding will go in relation to the defaults provided in the root POM? However we solve this, we need to emphasize intuitive XML as a solution IMO. The implicit ordering in the phase-goal bindings is a step in the right direction, but when you factor inheritance into the mix, this could get really sticky. [/Added, jdcasey/2005-01-23] [Added, brett/2005-02-13: Inserting these as things left over from previous mails to m2-dev that were pre-lifecycle] Multiple lifecycles will be able to be used and defined - for example "site" would have an additional lifecycle. This interface may even be available to users, though strongly discouraged as the default lifecycles should accommodate almost any use case. As the site runs through, it will want to ensure that parts of the lifecycle already complete are not run again unless the parameters change. eg. For coverage - no need to compile again, but do add an additional instrumentation step, then run the tests again on the new instrumented classes (in a new directory, not over the top of the old ones). To simplify this, we may actually allow some steps to re-run and rely on the file timestamping to make it effecient. [/Added, brett/2005-02-13]