jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [PROPOSAL] CDI integration for UIComponent instances in JSF 2.3

From: Leonardo Uribe <leonardo.uribe_at_irian.at>
Date: Thu, 19 Jan 2017 20:50:56 -0500

Hi

I just wanted to resend this mail answers to the EG I'm discussing with
Thomas privately, because it explains in a better way some relevant
points and justify why I'm strongly lobbying to include
@ResolveComponent in JSF 2.3 spec.





TA> i thought about the feature the last days and i don't like it for 100%.

Well, nothing is perfect.

I would like to fix "binding" attribute but I have not been able to find
a good way to do it. @ResolveComponent is the best we have so far to my
eyes, and I have been thinking about this for many years.

TA> The @ResolveComponent should be a alternative for binding
TA> but this doesn't fix the binding itself.

Here I have to say that both "binding" and "ResolveComponent" are not the
same, but solves the same need. @ResolveComponent is a CDI centric
solution. "binding" attribute exists because in that time there was no
dependency injection, so we can't consider it as the best solution for
the problem, simply because the gamefield has changed over time.

This is what JSF spec section 3.1.5 says about "binding":

"... A component binding is a special value expression that can be used
to facilitate "wiring up" a component instance to a corresponding property
of a JavaBean that is associated with the page, and wants to manipulate
component instances programatically. ..."

Now, the objective of IoC or DI is provide a mechanism of injecting loosely
coupled but type-safe components into an application.

The key point here to understand is CDI is "the binding framework". With
CDI you define the components you need to interact and then CDI wires them
up for you. In CDI terms, every object you need to interact can be described
as a CDI bean. It is just natural to use @Inject on everything, because
this is the "standard" way to wire up "components".

EL expressions are very useful to bind properties or methods to JSF
components, because JSF component instances are created on pages, and in
that context it becomes easy to write them. But if you are writing java
code on a CDI bean, why do you need to do the following steps?:

- Get back to the view and locate the component you want.
- Add an EL expression to its "binding" attribute.
- Go back to the CDI bean java code and add getter and setters.

If you can just write this on the CDI bean:

    @Inject
    @ResolveComponent("@form:name")
    private HtmlInputText uiName;

And use it!.

Suppose you have a complex JSF page and you need a JSF component in 2 or
more beans. If you use "binding" you can only bind your component to
1 bean. Then you need to write repetitive code to grab the bean that
has the JSF component from your other beans. But if you use
@ResolveComponent, you can use it as many times as you want for the
same JSF component in different locations and your code will be decoupled,
precisely what we want with CDI.

@ResolveComponent is nice because it enable developers to use JSF 2.3
Search Expression API easily. The point of this API is help users to
search components from a specific component reference. This is just
another use case for it, where the "component reference" is given by
the context. If you are calling the instance from an actionListener,
the reference is the button, if you are validating something, the
reference is the input component and so on.

By these reasons, I consider @ResolveComponent a better solution than
"binding" attribute to locate JSF component from CDI beans.

But please note "binding" attribute is also used to provide an entry
point to inject component instances created programmatically by the
developer into a JSF component tree. That part is something not covered
by @ResolveComponent, because the intention of @ResolveComponent is
different. What happens here is "binding" attribute is something
that is being used for the wrong reason. This attribute should be
use only when the developer wants to provide the component instance
programmatically. In that case, you don't want to add a proxy to the
component instance, because it is the wrong place to do it.

TA> What about if the binding wouldn't set the component BUT creating a
proxy
TA> for it?

That's what I wanted at beginning, but later I found too hard to get a
proxy
instance with standard CDI.

The technical reason is the solution needs all JSF component classes to
create the necessary CDI producers at CDI startup. You can't register CDI
producers dynamically. It can be done using an API provided by openwebbeans
but that's not CDI standard.

TA> A generated proxy could look like:

TA> In DeltaSpike, we already have such proxies. It's no big deal.

TA> Whats the benefit:
TA> - the componentId must not be known in the bean
TA> - the binding attribute can be reused
TA> - no new api

The problem with this approach is:

- JSF cannot have a dependency with DeltaSpike. MyFaces can provide an SPI
that can be implemented by DeltaSpike.
- The proxy must be bound to a scope (view transient scope). A lookup each
time something is resolved can be very expensive in terms of performance.

So, I'm not saying we can't fix "binding", I'm saying we cannot solve it at
JSF spec level. But from a conceptual perspective, @ResolveComponent is
the way to go if we want to take advantage of the power of CDI.

But to be more specific, "binding" attribute is not a concept that is
broken
or something that needs to be fixed. Instead, it is something poorly
understood, because it is not the right tool to locate components from CDI
beans.


regards,

Leonardo Uribe

2017-01-11 14:29 GMT-05:00 Leonardo Uribe <leonardo.uribe_at_irian.at>:

> Hi
>
> Thanks Ed for review this.
>
> LU> In few words...
>
> EB> Ahh, it's been far too long since I've seen a mail with your famous
> EB> introduction "In few words..."! Thanks for spelling it out.
>
> Jejeje. Someday I will learn to write short emails. Jejeje
>
> EB>> I hope so too, but Manfred and I reserve judgement on this and other
> EB>> features at this point.
>
> Yes, of course. I understand the restrictions we have. I just work hoping
> for the best, but I understand not all proposals should pass.
>
> In my opinion, @ResolveComponent can live as an extension since the
> changes in UIComponent were already done (remove final modifiers from
> methods). Search Expression API is very mature at this point, it has been
> already tested in PrimeFaces with good opinions, and it standarize
> something that is loosely mentioned in the spec (JSF 2.2 section 14.2.2).
> Let's see what happens.
>
> regards,
>
> Leonardo Uribe
>
> 2017-01-11 11:39 GMT-05:00 Edward Burns <edward.burns_at_oracle.com>:
>
>> >>>>> On Wed, 21 Dec 2016 19:10:45 -0500, Leonardo Uribe <
>> leonardo.uribe_at_irian.at> said:
>>
>> LU> Hi
>> LU> I have some good news to tell.
>>
>> LU> After some attempts and using Arjan trick in Omnifaces, and based on
>> the
>> LU> previous discussion I was able to code a consistent solution using a
>> LU> CDI centric approach. I made this example work:
>>
>> [...]
>>
>> >>>>> On Fri, 23 Dec 2016 13:30:42 -0500, Leonardo Uribe <
>> leonardo.uribe_at_irian.at> said:
>>
>> LU> Hi Manfred
>> LU> Thanks for accept this change.
>>
>> I need to remind you that this is not an acceptance of the change. It
>> is an acceptance to consider the change. We are pretty much in lockdown
>> mode, and this feature does look like it might have the potential to
>> destabilize. Nonetheless, here in JSF we have always been very open to
>> community contribution so I promise a good hearing.
>>
>> [...]
>>
>> LU> The other option is ask Thomas Andraschko to include this,
>> LU> since he is working to include Search Expression API, which is
>> LU> related to this issue (that algorithm resolves the expression
>> LU> in @ResolveComponent, so this is another use case for that API).
>>
>> I reviewed Thomas's work on Monday and found it quite solid. He
>> responded to my request for revision on all the points. I will review
>> his further thanges today.
>>
>> LU> @Thomas: have you already committed the changes proposed
>> LU> for Search Expression API in Mojarra or it is still work in
>> LU> progress?
>>
>> No, it has not been committed, or even accepted to be committed. It's
>> still under review.
>>
>> >>>>> On Mon, 28 Nov 2016 07:08:13 -0500, Kito Mann <kito.mann_at_virtua.com>
>> said:
>>
>> KM> Leonardo, this looks awesome. One question, though: what about
>> wildcard /
>> KM> partial id matching? I'm surprised that is missing.
>>
>> >>>>> On Tue, 29 Nov 2016 01:12:12 -0500, Leonardo Uribe <
>> leonardo.uribe_at_irian.at> said:
>>
>> LU> The current proposal does not have it.
>>
>> Let's leave that out of the current iteration.
>>
>> >>>>> On Thu, 1 Dec 2016 02:11:30 -0500, Leonardo Uribe <
>> leonardo.uribe_at_irian.at> said:
>>
>> LU> In few words...
>>
>> Ahh, it's been far too long since I've seen a mail with your famous
>> introduction "In few words..."! Thanks for spelling it out.
>>
>> [...]
>>
>> LU> in Primefaces. But we need other examples to justify the "wildcard"
>> case
>> LU> proposed by Bootsfaces, because what I have seen so far is @id(...)
>> without
>> LU> wilcards is good enough. Maybe extend @id to receive multiple ids.
>>
>> Yes, I'd like to leave wildcards out for now.
>>
>> >>>>> On Sun, 8 Jan 2017 13:06:51 +0100, Bauke Scholtz <balusc_at_gmail.com>
>> said:
>>
>> B> In spite of the comments, which are mainly quality and technical
>> related,
>> B> the API itself looks good! Hopefully this will get into 2.3.
>>
>> I hope so too, but Manfred and I reserve judgement on this and other
>> features at this point.
>>
>> Thanks,
>>
>> Ed
>>
>> --
>> | edward.burns_at_oracle.com | office: +1 407 458 0017
>> | 8 business days until planned start of JSF 2.3 Public Review
>> | 28 business days until DevNexus 2017
>> | 53 business days until JavaLand 2017
>>
>
>