JSF 2.3 Table 5-3 JSF artifacts eligible for injection - Constructor Injection question


pnicoluc@...
 

Hi,

In the JAVAEE 8 Platform Specification there is Table EE.5-1 that lists component classes supporting injection. In this table the following JSF 2.3 artifacts are listed: JSF managed classes^b (support level Standard).

b. See the JSF specification section “JSF Managed Classes and Java EE Annotations” for a list of these managed classes.

The table in the JSF 2.3 specification for "JSF Managed Classes and Java EE Annotations" Table 5-3 lists the JSF artifacts that are eligible for injection. However, the example in the spec only details field and method injection and from the tests I've done neither MyFaces nor Mojarra support constructor injection on these artifacts.

I believe this is by design, however it causes confusion when reading the two specifications because the JavaEE 8 Platform Specification also says the following:

EE.5.24 Support for Dependency Injection
....
....
"Therefore, to make injection support more uniform across all Java EE component types, Java EE containers are required to support field, method, and
constructor injection using the javax.inject.Inject annotation into all component classes listed in Table EE.5-1 as having the “Standard” level of injection
support, as well as the use of interceptors for these classes.
"
...
...

Should we add a note to the JSF spec to be more clear about not supporting Constructor injection in the JSF artifacts listed in Table 5-3 and then in turn open a spec issues against the platform spec to say JSF is limited vs standard for support of Injection in EE.5-1?

Any additional thoughts?

Thanks,

Paul Nicolucci


pnicoluc@...
 

Anyone have any thoughts on this one? 

Thanks!


pnicoluc@...
 

I reached out to Ed Burns directly and got the following response:

Hello Paul,

Thanks for following the correct protocol for reaching out to us as
stewards of JSF.  I'm very sorry that I was unable to meet your correct
action with correct action of my own in the form of a timely response.

First, let me introduce you to Ren Zhijun.  Zhijun is taking over as
maintenance lead of JSF for all versions of JSF 2.3 and earlier.  What
happens with new JSRs after 2.3 is up to EE4J.  We can consider this
mail a handoff.

Second, the matter at hand.  I have reviewed the table in question and
agree with your implementation analysis.  Therefore, I agree with your
suggestion to file an issue against the platform spec and an errata for
JSF 2.3.

PN> What would you suggest is the next action for the JSF spec? Should I
PN> open an issue against the EE platform spec to say JSF offers limited
PN> support rather than standard support? Can we also add this to the
PN> errata for JSF 2.3 as we did for:
PN> https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_javaee_javaserverfaces-2Dspec_issues_1449-3F&d=DwICAg&c=jf_iaSHvJObTbx-siA1ZOg&r=n-2RUhyQkncKQNTGKy9UmSKIHKSZzEVYEqiy1H7hEwA&m=1XeUXyQF2NN8NdkZRzOxQ-tvQs1V0C7RflEpt4634d8&s=MKFR7U02PkRFXolrm89sB-YE4L9Db2wM-JKFAqVfwNA&e=

Zhijun, can you please add this issue to the JSF 2.3 change log for when
we are able to release an MR for JSF 2.3?

Ed


pnicoluc@...
 

I have the following JSF 2.3 Spec issue opened: https://github.com/javaee/javaserverfaces-spec/issues/1455

I'm working to open an issue with the EE8 platform spec. I'll post that in this thread once opened.


pnicoluc@...
 

The Platform spec issue is here: https://github.com/javaee/javaee-spec/issues/62


 

Hello Paul,

I secured some time to think about this today. If you like, you can
skip right to the CONCLUSION by searching for CONCLUSION:.

First, the general rationale for ctor injection is adequately described
in this stackoverflow post
https://stackoverflow.com/questions/19381846/why-use-constructor-over-setter-injection-in-cdi .
Given that rationale, ctor injection seems to make the most sense for
domain objects, rather than the classes in Table 5-3.

Let's take a look at each of the classes in Table 5-3 and ask ourselves
if it makes sense to have ctor injection for that class, and what it
would mean to have ctor injection. I will also suggest a potential use
for ctor injection for a future revision of JSF.

javax.el.ELResolver

Section 5.5.2.1 states "ELResolver instances have application lifetime
and scope." Since this is lifetime scope, we really don't know what
would make sense to pass to a ctor injection.

Future: Perhaps the presence of @Inject with an ELResolver argument
could be used to provide a reference to the parent ELResolver in the
chain.

javax.faces.application.ApplicationFactory

Section 7.2 states, "A single instance of
javax.faces.application.ApplicationFactory must be made available to
each JSF- based web application running in a servlet or portlet
container." Since this is a singleton, what would make sense to pass to
the ctor?

Also, this class is mentioned in section 11.4.7 Delegating
Implementation Support. In that section, the spec says, "For all of
these artifacts, the decorator design pattern is leveraged, so that if
one provides a constructor that takes a single argument of the
appropriate type, the custom implementation receives a reference to
the implementation that was previously fulfilling the role." So in
this sense we already support ctor injection for this class. Future
occurrences of this explanation will be labeled as "See 11.4.7
Delegating Implementation Support"

Future: Perhaps this @Inject could be passed the
javax.enterprise.inject.spi.CDI.

javax.faces.application.NavigationHandler

Section 7.4.1 states, "A single NavigationHandler instance is
responsible for consuming the logical outcome returned by an application
action that was invoked, along with additional state information that is
available from the FacesContext instance for the current request, and
(optionally) selecting a new view to be rendered." So, this is a singleton.

See 11.4.7 Delegating Implementation Support

javax.faces.application.ResourceHandler

This is also an application singleton. See 11.4.7 Delegating
Implementation Support.

See 11.4.7 Delegating Implementation Support

Future: Perhaps this @Inject could be passed the default
ViewDeclarationLanguage?

javax.faces.application.StateManager

Section 7.8 makes it clear the StateManager is an application
singleton, therefore ctor injection doesn't make a lot of sense.

See 11.4.7 Delegating Implementation Support

Future: Perhaps this @Inject could be passed the default
ViewDeclarationLanguage?

javax.faces.component.visit.VisitContextFactory

This is a singleton factory. I don't see what it would be useful to
pass for ctor injection.

See 11.4.7 Delegating Implementation Support

javax.faces.context.ExceptionHandlerFactory

This is a singleton factory. I don't see what it would be useful to
pass for ctor injection.

See 11.4.7 Delegating Implementation Support

javax.faces.context.ExternalContextFactory

Section 6.8 states, "A single instance of
javax.faces.context.ExternalContextFactory must be made available to
each JSF-based web application running in a servlet or portlet
container."

This is a singleton factory. I don't see what it would be useful to
pass for ctor injection.

See 11.4.7 Delegating Implementation Support

javax.faces.context.FacesContextFactory

This is a singleton factory.

Future: Since the default one simply turns around and calls the
exceptionHandlerFactory() and externalContextFactory, it would make
sense to allow these to be @Inject ctor injected, but that would be a
new feature.

See 11.4.7 Delegating Implementation Support

javax.faces.context.PartialViewContextFactory

Since this is an application singletion, I don't know it would make
sense to pass for ctor injection.

javax.faces.event.ActionListener

See 11.4.7 Delegating Implementation Support

javax.faces.event.SystemEventListener

This one is implemented by application code.

Future: Perhaps ctor injection could be passed the Application?

javax.faces.lifecycle.ClientWindowFactory

This is a singleton factory.

Future: the default impl gets a handle to the Application and
subscribes to the PostConstructApplicationEvent. Perhaps ctor
injection could be useful to pass the Application.

javax.faces.lifecycle.LifecycleFactory

This is a singleton factory.

Future: Perhaps this @Inject could be passed the
javax.enterprise.inject.spi.CDI.

See 11.4.7 Delegating Implementation Support

javax.faces.event.PhaseListener

These are application singletons.

Future: Perhaps ctor injection could pass a reference to the
Application, or the Lifecycle?

javax.faces.render.RenderKitFactory

This is a singleton factory.

Future: Perhaps ctor injection could pass a reference to the
Application.

See 11.4.7 Delegating Implementation Support

javax.faces.view.ViewDeclarationLanguageFactory

This is a singleton factory.

Future: Perhaps ctor injection could pass a reference to the
Application.

javax.faces.view.facelets.FaceletCacheFactory

This is a singleton factory.

Future: Perhaps ctor injection could pass a reference to the
Application.

javax.faces.view.facelets. TagHandlerDelegateFactory

This is a singleton factory.

Future: Perhaps ctor injection could pass a reference to the
Application.

CONCLUSION:

In conclusion I will propose the JSF maintenance lead to make the
following change to the spec.

In section 5.4.1, please change the text

In addition to managed beans being injectable in this manner, the
following JSF artifacts are also injectable.

to be instead

In addition to managed beans being injectable in this manner, the
following JSF artifacts are also injectable via field and setter
injection. Constructor injection does not make sense for these
artifacts and is not supported.

Thanks,

Ed