diff options
author | Jeff McAffer | 2010-09-21 18:00:20 +0000 |
---|---|---|
committer | Jeff McAffer | 2010-09-21 18:00:20 +0000 |
commit | 0501f653019d0481b4821b0da6e65a4c36551617 (patch) | |
tree | 59c4f2ce2599b3491e6bf519a43f136f282e653a | |
parent | 082f548888d89056030814f67a367cf7286901a8 (diff) | |
download | rt.equinox.framework-0501f653019d0481b4821b0da6e65a4c36551617.tar.gz rt.equinox.framework-0501f653019d0481b4821b0da6e65a4c36551617.tar.xz rt.equinox.framework-0501f653019d0481b4821b0da6e65a4c36551617.zip |
Bug 324618 Dynamic import resolver bug backportR36x_v20101015R36x_v20101014
7 files changed, 101 insertions, 19 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/StateResolverTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/StateResolverTest.java index 8329cfc88..57b1ed765 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/StateResolverTest.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/StateResolverTest.java @@ -12,9 +12,11 @@ package org.eclipse.osgi.tests.services.resolver; import java.io.File; import java.io.IOException; +import java.net.URL; import java.util.*; import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.osgi.framework.util.Headers; import org.eclipse.osgi.service.resolver.*; import org.eclipse.osgi.tests.OSGiTestsActivator; import org.osgi.framework.*; @@ -3289,6 +3291,20 @@ public class StateResolverTest extends AbstractStateTest { return false; } + private static final String MANIFEST_ROOT = "test_files/resolverTests/"; + + private Dictionary loadManifest(String manifest) { + URL url = getContext().getBundle().getEntry(MANIFEST_ROOT + manifest); + try { + return Headers.parseManifest(url.openStream()); + } catch (IOException e) { + fail("Unexpected error loading manifest: " + manifest, e); + } catch (BundleException e) { + fail("Unexpected error loading manifest: " + manifest, e); + } + return null; + } + public void testSelectionPolicy() throws BundleException { State state = buildEmptyState(); Resolver resolver = state.getResolver(); @@ -3805,6 +3821,34 @@ public class StateResolverTest extends AbstractStateTest { return true; } } + + public void testBug324618() throws BundleException { + State state = buildEmptyState(); + long bundleID = 0; + Dictionary manifest; + + manifest = loadManifest("p1.MF"); + BundleDescription p1 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("p2.MF"); + BundleDescription p2 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + manifest = loadManifest("c1.MF"); + BundleDescription c1 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++); + + state.addBundle(p1); + state.addBundle(p2); + state.addBundle(c1); + + state.resolve(); + + ExportPackageDescription x = state.linkDynamicImport(c1, "x"); + assertNotNull("x dynamic import is null", x); + ExportPackageDescription xSub = state.linkDynamicImport(c1, "x.sub"); + assertNotNull("x.sub dynamic import is null", xSub); + assertEquals("The exporter is not the same for x and x.sub", x.getExporter(), xSub.getExporter()); + + ExportPackageDescription xExtra = state.linkDynamicImport(c1, "x.extra"); + assertNotNull("x.extra dynamic import is null", xExtra); + } } //testFragmentUpdateNoVersionChanged() //testFragmentUpdateVersionChanged() diff --git a/bundles/org.eclipse.osgi.tests/test_files/resolverTests/c1.MF b/bundles/org.eclipse.osgi.tests/test_files/resolverTests/c1.MF new file mode 100644 index 000000000..ba4d7b305 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/resolverTests/c1.MF @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: c1 +Bundle-Version: 1.0 +DynamicImport-Package: * diff --git a/bundles/org.eclipse.osgi.tests/test_files/resolverTests/p1.MF b/bundles/org.eclipse.osgi.tests/test_files/resolverTests/p1.MF new file mode 100644 index 000000000..ed8eb8c51 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/resolverTests/p1.MF @@ -0,0 +1,8 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: p1 +Bundle-Version: 1.0 +Export-Package: + x; version="1.0"; uses:="x.sub", + x.sub; version="2.0", + x.extra diff --git a/bundles/org.eclipse.osgi.tests/test_files/resolverTests/p2.MF b/bundles/org.eclipse.osgi.tests/test_files/resolverTests/p2.MF new file mode 100644 index 000000000..e97cb83d8 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/resolverTests/p2.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: p2 +Bundle-Version: 1.0 +Export-Package: + x; version="2.0"; uses:="x.sub", + x.sub; version="1.0"
\ No newline at end of file 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 79f9e59dc..30c59635c 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 @@ -10,6 +10,7 @@ package org.eclipse.osgi.internal.module; import java.util.*; import org.eclipse.osgi.service.resolver.BundleSpecification; +import org.eclipse.osgi.service.resolver.ExportPackageDescription; /* * The GroupingChecker checks the 'uses' directive on exported packages for consistency @@ -36,11 +37,16 @@ public class GroupingChecker { isConsistentInternal(bundle, selectedSupplier, new ArrayList(1), true, null); } // process all imports - ResolverImport[] imports = bundle.getImportPackages(); - for (int j = 0; j < imports.length; j++) { - ResolverExport selectedSupplier = (ResolverExport) imports[j].getSelectedSupplier(); - if (selectedSupplier != null) - isConsistentInternal(bundle, selectedSupplier, true, null); + // must check resolved imports to get any dynamically resolved imports + ExportPackageDescription[] imports = bundle.getBundle().getResolvedImports(); + for (int i = 0; i < imports.length; i++) { + ExportPackageDescription importPkg = imports[i]; + Object[] exports = bundle.getResolver().getResolverExports().get(importPkg.getName()); + for (int j = 0; j < exports.length; j++) { + ResolverExport export = (ResolverExport) exports[j]; + if (export.getExportPackageDescription() == importPkg) + isConsistentInternal(bundle, export, true, null); + } } } @@ -137,14 +143,30 @@ public class GroupingChecker { return null; visited.add(bundle); // prevent endless cycles // check imports - ResolverImport imported = bundle.getImport(packageName); - if (imported != null && imported.getSelectedSupplier() != null) { - // make sure we are not resolved to our own import - ResolverExport selectedExport = (ResolverExport) imported.getSelectedSupplier(); - if (selectedExport.getExporter() != bundle) { - // found resolved import; get the roots from the resolved exporter; - // this is all the roots if the package is imported - return getPackageRoots(selectedExport.getExporter(), packageName, visited); + if (bundle.getBundle().isResolved()) { + // must check resolved imports to get any dynamically resolved imports + ExportPackageDescription[] imports = bundle.getBundle().getResolvedImports(); + for (int i = 0; i < imports.length; i++) { + ExportPackageDescription importPkg = imports[i]; + if (importPkg.getExporter() == bundle.getBundle() || !importPkg.getName().equals(packageName)) + continue; + Object[] exports = bundle.getResolver().getResolverExports().get(packageName); + for (int j = 0; j < exports.length; j++) { + ResolverExport export = (ResolverExport) exports[j]; + if (export.getExportPackageDescription() == importPkg) + return getPackageRoots(export.getExporter(), packageName, visited); + } + } + } else { + ResolverImport imported = bundle.getImport(packageName); + if (imported != null && imported.getSelectedSupplier() != null) { + // make sure we are not resolved to our own import + ResolverExport selectedExport = (ResolverExport) imported.getSelectedSupplier(); + if (selectedExport.getExporter() != bundle) { + // found resolved import; get the roots from the resolved exporter; + // this is all the roots if the package is imported + return getPackageRoots(selectedExport.getExporter(), packageName, visited); + } } } // check if the bundle exports the package diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java index b692b1155..85acb74e1 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java @@ -64,10 +64,6 @@ public abstract class ResolverConstraint { // returns whether this constraint is optional abstract boolean isOptional(); - public void setPossibleSuppliers(VersionSupplier[] possibleSuppliers) { - this.possibleSuppliers = possibleSuppliers; - } - void addPossibleSupplier(VersionSupplier supplier) { if (supplier == null) return; 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 92864544b..24b650ab9 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 @@ -1578,7 +1578,7 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver resolverImports[j].setName(null); if (!found) { // not found or there was a conflict; reset the suppliers and return null - resolverImports[j].setPossibleSuppliers(null); + resolverImports[j].clearPossibleSuppliers(); return null; } // If the import resolved then return it's matching export @@ -1588,7 +1588,7 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver // If it is a wildcard import then clear the wire, so other // exported packages can be found for it if (importName.endsWith("*")) //$NON-NLS-1$ - resolverImports[j].setPossibleSuppliers(null); + resolverImports[j].clearPossibleSuppliers(); return matchingExport; } } |