From 3172e5682ae1958ea219ffc504494c630cc9fdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Fri, 27 Dec 2024 08:16:22 +0100 Subject: [PATCH] Add retry to API Analysis Mojo Currently it can happen that due to concurrent run jobs the workspace the API analysis fails with a component disposed error. Rerun the whole build often fix the problem. This now adds a maximum of five retries to allow the analysis to complete. --- .../eclipse/tycho/apitools/ApiAnalysis.java | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/tycho-apitools-plugin/src/main/java/org/eclipse/tycho/apitools/ApiAnalysis.java b/tycho-apitools-plugin/src/main/java/org/eclipse/tycho/apitools/ApiAnalysis.java index c9136d6e16..e414d66098 100644 --- a/tycho-apitools-plugin/src/main/java/org/eclipse/tycho/apitools/ApiAnalysis.java +++ b/tycho-apitools-plugin/src/main/java/org/eclipse/tycho/apitools/ApiAnalysis.java @@ -31,6 +31,8 @@ import java.util.Objects; import java.util.Properties; import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IFolder; @@ -94,6 +96,9 @@ */ public class ApiAnalysis implements Serializable, Callable { + private static final Pattern COMPONENT_DISPOSED_ERROR = Pattern + .compile("Component '(.+)' in the baseline '(.+)' is disposed"); + private Collection baselineBundles; private Collection targetBundles; private String baselineName; @@ -164,7 +169,36 @@ public void aboutToRun(IJobChangeEvent event) { deleteAllProjects(); IPath projectPath = IPath.fromOSString(projectDir); IProject project = getProject(projectPath); - ApiAnalysisResult result = new ApiAnalysisResult(getVersion()); + RuntimeException exception = new RuntimeException("Can't get API result due to API application error"); + String version = getVersion(); + for (int i = 0; i < 5; i++) { + ApiAnalysisResult result = new ApiAnalysisResult(version); + IStatus status = runAnalysis(projectPath, project, result); + if (!status.isOK() && status.getException() instanceof Exception error) { + if (isRecoverable(error)) { + exception.addSuppressed(error); + TimeUnit.SECONDS.sleep(10); + continue; + } + throw error; + } + return result; + } + throw exception; + } + + private boolean isRecoverable(Exception error) { + if (error instanceof CoreException) { + String message = error.getMessage(); + if (message != null) { + return COMPONENT_DISPOSED_ERROR.matcher(message).matches(); + } + } + return false; + } + + private IStatus runAnalysis(IPath projectPath, IProject project, ApiAnalysisResult result) + throws InterruptedException { IStatus status; if (runAsJob) { WorkspaceJob job = new WorkspaceJob("Tycho API Analysis") { @@ -184,10 +218,7 @@ public IStatus runInWorkspace(IProgressMonitor monitor) { } JRTUtil.reset(); // reclaim space due to loaded multiple JRTUtil should better be fixed to not // use that much space - if (!status.isOK() && status.getException() instanceof Exception error) { - throw error; - } - return result; + return status; } private IStatus performAPIAnalysis(IProject project, IPath projectPath, ApiAnalysisResult result) {