You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tv...@apache.org on 2026/04/14 13:47:15 UTC
(commons-jcs) 01/03: JCS-247: Allow CacheMonitor to survive RuntimExceptions
This is an automated email from the ASF dual-hosted git repository.
tv pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jcs.git
commit e5c331dcf746c3425dfedb5831ea7f7292d2552e
Author: Thomas Vandahl <tv...@apache.org>
AuthorDate: Tue Apr 14 15:44:02 2026 +0200
JCS-247: Allow CacheMonitor to survive RuntimExceptions
---
.../auxiliary/AbstractAuxiliaryCacheMonitor.java | 11 ++-
.../auxiliary/lateral/LateralCacheMonitor.java | 2 +-
.../jcs4/auxiliary/remote/RemoteCacheMonitor.java | 2 +-
.../remote/http/client/RemoteHttpCacheMonitor.java | 2 +-
.../AbstractAuxiliaryCacheMonitorUnitTest.java | 89 ++++++++++++++++++++++
.../lateral/socket/tcp/TestTCPLateralUnitTest.java | 2 +-
6 files changed, 102 insertions(+), 6 deletions(-)
diff --git a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/AbstractAuxiliaryCacheMonitor.java b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/AbstractAuxiliaryCacheMonitor.java
index b5b0bd04..87136fe1 100644
--- a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/AbstractAuxiliaryCacheMonitor.java
+++ b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/AbstractAuxiliaryCacheMonitor.java
@@ -88,7 +88,7 @@ public abstract class AbstractAuxiliaryCacheMonitor extends Thread
/**
* do actual work
*/
- protected abstract void doWork();
+ protected abstract void doWork() throws Exception;
/**
* Notifies the cache monitor that an error occurred, and kicks off the error recovery process.
@@ -162,7 +162,14 @@ public abstract class AbstractAuxiliaryCacheMonitor extends Thread
log.debug( "Cache monitor running." );
- doWork();
+ try
+ {
+ doWork();
+ }
+ catch (Exception e)
+ {
+ log.error("Cache monitor loop threw exception", e);
+ }
try
{
diff --git a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/lateral/LateralCacheMonitor.java b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/lateral/LateralCacheMonitor.java
index deec07d0..4f92a8bb 100644
--- a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/lateral/LateralCacheMonitor.java
+++ b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/lateral/LateralCacheMonitor.java
@@ -108,7 +108,7 @@ public class LateralCacheMonitor extends AbstractAuxiliaryCacheMonitor
* Main processing method for the LateralCacheMonitor object
*/
@Override
- public void doWork()
+ public void doWork() throws Exception
{
// Monitor each cache instance one after the other.
log.info( "Number of caches to monitor = " + caches.size() );
diff --git a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/remote/RemoteCacheMonitor.java b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/remote/RemoteCacheMonitor.java
index ae3dca4b..47d01729 100644
--- a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/remote/RemoteCacheMonitor.java
+++ b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/remote/RemoteCacheMonitor.java
@@ -79,7 +79,7 @@ public class RemoteCacheMonitor extends AbstractAuxiliaryCacheMonitor
// just skip the monitoring until the next round.
/** Main processing method for the RemoteCacheMonitor object */
@Override
- public void doWork()
+ public void doWork() throws Exception
{
// Monitor each RemoteCacheManager instance one after the other.
// Each RemoteCacheManager corresponds to one remote connection.
diff --git a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/remote/http/client/RemoteHttpCacheMonitor.java b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/remote/http/client/RemoteHttpCacheMonitor.java
index e135cd75..4de784b2 100644
--- a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/remote/http/client/RemoteHttpCacheMonitor.java
+++ b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/auxiliary/remote/http/client/RemoteHttpCacheMonitor.java
@@ -68,7 +68,7 @@ public class RemoteHttpCacheMonitor extends AbstractAuxiliaryCacheMonitor
// just skip the monitoring until the next round.
/** Main processing method for the RemoteHttpCacheMonitor object */
@Override
- protected void doWork()
+ protected void doWork() throws Exception
{
// If no factory has been set, skip
if (factory == null)
diff --git a/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/auxiliary/AbstractAuxiliaryCacheMonitorUnitTest.java b/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/auxiliary/AbstractAuxiliaryCacheMonitorUnitTest.java
new file mode 100644
index 00000000..86f0352c
--- /dev/null
+++ b/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/auxiliary/AbstractAuxiliaryCacheMonitorUnitTest.java
@@ -0,0 +1,89 @@
+package org.apache.commons.jcs4.auxiliary;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Basic unit tests for the cache monitor.
+ */
+class AbstractAuxiliaryCacheMonitorUnitTest
+{
+ /**
+ * Test that the cache monitor survives runtime exceptions in doWork()
+ *
+ * @throws Exception
+ */
+ @Test
+ void testCacheMonitorResilience() throws Exception
+ {
+ // reduce the monitor idle period between 'fix' attempts for testing purposes
+ MockCacheMonitor.setIdle(100L);
+
+ final MockCacheMonitor monitor = new MockCacheMonitor();
+ monitor.start();
+ monitor.notifyError();
+ Thread.sleep(200L);
+ monitor.notifyError();
+ Thread.sleep(200L);
+
+ // verify that the monitor has been called multiple times
+ assertTrue(1 < monitor.doWorkCalls, "Should have multiple calls " + monitor.doWorkCalls);
+
+ monitor.notifyShutdown();
+ Thread.sleep(200L);
+ // verify that the monitor shutdown has been called once
+ assertEquals(1, monitor.disposeCalls, "Should have one call");
+ }
+
+ // used to reduce the monitor idle period between 'fix' attempts for testing purposes
+ private static class MockCacheMonitor extends AbstractAuxiliaryCacheMonitor
+ {
+ protected int doWorkCalls = 0;
+ protected int disposeCalls = 0;
+
+ public static void setIdle(long idlePeriod)
+ {
+ AbstractAuxiliaryCacheMonitor.idlePeriod = idlePeriod;
+ }
+
+ public MockCacheMonitor()
+ {
+ super("test");
+ }
+
+ @Override
+ protected void dispose()
+ {
+ disposeCalls++;
+ }
+
+ @Override
+ protected void doWork() throws Exception
+ {
+ doWorkCalls++;
+ throw new NullPointerException("test");
+ }
+ }
+}
diff --git a/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/auxiliary/lateral/socket/tcp/TestTCPLateralUnitTest.java b/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/auxiliary/lateral/socket/tcp/TestTCPLateralUnitTest.java
index fe03f324..6f743625 100644
--- a/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/auxiliary/lateral/socket/tcp/TestTCPLateralUnitTest.java
+++ b/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/auxiliary/lateral/socket/tcp/TestTCPLateralUnitTest.java
@@ -406,7 +406,7 @@ class TestTCPLateralUnitTest
}
@Override
- protected void doWork()
+ protected void doWork() throws Exception
{
// nothing to do
}