use of org.eclipse.tycho.classpath.ClasspathEntry.AccessRule in project tycho by eclipse.
the class AbstractOsgiCompilerMojo method toString.
private String toString(List<AccessRule> rules) {
// include all
StringBuilder result = new StringBuilder();
if (rules != null) {
result.append("[");
for (AccessRule rule : rules) {
if (result.length() > 1)
result.append(RULE_SEPARATOR);
result.append(rule.isDiscouraged() ? "~" : "+");
result.append(rule.getPattern());
}
if (result.length() > 1)
result.append(RULE_SEPARATOR);
result.append(RULE_EXCLUDE_ALL);
result.append("]");
} else {
// include everything, not strictly necessary, but lets make this obvious
// result.append("[+**/*]");
}
return result.toString();
}
use of org.eclipse.tycho.classpath.ClasspathEntry.AccessRule in project tycho by eclipse.
the class AbstractOsgiCompilerMojo method configureBootclasspathAccessRules.
private void configureBootclasspathAccessRules(CompilerConfiguration compilerConfiguration) throws MojoExecutionException {
List<AccessRule> accessRules = new ArrayList<>();
if (requireJREPackageImports) {
accessRules.addAll(getStrictBootClasspathAccessRules());
} else {
accessRules.add(new DefaultAccessRule("java/**", false));
for (String pkg : getTargetExecutionEnvironment().getSystemPackages()) {
accessRules.add(new DefaultAccessRule(pkg.trim().replace('.', '/') + "/*", false));
}
// now add packages exported by framework extension bundles
accessRules.addAll(getBundleProject().getBootClasspathExtraAccessRules(project));
}
if (accessRules.size() > 0) {
compilerConfiguration.addCompilerCustomArgument("org.osgi.framework.system.packages", toString(accessRules));
}
}
use of org.eclipse.tycho.classpath.ClasspathEntry.AccessRule in project tycho by eclipse.
the class DependencyComputerTest method testStrictBootClasspathAccessRules.
@Test
public void testStrictBootClasspathAccessRules() throws Exception {
File basedir = getBasedir("projects/bootclasspath");
Map<File, MavenProject> basedirMap = MavenSessionUtils.getBasedirMap(getSortedProjects(basedir, null, getBasedir("p2repo")));
// 1. bundle importing a JRE package only
MavenProject bundle1Project = basedirMap.get(new File(basedir, "bundle1"));
List<DependencyEntry> bundle1Dependencies = computeDependencies(bundle1Project);
assertEquals(1, bundle1Dependencies.size());
DependencyEntry dependency = bundle1Dependencies.get(0);
assertEquals(1, dependency.rules.size());
assertEquals("javax/net/ssl/*", dependency.rules.get(0).getPattern());
// 2. bundle importing both a JRE package and an OSGi framework package
MavenProject bundle2Project = basedirMap.get(new File(basedir, "bundle2"));
List<DependencyEntry> bundle2Dependencies = computeDependencies(bundle2Project);
assertEquals(1, bundle2Dependencies.size());
DependencyEntry dependencyBundle2 = bundle2Dependencies.get(0);
Set<String> accessRules = new HashSet<>();
for (AccessRule rule : dependencyBundle2.rules) {
accessRules.add(rule.getPattern());
}
assertEquals(new HashSet<>(asList("javax/net/ssl/*", "org/osgi/framework/*")), accessRules);
}
use of org.eclipse.tycho.classpath.ClasspathEntry.AccessRule in project tycho by eclipse.
the class OsgiBundleProject method resolveClassPath.
@Override
public void resolveClassPath(MavenSession session, MavenProject project) {
DependencyArtifacts artifacts = getDependencyArtifacts(project);
State state = getResolverState(project, artifacts);
if (getLogger().isDebugEnabled() && DebugUtils.isDebugEnabled(session, project)) {
getLogger().debug(resolver.toDebugString(state));
}
BundleDescription bundleDescription = state.getBundleByLocation(project.getBasedir().getAbsolutePath());
List<ClasspathEntry> classpath = new ArrayList<>();
// project itself
ArtifactDescriptor artifact = getArtifact(artifacts, project.getBasedir(), bundleDescription.getSymbolicName());
ReactorProject projectProxy = DefaultReactorProject.adapt(project);
List<File> projectClasspath = getThisProjectClasspath(artifact, projectProxy);
classpath.add(new DefaultClasspathEntry(projectProxy, artifact.getKey(), projectClasspath, null));
// build.properties/jars.extra.classpath
addExtraClasspathEntries(classpath, projectProxy, artifacts);
// dependencies
List<AccessRule> strictBootClasspathAccessRules = new ArrayList<>();
strictBootClasspathAccessRules.add(new DefaultAccessRule("java/**", false));
for (DependencyEntry entry : dependencyComputer.computeDependencies(state.getStateHelper(), bundleDescription)) {
if (EquinoxResolver.SYSTEM_BUNDLE_ID == entry.desc.getBundleId()) {
if (entry.rules != null) {
strictBootClasspathAccessRules.addAll(entry.rules);
}
if (EquinoxResolver.SYSTEM_BUNDLE_SYMBOLIC_NAME.equals(entry.desc.getSymbolicName())) {
// synthetic system.bundle has no filesystem location
continue;
}
}
File location = new File(entry.desc.getLocation());
ArtifactDescriptor otherArtifact = getArtifact(artifacts, location, entry.desc.getSymbolicName());
ReactorProject otherProject = otherArtifact.getMavenProject();
List<File> locations;
if (otherProject != null) {
locations = getOtherProjectClasspath(otherArtifact, otherProject, null);
} else {
locations = getBundleClasspath(otherArtifact);
}
if (locations.isEmpty() && !entry.rules.isEmpty()) {
getLogger().warn("Empty classpath of required bundle " + otherArtifact);
}
classpath.add(new DefaultClasspathEntry(otherProject, otherArtifact.getKey(), locations, entry.rules));
}
project.setContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_CLASSPATH, classpath);
project.setContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_STRICT_BOOTCLASSPATH_ACCESSRULES, strictBootClasspathAccessRules);
project.setContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_BOOTCLASSPATH_EXTRA_ACCESSRULES, dependencyComputer.computeBootClasspathExtraAccessRules(state.getStateHelper(), bundleDescription));
addPDESourceRoots(project);
}
use of org.eclipse.tycho.classpath.ClasspathEntry.AccessRule in project tycho by eclipse.
the class DependencyComputer method computeBootClasspathExtraAccessRules.
/**
* Although totally not obvious from the specification text, section 3.15 "Extension Bundles" of
* OSGi Core Spec apparently says that framework extension bundles can export additional
* packaged of the underlying JRE. More specific explanation is provided in [1] and I verified
* that at least Equinox 3.7.1 does indeed behave like described.
* <p/>
* There does not seem to be a way to tell which packages exported by a framework extension
* bundle are supposed to come from JRE and which from the bundle itself, so returned classpath
* access rules include all packages exported by the framework extension bundles.
*
* [1] http://blog.meschberger.ch/2008/10/osgi-bundles-require-classes-from.html
*/
public List<AccessRule> computeBootClasspathExtraAccessRules(StateHelper helper, BundleDescription desc) {
List<AccessRule> result = new ArrayList<>();
ExportPackageDescription[] exports = helper.getVisiblePackages(desc);
for (ExportPackageDescription export : exports) {
BundleDescription host = export.getExporter();
BaseDescription fragment = ((ExportPackageDescriptionImpl) export).getFragmentDeclaration();
if (host.getBundleId() == 0 && fragment != null && isFrameworkExtension(fragment.getSupplier())) {
result.add(getRule(helper, host, export));
}
}
return result;
}
Aggregations