Skip to content

Commit

Permalink
Only add matching fragments to the classpath
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
laeubi committed Nov 4, 2024
1 parent 9464bc9 commit 6ae5ee9
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -41,8 +40,6 @@
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
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;
Expand All @@ -54,7 +51,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;
Expand All @@ -79,8 +75,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 {
Expand Down Expand Up @@ -441,12 +435,18 @@ private void addExtraClasspathEntries(List<ClasspathEntry> classpath, ReactorPro
}
}
}
Collection<TargetEnvironment> 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));
}
}
}
}
Expand Down Expand Up @@ -511,53 +511,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<String, String> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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<String, String> 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;
}

}

0 comments on commit 6ae5ee9

Please sign in to comment.