diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java index c89436dbf28..6eaa5da62fa 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2022 IBM Corporation and others. + * Copyright (c) 2003, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -152,7 +152,11 @@ protected void addListeners() { @Override protected void removeListeners() { - PDECore.getWorkspace().removeResourceChangeListener(this); + IWorkspace workspace = PDECore.getWorkspace(); + if (bundleRootChangedListener != null) { + Arrays.stream(workspace.getRoot().getProjects()).forEach(this::removeBundleRootChangedListener); + } + workspace.removeResourceChangeListener(this); super.removeListeners(); } @@ -198,6 +202,9 @@ public boolean visit(IResourceDelta delta) throws CoreException { if (addedOrOpened && bundleRootChangedListener != null) { addBundleRootChangedListener(project); } + if (delta.getKind() == IResourceDelta.REMOVED && bundleRootChangedListener != null) { + removeBundleRootChangedListener(project); + } if (isInterestingProject(project) && addedOrOpened) { createModel(project, true); return false; @@ -227,6 +234,13 @@ private void addBundleRootChangedListener(IProject project) { pdeNode.addPreferenceChangeListener(bundleRootChangedListener); } + private void removeBundleRootChangedListener(IProject project) { + IEclipsePreferences pdeNode = new ProjectScope(project).getNode(PDECore.PLUGIN_ID); + // Remove the preference change listener when the project is removed + // from the workspace to make it eligible for garbage collection + pdeNode.removePreferenceChangeListener(bundleRootChangedListener); + } + protected IPreferenceChangeListener createBundleRootChangeListener() { return e -> { if (PDEProject.BUNDLE_ROOT_PATH.equals(e.getKey()) && !isInRemovedBranch(e.getNode())) {