diff options
author | Thomas Watson | 2017-02-03 16:11:57 +0000 |
---|---|---|
committer | Thomas Watson | 2017-02-03 21:42:54 +0000 |
commit | fcab3e35945c3d10db5b22838c1230c67afdaee2 (patch) | |
tree | 1dc34e838247a4200c7615eb54358343db3697f4 | |
parent | f9777863a046cb6516c5846f2d592ff6aa25fb15 (diff) | |
download | rt.equinox.framework-fcab3e35945c3d10db5b22838c1230c67afdaee2.tar.gz rt.equinox.framework-fcab3e35945c3d10db5b22838c1230c67afdaee2.tar.xz rt.equinox.framework-fcab3e35945c3d10db5b22838c1230c67afdaee2.zip |
Bug 511593 - Issue resolving split packagesI20170205-2000I20170204-2000I20170203-2000
The resolver implementation fix.
Change-Id: I71384aec4decc0a7b009c5d48815ade3a8a4c010
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
3 files changed, 140 insertions, 8 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java index 035bdffaf..201a26bd4 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2016 IBM Corporation and others. + * Copyright (c) 2012, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,6 +14,7 @@ import java.net.URL; import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; +import org.apache.felix.resolver.FelixWiring; import org.eclipse.osgi.container.ModuleRevisionBuilder.GenericInfo; import org.eclipse.osgi.internal.container.AtomicLazyInitializer; import org.eclipse.osgi.internal.container.InternalUtils; @@ -28,7 +29,7 @@ import org.osgi.resource.*; * An implementation of {@link BundleWiring}. * @since 3.10 */ -public final class ModuleWiring implements BundleWiring { +public final class ModuleWiring implements BundleWiring, FelixWiring { class LoaderInitializer implements Callable<ModuleLoader> { @Override public ModuleLoader call() throws Exception { @@ -458,4 +459,26 @@ public final class ModuleWiring implements BundleWiring { public String toString() { return revision.toString(); } + + /** + * @since 3.12 + */ + @Override + public Collection<Wire> getSubstitutionWires() { + if (substitutedPkgNames.isEmpty()) { + return Collections.emptyList(); + } + // Could cache this, but seems unnecessary since it will only be used by the resolver + Collection<Wire> substitutionWires = new ArrayList<>(substitutedPkgNames.size()); + List<ModuleWire> current = requiredWires; + for (ModuleWire wire : current) { + Capability cap = wire.getCapability(); + if (PackageNamespace.PACKAGE_NAMESPACE.equals(cap.getNamespace())) { + if (substitutedPkgNames.contains(cap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))) { + substitutionWires.add(wire); + } + } + } + return substitutionWires; + } } diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/FelixWiring.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/FelixWiring.java new file mode 100644 index 000000000..ce453b029 --- /dev/null +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/FelixWiring.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */package org.apache.felix.resolver; + +import java.util.Collection; +import org.osgi.resource.Wire; + +public interface FelixWiring +{ + Collection<Wire> getSubstitutionWires(); +} diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java index 13c7ca4f7..897b9698f 100755 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java @@ -899,7 +899,6 @@ public class ResolverImpl implements Resolver } else if (candCap.getNamespace().equals(BundleNamespace.BUNDLE_NAMESPACE)) { - // Get the candidate's package space to determine which packages // will be visible to the current resource. if (visitedRequiredBundles.add(candCap.getResource())) @@ -913,6 +912,13 @@ public class ResolverImpl implements Resolver currentReq, blame.m_cap); } + // now merge in substitutes + for (Blame blame : resourcePkgMap.get( + candCap.getResource()).m_substitePkgs.values()) + { + mergeCandidatePackage(packages.m_requiredPkgs, currentReq, + blame.m_cap); + } } // If the candidate requires any other bundles with reexport visibility, @@ -1143,7 +1149,8 @@ public class ResolverImpl implements Resolver { public void run() { - calculateExportedPackages(session, allCandidates, resource, packages.m_exportedPkgs); + calculateExportedPackages(session, allCandidates, resource, + packages.m_exportedPkgs, packages.m_substitePkgs); } }); } @@ -1573,7 +1580,7 @@ public class ResolverImpl implements Resolver ResolveSession session, Candidates allCandidates, Resource resource, - OpenHashMap<String, Blame> exports) + OpenHashMap<String, Blame> exports, OpenHashMap<String, Blame> substitutes) { // Get all exported packages. Wiring wiring = session.getContext().getWirings().get(resource); @@ -1598,9 +1605,34 @@ public class ResolverImpl implements Resolver // already excludes imported substitutable exports, but // for resolving resources we must look in the candidate // map to determine which exports are substitutable. - if (!exports.isEmpty()) + if (wiring != null) { - if (wiring == null) + Collection<Wire> substitutionWires; + if (wiring instanceof FelixWiring) + { + substitutionWires = ((FelixWiring) wiring).getSubstitutionWires(); + } + else + { + substitutionWires = getSubstitutionWires(wiring); + } + for (Wire wire : substitutionWires) + { + Capability cap = wire.getCapability(); + if (!cap.getResource().equals(wire.getProvider())) + { + cap = new WrappedCapability(wire.getProvider(), cap); + } + substitutes.put( + // Using a null on requirement instead of the wire requirement here. + // It is unclear if we want to treat the substitution requirement as a permutation req here. + (String) cap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE), + new Blame(cap, null)); + } + } + else + { + if (!exports.isEmpty()) { for (Requirement req : resource.getRequirements(null)) { @@ -1610,7 +1642,13 @@ public class ResolverImpl implements Resolver if (cand != null) { String pkgName = (String) cand.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE); - exports.remove(pkgName); + Blame blame = exports.remove(pkgName); + if (blame != null) + { + // Using a null on requirement instead of the wire requirement here. + // It is unclear if we want to treat the substitution requirement as a permutation req here. + substitutes.put(pkgName, new Blame(cand, null)); + } } } } @@ -1619,6 +1657,49 @@ public class ResolverImpl implements Resolver return exports; } + private static Collection<Wire> getSubstitutionWires(Wiring wiring) + { + Set<String> exportNames = new HashSet<String>(); + for (Capability cap : wiring.getResource().getCapabilities(null)) + { + if (PackageNamespace.PACKAGE_NAMESPACE.equals(cap.getNamespace())) + { + exportNames.add( + (String) cap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE)); + } + } + // Add fragment exports + for (Wire wire : wiring.getProvidedResourceWires(null)) + { + if (HostNamespace.HOST_NAMESPACE.equals(wire.getCapability().getNamespace())) + { + for (Capability cap : wire.getRequirement().getResource().getCapabilities( + null)) + { + if (PackageNamespace.PACKAGE_NAMESPACE.equals(cap.getNamespace())) + { + exportNames.add((String) cap.getAttributes().get( + PackageNamespace.PACKAGE_NAMESPACE)); + } + } + } + } + Collection<Wire> substitutionWires = new ArrayList<Wire>(); + for (Wire wire : wiring.getRequiredResourceWires(null)) + { + if (PackageNamespace.PACKAGE_NAMESPACE.equals( + wire.getCapability().getNamespace())) + { + if (exportNames.contains(wire.getCapability().getAttributes().get( + PackageNamespace.PACKAGE_NAMESPACE))) + { + substitutionWires.add(wire); + } + } + } + return substitutionWires; + } + private static boolean isCompatible( Blame currentBlame, Capability candCap, Map<Resource, Packages> resourcePkgMap) @@ -2022,6 +2103,7 @@ public class ResolverImpl implements Resolver public static class Packages { public final OpenHashMap<String, Blame> m_exportedPkgs; + public final OpenHashMap<String, Blame> m_substitePkgs; public final OpenHashMap<String, List<Blame>> m_importedPkgs; public final OpenHashMap<String, List<Blame>> m_requiredPkgs; public final OpenHashMap<String, ArrayMap<Capability, UsedBlames>> m_usedPkgs; @@ -2034,6 +2116,7 @@ public class ResolverImpl implements Resolver int nbReqs = resource.getRequirements(null).size(); m_exportedPkgs = new OpenHashMap<String, Blame>(nbCaps); + m_substitePkgs = new OpenHashMap<String, Blame>(nbCaps); m_importedPkgs = new OpenHashMap<String, List<Blame>>(nbReqs) { public List<Blame> compute(String s) { return new ArrayList<Blame>(); |