This is an automated email from the ASF dual-hosted git repository. remm pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push: new 8d46615fdd Add FAILED_INIT lifecycle state 8d46615fdd is described below commit 8d46615fdd248483e8f10cc6cd130839c429d508 Author: remm <r...@apache.org> AuthorDate: Sat Oct 26 00:11:02 2024 +0200 Add FAILED_INIT lifecycle state Differentiate FAILED after init, otherwise the component could become started. start() would call stop() after FAILED, despite the component never having completed init. After that the state might become STOPPED, paving the way for a subsequent successful start in some cases. This could happen with a TLS enabled connector in particular, where init() would fail for some reason. --- java/org/apache/catalina/LifecycleState.java | 3 ++- java/org/apache/catalina/util/LifecycleBase.java | 23 ++++++++++++++++++----- webapps/docs/changelog.xml | 6 ++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/java/org/apache/catalina/LifecycleState.java b/java/org/apache/catalina/LifecycleState.java index ec0fd2d10e..cc9a91005f 100644 --- a/java/org/apache/catalina/LifecycleState.java +++ b/java/org/apache/catalina/LifecycleState.java @@ -32,7 +32,8 @@ public enum LifecycleState { STOPPED(false, Lifecycle.AFTER_STOP_EVENT), DESTROYING(false, Lifecycle.BEFORE_DESTROY_EVENT), DESTROYED(false, Lifecycle.AFTER_DESTROY_EVENT), - FAILED(false, null); + FAILED(false, null), + FAILED_INIT(false, null); private final boolean available; private final String lifecycleEvent; diff --git a/java/org/apache/catalina/util/LifecycleBase.java b/java/org/apache/catalina/util/LifecycleBase.java index ec7abb1b22..075a349a1a 100644 --- a/java/org/apache/catalina/util/LifecycleBase.java +++ b/java/org/apache/catalina/util/LifecycleBase.java @@ -153,9 +153,14 @@ public abstract class LifecycleBase implements Lifecycle { if (state.equals(LifecycleState.NEW)) { init(); - } else if (state.equals(LifecycleState.FAILED)) { + } + if (state.equals(LifecycleState.FAILED)) { stop(); - } else if (!state.equals(LifecycleState.INITIALIZED) && !state.equals(LifecycleState.STOPPED)) { + } else if (state.equals(LifecycleState.FAILED_INIT)) { + destroy(); + return; + } + if (!state.equals(LifecycleState.INITIALIZED) && !state.equals(LifecycleState.STOPPED)) { invalidTransition(BEFORE_START_EVENT); } @@ -285,7 +290,8 @@ public abstract class LifecycleBase implements Lifecycle { } if (!state.equals(LifecycleState.STOPPED) && !state.equals(LifecycleState.FAILED) && - !state.equals(LifecycleState.NEW) && !state.equals(LifecycleState.INITIALIZED)) { + !state.equals(LifecycleState.NEW) && !state.equals(LifecycleState.INITIALIZED) && + !state.equals(LifecycleState.FAILED_INIT)) { invalidTransition(BEFORE_DESTROY_EVENT); } @@ -371,9 +377,12 @@ public abstract class LifecycleBase implements Lifecycle { // stopInternal() permits STOPPING_PREP to STOPPING and FAILED to // STOPPING if (!(state == LifecycleState.FAILED || + (this.state == LifecycleState.INITIALIZING && state == LifecycleState.FAILED_INIT) || + (this.state == LifecycleState.DESTROYING && state == LifecycleState.FAILED_INIT) || (this.state == LifecycleState.STARTING_PREP && state == LifecycleState.STARTING) || (this.state == LifecycleState.STOPPING_PREP && state == LifecycleState.STOPPING) || - (this.state == LifecycleState.FAILED && state == LifecycleState.STOPPING))) { + (this.state == LifecycleState.FAILED && state == LifecycleState.STOPPING) || + (this.state == LifecycleState.FAILED_INIT && state == LifecycleState.DESTROYING))) { // No other transition permitted invalidTransition(state.name()); } @@ -394,7 +403,11 @@ public abstract class LifecycleBase implements Lifecycle { private void handleSubClassException(Throwable t, String key, Object... args) throws LifecycleException { - setStateInternal(LifecycleState.FAILED, null, false); + if (LifecycleState.INITIALIZING.equals(state) || LifecycleState.DESTROYING.equals(state)) { + setStateInternal(LifecycleState.FAILED_INIT, null, false); + } else { + setStateInternal(LifecycleState.FAILED, null, false); + } ExceptionUtils.handleThrowable(t); String msg = sm.getString(key, args); if (getThrowOnFailure()) { diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 2353c25812..6dc80dcb13 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -199,6 +199,12 @@ Implement WebDAV <code>PROPPATCH</code> method using the newly added <code>PropertyStore</code>. (remm) </update> + <update> + Add new <code>lifecycleState.FAILED_INIT</code> to identify failures + during initialization. Otherwise, start and stop could be attempted + on a <code>Lifecycle</code> that did not go through initialization. + (remm) + </update> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org