[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [faces-dev] Clarification Needed on the CDI Injection of Jakarta Faces Maps
|
Hi,
We originally allowed for both, but MyFaces (via OpenLiberty) challenged that, so we removed the TCK test to inject and request raw Map types. We’ll be removing this ability from Mojarra soon, probably for the 4.0.1 release and if people really want it for the 2.3.x and 3.0.x branches.
Kind regards,
Arjan Tijms
On Thursday, October 13, 2022, Volodymyr Siedlecki <
volosied@xxxxxxxxx> wrote:
Hello,
I would like some clarification regarding types and CDI injection. Please take a look at the following two scenarios.
@Inject
@RequestCookieMap
Map<String, Object> cookieMap;
@Inject
@RequestCookieMap
Map cookieMap;
Are
both of these valid scenarios from a JSF perspective? Or alternatively,
what type should CDI store internally for the RequestCookieMap?
Depending on how the RequestCookieMap producers are set up (discussed
later in email), the second scenario will produce the following error:
"WELD-001334: Unsatisfied dependencies for type Map with qualifiers
@RequestCookieMap".
CDI handles types carefully as can be read in
the parameterized types (1) section of the CDI specification, and my
understanding is that you can inject the raw type Map into the generics
Map<String, Object>, but not vice versa. This can explain the
WELD-001334 error.
As for documentation, the API on jakarta.faces.annotation.
RequestCookieMap states:
"The
presence of this annotation (along with @Inject) on a field of type
Map<String, Object> causes the map returned from ExternalContext.getRequestCookieMap() to be injected as the value of that field." (2)
This
at first seems injection should occur in the first case. However, the
specification also mentions injection could happen on a raw type, as
generics are optional.
5.6.1. Jakarta Faces Objects Valid for @Inject Injection:
"The
annotations in package jakarta.faces.annotation are used to cause
@Inject injection of the corresponding Map into a field. Generics may be
used." (3)
However, the API specification lists that ExternalContext#getRequestCookieMap returns Map<String, Object>. (4)
This leads me to ask, what type should the CDI producer be expected to return? Raw, Parameterized, or even both?
Mojarra
and MyFaces implement the producer code differently, and this leads to
different behaviors: only the first scenario is valid with MyFaces
(second one produces that WELD error), but both are valid with Mojarra,
MyFaces uses the @Produces Annotation here:
https://github.com/apache/myfaces/blob/e9fe59f96410f31a7f5c0fbd6838c1a22683a691/impl/src/main/java/org/apache/myfaces/cdi/FacesArtifactProducer.java#L139-L146
@Produces
@Named("cookie")
@RequestCookieMap
@FacesScoped
public Map<String, Object> getRequestCookieMap()
Mojarra
meanwhile uses a producer bean: RequestCookieMapProducer extends
CdiProducer<Map<String, Object>> (which then implements
Bean<T>, PassivationCapable, Serializable)
I don't fully
understand this approach, but the types call seems to have it registered
all all three (ParameterizedType, Map, Object)
https://github.com/eclipse-ee4j/mojarra/blob/8a2124c7a5c66642f898ff32924887f55990bc5b/impl/src/main/java/com/sun/faces/cdi/RequestCookieMapProducer.java#L42-L45
public RequestCookieMapProducer() {
super.name("cookie").scope(RequestScoped.class).qualifiers(new RequestCookieMapAnnotationLiteral())
.types(new ParameterizedTypeImpl(Map.class, new Type[] { String.class, Object.class }), Map.class, Object.class).beanClass(Map.class)
.create(e -> FacesContext.getCurrentInstance().getExternalContext().getRequestCookieMap());
}
I appreciate any help, and thank you.
_______
1) https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#assignable_parameters
2) https://jakarta.ee/specifications/faces/4.0/apidocs/jakarta/faces/annotation/requestcookiemap
3) https://jakarta.ee/specifications/faces/4.0/jakarta-faces-4.0.html#a3054
4) https://jakarta.ee/specifications/faces/4.0/apidocs/jakarta/faces/context/externalcontext#getRequestCookieMap()