From 4a26ed7da558632c694567122fcb509f5903ff3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Thu, 31 Mar 2022 10:46:58 +0200 Subject: [PATCH] Fix #822 - If multiple fragments match a bundle all items are added to the classpath while only the one with the highest version should match --- .../p2/resolver/P2ResolverFactoryImpl.java | 29 ++++++++++-- .../bundle1/META-INF/MANIFEST.MF | 7 +++ .../bundle1/build.properties | 4 ++ .../bundle1/pom.xml | 14 ++++++ .../resolver.multipleDownloads/pom.xml | 46 +++++++++++++++++++ .../sdk_4.21.target | 10 ++++ .../sdk_4.22.target | 10 ++++ .../sdk_4.23.target | 10 ++++ .../resolver.multipleDownloads/test.target | 9 ++++ .../tycho/test/resolver/ResolverTests.java | 45 ++++++++++++++++++ 10 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 tycho-its/projects/resolver.multipleDownloads/bundle1/META-INF/MANIFEST.MF create mode 100644 tycho-its/projects/resolver.multipleDownloads/bundle1/build.properties create mode 100644 tycho-its/projects/resolver.multipleDownloads/bundle1/pom.xml create mode 100644 tycho-its/projects/resolver.multipleDownloads/pom.xml create mode 100644 tycho-its/projects/resolver.multipleDownloads/sdk_4.21.target create mode 100644 tycho-its/projects/resolver.multipleDownloads/sdk_4.22.target create mode 100644 tycho-its/projects/resolver.multipleDownloads/sdk_4.23.target create mode 100644 tycho-its/projects/resolver.multipleDownloads/test.target diff --git a/tycho-bundles/org.eclipse.tycho.p2.resolver.impl/src/main/java/org/eclipse/tycho/p2/resolver/P2ResolverFactoryImpl.java b/tycho-bundles/org.eclipse.tycho.p2.resolver.impl/src/main/java/org/eclipse/tycho/p2/resolver/P2ResolverFactoryImpl.java index 7453d0ddbc..629957fc95 100644 --- a/tycho-bundles/org.eclipse.tycho.p2.resolver.impl/src/main/java/org/eclipse/tycho/p2/resolver/P2ResolverFactoryImpl.java +++ b/tycho-bundles/org.eclipse.tycho.p2.resolver.impl/src/main/java/org/eclipse/tycho/p2/resolver/P2ResolverFactoryImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2020 Sonatype Inc. and others. + * Copyright (c) 2008, 2022 Sonatype Inc. and others. * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -11,6 +11,7 @@ * Sonatype Inc. - initial API and implementation * Christoph Läubrich - Bug 567098 - pomDependencies=consider should wrap non-osgi jars * Issue #443 - Use regular Maven coordinates -when possible- for dependencies + * Issue #822 - If multiple fragments match a bundle all items are added to the classpath while only the one with the highest version should match *******************************************************************************/ package org.eclipse.tycho.p2.resolver; @@ -19,6 +20,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -132,11 +134,18 @@ public Set calculateDependencyFragments(ResolutionData data, if (fragmentsList.isEmpty()) { return Collections.emptySet(); } + MavenLogger logger = mavenContext.getLogger(); + if (logger.isExtendedDebugEnabled() && !fragmentsList.isEmpty()) { + logger.debug("Possible candidate fragments:"); + for (Entry fragmentEntry : fragmentsList) { + logger.debug(" " + fragmentEntry.getKey().toString()); + } + } Map> resolvedUnitsById = resolvedUnits.stream()// .collect(Collectors.groupingBy(iu -> iu.getId())); - return fragmentsList.stream()// + Map> matching = fragmentsList.stream()// .filter(entry -> { IRequiredCapability hostRequirement = entry.getValue(); List potentialHosts = resolvedUnitsById.get(hostRequirement.getName()); @@ -151,7 +160,21 @@ public Set calculateDependencyFragments(ResolutionData data, return false; })// .map(entry -> entry.getKey())// - .collect(Collectors.toSet()); + .collect(Collectors.groupingBy(IInstallableUnit::getId)); + Set filteredResult = matching.values().stream().map(candidates -> { + if (candidates.size() == 1) { + return candidates.get(0); + } + return candidates.stream().max(Comparator.comparing(IInstallableUnit::getVersion)).get(); + }).collect(Collectors.toSet()); + + if (logger.isDebugEnabled() && !filteredResult.isEmpty()) { + logger.info("Resolved fragments:"); + for (IInstallableUnit unit : filteredResult) { + logger.info(" " + unit.toString()); + } + } + return filteredResult; } private static Optional> findFragmentHostRequirement( diff --git a/tycho-its/projects/resolver.multipleDownloads/bundle1/META-INF/MANIFEST.MF b/tycho-its/projects/resolver.multipleDownloads/bundle1/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..7e839d9a11 --- /dev/null +++ b/tycho-its/projects/resolver.multipleDownloads/bundle1/META-INF/MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Bundle 1 +Bundle-SymbolicName: bundle1;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.swt;bundle-version="3.119.0" diff --git a/tycho-its/projects/resolver.multipleDownloads/bundle1/build.properties b/tycho-its/projects/resolver.multipleDownloads/bundle1/build.properties new file mode 100644 index 0000000000..34d2e4d2da --- /dev/null +++ b/tycho-its/projects/resolver.multipleDownloads/bundle1/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/tycho-its/projects/resolver.multipleDownloads/bundle1/pom.xml b/tycho-its/projects/resolver.multipleDownloads/bundle1/pom.xml new file mode 100644 index 0000000000..597030aee0 --- /dev/null +++ b/tycho-its/projects/resolver.multipleDownloads/bundle1/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + + org.eclipse.tycho.its + resolver-multiple-downloads-parent + 1.0.0-SNAPSHOT + + + bundle1 + eclipse-plugin + + \ No newline at end of file diff --git a/tycho-its/projects/resolver.multipleDownloads/pom.xml b/tycho-its/projects/resolver.multipleDownloads/pom.xml new file mode 100644 index 0000000000..fc5d494af2 --- /dev/null +++ b/tycho-its/projects/resolver.multipleDownloads/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + + org.eclipse.tycho.its + resolver-multiple-downloads-parent + 1.0.0-SNAPSHOT + pom + + 3.0.0-SNAPSHOT + + + + bundle1 + + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + org.eclipse.tycho + target-platform-configuration + ${tycho-version} + + + ../test.target + + + + linux + gtk + x86_64 + + + + + + + + diff --git a/tycho-its/projects/resolver.multipleDownloads/sdk_4.21.target b/tycho-its/projects/resolver.multipleDownloads/sdk_4.21.target new file mode 100644 index 0000000000..679ba12bc4 --- /dev/null +++ b/tycho-its/projects/resolver.multipleDownloads/sdk_4.21.target @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/tycho-its/projects/resolver.multipleDownloads/sdk_4.22.target b/tycho-its/projects/resolver.multipleDownloads/sdk_4.22.target new file mode 100644 index 0000000000..1efdccde63 --- /dev/null +++ b/tycho-its/projects/resolver.multipleDownloads/sdk_4.22.target @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/tycho-its/projects/resolver.multipleDownloads/sdk_4.23.target b/tycho-its/projects/resolver.multipleDownloads/sdk_4.23.target new file mode 100644 index 0000000000..39f5cef652 --- /dev/null +++ b/tycho-its/projects/resolver.multipleDownloads/sdk_4.23.target @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/tycho-its/projects/resolver.multipleDownloads/test.target b/tycho-its/projects/resolver.multipleDownloads/test.target new file mode 100644 index 0000000000..d03ff438de --- /dev/null +++ b/tycho-its/projects/resolver.multipleDownloads/test.target @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/resolver/ResolverTests.java b/tycho-its/src/test/java/org/eclipse/tycho/test/resolver/ResolverTests.java index 51a2e0dc3e..7618742255 100644 --- a/tycho-its/src/test/java/org/eclipse/tycho/test/resolver/ResolverTests.java +++ b/tycho-its/src/test/java/org/eclipse/tycho/test/resolver/ResolverTests.java @@ -9,12 +9,21 @@ *******************************************************************************/ package org.eclipse.tycho.test.resolver; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.List; + import org.apache.maven.it.Verifier; import org.eclipse.tycho.test.AbstractTychoIntegrationTest; import org.junit.Test; public class ResolverTests extends AbstractTychoIntegrationTest { + private static final String SDK_23 = "org.eclipse.swt.gtk.linux.x86_64 3.119.0.v20220223-1102"; + private static final String SDK_22 = "org.eclipse.swt.gtk.linux.x86_64 3.118.0.v20211123-0851"; + private static final String SDK_21 = "org.eclipse.swt.gtk.linux.x86_64 3.117.0.v20210906-0842"; + /** * This test case tests a combination that at a first glance looks very simple * but is hard to resolve due to the structure of 'org.eclipse.core.runtime' @@ -53,4 +62,40 @@ public void testMixedReactor() throws Exception { verifier.verifyErrorFreeLog(); } + @Test + public void testMultipleFragmentsOnlyOneIsChoosen() throws Exception { + + Verifier verifier = getVerifier("resolver.multipleDownloads", false, false); + verifier.executeGoal("compile"); + verifier.verifyErrorFreeLog(); + List lines = verifier.loadFile(verifier.getBasedir(), verifier.getLogFileName(), false); + +// [INFO] Resolved fragments: +// [INFO] org.eclipse.swt.gtk.linux.x86_64 3.118.0.v20211123-0851 +// [INFO] org.eclipse.swt.gtk.linux.x86_64 3.119.0.v20220223-1102 +// [INFO] org.eclipse.swt.gtk.linux.x86_64 3.117.0.v20210906-0842 +// [INFO] ------------------------------------------------------------------------ + boolean startLine = false; + boolean highestVersionFound = false; + for (String ansiLine : lines) { + String line = Verifier.stripAnsi(ansiLine); + if (startLine) { + if (line.endsWith("------")) { + break; + } + if (line.endsWith(SDK_21)) { + fail("3.117 was found but should not be part of the result"); + } + if (line.endsWith(SDK_22)) { + fail("3.118 was found but should not be part of the result"); + } + highestVersionFound |= line.endsWith(SDK_23); + } else { + startLine = line.endsWith("Resolved fragments:"); + } + } + assertTrue("Start line not found!", startLine); + assertTrue("Highest version was not found", highestVersionFound); + } + }