From 497a041f75836907c98d130396f8fdea2dd7f38e Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Fri, 21 Aug 2026 16:42:30 +0200 Subject: [PATCH] ClasspathUpdater: PDE ClasspathComputer works fine in 2026-06 All the bugs in PDE ClasspathComputer we have previously worked around are solved, seen in Eclipse 2026-06. Beyond that, our workaround breaks when classpath entries have additional attributes. Better drop any workaround, but use the PDE ClasspathComputer, and require org.eclipse.pde.core version as of Eclipse 2026-06. This also removes the (unused) ClasspathUpdater.setSourcePaths() API. --- .../META-INF/MANIFEST.MF | 2 +- .../library/build/util/ClasspathUpdater.java | 105 +----------------- 2 files changed, 2 insertions(+), 105 deletions(-) diff --git a/bundles/org.eclipse.tea.library.build/META-INF/MANIFEST.MF b/bundles/org.eclipse.tea.library.build/META-INF/MANIFEST.MF index 1ea77af..97bb534 100644 --- a/bundles/org.eclipse.tea.library.build/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.tea.library.build/META-INF/MANIFEST.MF @@ -14,7 +14,7 @@ Require-Bundle: org.eclipse.core.resources;bundle-version="3.21.0", org.eclipse.tea.core, org.eclipse.ui.workbench;bundle-version="3.133.0", org.eclipse.e4.core.di.extensions;bundle-version="0.18.300", - org.eclipse.pde.core;bundle-version="3.19.0", + org.eclipse.pde.core;bundle-version="3.21.300", org.eclipse.e4.core.contexts;bundle-version="1.12.600", org.eclipse.tea.core.ui, org.eclipse.e4.core.di;bundle-version="1.9.500", diff --git a/bundles/org.eclipse.tea.library.build/src/org/eclipse/tea/library/build/util/ClasspathUpdater.java b/bundles/org.eclipse.tea.library.build/src/org/eclipse/tea/library/build/util/ClasspathUpdater.java index ca76ab2..556c55f 100644 --- a/bundles/org.eclipse.tea.library.build/src/org/eclipse/tea/library/build/util/ClasspathUpdater.java +++ b/bundles/org.eclipse.tea.library.build/src/org/eclipse/tea/library/build/util/ClasspathUpdater.java @@ -11,26 +11,16 @@ package org.eclipse.tea.library.build.util; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Objects; import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.jdt.core.IClasspathEntry; -import org.eclipse.jdt.core.IPackageFragmentRoot; -import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.pde.core.plugin.IPluginModelBase; import org.eclipse.pde.core.plugin.PluginRegistry; import org.eclipse.pde.internal.core.ClasspathComputer; -import org.eclipse.pde.internal.core.PDECore; import org.eclipse.tea.core.services.TaskingLog; import org.eclipse.tea.library.build.model.PluginData; import org.eclipse.tea.library.build.model.WorkspaceData; @@ -43,7 +33,6 @@ public class ClasspathUpdater { private final WorkspaceData wsData; private Predicate predicate; - private Map sourcePaths = new HashMap<>(); /** * Creates the updater on top of a {@link WorkspaceData} instance. @@ -59,14 +48,6 @@ public void setPredicate(Predicate predicate) { this.predicate = predicate; } - /** - * @param sourcePaths - * a map from plugin name to source path. - */ - public void setSourcePaths(Map sourcePaths) { - this.sourcePaths = sourcePaths != null ? sourcePaths : new HashMap<>(); - } - public void update(TaskingLog console, IProgressMonitor monitor) { console.info("running class-path update"); SubMonitor mon = SubMonitor.convert(monitor, 100); @@ -95,84 +76,8 @@ public void update(TaskingLog console, IProgressMonitor monitor) { continue; } - // PDE may fail to update the classpath based on the original, - // see https://github.com/eclipse-pde/eclipse.pde/pull/497 - // But calculating from scratch drops existing attributes and - // destroys the existing order. - // Workaround here merges fresh classpath with the original one. - IClasspathEntry[] origCP = JavaCore.create(project).getRawClasspath(); - IClasspathEntry[] freshCP = ClasspathComputer.getClasspath(project, model, null, true, true); + ClasspathComputer.setClasspath(project, model); - // remove trailing slash from source path if any: - for (int i = 0; i < freshCP.length; i++) { - IClasspathEntry old = freshCP[i]; - if (old.getEntryKind() == IClasspathEntry.CPE_SOURCE) { - IPath path = old.getPath().removeTrailingSeparator(); - freshCP[i] = JavaCore.newSourceEntry(path, old.getInclusionPatterns(), - old.getExclusionPatterns(), old.getOutputLocation(), old.getExtraAttributes()); - } - } - - Map collectedCPofPath = Stream.concat(Stream.of(freshCP), Stream.of(origCP)) - .collect(Collectors.toMap(e -> keyOf(e), e -> e, (first, dupe) -> first)); - - List mergedCP = new ArrayList<>(); - for (final IClasspathEntry orig : origCP) { - final IClasspathEntry collect = collectedCPofPath.remove(keyOf(orig)); - if (collect == null) { - continue; // dupe in the original already - } - IClasspathEntry merged = collect; - switch (collect.getEntryKind()) { - case IClasspathEntry.CPE_LIBRARY: - if (collect.getContentKind() == IPackageFragmentRoot.K_BINARY) { - IPath source = sourcePaths.get(collect.getPath().lastSegment()); // override - source = source != null ? source : orig.getSourceAttachmentPath(); // current - source = source != null ? source : collect.getSourceAttachmentPath(); // default - if (!collect.equals(orig) || !Objects.equals(collect.getSourceAttachmentPath(), source)) { - merged = JavaCore.newLibraryEntry(collect.getPath(), source, null, - orig.getAccessRules(), orig.getExtraAttributes(), orig.isExported()); - } - } - break; - case IClasspathEntry.CPE_SOURCE: - merged = orig; - break; - case IClasspathEntry.CPE_CONTAINER: - if (!collect.equals(orig)) { - merged = JavaCore.newContainerEntry(collect.getPath(), orig.getAccessRules(), - orig.getExtraAttributes(), orig.isExported()); - } - break; - case IClasspathEntry.CPE_PROJECT: - if (!collect.equals(orig)) { - merged = JavaCore.newProjectEntry(collect.getPath(), orig.getAccessRules(), - orig.combineAccessRules(), orig.getExtraAttributes(), orig.isExported()); - } - break; - case IClasspathEntry.CPE_VARIABLE: - merged = orig; - break; - } - mergedCP.add(merged); - } - - for (IClasspathEntry fresh : freshCP) { - if (collectedCPofPath.remove(keyOf(fresh)) == null) { - continue; // not a new one - } - if (fresh.getEntryKind() == IClasspathEntry.CPE_LIBRARY - && fresh.getContentKind() == IPackageFragmentRoot.K_BINARY) { - IPath source = sourcePaths.get(fresh.getPath().lastSegment()); - if (source != null && !source.equals(fresh.getSourceAttachmentPath())) { - fresh = JavaCore.newLibraryEntry(fresh.getPath(), source, null, fresh.getAccessRules(), - fresh.getExtraAttributes(), fresh.isExported()); - } - } - mergedCP.add(fresh); - } - - JavaCore.create(project).setRawClasspath(mergedCP.toArray(new IClasspathEntry[mergedCP.size()]), null); refreshList.add(pd); } catch (Exception ex) { console.error("skipped classpath update for " + bundleName + " because of: " + ex); @@ -191,12 +96,4 @@ public void update(TaskingLog console, IProgressMonitor monitor) { monitor.done(); } } - - private static IPath keyOf(IClasspathEntry entry) { - if (PDECore.JRE_CONTAINER_PATH.isPrefixOf(entry.getPath())) { - return PDECore.JRE_CONTAINER_PATH; // entry path contains properties - } - return entry.getPath(); - } - }