### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java,v retrieving revision 1.3 diff -u -r1.3 ProjectReferenceChange.java --- model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java 6 Mar 2007 02:38:49 -0000 1.3 +++ model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java 11 Jan 2008 11:32:28 -0000 @@ -15,8 +15,12 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.compiler.CharOperation; @@ -37,61 +41,69 @@ */ public void updateProjectReferencesIfNecessary() throws JavaModelException { - String[] oldRequired = this.oldResolvedClasspath == null ? CharOperation.NO_STRINGS : this.project.projectPrerequisites(this.oldResolvedClasspath); + final String[] oldRequired = this.oldResolvedClasspath == null ? CharOperation.NO_STRINGS : this.project.projectPrerequisites(this.oldResolvedClasspath); IClasspathEntry[] newResolvedClasspath = this.project.getResolvedClasspath(); - String[] newRequired = this.project.projectPrerequisites(newResolvedClasspath); - try { - IProject projectResource = this.project.getProject(); - IProjectDescription description = projectResource.getDescription(); - - IProject[] projectReferences = description.getDynamicReferences(); - - HashSet oldReferences = new HashSet(projectReferences.length); - for (int i = 0; i < projectReferences.length; i++){ - String projectName = projectReferences[i].getName(); - oldReferences.add(projectName); - } - HashSet newReferences = (HashSet)oldReferences.clone(); - - for (int i = 0; i < oldRequired.length; i++){ - String projectName = oldRequired[i]; - newReferences.remove(projectName); - } - for (int i = 0; i < newRequired.length; i++){ - String projectName = newRequired[i]; - newReferences.add(projectName); - } - - Iterator iter; - int newSize = newReferences.size(); - - checkIdentity: { - if (oldReferences.size() == newSize){ - iter = newReferences.iterator(); - while (iter.hasNext()){ - if (!oldReferences.contains(iter.next())){ - break checkIdentity; + final String[] newRequired = this.project.projectPrerequisites(newResolvedClasspath); + final IProject projectResource = this.project.getProject(); + IWorkspaceRunnable runnable = new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + IProjectDescription description = projectResource.getDescription(); + + IProject[] projectReferences = description.getDynamicReferences(); + + HashSet oldReferences = new HashSet(projectReferences.length); + for (int i = 0; i < projectReferences.length; i++){ + String projectName = projectReferences[i].getName(); + oldReferences.add(projectName); + } + HashSet newReferences = (HashSet)oldReferences.clone(); + + for (int i = 0; i < oldRequired.length; i++){ + String projectName = oldRequired[i]; + newReferences.remove(projectName); + } + for (int i = 0; i < newRequired.length; i++){ + String projectName = newRequired[i]; + newReferences.add(projectName); + } + + Iterator iter; + int newSize = newReferences.size(); + + checkIdentity: { + if (oldReferences.size() == newSize){ + iter = newReferences.iterator(); + while (iter.hasNext()){ + if (!oldReferences.contains(iter.next())){ + break checkIdentity; + } } + return; } - return; } + String[] requiredProjectNames = new String[newSize]; + int index = 0; + iter = newReferences.iterator(); + while (iter.hasNext()){ + requiredProjectNames[index++] = (String)iter.next(); + } + Util.sort(requiredProjectNames); // ensure that if changed, the order is consistent + + IProject[] requiredProjectArray = new IProject[newSize]; + IWorkspaceRoot wksRoot = projectResource.getWorkspace().getRoot(); + for (int i = 0; i < newSize; i++){ + requiredProjectArray[i] = wksRoot.getProject(requiredProjectNames[i]); + } + description.setDynamicReferences(requiredProjectArray); + projectResource.setDescription(description, null); } - String[] requiredProjectNames = new String[newSize]; - int index = 0; - iter = newReferences.iterator(); - while (iter.hasNext()){ - requiredProjectNames[index++] = (String)iter.next(); - } - Util.sort(requiredProjectNames); // ensure that if changed, the order is consistent - - IProject[] requiredProjectArray = new IProject[newSize]; - IWorkspaceRoot wksRoot = projectResource.getWorkspace().getRoot(); - for (int i = 0; i < newSize; i++){ - requiredProjectArray[i] = wksRoot.getProject(requiredProjectNames[i]); - } - description.setDynamicReferences(requiredProjectArray); - projectResource.setDescription(description, null); - + }; + try { + // ensure that a sheduling rule is used so that the project description is not modified by another thread while we update it + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=214981 + IWorkspace workspace = projectResource.getWorkspace(); + ISchedulingRule rule = workspace.getRuleFactory().modifyRule(projectResource); // sheduling rule for modifying the project + workspace.run(runnable, rule, IWorkspace.AVOID_UPDATE, null); } catch(CoreException e){ if (!ExternalJavaProject.EXTERNAL_PROJECT_NAME.equals(this.project.getElementName())) throw new JavaModelException(e);