Bug 578713 - NullPointerException during: "Performing API Analysis"
Avoid running analysis on *same* project in parallel (may happen if
during the analysis build will be re-triggered again due resource
changes).
The termination of the one job might cause NPE's (or other issues) in
another one, because they use (shared) data from same project builder.
Change-Id: I54e6192941164ce9351a08f9b90a11ad8ecb6bb9
Reviewed-on: https://git.eclipse.org/r/c/pde/eclipse.pde.ui/+/192370
Tested-by: PDE Bot <pde-bot@eclipse.org>
Reviewed-by: Andrey Loskutov <loskutov@gmx.de>
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/ApiAnalysisBuilder.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/ApiAnalysisBuilder.java
index b0a4b23..c877f8f 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/ApiAnalysisBuilder.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/ApiAnalysisBuilder.java
@@ -567,8 +567,9 @@
this.fullBuild = fullBuild;
this.wbaseline = wbaseline;
this.projects = projects;
- // Intentionally no rule set to allow run in parallel with build locking entire workspace
- // setRule(project);
+ // Intentionally not using project as rule to allow run in parallel with build
+ // locking entire workspace
+ setRule(new ApiAnalysisJobRule(project));
}
@Override
@@ -581,7 +582,7 @@
return Status.CANCEL_STATUS;
} else {
if (status.getCode() == IResourceStatus.RESOURCE_NOT_FOUND && project.isAccessible()) {
- waitForLockAndReschedule(monitor, e);
+ waitForBuildAndReschedule(monitor, e);
return Status.OK_STATUS;
} else {
return status;
@@ -592,22 +593,19 @@
}
/**
- * In case the analysis job was interrupted by the build, let wait for the build
- * and start analysis again
+ * In case the analysis job was interrupted by the resource changes, let wait
+ * for the build and start analysis again
*/
- private void waitForLockAndReschedule(IProgressMonitor monitor, CoreException e) {
+ private void waitForBuildAndReschedule(IProgressMonitor monitor, CoreException e) {
try {
- Job.getJobManager().beginRule(project, monitor);
- IStatus s = new Status(IStatus.INFO, ApiAnalysisBuilder.class,
- "Re-scheduling API analysis for " + project.getName(), e); //$NON-NLS-1$
- ApiPlugin.log(s);
- schedule();
- } catch (OperationCanceledException e1) {
+ Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, monitor);
+ } catch (OperationCanceledException | InterruptedException e1) {
// nothing to do
- } finally {
- // release lock, we don't want to block workspace while analysis
- Job.getJobManager().endRule(project);
}
+ IStatus s = new Status(IStatus.INFO, ApiAnalysisBuilder.class,
+ "Re-scheduling API analysis for " + project.getName(), e); //$NON-NLS-1$
+ ApiPlugin.log(s);
+ schedule();
}
@Override
@@ -626,6 +624,30 @@
}
}
+ private static class ApiAnalysisJobRule implements ISchedulingRule {
+
+ private final IProject project;
+
+ public ApiAnalysisJobRule(IProject project) {
+ this.project = project;
+ }
+
+ @Override
+ public boolean contains(ISchedulingRule rule) {
+ return isConflicting(rule);
+ }
+
+ @Override
+ public boolean isConflicting(ISchedulingRule rule) {
+ if (!(rule instanceof ApiAnalysisJobRule)) {
+ return false;
+ }
+ ApiAnalysisJobRule other = (ApiAnalysisJobRule) rule;
+ return project.equals(other.project);
+ }
+
+ }
+
/**
* Returns if the backing project should be fully built, based on the delta
*