Specify the runtime mechanism for obtaining the @FacesDataModel registry (currently implementation-invented)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 127
- Forks
- 59
- Avg merge
- 23h
- Merged PRs (30d)
- 7
Description
Background
Since Faces 2.3, @FacesDataModel lets applications register custom DataModel wrappers. The jakarta.faces.model.FacesDataModel javadoc specifies the behavior in detail — the runtime must maintain a collection of these DataModels, UIData (and other components) must query it for the most-specific wrapper of a value's type, and it defines the inheritance-based sorting/selection algorithm.
What the spec does not define is the mechanism: how a component actually obtains that collection (or a wrapper from it) at runtime.
Problem
Because the mechanism is unspecified, each implementation invented its own — and they're mutually incompatible, both in identifier and in shape:
- Mojarra:
jakarta.faces.component.UIDataqueries the CDIBeanManagerfor a bean by a well-known name (historically the internal stringcomSunFacesDataModelClassesMap, now an impl constant), which yields aMap<Class<?>, Class<? extends DataModel<?>>>;UIDataitself performs the most-specific-match selection. - MyFaces:
jakarta.faces.component.UIDatareflectively loads the impl classorg.apache.myfaces.cdi.model.FacesDataModelManagerby FQN and invokes a staticcreateDataModel(FacesContext, Class, Object); selection happens inside the impl manager.
Consequences:
- The well-known identifier is an undocumented contract that each impl must invent, guess, and duplicate across its API-level component code and its provider — on both sides of the API/impl module boundary.
- No portable way exists for components (or third-party libraries) to obtain the registry; code written against one impl's mechanism won't work on the other.
- The behavior is interoperable but the mechanism is not, which undercuts the point of standardizing
@FacesDataModelin the first place.
Proposal
Define the lookup as a CDI contract in the specification. CDI is already the extension mechanism for @FacesDataModel (CDI discovers the annotated beans, the registry is built by a CDI extension, and UIData already requires CDI.current() to resolve it), so CDI itself is the SPI here — no additional factory interface is warranted. MyFaces' reflective class-load is precisely a workaround for the missing spec-defined CDI name; standardizing the name removes the reason that workaround exists.
Specifically, specify:
- a stable, spec-owned bean name (and/or qualifier) for the registry — e.g. a constant
FacesDataModel.DATA_MODEL_CLASSES_MAP_NAME = "jakarta.faces.DATA_MODEL_CLASSES_MAP"; - the bean type:
Map<Class<?>, Class<? extends DataModel<?>>>; - the semantics: sorted by inheritance (subclasses before superclasses) exactly as already described in
FacesDataModel, so a component iterating it finds the most-specific match.
The runtime produces this bean; components (and third-party libraries) obtain it via the standard BeanManager, with no impl-specific identifier and no reflective class-loading. Implementations reference the one spec-defined constant instead of duplicating a private literal across the API/impl boundary.
Notes
- This formalizes existing, shipping behavior — it standardizes a contract both implementations already satisfy (differently), so the risk is low and it's largely additive.
- Mojarra recently moved off its legacy
com.sun.faces-flavored bean name and currently uses an internaljakarta.faces.DATA_MODEL_CLASSES_MAPconstant with a TODO noting it should be spec-defined; this issue is the upstream follow-through.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the jakarta.faces.model.FacesDataModel javadoc and the UIData implementations in Mojarra and MyFaces, comparing their registry lookup mechanisms. Define the spec-owned CDI bean name, Map type, and inheritance-order semantics so components and third-party libraries can obtain the registry portably without implementation-specific identifiers or reflective class loading.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100