389

What is the difference/relation between Maven goals and phases? How they are related to each other?

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Tarun Kumar
  • 5,150
  • 6
  • 26
  • 30
  • 3
    Asked and [answered](http://stackoverflow.com/a/30953905/1744774) in [Maven: Lifecycle vs. Phase vs. Plugin vs. Goal](http://stackoverflow.com/questions/26607834/maven-lifecycle-vs-phase-vs-plugin-vs-goal/) (one more time). – Gerold Broser Jun 20 '15 at 13:07
  • 1
    Possible duplicate of [Maven: Lifecycle vs. Phase vs. Plugin vs. Goal](https://stackoverflow.com/questions/26607834/maven-lifecycle-vs-phase-vs-plugin-vs-goal) –  Aug 18 '17 at 18:06

9 Answers9

292

Goals are executed in phases which help determine the order goals get executed in. The best understanding of this is to look at the default Maven lifecycle bindings which shows which goals get run in which phases by default. The compile phase goals will always be executed before the test phase goals, which will always be executed before the package phase goals and so on.

Part of the confusion is exacerbated by the fact that when you execute Maven you can specify a goal or a phase. If you specify a phase then Maven will run all phases up to the phase you specified in order (e.g. if you specify package it will first run through the compile phase and then the test phase and finally the package phase) and for each phase it will run all goals attached to that phase.

When you create a plugin execution in your Maven build file and you only specify the goal then it will bind that goal to a given default phase. For example, the jaxb:xjc goal binds by default to the generate-resources phase. However, when you specify the execution you can also explicitly specify the phase for that goal as well.

If you specify a goal when you execute Maven then it will run that goal and only that goal. In other words, if you specify the jar:jar goal it will only run the jar:jar goal to package your code into a jar. If you have not previously run the compile goal or prepared your compiled code in some other way this may very likely fail.

Lii
  • 11,553
  • 8
  • 64
  • 88
Pace
  • 41,875
  • 13
  • 113
  • 156
  • 16
    I've made it a habit to say "Maven **passes** all phases (up to and including the given)" instead of _"runs"_ or _"executes"_ (the latter as it is called in Maven's _Introduction to the Build Lifecycle_). Such distincting it clearer from the goal's code which is really executed. But that might be personal taste. – Gerold Broser Jun 20 '15 at 13:25
  • But we can also run goals that does not belong to any phase, i.e. `mvn archetype:generate`, and in that case maven only executes the goal? – Quazi Irfan Jun 03 '17 at 21:27
  • Check the last paragraph. No, it does not only execute the goal. – Pace Jun 04 '17 at 16:51
  • 1
    @Pace Do you have a reference for the last paragraph? I've been doubting that and tried it with a simple project here: `mvn test` runs: `--- maven-resources-plugin:2.6:resources ... --- maven-compiler-plugin:3.1:compile ... --- maven-resources-plugin:2.6:testResources ... --- maven-compiler-plugin:3.1:testCompile ... --- maven-surefire-plugin:2.12.4:test`, while `mvn compiler:testCompile` just runs `--- maven-compiler-plugin:3.1:testCompile ...`. – Gerold Broser Feb 03 '18 at 18:01
  • @GeroldBroser If you delete your target directory and run `mvn compiler:testCompile` will it fail (because it can't find the compiled source code)? That should be a pretty easy way to test the theory. – Pace Feb 03 '18 at 23:04
  • 4
    @Pace `mvn clean compiler:testCompile` runs `--- maven-clean-plugin:2.5:clean ... --- maven-compiler-plugin:3.1:testCompile` which fails with `Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-cli) on project mvnphase: Compilation failure ... cannot find symbol ... symbol: variable MvnPhase` (where `MvnPhase` is the class under test referenced in the test class). Apparently phases are not invoked if a goal is invoked explicitely. – Gerold Broser Feb 04 '18 at 11:08
  • @Pace And it's even more sophisticated: If a goal is created with the [`@execute phase=""` annotation](https://people.apache.org/~ltheussl/maven-stage-site/developers/mojo-api-specification.html#The_Descriptor_and_Annotations) apparently a phase _is_ invoked parallelly. What puzzles me is the sentence "_The execution_ [...] _will not affect the current project_" there. Do you have an idea what this means? – Gerold Broser Feb 04 '18 at 14:49
  • Last paragraph of this question is not correct, and I reckon that contributes to create chaos when trying to differentiate between phases and goals. I believe the second most rated answer is the best one. – kekko12 Dec 22 '19 at 17:44
  • 4
    Based on input from geroldbroser and @kekko12 I've updated the last paragraph to state that, when a goal is specified, only that goal is run, and not all preceding phases. – Pace Dec 27 '19 at 18:13
  • But why is it only executing the specified phase? And how do i solve that? I've implemented that it creates docker images of my application on install. but its not compiling my code anymore when i run clean install. I have something like this for my plugin: installgoals>buildrun – Abdullah Gheith Jun 26 '21 at 00:05
  • @AbdullahGheith I'm sorry but it's been over 5 years since I've done much Java and I cannot help you. You may want to consider asking a new question. – Pace Jun 28 '21 at 16:58
  • Yes, but what is a goal (for people not familiar with maven)? – nbro Apr 10 '22 at 13:39
  • @nbro Perhaps [this answer to _Maven: Lifecycle vs. Phase vs. Plugin vs. Goal_](http://stackoverflow.com/a/30953905/1744774) clarifies this. – Gerold Broser Jun 09 '22 at 13:04
235

Life cycle is a sequence of named phases.
Phases executes sequentially. Executing a phase means executes all previous phases.

Plugin is a collection of goals(i.e. tasks) which also called MOJO (Maven Old Java Object).

Maven is based around the central concept of a Build Life Cycles. Inside each Build Life Cycles there are Build Phases, and inside each Build Phases there are Build Goals.

We can execute either a build phase or build goal. When executing a build phase we execute all build goals within that build phase. Build goals are assigned to one or more build phases. We can also execute a build goal directly.

There are three major built-in Build Life Cycles:

  1. default
  2. clean
  3. site

Each Build Lifecycle is Made Up of Phases

For example the default lifecycle comprises of the following Build Phases:

◾validate - validate the project is correct and all necessary information is available
◾compile - compile the source code of the project
◾test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
◾package - take the compiled code and package it in its distributable format, such as a JAR.
◾integration-test - process and deploy the package if necessary into an environment where integration tests can be run
◾verify - run any checks to verify the package is valid and meets quality criteria
◾install - install the package into the local repository, for use as a dependency in other projects locally
◾deploy - done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

So to go through the above phases, we just have to call one command:

mvn <phase> { Ex: mvn install }

For the above command, starting from the first phase, all the phases are executed sequentially till the ‘install’ phase. mvn can either execute a goal or a phase (or even multiple goals or multiple phases) as follows:

mvn clean install plugin:goal  

However, if you want to customize the prefix used to reference your plugin, you can specify the prefix directly through a configuration parameter on the maven-plugin-plugin in your plugin's POM.

A Build Phase is Made Up of Plugin Goals

Most of Maven's functionality is in plugins. A plugin provides a set of goals that can be executed using the following syntax:

 mvn [plugin-name]:[goal-name]

For example, a Java project can be compiled with the compiler-plugin's compile-goal by running mvn compiler:compile.

Build lifecycle is a list of named phases that can be used to give order to goal execution.

Goals provided by plugins can be associated with different phases of the lifecycle. For example, by default, the goal compiler:compile is associated with the compile phase, while the goal surefire:test is associated with the test phase. Consider the following command:

mvn test

When the preceding command is executed, Maven runs all goals associated with each of the phases up to and including the test phase. In such a case, Maven runs the resources:resources goal associated with the process-resources phase, then compiler:compile, and so on until it finally runs the surefire:test goal.

However, even though a build phase is responsible for a specific step in the build lifecycle, the manner in which it carries out those responsibilities may vary. And this is done by declaring the plugin goals bound to those build phases.

A plugin goal represents a specific task (finer than a build phase) which contributes to the building and managing of a project. It may be bound to zero or more build phases. A goal not bound to any build phase could be executed outside of the build lifecycle by direct invocation. The order of execution depends on the order in which the goal(s) and the build phase(s) are invoked. For example, consider the command below. The clean and package arguments are build phases, while the dependency:copy-dependencies is a goal (of a plugin).

mvn clean dependency:copy-dependencies package

If this were to be executed, the clean phase will be executed first (meaning it will run all preceding phases of the clean lifecycle, plus the clean phase itself), and then the dependency:copy-dependencies goal, before finally executing the package phase (and all its preceding build phases of the default lifecycle).

Moreover, if a goal is bound to one or more build phases, that goal will be called in all those phases.

Furthermore, a build phase can also have zero or more goals bound to it. If a build phase has no goals bound to it, that build phase will not execute. But if it has one or more goals bound to it, it will execute all those goals.

Built-in Lifecycle Bindings
Some phases have goals bound to them by default. And for the default lifecycle, these bindings depend on the packaging value.

Maven Architecture:

enter image description here

Reference 1
Reference 2

Eclipse sample for Maven Lifecycle Mapping

Eclipse sample for Maven Lifecycle Mapping

Premraj
  • 72,055
  • 26
  • 237
  • 180
  • If I have 2 profiles, can I run all plugins of profile 1 first, and then that of profile 2? – Bee Dec 19 '16 at 12:07
  • `[plugin-name]` in the example `mvn [plugin-name]:[goal-name]` is rather a [plugin prefix](https://maven.apache.org/guides/introduction/introduction-to-plugin-prefix-mapping.html). `mvn clean install` can not only "_be used in a multi-module scenario_". Multi-module is a totally different topic. – Gerold Broser Feb 03 '18 at 19:01
  • Do goals attached to the same phase abide by any order? – eel ghEEz Mar 21 '18 at 19:13
  • 14
    Most of this text is copied verbatim from the [Maven documentation](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html). This should be clearly stated! – Lii Jun 07 '18 at 11:01
  • "The clean and package arguments are build phases" I think `clean` actually refers to life cycle rather than build phase, according to Maven's [guide](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#build-lifecycle-basics). Life cycle consists of multiple build phases – torez233 Jul 23 '20 at 03:48
  • @hafan96 No, at `mvn clean` the `clean` means the _phase_ of the `clean` lifecycle. Lifcycles are (ordered) collections of phases. You can't use them as arguments to `mvn`. However, using `clean` in an example isn't the best choice anyway, since there are actually _four_ items namend `clean`: [lifecycle, phase of lifecycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference), [plugin-prefix of the Clean Plugin, goal of the Clean Plugin](https://maven.apache.org/plugins/maven-clean-plugin/). Which may be confusing, especially for beginners. – Gerold Broser Aug 12 '20 at 08:43
57

The definitions are detailed at the Maven site's page Introduction to the Build Lifecycle, but I have tried to summarize:

Maven defines 4 items of a build process:

  1. Lifecycle

    Three built-in lifecycles (aka build lifecycles): default, clean, site. (Lifecycle Reference)

  2. Phase

    Each lifecycle is made up of phases, e.g. for the default lifecycle: compile, test, package, install, etc.

  3. Plugin

    An artifact that provides one or more goals.

    Based on packaging type (jar, war, etc.) plugins' goals are bound to phases by default. (Built-in Lifecycle Bindings)

  4. Goal

    The task (action) that is executed. A plugin can have one or more goals.

    One or more goals need to be specified when configuring a plugin in a POM. Additionally, in case a plugin does not have a default phase defined, the specified goal(s) can be bound to a phase.

Maven can be invoked with:

  1. a phase (e.g clean, package)
  2. <plugin-prefix>:<goal> (e.g. dependency:copy-dependencies)
  3. <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal> (e.g. org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile)

with one or more combinations of any or all, e.g.:

mvn clean dependency:copy-dependencies package
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
Sandeep Jindal
  • 14,510
  • 18
  • 83
  • 121
  • Only _lifecycle phases_ make really sense to be considered as _"steps"_ (of a build process). I'd rather call it _4 entities/items/things_. – Gerold Broser Jun 20 '15 at 13:38
  • When I see the world `Build Phase`, I think of it as another phase in a lifecycle, and it confuses me. – Quazi Irfan Jun 03 '17 at 21:36
  • 1
    Great answer. A small note: Regarding the last section "Maven can be invoked with" there is a forth option (since Maven 3.3.1) which is plugin:goal@executation_id e.g. mvn antrun:run@my-execution see https://stackoverflow.com/questions/3166538/how-to-execute-maven-plugin-execution-directly-from-command-line – Eliyahu Machluf Dec 10 '20 at 20:35
57

The chosen answer is great, but still I would like to add something small to the topic. An illustration.

It clearly demonstrates how the different phases binded to different plugins and the goals that those plugins expose.

So, let's examine a case of running something like mvn compile:

  • It's a phase which execute the compiler plugin with compile goal
  • Compiler plugin got different goals. For mvn compile it's mapped to a specific goal, the compile goal.
  • It's the same as running mvn compiler:compile

Therefore, phase is made up of plugin goals.

enter image description here

Link to the reference

Johnny
  • 14,397
  • 15
  • 77
  • 118
  • 28
    why is `mvn test` pointing to `package`, and `mvn install` pointing to `deploy`? – Abdull Oct 11 '15 at 11:11
  • 3
    Looks like an illustration error, thanks for noticing (founded it in the web). – Johnny Oct 11 '15 at 11:22
  • 4
    Where did you get the illustration from? Did you check copyright and usage terms? – Abdull Oct 11 '15 at 11:24
  • 1
    @Abdull image taken from here http://www.carminespagnuolo.eu/otheractivities/tutorato/PR-2014-2015/apache-maven-PR-27-04-2015.pdf (and it's appear in many other web pages as well) adding it to the answer. Thanks for raising this point, wasn't aware of the importance of it. – Johnny Jan 13 '16 at 10:45
  • 1
    The pointers from phases to plugins in the diagram aren't quite right either, the `jar` plugin actually runs in the `package` phase. And the pom in the sandwich between phases and plugins is a bit confusing (I assume it should mean that in the pom you can configure which plugins run in which phases, in addition to the default bindings). The general principle is right, though. – Alexander Klimetschek Dec 08 '17 at 19:21
  • 1
    Re "[_`mvn compile`_] _It's the same as running `mvn compiler:compile`_" – No, it's NOT. `mvn compile` passes _all_ phases from `validate` up to the `compile` phase. `mvn compiler:compile` just runs the `compile` goal of the [Maven Compiler Plugin](https://maven.apache.org/plugins/maven-compiler-plugin/) with its [prefix](https://maven.apache.org/guides/introduction/introduction-to-plugin-prefix-mapping.html) `compiler`. – Gerold Broser Feb 04 '18 at 13:07
  • 1
    Thanks, @GeroldBroser. I was about to ask this based upon my understanding. – jsmtslch Nov 25 '22 at 17:36
40

I believe a good answer is already provided, but I would like to add an easy-to-follow diagram of the different 3 life-cycles (build, clean, and site) and the phases in each.

enter image description here

The phases in bold - are the main phases commonly used.

Lior Bar-On
  • 10,784
  • 5
  • 34
  • 46
19

Credit to Sandeep Jindal and Premraj. Their explanation help me to understand after confused about this for a while.

I created some full code examples & some simple explanations here https://www.surasint.com/maven-life-cycle-phase-and-goal-easy-explained/ . I think it may help others to understand.

In short from the link, You should not try to understand all three at once, first you should understand the relationship in these groups:

  • Life Cycle vs Phase
  • Plugin vs Goal

1. Life Cycle vs Phase

Life Cycle is a collection of phase in sequence see here Life Cycle References. When you call a phase, it will also call all phase before it.

For example, the clean life cycle has 3 phases (pre-clean, clean, post-clean).

mvn clean

It will call pre-clean and clean.

2. Plugin vs Goal

Goal is like an action in Plugin. So if plugin is a class, goal is a method.

you can call a goal like this:

mvn clean:clean

This means "call the clean goal, in the clean plugin" (Nothing relates to the clean phase here. Don't let the word"clean" confusing you, they are not the same!)

3. Now the relation between Phase & Goal:

Phase can (pre)links to Goal(s).For example, normally, the clean phase links to the clean goal. So, when you call this command:

mvn clean

It will call the pre-clean phase and the clean phase which links to the clean:clean goal.

It is almost the same as:

mvn pre-clean clean:clean

More detail and full examples are in https://www.surasint.com/maven-life-cycle-phase-and-goal-easy-explained/

Surasin Tancharoen
  • 5,520
  • 4
  • 32
  • 40
3

There are following three built-in build lifecycles:

  • default
  • clean
  • site

Lifecycle default -> [validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy]

Lifecycle clean -> [pre-clean, clean, post-clean]

Lifecycle site -> [pre-site, site, post-site, site-deploy]

The flow is sequential, for example, for default lifecycle, it starts with validate, then initialize and so on...

You can check the lifecycle by enabling debug mode of mvn i.e., mvn -X <your_goal>

Vishrant
  • 15,456
  • 11
  • 71
  • 120
2

Maven working terminology having phases and goals.

Phase:Maven phase is a set of action which is associated with 2 or 3 goals

exmaple:- if you run mvn clean

this is the phase will execute the goal mvn clean:clean

Goal:Maven goal bounded with the phase

for reference http://books.sonatype.com/mvnref-book/reference/lifecycle-sect-structure.html

Venky Vungarala
  • 1,175
  • 10
  • 6
  • 4
    It doesn' have to be _"associated with 2 or 3 goals"_ necessarily. It can be _none_, _one_ or _more than three_, as well. – Gerold Broser Jun 20 '15 at 13:29
2

In reference to Pace's answer,

If you specify a goal when you execute Maven then it will run that goal and only that goal. In other words, if you specify the jar:jar goal it will only run the jar:jar goal to package your code into a jar.

there is an exception to this statement. Maven Plugin API allows a goal to trigger execution of a lifecycle phase.

Consider the following project:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>simple-maven-project</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
</project>

When you execute the goal run defined in spring-boot-maven-plugin

mvn org.springframework.boot:spring-boot-maven-plugin:run

it prints

[INFO] ------------------< org.example:simple-maven-project >------------------
[INFO] Building simple-maven-project 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] >>> spring-boot-maven-plugin:3.0.0:run (default-cli) > test-compile @ simple-maven-project >>>
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ simple-maven-project ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\Users\Bartosz\IdeaProjects\simple-maven-project\src\main\resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ simple-maven-project ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ simple-maven-project ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\Users\Bartosz\IdeaProjects\simple-maven-project\src\test\resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ simple-maven-project ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] <<< spring-boot-maven-plugin:3.0.0:run (default-cli) < test-compile @ simple-maven-project <<<
[INFO] 
[INFO] 
[INFO] --- spring-boot-maven-plugin:3.0.0:run (default-cli) @ simple-maven-project ---
[INFO] ------------------------------------------------------------------------

This is because the goal definition in spring-boot-maven-plugin-X.X.X.jar/META-INF/maven/plugin.xml contains <executePhase>test-compile</executePhase>, which executes test-compile and all the preceding phases.

<mojo>
    <goal>run</goal>
    (...)
    <executePhase>test-compile</executePhase>
    (...)
</mojo>

Moreover, because of the default bindings for the "jar" packaging, few other goals are executed. If the packaging is changed to "pom", the same command results with

[INFO] ------------------< org.example:simple-maven-project >------------------
[INFO] Building simple-maven-project 1.0-SNAPSHOT
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] >>> spring-boot-maven-plugin:3.0.0:run (default-cli) > test-compile @ simple-maven-project >>>
[INFO] 
[INFO] <<< spring-boot-maven-plugin:3.0.0:run (default-cli) < test-compile @ simple-maven-project <<<
[INFO] 
[INFO] 
[INFO] --- spring-boot-maven-plugin:3.0.0:run (default-cli) @ simple-maven-project ---
[INFO] ------------------------------------------------------------------------

because there are no default bindings for test-compile or any previous phase and this packaging type.

Bartosz Popiela
  • 951
  • 10
  • 14