diff options
author | Thomas Watson | 2012-10-10 14:56:16 +0000 |
---|---|---|
committer | Thomas Watson | 2012-10-10 14:56:16 +0000 |
commit | c4443d18acafe486c4f38ea4ce880a304ba8892f (patch) | |
tree | 86d2819972f039eaf2a550f73779aabaeb6b365a /bundles | |
parent | afd5f96ac81c0cc17918da755c85b32ce4fabded (diff) | |
download | rt.equinox.framework-c4443d18acafe486c4f38ea4ce880a304ba8892f.tar.gz rt.equinox.framework-c4443d18acafe486c4f38ea4ce880a304ba8892f.tar.xz rt.equinox.framework-c4443d18acafe486c4f38ea4ce880a304ba8892f.zip |
Bug 358923 - [R5] Improve support for multiple cardinality and uses constraints on generic capabilitiesv20121010-145616
Diffstat (limited to 'bundles')
13 files changed, 215 insertions, 38 deletions
diff --git a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF index 4e1b54fd7..64a7849bd 100644 --- a/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.osgi.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Core OSGi Tests Bundle-SymbolicName: org.eclipse.osgi.tests;singleton:=true -Bundle-Version: 3.8.0.qualifier +Bundle-Version: 3.9.0.qualifier Bundle-ClassPath: osgitests.jar Bundle-Vendor: Eclipse.org Bundle-Localization: plugin diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/OSGiCapabilityTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/OSGiCapabilityTest.java index 6e00f7614..69514c36e 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/OSGiCapabilityTest.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/OSGiCapabilityTest.java @@ -415,6 +415,110 @@ public class OSGiCapabilityTest extends AbstractStateTest { checkUsedCapability(c4v130, p5v100Capability); } + public void testOSGiCardinalityUses() throws BundleException { + State state = buildEmptyState(); + long bundleID = 0; + Dictionary manifest; + + manifest = loadManifest("p5.v100.osgi.MF"); + BundleDescription p5v100 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("p5.v101.osgi.MF"); + BundleDescription p5v101 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("p5.v110.osgi.MF"); + BundleDescription p5v110 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("p6.v100.osgi.MF"); + BundleDescription p6v100 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("p6.v110.osgi.MF"); + BundleDescription p6v110 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("p7.v100.osgi.MF"); + BundleDescription p7v100 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("p7.v110.osgi.MF"); + BundleDescription p7v110 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("c6.v100.osgi.MF"); + BundleDescription c6v100 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("c6.v110.osgi.MF"); + BundleDescription c6v110 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("c6.v120.osgi.MF"); + BundleDescription c6v120 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("c6.v130.osgi.MF"); + BundleDescription c6v130 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("c6.v140.osgi.MF"); + BundleDescription c6v140 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + + state.addBundle(p5v100); + state.addBundle(p5v101); + state.addBundle(p5v110); + state.addBundle(p6v100); + state.addBundle(p6v110); + state.addBundle(p7v100); + state.addBundle(p7v110); + state.addBundle(c6v100); + state.addBundle(c6v110); + state.addBundle(c6v120); + state.addBundle(c6v130); + state.addBundle(c6v140); + + state.resolve(); + + assertTrue("p5v100", p5v100.isResolved()); + assertTrue("p5v100", p5v101.isResolved()); + assertTrue("p5v110", p5v110.isResolved()); + assertTrue("p6v100", p6v100.isResolved()); + assertTrue("p6v110", p6v110.isResolved()); + assertTrue("p7v100", p7v100.isResolved()); + assertTrue("p7v110", p7v110.isResolved()); + assertTrue("c6v100", c6v100.isResolved()); + assertTrue("c6v110", c6v110.isResolved()); + assertTrue("c6v120", c6v120.isResolved()); + assertTrue("c6v130", c6v130.isResolved()); + assertTrue("c6v140", c6v140.isResolved()); + + state.linkDynamicImport(c6v120, "p6"); + state.linkDynamicImport(c6v120, "p7"); + + GenericDescription[] p5v100Capability = p5v100.getSelectedGenericCapabilities(); + GenericDescription[] p5v101Capability = p5v101.getSelectedGenericCapabilities(); + List expectedCapabilityList = new ArrayList(); + expectedCapabilityList.addAll(Arrays.asList(p5v100Capability)); + expectedCapabilityList.addAll(Arrays.asList(p5v101Capability)); + for (Iterator iCapabilities = expectedCapabilityList.iterator(); iCapabilities.hasNext();) { + if (!"namespace.5".equals(((GenericDescription) iCapabilities.next()).getType())) { + iCapabilities.remove(); + } + } + + ExportPackageDescription[] p6v100Exports = p6v100.getSelectedExports(); + ExportPackageDescription[] p7v100Exports = p7v100.getSelectedExports(); + ExportPackageDescription[] expectedPackages = new ExportPackageDescription[] {p6v100Exports[0], p7v100Exports[0]}; + + checkUsedImports(c6v100, expectedPackages); + checkUsedImports(c6v110, expectedPackages); + checkUsedImports(c6v120, expectedPackages); + + BundleDescription[] expectedRequired = new BundleDescription[] {p6v100, p7v100}; + checkUsedRequires(c6v130, expectedRequired); + checkUsedRequires(c6v140, expectedRequired); + + GenericDescription[] expectedCapabilities = (GenericDescription[]) expectedCapabilityList.toArray(new GenericDescription[expectedCapabilityList.size()]); + checkUsedCapability(c6v100, expectedCapabilities); + checkUsedCapability(c6v110, expectedCapabilities); + checkUsedCapability(c6v120, expectedCapabilities); + checkUsedCapability(c6v130, expectedCapabilities); + checkUsedCapability(c6v140, expectedCapabilities); + + manifest = loadManifest("c6.v150.osgi.MF"); + BundleDescription c6v150 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("c6.v160.osgi.MF"); + BundleDescription c6v160 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + + state.addBundle(c6v150); + state.addBundle(c6v160); + state.resolve(); + + assertFalse("c6v150", c6v150.isResolved()); + assertFalse("c6v160", c6v160.isResolved()); + } + public void testDeclaringIdentityCapability() { State state = buildEmptyState(); Hashtable manifest = new Hashtable(); diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v100.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v100.osgi.MF new file mode 100644 index 000000000..1ebc43565 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v100.osgi.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: c6.osgi +Bundle-Version: 1.0 +Require-Capability: + namespace.5; filter:="(version=1.0)"; cardinality:="multiple" +Import-Package: p6, p7 diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v110.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v110.osgi.MF new file mode 100644 index 000000000..ffb12e753 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v110.osgi.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: c6.osgi +Bundle-Version: 1.1 +Require-Capability: + namespace.5; filter:="(namespace.5=test)"; cardinality:="multiple" +Import-Package: p6; p7; version="[1.0,1.1)" diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v120.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v120.osgi.MF new file mode 100644 index 000000000..e684e0771 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v120.osgi.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: c6.osgi +Bundle-Version: 1.2 +Require-Capability: + namespace.5; filter:="(version=1.0)"; cardinality:="multiple" +DynamicImport-Package: p6, p7 diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v130.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v130.osgi.MF new file mode 100644 index 000000000..44fe7cfcb --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v130.osgi.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: c6.osgi +Bundle-Version: 1.3 +Require-Capability: + namespace.5; filter:="(version=1.0)"; cardinality:="multiple" +Require-Bundle: p6.osgi, p7.osgi diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v140.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v140.osgi.MF new file mode 100644 index 000000000..9e0d9963a --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v140.osgi.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: c6.osgi +Bundle-Version: 1.4 +Require-Capability: + namespace.5; filter:="(namespace.5=test)"; cardinality:="multiple" +Require-Bundle: p6.osgi; bundle-version="[1.0,1.1)", p7.osgi; bundle-version="[1.0,1.1)" diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v150.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v150.osgi.MF new file mode 100644 index 000000000..9693fa4a0 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v150.osgi.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: c6.osgi +Bundle-Version: 1.5 +Require-Capability: + namespace.5; filter:="(version=1.0)"; cardinality:="multiple" +Import-Package: p6; p7; version="[1.1,1.2)" diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v160.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v160.osgi.MF new file mode 100644 index 000000000..b4b513318 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/c6.v160.osgi.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: c6.osgi +Bundle-Version: 1.6 +Require-Capability: + namespace.5; filter:="(version=1.0)"; cardinality:="multiple" +Require-Bundle: p6.osgi; bundle-version="[1.1,1.2)", p7.osgi; bundle-version="[1.1,1.2)" diff --git a/bundles/org.eclipse.osgi.tests/test_files/genericCapability/p5.v101.osgi.MF b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/p5.v101.osgi.MF new file mode 100644 index 000000000..b17f58dfb --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/genericCapability/p5.v101.osgi.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: p5.osgi +Bundle-Version: 1.0.1 +Provide-Capability: + namespace.5; namespace.5=test; version:Version="1.0"; uses:="p6, p7" +Import-Package: p6; p7; version="[1.0,1.1)" diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GenericConstraint.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GenericConstraint.java index a84a05812..44589173c 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GenericConstraint.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GenericConstraint.java @@ -17,12 +17,13 @@ import org.osgi.framework.Constants; public class GenericConstraint extends ResolverConstraint { private final boolean effective; - private boolean supplierHasUses; + private final boolean multiple; GenericConstraint(ResolverBundle bundle, GenericSpecification constraint) { super(bundle, constraint); String effectiveDirective = constraint.getRequirement().getDirectives().get(Constants.EFFECTIVE_DIRECTIVE); effective = effectiveDirective == null || Constants.EFFECTIVE_RESOLVE.equals(effectiveDirective); + multiple = (constraint.getResolution() & GenericSpecification.RESOLUTION_MULTIPLE) != 0; } boolean isOptional() { @@ -34,7 +35,7 @@ public class GenericConstraint extends ResolverConstraint { } boolean isMultiple() { - return !supplierHasUses && (((GenericSpecification) constraint).getResolution() & GenericSpecification.RESOLUTION_MULTIPLE) != 0; + return multiple; } boolean isEffective() { @@ -51,21 +52,4 @@ public class GenericConstraint extends ResolverConstraint { VersionSupplier supplier = getSelectedSupplier(); return supplier == null ? null : new VersionSupplier[] {supplier}; } - - @Override - void addPossibleSupplier(VersionSupplier supplier) { - // if there is a supplier with uses constraints then we no longer allow multiples - supplierHasUses |= ((GenericCapability) supplier).getUsesDirective() != null; - super.addPossibleSupplier(supplier); - } - - @Override - void clearPossibleSuppliers() { - super.clearPossibleSuppliers(); - supplierHasUses = false; - } - - boolean supplierHasUses() { - return supplierHasUses; - } } diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java index ea39971bd..0acce4bd7 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. All rights reserved. + * Copyright (c) 2004, 2012 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 http://www.eclipse.org/legal/epl-v10.html @@ -145,16 +145,18 @@ public class GroupingChecker { // We also must check any generic capabilities are consistent GenericConstraint[] genericRequires = importingBundle.getGenericRequires(); for (GenericConstraint constraint : genericRequires) { - if (!constraint.supplierHasUses()) - continue; - GenericCapability supplier = (GenericCapability) constraint.getSelectedSupplier(); - String[] uses = supplier.getUsesDirective(); - if (uses != null) - for (String usedPackage : uses) { - if (usedPackage.equals(matchingExport.getName())) { - results = exportingRoots.addConflicts(supplier.getResolverBundle(), usedPackage, null, results); - } + VersionSupplier[] suppliers = constraint.getMatchingCapabilities(); + if (suppliers != null) { + for (VersionSupplier supplier : suppliers) { + String[] uses = ((GenericCapability) supplier).getUsesDirective(); + if (uses != null) + for (String usedPackage : uses) { + if (usedPackage.equals(matchingExport.getName())) { + results = exportingRoots.addConflicts(supplier.getResolverBundle(), usedPackage, null, results); + } + } } + } } return results; } diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java index beeed64c9..d0d54fdaa 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java @@ -872,8 +872,9 @@ public class ResolverImpl implements Resolver { return null; Set<String> bundleConstraints = new HashSet<String>(); Set<String> packageConstraints = new HashSet<String>(); + Collection<GenericConstraint> multiRequirementWithMultiSuppliers = new ArrayList<GenericConstraint>(); // first try out the initial selections - List<ResolverConstraint> initialConflicts = getConflicts(bundles, packageConstraints, bundleConstraints); + List<ResolverConstraint> initialConflicts = getConflicts(bundles, packageConstraints, bundleConstraints, multiRequirementWithMultiSuppliers); if (initialConflicts == null || "tryFirst".equals(usesMode) || usesCalculationTimeout) { //$NON-NLS-1$ groupingChecker.clear(); // the first combination have no conflicts or @@ -899,7 +900,19 @@ public class ResolverImpl implements Resolver { selectedSupplier.setSubstitute(null); } } - + if (!multiRequirementWithMultiSuppliers.isEmpty()) { + groupingChecker.clear(); + for (GenericConstraint multiConstraint : multiRequirementWithMultiSuppliers) { + VersionSupplier[] matchingSuppliers = multiConstraint.getMatchingCapabilities(); + if (matchingSuppliers != null) { + for (VersionSupplier supplier : matchingSuppliers) { + if (groupingChecker.isConsistent(multiConstraint.getBundle(), (GenericCapability) supplier) != null) { + multiConstraint.removePossibleSupplier(supplier); + } + } + } + } + } // do not need to keep uses data in memory groupingChecker.clear(); return conflicts; @@ -936,7 +949,7 @@ public class ResolverImpl implements Resolver { // first count the conflicts for the bundles with conflicts from the best combination // this significantly reduces the time it takes to populate the GroupingChecker for cases where // the combination is no better. - List<ResolverConstraint> conflicts = getConflicts(bestConflictBundles, null, null); + List<ResolverConstraint> conflicts = getConflicts(bestConflictBundles, null, null, null); int conflictCount = getConflictCount(conflicts); if (conflictCount >= bestConflictCount) { if (DEBUG_USES) @@ -947,7 +960,7 @@ public class ResolverImpl implements Resolver { } // this combination improves upon the conflicts for the bundles which conflict with the current best combination; // do an complete conflict count - conflicts = getConflicts(bundles, null, null); + conflicts = getConflicts(bundles, null, null, null); conflictCount = getConflictCount(conflicts); if (conflictCount < bestConflictCount) { // this combination is better that the current best combination; save this combination as the current best @@ -1012,15 +1025,15 @@ public class ResolverImpl implements Resolver { return result; } - private List<ResolverConstraint> getConflicts(ResolverBundle[] bundles, Set<String> packageConstraints, Set<String> bundleConstraints) { + private List<ResolverConstraint> getConflicts(ResolverBundle[] bundles, Set<String> packageConstraints, Set<String> bundleConstraints, Collection<GenericConstraint> multiRequirementWithMultiSuppliers) { groupingChecker.clear(); List<ResolverConstraint> conflicts = null; for (int i = 0; i < bundles.length; i++) - conflicts = addConflicts(bundles[i], packageConstraints, bundleConstraints, conflicts); + conflicts = addConflicts(bundles[i], packageConstraints, bundleConstraints, multiRequirementWithMultiSuppliers, conflicts); return conflicts; } - private List<ResolverConstraint> addConflicts(ResolverBundle bundle, Set<String> packageConstraints, Set<String> bundleConstraints, List<ResolverConstraint> conflicts) { + private List<ResolverConstraint> addConflicts(ResolverBundle bundle, Set<String> packageConstraints, Set<String> bundleConstraints, Collection<GenericConstraint> multiRequirementWithMultiSuppliers, List<ResolverConstraint> conflicts) { BundleConstraint[] requires = bundle.getRequires(); for (int i = 0; i < requires.length; i++) { ResolverBundle selectedSupplier = (ResolverBundle) requires[i].getSelectedSupplier(); @@ -1049,10 +1062,28 @@ public class ResolverImpl implements Resolver { VersionSupplier[] suppliers = capabilityRequirement.getMatchingCapabilities(); if (suppliers == null) continue; + + if (multiRequirementWithMultiSuppliers != null && capabilityRequirement.isMultiple() && suppliers.length > 1) { + multiRequirementWithMultiSuppliers.add(capabilityRequirement); + } + // search for at least one capability that does not conflict + // in case of single cardinality there will only be one matching supplier + // in case of multiple there may be multiple suppliers, but we only need one or more to not conflict with the class space + Collection<PackageRoots[][]> capabilityConflicts = null; for (VersionSupplier supplier : suppliers) { PackageRoots[][] conflict = groupingChecker.isConsistent(bundle, (GenericCapability) supplier); if (conflict != null) { + if (capabilityConflicts == null) + capabilityConflicts = new ArrayList<PackageRoots[][]>(1); + capabilityConflicts.add(conflict); + } + } + if (capabilityConflicts != null) { + for (PackageRoots[][] conflict : capabilityConflicts) { addConflictNames(conflict, packageConstraints, bundleConstraints); + } + if (capabilityConflicts.size() == suppliers.length) { + // every capability conflicted if (conflicts == null) conflicts = new ArrayList<ResolverConstraint>(1); conflicts.add(capabilityRequirement); @@ -1126,7 +1157,7 @@ public class ResolverImpl implements Resolver { } GenericConstraint[] genericRequires = bundle.getGenericRequires(); for (GenericConstraint genericRequire : genericRequires) - if (genericRequire.getNumPossibleSuppliers() > 1 && genericRequire.supplierHasUses()) + if (genericRequire.getNumPossibleSuppliers() > 1 && !genericRequire.isMultiple()) multipleGenericSupplierList.add(genericRequire); } List<ResolverConstraint[]> results = new ArrayList<ResolverConstraint[]>(); |