Skip to content

Commit b0d7fdb

Browse files
committed
Update the project with an empty classpath container on initialize
Currently there are some cases where an open JavaEditor is not updated, even though the build of the project is fine with that. Strange enough one can make it "work" by simply make some actions slower(!) e.g. setting breakpoints somewhere in the code that initialize classpath containers. The reason is that if initialize happens "too fast" it leads to missing classpath change notification because it looks like the saved to disk state is up-to-date with the new state and no event happens. This now set an empty intermediate container state to the JDT model so that any code arising at this point in time will see something has changed (from n > empty), and if then at any later time an update is performed from empty > n.
1 parent 95e6822 commit b0d7fdb

1 file changed

Lines changed: 36 additions & 1 deletion

File tree

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/RequiredPluginsInitializer.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.eclipse.core.runtime.jobs.Job;
2828
import org.eclipse.jdt.core.ClasspathContainerInitializer;
2929
import org.eclipse.jdt.core.IClasspathContainer;
30+
import org.eclipse.jdt.core.IClasspathEntry;
3031
import org.eclipse.jdt.core.IJavaProject;
3132
import org.eclipse.jdt.core.JavaCore;
3233
import org.eclipse.jdt.core.JavaModelException;
@@ -43,6 +44,30 @@ public class RequiredPluginsInitializer extends ClasspathContainerInitializer {
4344

4445
private static final DeferredClasspathContainerInitializerJob deferredClasspathContainerInitializerJob = new DeferredClasspathContainerInitializerJob();
4546

47+
private static final IClasspathContainer EMPTY_CLASSPATH_CONTAINER = new IClasspathContainer() {
48+
49+
@Override
50+
public IPath getPath() {
51+
return PDECore.REQUIRED_PLUGINS_CONTAINER_PATH;
52+
}
53+
54+
@Override
55+
public int getKind() {
56+
return K_APPLICATION;
57+
}
58+
59+
@Override
60+
public String getDescription() {
61+
return PDECoreMessages.RequiredPluginsClasspathContainer_description;
62+
}
63+
64+
@Override
65+
public IClasspathEntry[] getClasspathEntries() {
66+
// nothing yet, will be updated soon
67+
return new IClasspathEntry[0];
68+
}
69+
};
70+
4671
private static class DeferredClasspathContainerInitializerJob extends Job {
4772

4873
private final Set<IJavaProject> projects = new LinkedHashSet<>();
@@ -86,10 +111,20 @@ public boolean belongsTo(Object family) {
86111
@Override
87112
public void initialize(IPath containerPath, IJavaProject javaProject) throws CoreException {
88113
if (Job.getJobManager().isSuspended()) {
89-
// if the jobmanager is currently suspended we can't use the
114+
// If the jobmanager is currently suspended we can't use the
90115
// schedule/join pattern here, instead we must retry the requested
91116
// action once jobs are enabled again, this will the possibly
92117
// trigger a rebuild if required or notify other listeners.
118+
//
119+
// Second as JDT is caching the container state, it might happens
120+
// that the final results are the same and if PDE is too fast, it
121+
// then happens that there is no delta event send to the model
122+
// listeners leading to odd results.
123+
// We explicitly set an empty classpath container here, so JDT will
124+
// always see a delta when we later update the container to its
125+
// final entries.
126+
JavaCore.setClasspathContainer(PDECore.REQUIRED_PLUGINS_CONTAINER_PATH, new IJavaProject[] { javaProject },
127+
new IClasspathContainer[] { EMPTY_CLASSPATH_CONTAINER }, null);
93128
deferredClasspathContainerInitializerJob.initialize(javaProject);
94129
} else {
95130
setupClasspath(javaProject);

0 commit comments

Comments
 (0)