View | Details | Raw Unified | Return to bug 241751
Collapse All | Expand All

(-)model/org/eclipse/jdt/core/package.html (-1 / +9 lines)
Lines 13-19 Link Here
13
Package Specification</h2>
13
Package Specification</h2>
14
14
15
<p><br>This package contains the Java model classes, which implement Java
15
<p><br>This package contains the Java model classes, which implement Java
16
specific behaviour for resources and further decompose java resources into
16
specific behaviour for resources and further decompose Java resources into
17
model elements.
17
model elements.
18
</p><p>
19
Note that a lot of Java model operations require a Java project's classpath resolution.
20
For example IJavaProject#getResolvedClasspath(boolean) or JavaCore#setClasspathContainer()
21
will require to resolve the classpath of one or more projects. Client should be aware that
22
this resolution may require to take project modification rule 
23
(see IResourceRuleFactory#modifyRule(IResource)).
24
</p>
25
18
</body>
26
</body>
19
</html>
27
</html>
(-)model/org/eclipse/jdt/internal/core/DeltaProcessor.java (+5 lines)
Lines 1963-1968 Link Here
1963
				return;
1963
				return;
1964
1964
1965
			case IResourceChangeEvent.PRE_BUILD :
1965
			case IResourceChangeEvent.PRE_BUILD :
1966
				// force initialization of roots before builders run to avoid deadlock in another thread
1967
				// (note this is no-op if already initialized)
1968
				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=241751
1969
				this.state.initializeRoots(false/*not initiAfterLoad*/);
1970
				
1966
				boolean isAffected = isAffectedBy(delta);
1971
				boolean isAffected = isAffectedBy(delta);
1967
				boolean needCycleValidation = isAffected && validateClasspaths(delta);
1972
				boolean needCycleValidation = isAffected && validateClasspaths(delta);
1968
1973
(-)model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java (-55 / +58 lines)
Lines 41-109 Link Here
41
	 * Update projects references so that the build order is consistent with the classpath
41
	 * Update projects references so that the build order is consistent with the classpath
42
	 */
42
	 */
43
	public void updateProjectReferencesIfNecessary() throws JavaModelException {
43
	public void updateProjectReferencesIfNecessary() throws JavaModelException {
44
44
		
45
		final String[] oldRequired = this.oldResolvedClasspath == null ? CharOperation.NO_STRINGS : this.project.projectPrerequisites(this.oldResolvedClasspath);
45
		String[] oldRequired = this.oldResolvedClasspath == null ? CharOperation.NO_STRINGS : this.project.projectPrerequisites(this.oldResolvedClasspath);
46
		IClasspathEntry[] newResolvedClasspath = this.project.getResolvedClasspath();
46
		IClasspathEntry[] newResolvedClasspath = this.project.getResolvedClasspath();
47
		final String[] newRequired = this.project.projectPrerequisites(newResolvedClasspath);
47
		String[] newRequired = this.project.projectPrerequisites(newResolvedClasspath);
48
		final IProject projectResource = this.project.getProject();
48
		final IProject projectResource = this.project.getProject();
49
		IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
49
		
50
			public void run(IProgressMonitor monitor) throws CoreException {
50
		try {
51
				IProjectDescription description = projectResource.getDescription();
51
			IProject[] projectReferences = projectResource.getDescription().getDynamicReferences();
52
52
			
53
				IProject[] projectReferences = description.getDynamicReferences();
53
			HashSet oldReferences = new HashSet(projectReferences.length);
54
54
			for (int i = 0; i < projectReferences.length; i++){
55
				HashSet oldReferences = new HashSet(projectReferences.length);
55
				String projectName = projectReferences[i].getName();
56
				for (int i = 0; i < projectReferences.length; i++){
56
				oldReferences.add(projectName);
57
					String projectName = projectReferences[i].getName();
57
			}
58
					oldReferences.add(projectName);
58
			HashSet newReferences = (HashSet)oldReferences.clone();
59
				}
59
	
60
				HashSet newReferences = (HashSet)oldReferences.clone();
60
			for (int i = 0; i < oldRequired.length; i++){
61
61
				String projectName = oldRequired[i];
62
				for (int i = 0; i < oldRequired.length; i++){
62
				newReferences.remove(projectName);
63
					String projectName = oldRequired[i];
63
			}
64
					newReferences.remove(projectName);
64
			for (int i = 0; i < newRequired.length; i++){
65
				}
65
				String projectName = newRequired[i];
66
				for (int i = 0; i < newRequired.length; i++){
66
				newReferences.add(projectName);
67
					String projectName = newRequired[i];
67
			}
68
					newReferences.add(projectName);
68
	
69
				}
69
			Iterator iter;
70
70
			int newSize = newReferences.size();
71
				Iterator iter;
71
			
72
				int newSize = newReferences.size();
72
			checkIdentity: {
73
73
				if (oldReferences.size() == newSize){
74
				checkIdentity: {
74
					iter = newReferences.iterator();
75
					if (oldReferences.size() == newSize){
75
					while (iter.hasNext()){
76
						iter = newReferences.iterator();
76
						if (!oldReferences.contains(iter.next())){
77
						while (iter.hasNext()){
77
							break checkIdentity;
78
							if (!oldReferences.contains(iter.next())){
79
								break checkIdentity;
80
							}
81
						}
78
						}
82
						return;
83
					}
79
					}
80
					return;
84
				}
81
				}
85
				String[] requiredProjectNames = new String[newSize];
86
				int index = 0;
87
				iter = newReferences.iterator();
88
				while (iter.hasNext()){
89
					requiredProjectNames[index++] = (String)iter.next();
90
				}
91
				Util.sort(requiredProjectNames); // ensure that if changed, the order is consistent
92
93
				IProject[] requiredProjectArray = new IProject[newSize];
94
				IWorkspaceRoot wksRoot = projectResource.getWorkspace().getRoot();
95
				for (int i = 0; i < newSize; i++){
96
					requiredProjectArray[i] = wksRoot.getProject(requiredProjectNames[i]);
97
				}
98
				description.setDynamicReferences(requiredProjectArray);
99
				projectResource.setDescription(description, IResource.AVOID_NATURE_CONFIG, null);
100
			}
82
			}
101
		};
83
			String[] requiredProjectNames = new String[newSize];
102
		try {
84
			int index = 0;
103
			// ensure that a sheduling rule is used so that the project description is not modified by another thread while we update it
85
			iter = newReferences.iterator();
86
			while (iter.hasNext()){
87
				requiredProjectNames[index++] = (String)iter.next();
88
			}
89
			Util.sort(requiredProjectNames); // ensure that if changed, the order is consistent
90
			
91
			final IProject[] requiredProjectArray = new IProject[newSize];
92
			IWorkspaceRoot wksRoot = projectResource.getWorkspace().getRoot();
93
			for (int i = 0; i < newSize; i++){
94
				requiredProjectArray[i] = wksRoot.getProject(requiredProjectNames[i]);
95
			}
96
				
97
			// ensure that a scheduling rule is used so that the project description is not modified by another thread while we update it
104
			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=214981
98
			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=214981
99
			// also ensure that if no change (checkIdentify block returned above) we don't reach here
100
			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=241751
105
			IWorkspace workspace = projectResource.getWorkspace();
101
			IWorkspace workspace = projectResource.getWorkspace();
106
			ISchedulingRule rule = workspace.getRuleFactory().modifyRule(projectResource); // sheduling rule for modifying the project
102
			ISchedulingRule rule = workspace.getRuleFactory().modifyRule(projectResource); // scheduling rule for modifying the project
103
			IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
104
				public void run(IProgressMonitor monitor) throws CoreException {
105
					IProjectDescription description = projectResource.getDescription();
106
					description.setDynamicReferences(requiredProjectArray);
107
					projectResource.setDescription(description, IResource.AVOID_NATURE_CONFIG, null);
108
				}
109
			};
107
			workspace.run(runnable, rule, IWorkspace.AVOID_UPDATE, null);
110
			workspace.run(runnable, rule, IWorkspace.AVOID_UPDATE, null);
108
		} catch(CoreException e){
111
		} catch(CoreException e){
109
			if (!ExternalJavaProject.EXTERNAL_PROJECT_NAME.equals(this.project.getElementName()))
112
			if (!ExternalJavaProject.EXTERNAL_PROJECT_NAME.equals(this.project.getElementName()))

Return to bug 241751