Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Maven automatically retry (resume from failed module)?

I'm working on a large Maven project consisting of a number of different modules. The Maven build intermittently fails on certain modules but if all is well, a simple manually invoked --resume-from (sometimes on a couple of different modules) will allow it to continue to success.

Am deliberately omitting the details of exactly why this happens - suspect it may be due to Windows file locking on files in the target folder - but that's not the point of the question.

Question: Is it possible to get Maven to automatically retry (maybe just once, or maybe up to 3 times), resuming from the failed module?

Thoughts: The only way I can currently think of doing it is via a batch file, which reads the last line and somehow extracts the module name to resume from - but that doesn't look easy. Don't want to reinvent the wheel and was wondering if there's a nice Maven plugin that already does the job?

like image 244
Steve Chambers Avatar asked Jan 22 '19 09:01

Steve Chambers


People also ask

How do you write a resume in Maven after failing?

With Maven 4, you can make your life even easier and use --resume , or -r for short. It will automatically resume the build from the module that last failed.

What are the 3 build lifecycle of Maven?

There are three built-in build lifecycles: default, clean and site. The default lifecycle handles your project deployment, the clean lifecycle handles project cleaning, while the site lifecycle handles the creation of your project's web site.

What does mvn clean test do?

mvn clean: Cleans the project and removes all files generated by the previous build. mvn compile: Compiles source code of the project. mvn test-compile: Compiles the test source code. mvn test: Runs tests for the project.


2 Answers

I have one idea to solve your problem and maybe you don't need a batch file to do the job. You can create a Maven Core Extension and create an EventSpy library to execute --resume-from when the build fails. I already tested this example found in this answer Run a maven plugin when build fails

Based on this answer you could use Maven Invoker Maven Invoker

yet... I found an extension to safe parallel builds Maven Core Extensions Example for Safe Parallel Builds

I known you need the project info ... so looking inside of ExecutionEvent and MavenProject class we have all info about the current building project.

I hope it will work for you too.

Edit:

I'm looking for some extension that implements this behavior "automatically retry" when some module fails. If I do not find anything we should create an extension to that.

like image 130
Gustavo de Souza Avatar answered Oct 05 '22 07:10

Gustavo de Souza


Below is a fully fledged batch file, using Anitha.R's answer as a starting point.

Usage instructions:

  1. Ensure the Maven executable is in the Windows path.
  2. Ideally also ensure that a version of tee for Windows is in the Windows path. (E.g. I'm use the one provided as part of Git for Windows, having added Git's usr\bin folder to my path).
  3. Copy the batch file code into a new file.
  4. Change the max_retries value as desired.
  5. Save as "mvnretry.bat" in a folder in the Windows path.
  6. Run in the same way as Maven, e.g. mvnretry clean install -Pmyprofile -DskipTests.

Batch file code:

@echo off
setlocal enabledelayedexpansion
set max_retries=3
set retry_count=0
set output_file=%date:/=%%time::=%
set output_file=%output_file: =0%
set output_file=%temp%\mvn%output_file:.=%.out
set mvn_command=call mvn %*
set tee_found=true
where /q tee
if not errorlevel 1 goto retry
  set tee_found=false
  echo tee.exe not found in system path^^! Build will continue but output will be delayed...
:retry
  echo %mvn_command%
  if %tee_found%==true (
    %mvn_command% | tee %output_file%
  ) else (
    %mvn_command% > %output_file%
    type %output_file%
  )
  echo Parsing output...
  set "resume_from="
  for /f "tokens=2 delims=:" %%i in ('type %output_file% ^| find "mvn <goals> -rf"') do (
    set resume_from=%%i
  )
  if !retry_count! LSS %max_retries% if not [%resume_from%] == [] (
    echo Resuming from %resume_from%...
    set /a retry_count=retry_count+1
    set /a retries_remaining=max_retries-retry_count
    echo Retrying... [retries used: !retry_count!, retries remaining: !retries_remaining!]
    set mvn_command=call mvn -rf :%resume_from% %*
    goto retry
  )
del /q %output_file%
endlocal
like image 35
Steve Chambers Avatar answered Oct 05 '22 09:10

Steve Chambers