Specify that view map eviction must not destroy a view map in use by an in-flight request
- Dominant language
- Java
- Stars
- 127
- Forks
- 59
- Avg merge
- 23h
- Merged PRs (30d)
- 7
Description
### Background
`UIViewRoot.getViewMap()` is bounded in practice: implementations cap the number of active view maps per session and evict the eldest. The spec defines the view map's behavior (lazy creation, `PostConstructViewMapEvent`, `PreDestroyViewMapEvent` on `clear()`) but says nothing about that bound, nor about eviction.
### Problem — eviction can destroy a view map that is still in use
Because eviction is unspecified, nothing forbids evicting a view map that a concurrent, still-running request holds a reference to.
eclipse-ee4j/mojarra#5844 is exactly that. Two waves of concurrent requests within one session overflow the cap. LRU eviction fires `PreDestroyViewMapEvent` on the eldest map and clears it, while the request that owns it is still in flight. That request keeps holding the very same map, so during render it silently re-creates its `@ViewScoped` bean and loses the value `f:viewParam` had put in it. No exception, no log entry, just a lost value.
Fixed in Mojarra, unspecified everywhere.
**The spec should state that a view map must not be destroyed while a request that has bound it is in flight.**
### Testability — the bound is not configurable via public API
Reproducing the above requires lowering the cap to a handful, and the cap is only configurable via implementation-specific context params. A TCK module for this (`faces50/view-scope`, `Issue5844IT`) is written but deactivated for exactly this reason: it has to hardcode `org.glassfish.mojarra.numberOfActiveViewMaps`, which is not only implementation-specific but version-specific — Mojarra 4.x spells the same param `com.sun.faces.numberOfActiveViewMaps`.
Proposal: define `jakarta.faces.NUMBER_OF_ACTIVE_VIEW_MAPS` with a spec-defined default.
This would be the first spec-defined context param that bounds a per-session collection. Every existing bound is implementation-specific:
| Implementation | Param | Default |
| --- | --- | --- |
| Mojarra | `numberOfActiveViewMaps` | 25 |
| Mojarra | `numberOfViewsInSession` | 15 |
| Mojarra | `numberOfLogicalViews` | 15 |
| MyFaces | `org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION` | 20 |
| MyFaces | `org.apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION` | — |
(Mojarra's params carry the `com.sun.faces.` prefix in 4.x and `org.glassfish.mojarra.` in 5.x.)
That both implementations independently found the bound necessary is the argument for standardizing it. The counter-argument is that a bound is a tuning knob rather than portable behavior.
If the group prefers not to standardize the knob, the correctness rule above still stands on its own and is the more important half; `Issue5844IT` then simply stays deactivated.
### Notes
- Related: #2185 proposes moving the active-scope collection behind a CDI view-scope-map provider. That reshapes **who owns** the collection, but not **how large it is** nor **when eviction is safe**.
🤖 Generated with Claude Opus 4.8
Contributor guide
Research direction
Read the faces50/view-scope TCK module and Issue5844IT, then compare the requested lifecycle guarantee with the existing Faces specification language. Decide whether to standardize jakarta.faces.NUMBER_OF_ACTIVE_VIEW_MAPS or specify only safe eviction; done means the chosen rule is reflected in the spec and the test's activation path is resolved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100