Skip to content

WW-5716 Bound the per-locale definition caches in the Tiles plugin (6.x) - #1903

Open
lukaszlenart wants to merge 1 commit into
support/struts-6-x-xfrom
WW-5716-6.x
Open

WW-5716 Bound the per-locale definition caches in the Tiles plugin (6.x)#1903
lukaszlenart wants to merge 1 commit into
support/struts-6-x-xfrom
WW-5716-6.x

Conversation

@lukaszlenart

Copy link
Copy Markdown
Member

6.x backport of #1902.

The Tiles definition caches are keyed by the resolved Locale, which by default derives from the request. Two maps grew without limit and were never reduced for the lifetime of the web application:

  • CachingLocaleUrlDefinitionDAO#locale2definitionMap — populated on each cache miss, only cleared under the (default-off) checkRefresh path.
  • AbstractPatternDefinitionResolver#localePatternPaths — populated via computeIfAbsent per locale key, never swept.

Change

  • Bound locale2definitionMap with an insertion-order LinkedHashMap capped at maxCachedLocales (default 1000, configurable via setMaxCachedLocales). Insertion-order keeps the existing unsynchronized getDefinitions read unchanged.
  • On eviction the DAO removes the same key from the pattern resolver through the new PatternDefinitionResolver#removePatternPaths, keeping both maps in lockstep — the resolver's keys are always a subset of the DAO's.
  • localePatternPaths becomes a ConcurrentHashMap, as the DAO now removes keys off the request thread.

Eviction only re-incurs a load on next access; it never changes rendering. The code is Java 8 compatible (explicit type arguments on the bounded map). The full struts2-tiles-plugin module suite passes (547 tests) under the Java 8 release level.

Fixes WW-5716

🤖 Generated with Claude Code

The Tiles definition caches are keyed by the resolved Locale, which by
default derives from the request. Both CachingLocaleUrlDefinitionDAO's
locale2definitionMap and AbstractPatternDefinitionResolver's
localePatternPaths grew without limit and were never reduced for the
lifetime of the web application.

Bound locale2definitionMap with an insertion-order LinkedHashMap capped
at maxCachedLocales (default 1000, configurable via setMaxCachedLocales).
On eviction the DAO removes the same key from the pattern resolver via
the new PatternDefinitionResolver#removePatternPaths, keeping both maps
in lockstep (the resolver's keys are always a subset of the DAO's).
localePatternPaths becomes a ConcurrentHashMap since the DAO now removes
keys off the request thread. Eviction only re-incurs a load, never
changes rendering.

Fixes https://issues.apache.org/jira/browse/WW-5716

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015huuB72yvZygWEXKUYDAou
@sonarqubecloud

sonarqubecloud Bot commented Sep 4, 2026

Copy link
Copy Markdown

@lukaszlenart
lukaszlenart marked this pull request as ready for review September 4, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant