--- java/org/apache/catalina/core/ContainerBase.java (revision 1610400) +++ java/org/apache/catalina/core/ContainerBase.java (working copy) @@ -1335,14 +1335,51 @@ @Override public void run() { - while (!threadDone) { - try { - Thread.sleep(backgroundProcessorDelay * 1000L); - } catch (InterruptedException e) { - // Ignore + Throwable t = null; + String unexpectedDeathMessage = sm.getString( + "containerBase.backgroundProcess.unexpectedThreadDeath", + Thread.currentThread().getName()); + try { + while (!threadDone) { + try { + Thread.sleep(backgroundProcessorDelay * 1000L); + } catch (InterruptedException e) { + // Ignore + } + if (!threadDone) { + processChildren(ContainerBase.this); + } } + } catch (RuntimeException|Error e) { + t = e; + throw e; + } finally { + thread = null; if (!threadDone) { - processChildren(ContainerBase.this); + log.error(unexpectedDeathMessage, t); + if (t instanceof ThreadDeath + || backgroundProcessorDelay <= 0 + || !getState().isAvailable()) { + return; + } + try { + Thread.sleep(backgroundProcessorDelay * 1000L); + } catch (InterruptedException e) { + // Ignore + } + if (threadDone || backgroundProcessorDelay <= 0 + || !getState().isAvailable()) { + return; + } + try { + log.info(sm.getString( + "containerBase.backgroundProcess.restarting", + ContainerBase.this), t); + threadStart(); + } catch (RuntimeException | Error e) { + log.error(unexpectedDeathMessage, e); + throw e; + } } } } --- java/org/apache/catalina/core/LocalStrings.properties (revision 1610400) +++ java/org/apache/catalina/core/LocalStrings.properties (working copy) @@ -81,6 +81,8 @@ containerBase.backgroundProcess.cluster=Exception processing cluster {0} background process containerBase.backgroundProcess.realm=Exception processing realm {0} background process containerBase.backgroundProcess.valve=Exception processing valve {0} background process +containerBase.backgroundProcess.unexpectedThreadDeath=Unexpected death of background thread {0} +containerBase.backgroundProcess.restarting=Restarting background thread for {0} defaultInstanceManager.invalidInjection=Invalid method resource injection annotation filterChain.filter=Filter execution threw an exception filterChain.servlet=Servlet execution threw an exception