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 <[email protected]>
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
         }

Reply via email to