Phase name collisions in custom lifecycles in Maven? - maven

AFAIK, you can create a custom build lifecycle in maven.
Also, AFAIK, you cannot tell maven to execute a lifecycle. You can either:
Tell maven to execute a phase: In this case, maven finds in which lifecycle this phase is, and then executes all phases in that lifecycle, up to the phase specified.
Tell maven to execute a goal, by specifying it as mvn plugin_name:goal_name
So, assume that I have created a custom lifecycle. And assume that this custom lifecycle has a phase named install.
When I write mvn install, will maven execute the default lifecycle (which has a phase named install) or my custom lifecycle (which also has a phase named install)?
How will maven determine which lifecycle to follow?

This is not supported (yet), though recently Stephen started a thread about it: http://maven.markmail.org/thread/z57dzgunecgfcrf7

Related

Maven: How is a phase mapped to a lifecycle

i'm wondering about how Maven maps a phase to a lifecycle.
For example when running
mvn clean
then Maven executes the phases "pre-clean" and "clean" of the "clean" lifecycle.
But how does Maven determine that the phase "clean" (as provided as command line argument) belongs to the "clean" lifecycle? There could be another lifecycle that also has a "clean" phase.
It may be a rule that all phases over all lifecycles must have a unique name. But i don't know.
In Maven there existing only the following three life cycles
clean
default
site
The details are defined in the lifecycle binding of Maven core https://maven.apache.org/ref/3.8.1/maven-core/lifecycles.html
The existing and defined life cycles are defined in the following file:
META-INF/plexus/components.xml

Maven plugins binding when no execution details is specified in POM

When no execution details is specified for a plugin in the POM file, then is there a default phase of the maven lifecycle to which the plugin is bind to?
I assume the plugin could only be called explicitly via the command line in this scenario.
The execution of plugins depends on the phase (life cycle) you're calling and the artifact type you're producing e.g. when your project produces a pom (<packaging>pom</packaging>) instead of a jar (jar or no <packaging> element specified), the compile plugin is not called at all.
For a list of executed goals (plugins) see
the complete Maven reference.
If you want to check what plugins are configured for your project, check the effective pom which can be created by calling
mvn help:effective-pom
The effective pom is a merge of the super pom and your project's pom.
see this tutorial for an example of an effective pom
There are different things. First the life cycle which defines executions of particular plugins.
Apart from that a plugin can define a default life cycle phase where it will be executed which is defined by the plugin author.
For example the xml-maven-plugin binds to the generate-resources phase. Excerpt from the docs:
Requires a Maven project to be executed.
Binds by default to the lifecycle phase: generate-resources.
Here the plugin binds by default to the generate-resources life cycle phase. Or you can look at the maven-ear-plugin and many other plugins.
Of course you can call a plugin via command line if the appropriate plugin supports that. Otherwise you can bind the plugin via execution block to a particular life cycle phase.

Bind mvn jetty:run to a different phase?

I have a maven webapp, which can be run using jetty. If I call jetty with
mvn jetty:run
it is executed before the install phase. However, I want to run jetty at the very end of the maven lifecycle only. How can I achieve that?
Or to put it in a different way. The run goal of jetty maven plugin is bound by default to a certain maven phase. Can I change that binding?
Update: Just to make sure, I don't want to know how to execute jetty automatically each time a maven phase is executed like pre-integration-test. I just want to bind the jetty run goal to a later phase so that additional maven phases get executed when calling it manually.
That's not possible (using predefined packagings like jar or war). In Maven you run plugin's goal or phase (which starts lifecycle). If you run goal, only this goal is executed. If you run phase, lifecycle runs from the beginning to that phase included. Try to run (after mvn clean) mvn install:install (goal only) and then mvn install (default lifecycle to the install phase included).
You can create own plugins' goals to lifecycle's phases binding by creating own packaging type. Predefined packaging types (jar, war, ear, etc.) have this binding already specified.

Difference between Maven source plugin jar and jar-no-fork goal?

Could you give me a detail explanation about the difference between jar and jar-no-fork goal?
I see it from official site, but I can not get a clear idea for this.
My interpretation: the jar goal is meant to be run from the command line (mvn source:jar), the jar-no-fork is meant to be bound to the lifecycle.
If you look at the docs for the jar goal the key phrase is "Invokes the execution of the lifecycle phase generate-sources prior to executing itself." If you configure your POM to run the source:jar goal as part of the lifecycle, Maven will re-run all of the goals bound to generate-sources and its predecessors. If you have many plugin goals bound to the validate or initialize phases all of those will run twice, lengthening the time of your build.
In contrast, jar-no-fork is what you attach to the build lifecycle because it expects to be bound to a phase somewhere after generate-sources and will not run the bound goals again.
I have verified this behavior by running Maven 3 with -X and reviewing the plugin executions that run.

What does maven do with a bogus packaging type?

I'm working my way through learning a somewhat complicated maven build. I've found a module that is using a bogus packaging type, "custom-war" to be specific. If I execute:
mvn -e -X clean install
maven complains thus:
[DEBUG] Error looking up lifecycle mapping to retrieve optional mojos. Lifecycle
ID: clean. Error: Component descriptor cannot be found in the component repository:
org.apache.maven.lifecycle.mapping.LifecycleMappingcustom-war.
However, it appears to go ahead and execute clean:clean, so it must have made some decisions on which goals to map to the lifecycle phases. Can anyone provide some insight into the decision making of maven in the face of a bogus packaging type?
I think I should add that this custom module appears to be "defining it's own default lifecycle bindings"; I've found a component.xml file that defines goal bindings for phases of the default lifecycle. In the light of this, the error appears to be complaining that there are no bindings declared for clean, but the format of the component.xml doesn't appear to support that.
The clean phase runs through to completion because the goals that are bound to this phase are independent of the packaging.
What should be done in response to the command mvn install on the other hand is predicated on the packaging. Maven encountered an unknown packaging of "custom-war" and so it threw its hands up.
See correlation of phases to packaging at Maven.

Resources