From 445a52083acc513219397aa57c7a95afd8b2cbad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Mon, 4 Nov 2024 10:19:15 +0100 Subject: [PATCH] Only add matching fragments to the classpath Currently all discovered fragments are added to the classpath of a project for all os/ws combinations. But in the case of os-specific fragments this is actually wrong and can lead to strange results as classpath order now controls what classes are visible at compile time. This now determines the configured environments for a project and only add those fragments that either have no filter or match any of the given environments. (cherry picked from commit 6ae5ee95e78243e8cef72c88ce4fe5e7be9610d6) --- .../core/osgitools/OsgiBundleProject.java | 61 +++---------------- .../tycho/core/osgitools/OsgiManifest.java | 55 +++++++++++++++++ 2 files changed, 65 insertions(+), 51 deletions(-) diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiBundleProject.java b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiBundleProject.java index 5c51557638..a70df89d68 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiBundleProject.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiBundleProject.java @@ -22,7 +22,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; @@ -42,8 +41,6 @@ import org.codehaus.plexus.logging.Logger; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.IRequirement; -import org.eclipse.osgi.container.namespaces.EclipsePlatformNamespace; -import org.eclipse.osgi.internal.framework.FilterImpl; import org.eclipse.tycho.ArtifactDescriptor; import org.eclipse.tycho.ArtifactKey; import org.eclipse.tycho.ArtifactType; @@ -55,7 +52,6 @@ import org.eclipse.tycho.ExecutionEnvironmentConfiguration; import org.eclipse.tycho.OptionalResolutionAction; import org.eclipse.tycho.PackagingType; -import org.eclipse.tycho.PlatformPropertiesUtils; import org.eclipse.tycho.ReactorProject; import org.eclipse.tycho.ResolvedArtifactKey; import org.eclipse.tycho.TargetEnvironment; @@ -85,8 +81,6 @@ import org.eclipse.tycho.model.classpath.LibraryClasspathEntry; import org.eclipse.tycho.model.classpath.ProjectClasspathEntry; import org.osgi.framework.Filter; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.InvalidSyntaxException; @Component(role = TychoProject.class, hint = PackagingType.TYPE_ECLIPSE_PLUGIN) public class OsgiBundleProject extends AbstractTychoProject implements BundleProject { @@ -480,12 +474,18 @@ private void addExtraClasspathEntries(List classpath, ReactorPro } } } + Collection environments = projectManager + .getTargetEnvironments(project.adapt(MavenProject.class)); //Fragments are like embedded dependencies... for (ArtifactDescriptor fragment : artifacts.getFragments()) { File location = fragment.getLocation(true); if (location != null) { - classpath.add(new DefaultClasspathEntry(null, readArtifactKey(location), - Collections.singletonList(location), null)); + OsgiManifest manifest = bundleReader.loadManifest(location); + Filter filter = manifest.getTargetEnvironmentFilter(); + if (filter == null || environments.stream().anyMatch(env -> env.match(filter))) { + classpath.add(new DefaultClasspathEntry(null, readArtifactKey(location), + Collections.singletonList(location), null)); + } } } } @@ -550,53 +550,12 @@ private File getNestedJarOrDir(ArtifactDescriptor bundle, String cp) { @Override public TargetEnvironment getImplicitTargetEnvironment(MavenProject project) { - String filterStr = getManifestValue(EclipsePlatformNamespace.ECLIPSE_PLATFORM_FILTER_HEADER, project); - - if (filterStr != null) { - try { - FilterImpl filter = FilterImpl.newInstance(filterStr); - - String ws = sn(filter.getPrimaryKeyValue(PlatformPropertiesUtils.OSGI_WS)); - String os = sn(filter.getPrimaryKeyValue(PlatformPropertiesUtils.OSGI_OS)); - String arch = sn(filter.getPrimaryKeyValue(PlatformPropertiesUtils.OSGI_ARCH)); - - // validate if os/ws/arch are not null and actually match the filter - if (ws != null && os != null && arch != null) { - Map properties = new HashMap<>(); - properties.put(PlatformPropertiesUtils.OSGI_WS, ws); - properties.put(PlatformPropertiesUtils.OSGI_OS, os); - properties.put(PlatformPropertiesUtils.OSGI_ARCH, arch); - - if (filter.matches(properties)) { - return new TargetEnvironment(os, ws, arch); - } - } - } catch (InvalidSyntaxException e) { - // at least we tried... - } - } - - return null; + return getManifest(DefaultReactorProject.adapt(project)).getImplicitTargetEnvironment(); } @Override public Filter getTargetEnvironmentFilter(MavenProject project) { - String filterStr = getManifestValue(EclipsePlatformNamespace.ECLIPSE_PLATFORM_FILTER_HEADER, project); - if (filterStr != null) { - try { - return FrameworkUtil.createFilter(filterStr); - } catch (InvalidSyntaxException e) { - // at least we tried... - } - } - return super.getTargetEnvironmentFilter(project); - } - - private static String sn(String str) { - if (str != null && !str.isBlank()) { - return str; - } - return null; + return getManifest(DefaultReactorProject.adapt(project)).getTargetEnvironmentFilter(); } @Override diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiManifest.java b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiManifest.java index 6c2d7417d2..2dbc80e3c6 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiManifest.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiManifest.java @@ -5,18 +5,26 @@ import java.io.IOException; import java.io.InputStream; +import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.jar.Attributes.Name; import org.eclipse.osgi.container.builders.OSGiManifestBuilderFactory; +import org.eclipse.osgi.container.namespaces.EclipsePlatformNamespace; import org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap; +import org.eclipse.osgi.internal.framework.FilterImpl; import org.eclipse.osgi.util.ManifestElement; import org.eclipse.tycho.ArtifactKey; import org.eclipse.tycho.ArtifactType; import org.eclipse.tycho.DefaultArtifactKey; +import org.eclipse.tycho.PlatformPropertiesUtils; +import org.eclipse.tycho.TargetEnvironment; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; +import org.osgi.framework.Filter; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.Version; /** @@ -204,4 +212,51 @@ private String[] parseBundleClasspath() { return result; } + public Filter getTargetEnvironmentFilter() { + String filterStr = getValue(EclipsePlatformNamespace.ECLIPSE_PLATFORM_FILTER_HEADER); + if (filterStr != null) { + try { + return FrameworkUtil.createFilter(filterStr); + } catch (InvalidSyntaxException e) { + // at least we tried... + } + } + return null; + } + + public TargetEnvironment getImplicitTargetEnvironment() { + String filterStr = getValue(EclipsePlatformNamespace.ECLIPSE_PLATFORM_FILTER_HEADER); + if (filterStr != null) { + try { + FilterImpl filter = FilterImpl.newInstance(filterStr); + + String ws = sn(filter.getPrimaryKeyValue(PlatformPropertiesUtils.OSGI_WS)); + String os = sn(filter.getPrimaryKeyValue(PlatformPropertiesUtils.OSGI_OS)); + String arch = sn(filter.getPrimaryKeyValue(PlatformPropertiesUtils.OSGI_ARCH)); + + // validate if os/ws/arch are not null and actually match the filter + if (ws != null && os != null && arch != null) { + Map properties = new HashMap<>(); + properties.put(PlatformPropertiesUtils.OSGI_WS, ws); + properties.put(PlatformPropertiesUtils.OSGI_OS, os); + properties.put(PlatformPropertiesUtils.OSGI_ARCH, arch); + + if (filter.matches(properties)) { + return new TargetEnvironment(os, ws, arch); + } + } + } catch (InvalidSyntaxException e) { + // at least we tried... + } + } + return null; + } + + private static String sn(String str) { + if (str != null && !str.isBlank()) { + return str; + } + return null; + } + }