From 454c24e7d0480542d9c88fcc4ded15d7116688d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Mon, 12 Aug 2024 15:09:40 +0200 Subject: [PATCH] Use a Workspace Job to perform API analysis We sometimes see "disposed" components from the workspace Baseline e.g. https://github.com/eclipse-pde/eclipse.pde/issues/1310 what seem to indicate that some operation interfere here. This wraps the execution of the Api Analysis part in a workspace job to ensure these actions are delayed until we are done with the baseline. --- .../eclipse/tycho/apitools/ApiAnalysis.java | 68 ++++++++++++------- 1 file changed, 45 insertions(+), 23 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 2471295c32..0106ca9bab 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 @@ -40,10 +40,14 @@ import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceDescription; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.IJobChangeListener; import org.eclipse.core.runtime.jobs.IJobManager; @@ -158,33 +162,51 @@ public void aboutToRun(IJobChangeEvent event) { deleteAllProjects(); IPath projectPath = IPath.fromOSString(projectDir); IProject project = getProject(projectPath); - BundleComponent projectComponent = getApiComponent(project, projectPath); - IApiBaseline baseline = createBaseline(baselineBundles, baselineName + " - baseline"); - ResolverError[] resolverErrors = projectComponent.getErrors(); ApiAnalysisResult result = new ApiAnalysisResult(getVersion()); - if (resolverErrors != null && resolverErrors.length > 0) { - for (ResolverError error : resolverErrors) { - result.addResolverError(error); - } - } - IApiFilterStore filterStore = getApiFilterStore(projectComponent); - Properties preferences = getPreferences(); - BaseApiAnalyzer analyzer = new BaseApiAnalyzer(); - try { - analyzer.setContinueOnResolverError(true); - analyzer.analyzeComponent(null, filterStore, preferences, baseline, projectComponent, new BuildContext(), - new NullProgressMonitor()); - IApiProblem[] problems = analyzer.getProblems(); - for (IApiProblem problem : problems) { - result.addProblem(problem, project); - debug(String.valueOf(problem)); + WorkspaceJob job = new WorkspaceJob("Tycho API Analysis") { + + @Override + public IStatus runInWorkspace(IProgressMonitor monitor) { + try { + BundleComponent projectComponent = getApiComponent(project, projectPath); + IApiBaseline baseline = createBaseline(baselineBundles, baselineName + " - baseline"); + ResolverError[] resolverErrors = projectComponent.getErrors(); + if (resolverErrors != null && resolverErrors.length > 0) { + for (ResolverError error : resolverErrors) { + result.addResolverError(error); + } + } + IApiFilterStore filterStore = getApiFilterStore(projectComponent); + Properties preferences = getPreferences(); + BaseApiAnalyzer analyzer = new BaseApiAnalyzer(); + try { + analyzer.setContinueOnResolverError(true); + analyzer.analyzeComponent(null, filterStore, preferences, baseline, projectComponent, + new BuildContext(), new NullProgressMonitor()); + IApiProblem[] problems = analyzer.getProblems(); + for (IApiProblem problem : problems) { + result.addProblem(problem, project); + debug(String.valueOf(problem)); + } + } finally { + analyzer.dispose(); + ResourcesPlugin.getWorkspace().save(true, new NullProgressMonitor()); + } + } catch (Exception e) { + return Status.error("Api Analysis failed", e); + } + return Status.OK_STATUS; } - } finally { - analyzer.dispose(); - ResourcesPlugin.getWorkspace().save(true, new NullProgressMonitor()); - } + }; + job.setRule(ResourcesPlugin.getWorkspace().getRoot()); + job.schedule(); + job.join(); + IStatus status = job.getResult(); 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; }