[ 
https://issues.apache.org/jira/browse/WW-5832?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Lukasz Lenart updated WW-5832:
------------------------------
    Fix Version/s: 7.5.0

> FreeMarker template cache is not bounded by default and is keyed on the 
> request-derived locale
> ----------------------------------------------------------------------------------------------
>
>                 Key: WW-5832
>                 URL: https://issues.apache.org/jira/browse/WW-5832
>             Project: Struts 2
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 6.12.0, 7.0.0, 7.3.0, 7.4.0
>            Reporter: Gouri Sankar A
>            Priority: Minor
>             Fix For: 7.5.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> With struts.freemarker.mru.max.strong.size=0 (the default in 
> default.properties), FreemarkerManager.createConfiguration does not set a 
> cache storage, so FreeMarker's template cache uses its default 
> SoftCacheStorage, which has no entry limit. The cache key includes the 
> locale. For actions that provide a locale (LocaleProvider, for example 
> ActionSupport), FreemarkerResult uses the ActionContext locale, which by 
> default comes from the request (Accept-Language). Every distinct locale 
> therefore adds template cache entries, with no count bound. Same class as 
> WW-5668 (localized-text caches, capped at 10000) and WW-5716 (Tiles locale 
> caches, capped at 1000).
> Reproduction (main, against a running Struts Boot app): an ActionSupport 
> action rendering a FreeMarker template, requested with 12,000 distinct 
> Accept-Language headers. The template cache (Configuration.getCacheStorage(), 
> a DefaultSoftCacheStorage) grew from 1 to 12,001 entries. Repeating the same 
> locales added none.
> Impact: the entries are soft references, so this alone does not exhaust the 
> heap; they are kept until the GC clears them, and each locale re-reads and 
> re-parses the template.
> Affected versions: the same createConfiguration code (no cache storage is set 
> when the value is 0, the default) is present in the 6.12.0, 7.0.0, 7.3.0 and 
> 7.4.0 tags, by source inspection. The reproduction was only run on main.
> Fix: when mru.max.strong.size is 0, use a SoftCacheStorage subclass that 
> empties itself at 10000 entries. It stays a ConcurrentCacheStorage, so 
> lookups remain lock-free (soft:10000 would create an MruCacheStorage, which 
> TemplateCache synchronizes on, see WW-3766). The strong:N path is unchanged. 
> The bound is approximate under concurrency.
> Tests: FreemarkerManagerTest#testTemplateCacheIsBoundedByDefault (fails 
> without the change, passes with it). With the fix, the same 12,000-locale run 
> on a live app ends with 2,002 entries instead of 12,001.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to