diff options
author | Thomas Watson | 2004-06-10 21:19:38 +0000 |
---|---|---|
committer | Thomas Watson | 2004-06-10 21:19:38 +0000 |
commit | 758793b7d981f387fe32608bc3fd333e12ba1afc (patch) | |
tree | 41c73bcff6ec74f2d9ff1dad2cd580a2fb881b54 | |
parent | fee4a524913850668d589304d504a9b783e23b84 (diff) | |
download | rt.equinox.framework-758793b7d981f387fe32608bc3fd333e12ba1afc.tar.gz rt.equinox.framework-758793b7d981f387fe32608bc3fd333e12ba1afc.tar.xz rt.equinox.framework-758793b7d981f387fe32608bc3fd333e12ba1afc.zip |
Bug 61942v20040610b
dangerous practice of catching Throwable
9 files changed, 62 insertions, 7 deletions
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/FrameworkAdaptor.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/FrameworkAdaptor.java index 7c0232e11..b2b670083 100644 --- a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/FrameworkAdaptor.java +++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/FrameworkAdaptor.java @@ -290,4 +290,14 @@ public interface FrameworkAdaptor { * @return the parent ClassLoader for all BundleClassLoaders created. */ public ClassLoader getBundleClassLoaderParent(); + + /** + * Handles a RuntimeException or Error that was caught by the Framework and + * there is not a suitable caller to propagate the Throwable to. This gives + * the FrameworkAdaptor the ablity to handle such cases. For example, a + * FrameworkAdaptor may decide that such unexpected errors should cause an error + * message to be logged, or that the Framework should be terminated immediately. + * @param error The Throwable for the runtime error that is to be handled. + */ + public void handleRuntimeError(Throwable error); }
\ No newline at end of file diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleContextImpl.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleContextImpl.java index 500bfc22e..07daac3e7 100644 --- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleContextImpl.java +++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleContextImpl.java @@ -1187,7 +1187,8 @@ public class BundleContextImpl implements BundleContext, EventDispatcher { Debug.println("Exception in bottom level event dispatcher: " + t.getMessage()); //$NON-NLS-1$ Debug.printStackTrace(t); } - + // allow the adaptor to handle this unexpected error + framework.adaptor.handleRuntimeError(t); publisherror: { if (action == Framework.FRAMEWORKEVENT) { FrameworkEvent event = (FrameworkEvent) object; diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java index 6cd66318b..fcc080f5a 100644 --- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java +++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java @@ -1491,6 +1491,8 @@ public class Framework implements EventDispatcher, EventPublisher { Debug.println("Exception in Top level event dispatcher: " + t.getMessage()); //$NON-NLS-1$ Debug.printStackTrace(t); } + // allow the adaptor to handle this unexpected error + adaptor.handleRuntimeError(t); publisherror: { if (action == FRAMEWORKEVENT) { FrameworkEvent event = (FrameworkEvent) object; diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/ServiceUse.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/ServiceUse.java index bede8fe5b..b4438eb02 100644 --- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/ServiceUse.java +++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/ServiceUse.java @@ -112,10 +112,10 @@ public class ServiceUse { Debug.println(factory + ".getService() exception: " + t.getMessage()); //$NON-NLS-1$ Debug.printStackTrace(t); } - + // allow the adaptor to handle this unexpected error + context.framework.adaptor.handleRuntimeError(t); BundleException be = new BundleException(Msg.formatter.getString("SERVICE_FACTORY_EXCEPTION", factory.getClass().getName(), "getService"), t); //$NON-NLS-1$ //$NON-NLS-2$ context.framework.publishFrameworkEvent(FrameworkEvent.ERROR, factorybundle, be); - return (null); } diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java index 351d59950..db6443b52 100644 --- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java +++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java @@ -435,13 +435,18 @@ public class StartLevelManager implements EventDispatcher, EventListener, Servic * can complete the delivery of the event to the listener. */ public void dispatchEvent(Object listener, Object listenerObject, int eventAction, Object eventObject) { - switch (eventAction) { - case StartLevelEvent.CHANGE_BUNDLE_SL : + try { + switch (eventAction) { + case StartLevelEvent.CHANGE_BUNDLE_SL: setBundleSL((StartLevelEvent) eventObject); break; - case StartLevelEvent.CHANGE_FW_SL : + case StartLevelEvent.CHANGE_FW_SL: doSetStartLevel(((StartLevelEvent) eventObject).getNewSL(), ((StartLevelEvent) eventObject).getBundle()); break; + } + } catch (Throwable t) { + // allow the adaptor to handle this unexpected error + framework.adaptor.handleRuntimeError(t); } } diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/SystemBundle.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/SystemBundle.java index c95ada8aa..dabe6913d 100644 --- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/SystemBundle.java +++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/SystemBundle.java @@ -178,7 +178,12 @@ public class SystemBundle extends BundleHost { if (state == ACTIVE) { Thread shutdown = SecureAction.createThread(new Runnable() { public void run() { - framework.shutdown(); + try { + framework.shutdown(); + } catch (Throwable t) { + // allow the adaptor to handle this unexpected error + framework.adaptor.handleRuntimeError(t); + } } }, "System Bundle Shutdown"); //$NON-NLS-1$ diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractFrameworkAdaptor.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractFrameworkAdaptor.java index 02fc413ed..678c537a8 100644 --- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractFrameworkAdaptor.java +++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractFrameworkAdaptor.java @@ -377,6 +377,10 @@ public abstract class AbstractFrameworkAdaptor implements FrameworkAdaptor { return bundleClassLoaderParent; } + public void handleRuntimeError(Throwable error) { + // do nothing by default. + } + /** * Creates a BundleFile object from a File object and a BundleData * object. This implementation checks to see if the basefile is diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java index f0b285d37..61a4f725e 100644 --- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java +++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java @@ -39,6 +39,7 @@ import org.osgi.framework.*; */ public class EclipseAdaptor extends DefaultAdaptor { public static final String PROP_CLEAN = "osgi.clean"; //$NON-NLS-1$ + public static final String PROP_EXITONERROR = "eclipse.exitOnError"; //$NON-NLS-1$ static final String F_LOG = ".log"; //$NON-NLS-1$ //TODO rename it to Eclipse-PluginClass @@ -70,6 +71,7 @@ public class EclipseAdaptor extends DefaultAdaptor { private long timeStamp = 0; private String installURL = null; + private boolean exitOnError = true; /* * Should be instantiated only by the framework (through reflection). @@ -547,6 +549,31 @@ public class EclipseAdaptor extends DefaultAdaptor { new BundleStopper().stopBundles(); } + public void handleRuntimeError(Throwable error) { + try { + // check the prop each time this happens (should NEVER happen!) + exitOnError = Boolean.valueOf(System.getProperty(PROP_EXITONERROR, "true")).booleanValue(); //$NON-NLS-1$ + String message = EclipseAdaptorMsg.formatter.getString("ECLIPSE_ADAPTOR_RUNTIME_ERROR"); //$NON-NLS-1$ + FrameworkLogEntry logEntry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, message, 0, error, null); + frameworkLog.log(logEntry); + } catch (Throwable t) { + // we may be in a currupted state and must be able to handle any errors (ie OutOfMemoryError) + // that may occur when handling the first error; this is REALLY the last resort. + try { + error.printStackTrace(); + t.printStackTrace(); + } + catch (Throwable t1) { + // if we fail that then we are beyond help. + } + } + finally { + // do the exit outside the try block just incase another runtime error was thrown while logging + if (exitOnError) + System.exit(13); + } + } + protected void setLog(FrameworkLog log) { frameworkLog = log; } diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties index 291fcc2f3..61f27bab6 100644 --- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties +++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties @@ -14,6 +14,7 @@ #EclipseAdaptor messages ECLIPSE_ADAPTOR_ERROR_RM_CACHE=Cannot clean the cache directory {0}. ECLIPSE_ADAPTOR_ERROR_XML_SERVICE=Error registering XML parser services. +ECLIPSE_ADAPTOR_RUNTIME_ERROR=An unexpected runtime error has occurred. The application will terminate. #EclipseStarter messages ECLIPSE_STARTUP_BUNDLE_NOT_FOUND=Bundle {0} not found. |