This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/11.0.x by this push:
     new 2ceae8fb1a Ensure evictions from the static resource cache are in the 
correct order
2ceae8fb1a is described below

commit 2ceae8fb1a2114c5053fefca6537554fea4bf7e7
Author: Mark Thomas <[email protected]>
AuthorDate: Thu Sep 3 09:18:58 2026 +0100

    Ensure evictions from the static resource cache are in the correct order
---
 java/org/apache/catalina/webresources/Cache.java     | 10 ++++++----
 .../apache/catalina/webresources/CachedResource.java | 20 +++++++++++++++-----
 webapps/docs/changelog.xml                           |  4 ++++
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/java/org/apache/catalina/webresources/Cache.java 
b/java/org/apache/catalina/webresources/Cache.java
index f1b1076ea3..55ce6b649f 100644
--- a/java/org/apache/catalina/webresources/Cache.java
+++ b/java/org/apache/catalina/webresources/Cache.java
@@ -72,8 +72,9 @@ public class Cache {
     /**
      * Retrieves a single resource from the cache.
      *
-     * @param path resource path
+     * @param path                    resource path
      * @param useClassLoaderResources whether to use class loader resources
+     *
      * @return the web resource
      */
     protected WebResource getResource(String path, boolean 
useClassLoaderResources) {
@@ -170,8 +171,9 @@ public class Cache {
     /**
      * Retrieves multiple resources from the cache.
      *
-     * @param path resource path
+     * @param path                    resource path
      * @param useClassLoaderResources whether to use class loader resources
+     *
      * @return the web resources
      */
     protected WebResource[] getResources(String path, boolean 
useClassLoaderResources) {
@@ -243,8 +245,8 @@ public class Cache {
         // Create an ordered set of all cached resources with the least 
recently
         // used first. This is a background process so we can afford to take 
the
         // time to order the elements first
-        TreeSet<CachedResource> orderedResources =
-                new 
TreeSet<>(Comparator.comparingLong(CachedResource::getNextCheck));
+        TreeSet<CachedResource> orderedResources = new TreeSet<>(
+                
Comparator.comparingLong(CachedResource::getNextCheck).thenComparingLong(CachedResource::getUniqueId));
         orderedResources.addAll(resourceCache.values());
 
         Iterator<CachedResource> iter = orderedResources.iterator();
diff --git a/java/org/apache/catalina/webresources/CachedResource.java 
b/java/org/apache/catalina/webresources/CachedResource.java
index 6326fde8b6..09ff1fb7be 100644
--- a/java/org/apache/catalina/webresources/CachedResource.java
+++ b/java/org/apache/catalina/webresources/CachedResource.java
@@ -33,6 +33,7 @@ import java.text.Collator;
 import java.util.Arrays;
 import java.util.Locale;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 
@@ -57,6 +58,10 @@ public class CachedResource implements WebResource {
     // based on profiler data.
     private static final long CACHE_ENTRY_SIZE = 500;
 
+    // The ordering process in cache eviction requires a unique ID for each 
cached resource
+    private static final AtomicLong uniqueIdSource = new AtomicLong(0);
+    private final long uniqueId = uniqueIdSource.getAndIncrement();
+
     private final Cache cache;
     private final StandardRoot root;
     private final String webAppPath;
@@ -82,11 +87,11 @@ public class CachedResource implements WebResource {
     /**
      * Construct a cached resource.
      *
-     * @param cache The cache
-     * @param root The standard root
-     * @param path The web application path
-     * @param ttl The time to live in milliseconds
-     * @param objectMaxSizeBytes The maximum size of objects to cache
+     * @param cache                    The cache
+     * @param root                     The standard root
+     * @param path                     The web application path
+     * @param ttl                      The time to live in milliseconds
+     * @param objectMaxSizeBytes       The maximum size of objects to cache
      * @param usesClassLoaderResources Whether class loader resources are used
      */
     public CachedResource(Cache cache, StandardRoot root, String path, long 
ttl, int objectMaxSizeBytes,
@@ -460,6 +465,11 @@ public class CachedResource implements WebResource {
     }
 
 
+    long getUniqueId() {
+        return uniqueId;
+    }
+
+
     /*
      * Mimics the behaviour of FileURLConnection.getInputStream for a 
directory. Deliberately uses default locale.
      */
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 471227326b..eb2eb8aced 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -179,6 +179,10 @@
       <fix>
         WAR URLConnection should propagate use of caching. (remm)
       </fix>
+      <fix>
+        Ensure resources are evicted from the static resource cache in the
+        correct order. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to