如何让 Maven 自动重试(从失败的模块中恢复)?
How to make Maven automatically retry (resume from failed module)?
我正在处理一个由许多不同模块组成的大型 Maven 项目。 Maven 构建在某些模块上间歇性地失败,但如果一切顺利,一个简单的手动调用 --resume-from
(有时在几个不同的模块上)将允许它继续成功。
我故意省略了发生这种情况的确切原因的详细信息 - 怀疑这可能是由于 Windows 文件锁定目标文件夹中的文件 - 但这不是问题的重点。
问题:是否可以让 Maven 自动重试(可能只是一次,也可能最多 3 次),从失败的模块恢复?
想法: 我目前能想到的唯一方法是通过批处理文件,它读取最后一行并以某种方式提取模块名称以从中恢复 - 但是看起来并不容易。不想重新发明轮子,想知道是否有一个不错的 Maven 插件已经可以完成这项工作?
我有一个想法可以解决您的问题,也许您不需要批处理文件来完成这项工作。您可以创建一个 Maven 核心扩展并创建一个 EventSpy 库以在构建失败时执行 --resume-from。
我已经测试了这个答案 Run a maven plugin when build fails
中的这个例子
根据这个答案,您可以使用 Maven Invoker Maven Invoker
还...我找到了安全并行构建的扩展 Maven Core Extensions Example for Safe Parallel Builds
我知道您需要项目信息...所以查看 ExecutionEvent and MavenProject class 内部,我们拥有有关当前建筑项目的所有信息。
我希望它也对你有用。
编辑:
我正在寻找一些在某些模块失败时实现此行为的扩展 "automatically retry"。如果我没有找到任何东西,我们应该创建一个扩展。
我相信使用批处理脚本实现这一点看起来很容易。希望下面的脚本适合你。
@echo off
setlocal enabledelayedexpansion
for /f "tokens=2 delims=:" %%i in ('call mvn clean install ^| find "mvn <goals> -rf"') do (
call mvn clean install -e -rf : %%i
)
endlocal
后悔没测试
下面是一个完整的批处理文件,使用 作为起点。
使用说明:
- 确保 Maven 可执行文件位于 Windows path.
- 最好还要确保 Windows 的 tee 版本在 Windows 路径中。 (例如,我正在使用作为 Git for Windows 的一部分提供的文件夹,已将 Git 的
usr\bin
文件夹添加到我的路径中)。
- 将批处理文件代码复制到新文件中。
- 根据需要更改
max_retries
值。
- 在 Windows 路径的文件夹中另存为 "mvnretry.bat"。
- 运行 与 Maven 相同,例如
mvnretry clean install -Pmyprofile -DskipTests
.
批处理文件代码:
@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
我正在处理一个由许多不同模块组成的大型 Maven 项目。 Maven 构建在某些模块上间歇性地失败,但如果一切顺利,一个简单的手动调用 --resume-from
(有时在几个不同的模块上)将允许它继续成功。
我故意省略了发生这种情况的确切原因的详细信息 - 怀疑这可能是由于 Windows 文件锁定目标文件夹中的文件 - 但这不是问题的重点。
问题:是否可以让 Maven 自动重试(可能只是一次,也可能最多 3 次),从失败的模块恢复?
想法: 我目前能想到的唯一方法是通过批处理文件,它读取最后一行并以某种方式提取模块名称以从中恢复 - 但是看起来并不容易。不想重新发明轮子,想知道是否有一个不错的 Maven 插件已经可以完成这项工作?
我有一个想法可以解决您的问题,也许您不需要批处理文件来完成这项工作。您可以创建一个 Maven 核心扩展并创建一个 EventSpy 库以在构建失败时执行 --resume-from。 我已经测试了这个答案 Run a maven plugin when build fails
中的这个例子根据这个答案,您可以使用 Maven Invoker Maven Invoker
还...我找到了安全并行构建的扩展 Maven Core Extensions Example for Safe Parallel Builds
我知道您需要项目信息...所以查看 ExecutionEvent and MavenProject class 内部,我们拥有有关当前建筑项目的所有信息。
我希望它也对你有用。
编辑:
我正在寻找一些在某些模块失败时实现此行为的扩展 "automatically retry"。如果我没有找到任何东西,我们应该创建一个扩展。
我相信使用批处理脚本实现这一点看起来很容易。希望下面的脚本适合你。
@echo off
setlocal enabledelayedexpansion
for /f "tokens=2 delims=:" %%i in ('call mvn clean install ^| find "mvn <goals> -rf"') do (
call mvn clean install -e -rf : %%i
)
endlocal
后悔没测试
下面是一个完整的批处理文件,使用
使用说明:
- 确保 Maven 可执行文件位于 Windows path.
- 最好还要确保 Windows 的 tee 版本在 Windows 路径中。 (例如,我正在使用作为 Git for Windows 的一部分提供的文件夹,已将 Git 的
usr\bin
文件夹添加到我的路径中)。 - 将批处理文件代码复制到新文件中。
- 根据需要更改
max_retries
值。 - 在 Windows 路径的文件夹中另存为 "mvnretry.bat"。
- 运行 与 Maven 相同,例如
mvnretry clean install -Pmyprofile -DskipTests
.
批处理文件代码:
@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