Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=51610
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 5 Aug 2011 16:29:58 +0000 (16:29 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 5 Aug 2011 16:29:58 +0000 (16:29 +0000)
Make lifecycle transitions more robust at handling unchecked exceptions

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1154297 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/util/LifecycleBase.java
java/org/apache/catalina/util/LocalStrings.properties
webapps/docs/changelog.xml

index 72ed847..7e7c56c 100644 (file)
@@ -23,6 +23,7 @@ import org.apache.catalina.LifecycleListener;
 import org.apache.catalina.LifecycleState;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.ExceptionUtils;
 import org.apache.tomcat.util.res.StringManager;
 
 
@@ -99,9 +100,11 @@ public abstract class LifecycleBase implements Lifecycle {
 
         try {
             initInternal();
-        } catch (LifecycleException e) {
+        } catch (Throwable t) {
+            ExceptionUtils.handleThrowable(t);
             setStateInternal(LifecycleState.FAILED, null, false);
-            throw e;
+            throw new LifecycleException(
+                    sm.getString("lifecycleBase.initFail",toString()), t);
         }
 
         setStateInternal(LifecycleState.INITIALIZED, null, false);
@@ -143,9 +146,11 @@ public abstract class LifecycleBase implements Lifecycle {
 
         try {
             startInternal();
-        } catch (LifecycleException e) {
+        } catch (Throwable t) {
+            ExceptionUtils.handleThrowable(t);
             setStateInternal(LifecycleState.FAILED, null, false);
-            throw e;
+            throw new LifecycleException(
+                    sm.getString("lifecycleBase.startFail",toString()), t);
         }
 
         if (state.equals(LifecycleState.FAILED) ||
@@ -223,9 +228,11 @@ public abstract class LifecycleBase implements Lifecycle {
 
         try {
             stopInternal();
-        } catch (LifecycleException e) {
+        } catch (Throwable t) {
+            ExceptionUtils.handleThrowable(t);
             setStateInternal(LifecycleState.FAILED, null, false);
-            throw e;
+            throw new LifecycleException(
+                    sm.getString("lifecycleBase.stopFail",toString()), t);
         }
 
         if (state.equals(LifecycleState.MUST_DESTROY)) {
@@ -283,9 +290,11 @@ public abstract class LifecycleBase implements Lifecycle {
         
         try {
             destroyInternal();
-        } catch (LifecycleException e) {
+        } catch (Throwable t) {
+            ExceptionUtils.handleThrowable(t);
             setStateInternal(LifecycleState.FAILED, null, false);
-            throw e;
+            throw new LifecycleException(
+                    sm.getString("lifecycleBase.destroyFail",toString()), t);
         }
         
         setStateInternal(LifecycleState.DESTROYED, null, false);
index af98d77..7a4d262 100644 (file)
@@ -22,12 +22,16 @@ extensionValidator.web-application-manifest=Web Application Manifest
 extensionValidator.extension-not-found-error=ExtensionValidator[{0}][{1}]: Required extension [{2}] not found.
 extensionValidator.extension-validation-error=ExtensionValidator[{0}]: Failure to find [{1}] required extension(s).
 extensionValidator.failload=Failure loading extension [{0}]
-lifecycleBase.initMBeanFail=Failed to register component [{0}] with MBean name [{1}]
+lifecycleBase.alreadyDestroyed=The destroy() method was called on component [{0}] after destroy() had already been called. The second call will be ignored.
 lifecycleBase.alreadyStarted=The start() method was called on component [{0}] after start() had already been called. The second call will be ignored.
 lifecycleBase.alreadyStopped=The stop() method was called on component [{0}] after stop() had already been called. The second call will be ignored.
-lifecycleBase.alreadyDestroyed=The destroy() method was called on component [{0}] after destroy() had already been called. The second call will be ignored.
+lifecycleBase.destroyFail=Failed to destroy component [{0}]
+lifecycleBase.initFail=Failed to initialize component [{0}]
+lifecycleBase.initMBeanFail=Failed to register component [{0}] with MBean name [{1}]
 lifecycleBase.invalidTransition=An invalid Lifecycle transition was attempted ([{0}]) for component [{1}] in state [{2}]
 lifecycleBase.setState=Setting state for [{0}] to [{1}]
+lifecycleBase.startFail=Failed to start component [{0}]
+lifecycleBase.stopFail=Failed to stop component [{0}]
 lifecycleMBeanBase.registerFail=Failed to register object [{0}] with name [{0}] during component initialisation
 lifecycleMBeanBase.unregisterFail=Failed to unregister MBean with name [{0}] during component destruction
 lifecycleMBeanBase.unregisterNoServer=No MBean server was available to unregister the MBean [{0}]
index 4667eed..1ced493 100644 (file)
         in the same Context). (kkolinko)
       </fix>
       <fix>
+        <bug>51610</bug>: If an unchecked exception occurs during a lifecycle
+        transition (e.g. web application start) ensure that the component is
+        put into the failed state. (markt)
+      </fix>
+      <fix>
         <bug>51614</bug>: Avoid calling store.load() and  session.expire()
         twice in PersistentManager when expiring sessions. (kfujino)
       </fix>