Mastering The Maven Command Line – Managing failures

The last post of this series has introduced a couple of useful options to manage built modules in a multi-module project. This post focuses on failure. Maven proposes three different way to manage failures in reactor builds: fail-fast (default), fail-at-end and fail-never which will be described in this post.

An example

To illustrate the topic, let’s imagine a simple multi-module project (the same as in the previous post):

  • Project is the ‘root’ project, declares the others modules
  • Module-A is a simple project
  • Module-B depends on Module-A
  • Module-C depends on Module-A
  • Module-D depends on Module-C

The Module-C contains a failing unit tests:

public class FirstTest {

    @Test
    public void a() {
        System.out.println("A executed...");
        org.junit.Assert.fail("oh oh");
    }

    @Test
    public void b() {
        System.out.println("B executed...");
        // OK
    }

Depending on the options used to build the complete project (i.e. the reactor build), the result will differ.

Fail-Fast

The first policy is the default one. Fail Fast stops the reactor build after the first failing project. Despite used by default, you can enable this policy with: --fail-fast or just -ff
One our example, the build will stop after Module-C:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running maven.test.FirstTest
B executed...
A executed...
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.223 sec <<< FAILURE!
Running maven.test.SecondTest
C executed...
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.006 sec

Results :

Failed tests:
  a(maven.test.FirstTest)

Tests run: 3, Failures: 1, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] There are test failures.

With this policy, the build is stopped after the first failing module. It gives you the opportunity to fix the issue. This avoids the propagation of the ‘bug’ to others modules. However, it does not necessary fit for big project where the failure may not impact others modules. Moreover, quality builds generally analyzes all modules and shouldn’t be stopped after the first failed tests.

Fail-at-end

The second policy to manage failure is named fail-at-end. To enable this policy, use the --fail-at-end (or just -fae) parameter. This policy fails the build afterward and allows all non-impacted builds to continue. On our project:

mvn clean install --fae => builds Module A, B, C (failed), skip D

produces

[INFO]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Module A .............................................. SUCCESS [2.849s]
[INFO] Module B .............................................. SUCCESS [0.070s]
[INFO] Module C .............................................. FAILED [9.474s]
[INFO] Module D .............................................. SKIPPED (dependency build failed or was skipped)
[INFO] Reactor ............................................... SUCCESS [0.948s]
[INFO] ------------------------------------------------------------------------
[INFO] Error for project: Module C (during install)
[INFO] ------------------------------------------------------------------------
[INFO] There are test failures.

Please refer to /Users/clement/workspaces/experiments/Project/module-C/target/surefire-reports for the individual test results.

This policy allows all non-impacted builds to continue. However, D depends on C, so as C failed, D is skipped. The global build is also considered as failed. This option avoid issue propagation, which is an interesting feature.

This option is useful to try to compile a maximum of modules. If the project contains independent modules, this option is really interesting (especially if we are interested by modules built after the initial failures). A last detail to know about this option, it does not only support test failures, but all project failures (wrong configuration, missing dependencies, etc.). However, for quality builds, or for builds with post-actions, this option is not enough, that’s why there is a third option.

Fail-Never

This last option must be used carefully, but can be useful. The build never fails, regardless of the project result. All failures are ignore, the build just continues. On your project:

mvn clean install --fail-never (or just --fn)

produces:

[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Module A .............................................. SUCCESS [2.583s]
[INFO] Module B .............................................. SUCCESS [0.086s]
[INFO] Module C .............................................. FAILED [1.598s]
[INFO] Module D .............................................. SUCCESS [0.051s]
[INFO] Reactor ............................................... SUCCESS [0.921s]
[INFO] ------------------------------------------------------------------------
[INFO] Error for project: Module C (during install)
[INFO] ------------------------------------------------------------------------
[INFO] There are test failures.

Please refer to /Users/clement/workspaces/experiments/Project/module-C/target/surefire-reports for the individual test results.
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO]  + Ignoring failures
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5 seconds
[INFO] Finished at: Sun May 09 10:43:41 CEST 2010
[INFO] Final Memory: 31M/79M
[INFO] ------------------------------------------------------------------------

Module C failed, D is not skipped, and the global build is successful.

This policy is generally used for quality builds that must be executed on all modules. Build with post-actions may also be interested. However, I don’t recommend this options for regular builds (e.g., on the developer machine).

3 thoughts on “Mastering The Maven Command Line – Managing failures

  1. Hello, thank you for this post. However, I have a question. I am not sure about the behaviour of the fail-at-end.

    You say, that module D is skipped:
    mvn clean install –fae => builds Module A, B, C (failed), skip D

    But I would expect that D build will be executed as well, but the total build result will be failed?

  2. great, to avoid a bug in maven 2.2.1 we need to do a first clean install which fails and then do another build.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s