如何让 Maven 自动重试(从失败的模块恢复)?

Posted

技术标签:

【中文标题】如何让 Maven 自动重试(从失败的模块恢复)?【英文标题】:How to make Maven automatically retry (resume from failed module)? 【发布时间】:2019-06-15 18:06:34 【问题描述】:

我正在处理一个由许多不同模块组成的大型 Maven 项目。 Maven 构建在某些模块上间歇性地失败,但如果一切正常,一个简单的手动调用 --resume-from(有时在几个不同的模块上)将允许它继续成功。

我故意省略了发生这种情况的确切原因 - 怀疑这可能是由于 Windows 文件锁定了目标文件夹中的文件 - 但这不是问题的重点。

问题:是否可以让 Maven 从失败的模块中自动重试(可能只重试一次,或者最多 3 次)?

想法:我目前能想到的唯一方法是通过批处理文件,该文件读取最后一行并以某种方式提取要从中恢复的模块名称 - 但这看起来并不容易.不想重新发明***,想知道是否有一个很好的 Maven 插件已经可以完成这项工作?

【问题讨论】:

使用 Maven 4.0.0(2021 年第一季度)应该会更容易:请参阅 my answer here 【参考方案1】:

我有一个想法可以解决您的问题,也许您不需要批处理文件来完成这项工作。您可以创建一个 Maven 核心扩展并创建一个 EventSpy 库以在构建失败时执行 --resume-from。 我已经测试了这个答案中找到的这个例子Run a maven plugin when build fails

根据这个答案,您可以使用 Maven Invoker Maven Invoker

然而...我找到了安全并行构建的扩展Maven Core Extensions Example for Safe Parallel Builds

我知道您需要项目信息...所以查看ExecutionEvent 和MavenProject 类的内部,我们可以获得有关当前建筑项目的所有信息。

我希望它也对你有用。

编辑:

我正在寻找一些扩展,当某些模块出现故障时,它会“自动重试”这种行为。如果我没有找到任何东西,我们应该为此创建一个扩展。

【讨论】:

【参考方案2】:

下面是一个完整的批处理文件,以Anitha.R's answer 为起点。

使用说明:

    确保 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

【讨论】:

【参考方案3】:

我相信使用批处理脚本来实现这一点看起来很容易。希望下面的脚本对你有用。

@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

很遗憾我没有测试它。

【讨论】:

这可能需要一些调整,但对我来说它看起来像是阻力最小的路径。 (如果我能让它可靠地工作并且可能包括重试等,我将来可能会发布我自己的答案。) 更新: 此处编写的代码对我不起作用,但提供了一个很好的起点。现在已经发布了带有修改版本的answer。

以上是关于如何让 Maven 自动重试(从失败的模块恢复)?的主要内容,如果未能解决你的问题,请参考以下文章

JPA 事务回滚重试和恢复:将实体与自动递增的@Version 合并

如何在断路器中添加重试和自定义恢复方法 - 功能性 java

自动化测试的一些思考

从 HTTP 下载大文件并在 .NET 中支持恢复/重试?

如何从 Nim 的导入失败中恢复?

从gRPC的重试策略说起