This is an automated email from the ASF dual-hosted git repository. markt-asf pushed a commit to branch fix-websocket-timeout in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 1959db41b42dc93fd71dd0ca2ad467ace943904d 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 9f401058d9..83b832692e 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 807348839b..e7e156ee38 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -306,6 +306,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]
