Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/PlatformAdminTest.java87
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java33
2 files changed, 116 insertions, 4 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/PlatformAdminTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/PlatformAdminTest.java
index df2c7b597..7bfbf5356 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/PlatformAdminTest.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/PlatformAdminTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2007 IBM Corporation and others.
+ * Copyright (c) 2003, 2008 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,8 +14,8 @@ import java.io.*;
import java.util.Hashtable;
import junit.framework.Test;
import junit.framework.TestSuite;
-import org.eclipse.osgi.service.resolver.BundleDescription;
-import org.eclipse.osgi.service.resolver.State;
+import org.eclipse.osgi.internal.baseadaptor.StateManager;
+import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
@@ -71,6 +71,87 @@ public class PlatformAdminTest extends AbstractStateTest {
fail("Unexpected error while cloning a BundleDescription", t);
}
}
+
+ public void testBug184127() throws BundleException {
+ File resolverData = getContext().getDataFile("resolverData");
+ resolverData.mkdirs();
+
+ File stateFile = new File(resolverData, ".state");
+ File lazyFile = new File(resolverData, ".lazy");
+ stateFile.delete();
+ lazyFile.delete();
+ StateManager sm = new StateManager(stateFile, lazyFile, getContext());
+ State systemState = sm.readSystemState();
+ assertNull("SystemState is not null", systemState);
+ systemState = sm.createSystemState();
+
+ Hashtable manifest = new Hashtable();
+ int id = 0;
+ manifest = new Hashtable();
+
+ manifest.clear();
+ manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ manifest.put(Constants.BUNDLE_SYMBOLICNAME, "a");
+ manifest.put(Constants.BUNDLE_VERSION, "1.0.0");
+ BundleDescription a = systemState.getFactory().createBundleDescription(systemState, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME) + "_" + manifest.get(Constants.BUNDLE_VERSION), id++);
+
+ manifest.clear();
+ manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ manifest.put(Constants.BUNDLE_SYMBOLICNAME, "b");
+ manifest.put(Constants.BUNDLE_VERSION, "1.0.0");
+ manifest.put(Constants.EXPORT_PACKAGE, "b, c");
+ manifest.put(Constants.REQUIRE_BUNDLE, "a");
+ manifest.put(Constants.IMPORT_PACKAGE, "afrag2");
+ BundleDescription b = systemState.getFactory().createBundleDescription(systemState, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME) + "_" + manifest.get(Constants.BUNDLE_VERSION), id++);
+
+ manifest.clear();
+ manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ manifest.put(Constants.BUNDLE_SYMBOLICNAME, "afrag2");
+ manifest.put(Constants.BUNDLE_VERSION, "1.0.0");
+ manifest.put(Constants.EXPORT_PACKAGE, "afrag2");
+ manifest.put(Constants.FRAGMENT_HOST, "a");
+ manifest.put(Constants.IMPORT_PACKAGE, "c");
+ BundleDescription afrag2 = systemState.getFactory().createBundleDescription(systemState, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME) + "_" + manifest.get(Constants.BUNDLE_VERSION), id++);
+
+ manifest.clear();
+ manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ manifest.put(Constants.BUNDLE_SYMBOLICNAME, "afrag1");
+ manifest.put(Constants.BUNDLE_VERSION, "1.0.0");
+ manifest.put(Constants.FRAGMENT_HOST, "a");
+ manifest.put(Constants.IMPORT_PACKAGE, "b");
+ BundleDescription afrag1 = systemState.getFactory().createBundleDescription(systemState, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME) + "_" + manifest.get(Constants.BUNDLE_VERSION), id++);
+
+ systemState.addBundle(afrag1);
+ systemState.addBundle(afrag2);
+ systemState.addBundle(a);
+ systemState.addBundle(b);
+
+ systemState.resolve();
+
+ assertTrue("aFrag1 is not resolved", afrag1.isResolved());
+ assertTrue("aFrag2 is not resolved", afrag2.isResolved());
+ assertTrue("a is not resolved", a.isResolved());
+ assertTrue("b is not resolved", b.isResolved());
+
+ try {
+ sm.shutdown(stateFile, lazyFile);
+ } catch (IOException e) {
+ fail("failed to shudown StateManager", e);
+ }
+
+ sm = new StateManager(stateFile, lazyFile, getContext());
+ systemState = sm.readSystemState();
+ assertNotNull("SystemState is null", systemState);
+ b = systemState.getBundle("b", null);
+ ExportPackageDescription[] exports = null;
+ try {
+ exports = b.getExportPackages();
+ } catch (Throwable e) {
+ fail("Unexpected exception getting exports", e);
+ }
+ assertNotNull("exports is null", exports);
+ assertEquals("Wrong number of exports", 2, exports.length);
+ }
}
//TODO tests to enable
//testFragmentUpdateNoVersionChanged()
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java
index 53aea0764..d6d453ee4 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java
@@ -233,7 +233,38 @@ public class StateHelperImpl implements StateHelper {
for (int i = 0; i < toSort.length; i++)
if (toSort[i].isResolved())
buildReferences(toSort[i], references);
- return ComputeNodeOrder.computeNodeOrder(toSort, (Object[][]) references.toArray(new Object[references.size()][]));
+ Object[][] cycles = ComputeNodeOrder.computeNodeOrder(toSort, (Object[][]) references.toArray(new Object[references.size()][]));
+ if (cycles.length == 0)
+ return cycles;
+ // fix up host/fragment orders (bug 184127)
+ for (int i = 0; i < cycles.length; i++) {
+ for (int j = 0; j < cycles[i].length; j++) {
+ BundleDescription fragment = (BundleDescription) cycles[i][j];
+ if (fragment.getHost() == null)
+ continue;
+ BundleDescription host = (BundleDescription) fragment.getHost().getSupplier();
+ if (host == null)
+ continue;
+ fixFragmentOrder(host, fragment, toSort);
+ }
+ }
+ return cycles;
+ }
+
+ private void fixFragmentOrder(BundleDescription host, BundleDescription fragment, BundleDescription[] toSort) {
+ int hostIndex = -1;
+ int fragIndex = -1;
+ for (int i = 0; i < toSort.length && (hostIndex == -1 || fragIndex == -1); i++) {
+ if (toSort[i] == host)
+ hostIndex = i;
+ else if (toSort[i] == fragment)
+ fragIndex = i;
+ }
+ if (fragIndex > -1 && fragIndex < hostIndex) {
+ for (int i = fragIndex; i < hostIndex; i++)
+ toSort[i] = toSort[i + 1];
+ toSort[hostIndex] = fragment;
+ }
}
private void buildReferences(BundleDescription description, List references) {

Back to the top