Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2012-01-31 20:27:12 +0000
committerThomas Watson2012-01-31 20:27:12 +0000
commit3c44a9bf479eca906fbba996777583acf40d6721 (patch)
tree5e4dda18c34f545c750ebf88c4d7e5fcb4219e7e
parenta05b273883a39de44a4e65c1eaea59e9d749a95e (diff)
downloadrt.equinox.framework-3c44a9bf479eca906fbba996777583acf40d6721.tar.gz
rt.equinox.framework-3c44a9bf479eca906fbba996777583acf40d6721.tar.xz
rt.equinox.framework-3c44a9bf479eca906fbba996777583acf40d6721.zip
Bug 370258 - [R5] Clarification for calls to ResolverHook.endv20120131-2027
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java116
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/CoreResolverHookFactory.java47
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java6
3 files changed, 152 insertions, 17 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java
index 1c537882b..aed625b6c 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2011 IBM Corporation and others.
+ * Copyright (c) 2006, 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
@@ -1697,6 +1697,120 @@ public class ClassLoadingBundleTests extends AbstractBundleTests {
}
}
+ public void testBug370258_beginException() {
+ final boolean[] endCalled = {false};
+ ResolverHookFactory endHook = new ResolverHookFactory() {
+ public ResolverHook begin(Collection triggers) {
+ return new ResolverHook() {
+ public void filterSingletonCollisions(BundleCapability singleton, Collection collisionCandidates) {
+ // Nothing
+ }
+
+ public void filterResolvable(Collection candidates) {
+ throw new RuntimeException("Error");
+ }
+
+ public void filterMatches(BundleRequirement requirement, Collection candidates) {
+ // Nothing
+ }
+
+ public void end() {
+ endCalled[0] = true;
+ }
+ };
+ }
+ };
+ ResolverHookFactory error = new ResolverHookFactory() {
+ public ResolverHook begin(Collection triggers) {
+ throw new RuntimeException("Error");
+ }
+ };
+
+ ServiceRegistration endReg = OSGiTestsActivator.getContext().registerService(ResolverHookFactory.class, endHook, null);
+ ServiceRegistration errorReg = OSGiTestsActivator.getContext().registerService(ResolverHookFactory.class, error, null);
+ try {
+ Bundle test = installer.installBundle("test"); //$NON-NLS-1$
+ try {
+ test.start();
+ fail("Should not be able to start this bundle");
+ } catch (BundleException e) {
+ // expected
+ assertEquals("Wrong exception type.", BundleException.REJECTED_BY_HOOK, e.getType());
+ }
+ } catch (BundleException e) {
+ fail("Unexpected install fail", e);
+ } finally {
+ errorReg.unregister();
+ endReg.unregister();
+ }
+ assertTrue("end is not called", endCalled[0]);
+ }
+
+ public void testBug370258_endException() {
+ final boolean[] endCalled = {false};
+ ResolverHookFactory endHook = new ResolverHookFactory() {
+ public ResolverHook begin(Collection triggers) {
+ return new ResolverHook() {
+ public void filterSingletonCollisions(BundleCapability singleton, Collection collisionCandidates) {
+ // Nothing
+ }
+
+ public void filterResolvable(Collection candidates) {
+ throw new RuntimeException("Error");
+ }
+
+ public void filterMatches(BundleRequirement requirement, Collection candidates) {
+ // Nothing
+ }
+
+ public void end() {
+ endCalled[0] = true;
+ }
+ };
+ }
+ };
+ ResolverHookFactory error = new ResolverHookFactory() {
+ public ResolverHook begin(Collection triggers) {
+ return new ResolverHook() {
+ public void filterSingletonCollisions(BundleCapability singleton, Collection collisionCandidates) {
+ // Nothing
+ }
+
+ public void filterResolvable(Collection candidates) {
+ // Nothing
+ }
+
+ public void filterMatches(BundleRequirement requirement, Collection candidates) {
+ // Nothing
+ }
+
+ public void end() {
+ throw new RuntimeException("Error");
+ }
+ };
+ }
+ };
+
+ ServiceRegistration errorReg = OSGiTestsActivator.getContext().registerService(ResolverHookFactory.class, error, null);
+ ServiceRegistration endReg = OSGiTestsActivator.getContext().registerService(ResolverHookFactory.class, endHook, null);
+ try {
+ Bundle test = installer.installBundle("test"); //$NON-NLS-1$
+ try {
+ test.start();
+ fail("Should not be able to start this bundle");
+ } catch (BundleException e) {
+ // expected
+ assertEquals("Wrong exception type.", BundleException.REJECTED_BY_HOOK, e.getType());
+ }
+ } catch (BundleException e) {
+ fail("Unexpected install fail", e);
+ } finally {
+ errorReg.unregister();
+ endReg.unregister();
+ }
+ assertTrue("end is not called", endCalled[0]);
+ }
+
private void doTestArrayTypeLoad(String name) {
try {
Class arrayType = OSGiTestsActivator.getContext().getBundle().loadClass(name);
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/CoreResolverHookFactory.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/CoreResolverHookFactory.java
index 3e5b3cffc..986de041d 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/CoreResolverHookFactory.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/CoreResolverHookFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2011 IBM Corporation and others.
+ * Copyright (c) 2010, 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
@@ -15,7 +15,6 @@ import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.internal.serviceregistry.*;
import org.eclipse.osgi.service.resolver.ResolverHookException;
import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.Bundle;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.hooks.resolver.ResolverHook;
import org.osgi.framework.hooks.resolver.ResolverHookFactory;
@@ -50,7 +49,7 @@ public class CoreResolverHookFactory implements ResolverHookFactory {
this.registry = registry;
}
- void handleHookException(Throwable t, Object hook, String method, Bundle hookBundle, List<HookReference> hookRefs) {
+ void handleHookException(Throwable t, Object hook, String method) {
if (Debug.DEBUG_HOOKS) {
Debug.println(hook.getClass().getName() + "." + method + "() exception:"); //$NON-NLS-1$ //$NON-NLS-2$
if (t != null)
@@ -87,7 +86,13 @@ public class CoreResolverHookFactory implements ResolverHookFactory {
if (hook != null)
hookRefs.add(new HookReference(hookRef, hook));
} catch (Throwable t) {
- handleHookException(t, factory, "begin", hookRef.getBundle(), hookRefs); //$NON-NLS-1$
+ // need to force an end call on the ResolverHooks we got and release them
+ try {
+ new CoreResolverHook(hookRefs).end();
+ } catch (Throwable endError) {
+ // we are already in failure mode; just continue
+ }
+ handleHookException(t, factory, "begin"); //$NON-NLS-1$
}
}
}
@@ -117,12 +122,12 @@ public class CoreResolverHookFactory implements ResolverHookFactory {
for (Iterator<HookReference> iHooks = hooks.iterator(); iHooks.hasNext();) {
HookReference hookRef = iHooks.next();
if (hookRef.reference.getBundle() == null) {
- handleHookException(null, hookRef.hook, "filterResolvable", hookRef.reference.getBundle(), hooks); //$NON-NLS-1$
+ handleHookException(null, hookRef.hook, "filterResolvable"); //$NON-NLS-1$
} else {
try {
hookRef.hook.filterResolvable(candidates);
} catch (Throwable t) {
- handleHookException(t, hookRef.hook, "filterResolvable", hookRef.reference.getBundle(), hooks); //$NON-NLS-1$
+ handleHookException(t, hookRef.hook, "filterResolvable"); //$NON-NLS-1$
}
}
}
@@ -138,12 +143,12 @@ public class CoreResolverHookFactory implements ResolverHookFactory {
for (Iterator<HookReference> iHooks = hooks.iterator(); iHooks.hasNext();) {
HookReference hookRef = iHooks.next();
if (hookRef.reference.getBundle() == null) {
- handleHookException(null, hookRef.hook, "filterSingletonCollisions", hookRef.reference.getBundle(), hooks); //$NON-NLS-1$
+ handleHookException(null, hookRef.hook, "filterSingletonCollisions"); //$NON-NLS-1$
} else {
try {
hookRef.hook.filterSingletonCollisions(singleton, collisionCandidates);
} catch (Throwable t) {
- handleHookException(t, hookRef.hook, "filterSingletonCollisions", hookRef.reference.getBundle(), hooks); //$NON-NLS-1$
+ handleHookException(t, hookRef.hook, "filterSingletonCollisions"); //$NON-NLS-1$
}
}
}
@@ -159,12 +164,12 @@ public class CoreResolverHookFactory implements ResolverHookFactory {
for (Iterator<HookReference> iHooks = hooks.iterator(); iHooks.hasNext();) {
HookReference hookRef = iHooks.next();
if (hookRef.reference.getBundle() == null) {
- handleHookException(null, hookRef.hook, "filterMatches", hookRef.reference.getBundle(), hooks); //$NON-NLS-1$
+ handleHookException(null, hookRef.hook, "filterMatches"); //$NON-NLS-1$
} else {
try {
hookRef.hook.filterMatches(requirement, candidates);
} catch (Throwable t) {
- handleHookException(t, hookRef.hook, "filterMatches", hookRef.reference.getBundle(), hooks); //$NON-NLS-1$
+ handleHookException(t, hookRef.hook, "filterMatches"); //$NON-NLS-1$
}
}
}
@@ -177,18 +182,32 @@ public class CoreResolverHookFactory implements ResolverHookFactory {
if (hooks.isEmpty())
return;
try {
+ HookReference missingHook = null;
+ Throwable endError = null;
+ HookReference endBadHook = null;
for (Iterator<HookReference> iHooks = hooks.iterator(); iHooks.hasNext();) {
HookReference hookRef = iHooks.next();
- // We do not remove unregistered services here because we are going to remove of of them at the end
- if (hookRef.reference.getBundle() != null) {
+ // We do not remove unregistered services here because we are going to remove all of them at the end
+ if (hookRef.reference.getBundle() == null) {
+ if (missingHook == null)
+ missingHook = hookRef;
+ } else {
try {
hookRef.hook.end();
} catch (Throwable t) {
- handleHookException(t, hookRef.hook, "end", hookRef.reference.getBundle(), hooks); //$NON-NLS-1$
+ // Must continue on to the next hook.end method
+ // save the error for throwing at the end
+ if (endError == null) {
+ endError = t;
+ endBadHook = hookRef;
+ }
}
-
}
}
+ if (missingHook != null)
+ handleHookException(null, missingHook.hook, "end"); //$NON-NLS-1$
+ if (endError != null)
+ handleHookException(endError, endBadHook.hook, "end"); //$NON-NLS-1$
} finally {
releaseHooks(hooks);
}
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 a57207539..346a7eda9 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
@@ -494,6 +494,10 @@ public class ResolverImpl implements Resolver {
current.end();
}
+ // set the resolved status of the bundles in the State
+ // Note this must be done after calling end above in case end throws errors
+ stateResolveBundles(bundleMapping.values().toArray(new ResolverBundle[bundleMapping.size()]));
+
for (ResolverBundle bundle : optionalResolved) {
state.resolveBundle(bundle.getBundleDescription(), false, null, null, null, null, null, null, null, null);
stateResolveBundle(bundle);
@@ -649,8 +653,6 @@ public class ResolverImpl implements Resolver {
resolveBundles0(bundles, platformProperties);
if (DEBUG_WIRING)
printWirings();
- // set the resolved status of the bundles in the State
- stateResolveBundles(bundleMapping.values().toArray(new ResolverBundle[bundleMapping.size()]));
}
private void selectSingletons(ResolverBundle[] bundles) {

Back to the top