Skip to main content

[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()

Back to the top