You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Andrew robinson <an...@gmail.com> on 2005/11/07 00:41:28 UTC

MyFaces is not JSF API compliant?

I'm trying to make an JSF page onload event code, and have come across
and issue with both the JSF RI and MyFaces where the code violates the
JSF API rules.

According to the "FacesContext" JavaDoc API, the view should only be
created and set during the INVOKE_APPLICATION lifecycle phase:

public abstract void setViewRoot(javax.faces.component.UIViewRoot root)
Set the root component that is associated with this request. This
method can only be called by the application handler (or a class that
the handler calls), and only during the Invoke Application phase of
the request processing lifecycle.
Link: http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#setViewRoot(javax.faces.component.UIViewRoot)

Now, if you look into the MyFaces code, you will see that in the
LifecycleImpl.java that during the restoreView function, if the
current view is null (none was restored), it creates a new view from
the view handler and then calls setViewRoot and renderResponse.
Calling renderResponse will cause all phases to be skipped.

This is a direct violation of the "only during the Invoke Application
phase" comments! Not only does it set the view in the wrong phase, it
causes the phase in which the view is to be set to be skipped!

I looked through the JSF 1.1_01 specification, and there is nothing
stating that any phases should be skipped by the JSF implementation.
The one diagram almost hints at it, but unfortunately the diagram is
poorly drawn and documented.

Is this a bug in both MyFaces and the JSF-RI, or is the JavaDoc
incorrect (obviously both cannot be right).

Anyone know why the code ignores the specification/API?

-Andrew

Re: MyFaces is not JSF API compliant?

Posted by Andrew robinson <an...@gmail.com>.
Well despite the Phase listener question, I was able to get this to
work. I was looking at the code for the view handlers for myfaces at
least, and it seems that creating the view root is a very low
overhead.

If anyone is interested, the code is at
http://sourceforge.net/projects/jsf-comp/

Download the latest jsfExt release

On 11/6/05, Andrew robinson <an...@gmail.com> wrote:
> Yes I have. What I am actually doing, which is working, is to handle
> the before render response. That way, I know the new view ID. I am
> invoking a configurable action and if the result is not null or a
> "success result" I am re-invoking the navigation handler. The result
> is that a second view root is created and rendered, and the requested
> view is never created. The only thing I am concerned with here is that
> 2 views are created which will cause some overhead.
>
> The other possibility is to handle it in the createView method of a
> ViewHandler. The problem there is that invoking the navigation handler
> in that function is a bit sketchy, as the call may already be inside
> of the navigation handler. I am invoking the navigation handler so
> that the normal navigation rules from the faces configuration are
> applied. I would rather not implement the functionality of the
> navigation handler myself (parse the faces config and check all the
> paths and rules).
>
> Either way it isn't a great solution as the JSF specification was not
> made to handle on the fly actions being added by a phase listener.
>
> I'm going to include this as open source so am trying to make sure it
> is compliant with the spec and will not cause problems with different
> vendor implementations of JSF.

Re: MyFaces is not JSF API compliant?

Posted by Andrew robinson <an...@gmail.com>.
Yes I have. What I am actually doing, which is working, is to handle
the before render response. That way, I know the new view ID. I am
invoking a configurable action and if the result is not null or a
"success result" I am re-invoking the navigation handler. The result
is that a second view root is created and rendered, and the requested
view is never created. The only thing I am concerned with here is that
2 views are created which will cause some overhead.

The other possibility is to handle it in the createView method of a
ViewHandler. The problem there is that invoking the navigation handler
in that function is a bit sketchy, as the call may already be inside
of the navigation handler. I am invoking the navigation handler so
that the normal navigation rules from the faces configuration are
applied. I would rather not implement the functionality of the
navigation handler myself (parse the faces config and check all the
paths and rules).

Either way it isn't a great solution as the JSF specification was not
made to handle on the fly actions being added by a phase listener.

I'm going to include this as open source so am trying to make sure it
is compliant with the spec and will not cause problems with different
vendor implementations of JSF.

On 11/6/05, Martin Marinschek <ma...@gmail.com> wrote:
> There must be a misunderstanding here.
>
> The view needs to be created/recreated a long time before the
> INVOKE_APPLICATION phase, as you need it throughout the other phases.
> How would you go through the different components in the view if you
> don't have a view and a view root to start processing?
>
> Maybe decorating the viewhandler could help you with your problem -
> have you tried that out?
>
> regards,
>
> Martin
>
> On 11/7/05, Andrew robinson <an...@gmail.com> wrote:
> > It doesn't say anything about the phase listener callbacks. It just
> > says that if anyone calls renderReponse or responseComplete on the
> > contex, then the following phases should be skipped except for
> > possibly the renderResponse phase which is always invoked unless
> > someone calls responseComplete.
> >
> > I realize why they did it, the problem is that for implementing an
> > onload function of a page in which the view can be redirected, it
> > would be easiest in the invoke application phase, and that was the
> > phase I put my listener in until I found it wasn't getting called.
> >
> > I still cannot believe JSF has no on load functionality. There are so
> > many instances where it is needed to have a page redirected on load
> > (for example, if someone hits a page in the middle of a an order due
> > to a bookmark, it would be best to redirect them back to the first
> > page).
> >
> > On 11/6/05, Simon Kitching <sk...@obsidium.com> wrote:
> > > Andrew robinson wrote:
> > > > I'm trying to make an JSF page onload event code, and have come across
> > > > and issue with both the JSF RI and MyFaces where the code violates the
> > > > JSF API rules.
> > > >
> > > > According to the "FacesContext" JavaDoc API, the view should only be
> > > > created and set during the INVOKE_APPLICATION lifecycle phase:
> > > >
> > > > public abstract void setViewRoot(javax.faces.component.UIViewRoot root)
> > > > Set the root component that is associated with this request. This
> > > > method can only be called by the application handler (or a class that
> > > > the handler calls), and only during the Invoke Application phase of
> > > > the request processing lifecycle.
> > > > Link: http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#setViewRoot(javax.faces.component.UIViewRoot)
> > > >
> > > > Now, if you look into the MyFaces code, you will see that in the
> > > > LifecycleImpl.java that during the restoreView function, if the
> > > > current view is null (none was restored), it creates a new view from
> > > > the view handler and then calls setViewRoot and renderResponse.
> > > > Calling renderResponse will cause all phases to be skipped.
> > > >
> > > > This is a direct violation of the "only during the Invoke Application
> > > > phase" comments! Not only does it set the view in the wrong phase, it
> > > > causes the phase in which the view is to be set to be skipped!
> > > >
> > > > I looked through the JSF 1.1_01 specification, and there is nothing
> > > > stating that any phases should be skipped by the JSF implementation.
> > > > The one diagram almost hints at it, but unfortunately the diagram is
> > > > poorly drawn and documented.
> > > >
> > > > Is this a bug in both MyFaces and the JSF-RI, or is the JavaDoc
> > > > incorrect (obviously both cannot be right).
> > >
> > > Well, if there is no view then there are no components.
> > >
> > > So there is nothing to do in the decode phase (no components exist to
> > > have decode methods called). And there is nothing to do in the validate
> > > phase (no components exist to do any validation).
> > >
> > > And there is nothing to do in the update model phase.
> > > And there is nothing to do in the invoke application phase.
> > >
> > > Therefore setting the view then skipping to render seems ok to me.
> > >
> > > The only possible issue is that Phase Listener classes won't be called.
> > > What does the spec say about Phase Listener callbacks when the view is null?
> > >
> > > Regards,
> > >
> > > Simon
> > >
> >
>
>
> --
>
> http://www.irian.at
> Your JSF powerhouse -
> JSF Trainings in English and German
>

Re: MyFaces is not JSF API compliant?

Posted by Martin Marinschek <ma...@gmail.com>.
There must be a misunderstanding here.

The view needs to be created/recreated a long time before the
INVOKE_APPLICATION phase, as you need it throughout the other phases.
How would you go through the different components in the view if you
don't have a view and a view root to start processing?

Maybe decorating the viewhandler could help you with your problem -
have you tried that out?

regards,

Martin

On 11/7/05, Andrew robinson <an...@gmail.com> wrote:
> It doesn't say anything about the phase listener callbacks. It just
> says that if anyone calls renderReponse or responseComplete on the
> contex, then the following phases should be skipped except for
> possibly the renderResponse phase which is always invoked unless
> someone calls responseComplete.
>
> I realize why they did it, the problem is that for implementing an
> onload function of a page in which the view can be redirected, it
> would be easiest in the invoke application phase, and that was the
> phase I put my listener in until I found it wasn't getting called.
>
> I still cannot believe JSF has no on load functionality. There are so
> many instances where it is needed to have a page redirected on load
> (for example, if someone hits a page in the middle of a an order due
> to a bookmark, it would be best to redirect them back to the first
> page).
>
> On 11/6/05, Simon Kitching <sk...@obsidium.com> wrote:
> > Andrew robinson wrote:
> > > I'm trying to make an JSF page onload event code, and have come across
> > > and issue with both the JSF RI and MyFaces where the code violates the
> > > JSF API rules.
> > >
> > > According to the "FacesContext" JavaDoc API, the view should only be
> > > created and set during the INVOKE_APPLICATION lifecycle phase:
> > >
> > > public abstract void setViewRoot(javax.faces.component.UIViewRoot root)
> > > Set the root component that is associated with this request. This
> > > method can only be called by the application handler (or a class that
> > > the handler calls), and only during the Invoke Application phase of
> > > the request processing lifecycle.
> > > Link: http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#setViewRoot(javax.faces.component.UIViewRoot)
> > >
> > > Now, if you look into the MyFaces code, you will see that in the
> > > LifecycleImpl.java that during the restoreView function, if the
> > > current view is null (none was restored), it creates a new view from
> > > the view handler and then calls setViewRoot and renderResponse.
> > > Calling renderResponse will cause all phases to be skipped.
> > >
> > > This is a direct violation of the "only during the Invoke Application
> > > phase" comments! Not only does it set the view in the wrong phase, it
> > > causes the phase in which the view is to be set to be skipped!
> > >
> > > I looked through the JSF 1.1_01 specification, and there is nothing
> > > stating that any phases should be skipped by the JSF implementation.
> > > The one diagram almost hints at it, but unfortunately the diagram is
> > > poorly drawn and documented.
> > >
> > > Is this a bug in both MyFaces and the JSF-RI, or is the JavaDoc
> > > incorrect (obviously both cannot be right).
> >
> > Well, if there is no view then there are no components.
> >
> > So there is nothing to do in the decode phase (no components exist to
> > have decode methods called). And there is nothing to do in the validate
> > phase (no components exist to do any validation).
> >
> > And there is nothing to do in the update model phase.
> > And there is nothing to do in the invoke application phase.
> >
> > Therefore setting the view then skipping to render seems ok to me.
> >
> > The only possible issue is that Phase Listener classes won't be called.
> > What does the spec say about Phase Listener callbacks when the view is null?
> >
> > Regards,
> >
> > Simon
> >
>


--

http://www.irian.at
Your JSF powerhouse -
JSF Trainings in English and German

Re: MyFaces is not JSF API compliant?

Posted by Andrew robinson <an...@gmail.com>.
It doesn't say anything about the phase listener callbacks. It just
says that if anyone calls renderReponse or responseComplete on the
contex, then the following phases should be skipped except for
possibly the renderResponse phase which is always invoked unless
someone calls responseComplete.

I realize why they did it, the problem is that for implementing an
onload function of a page in which the view can be redirected, it
would be easiest in the invoke application phase, and that was the
phase I put my listener in until I found it wasn't getting called.

I still cannot believe JSF has no on load functionality. There are so
many instances where it is needed to have a page redirected on load
(for example, if someone hits a page in the middle of a an order due
to a bookmark, it would be best to redirect them back to the first
page).

On 11/6/05, Simon Kitching <sk...@obsidium.com> wrote:
> Andrew robinson wrote:
> > I'm trying to make an JSF page onload event code, and have come across
> > and issue with both the JSF RI and MyFaces where the code violates the
> > JSF API rules.
> >
> > According to the "FacesContext" JavaDoc API, the view should only be
> > created and set during the INVOKE_APPLICATION lifecycle phase:
> >
> > public abstract void setViewRoot(javax.faces.component.UIViewRoot root)
> > Set the root component that is associated with this request. This
> > method can only be called by the application handler (or a class that
> > the handler calls), and only during the Invoke Application phase of
> > the request processing lifecycle.
> > Link: http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#setViewRoot(javax.faces.component.UIViewRoot)
> >
> > Now, if you look into the MyFaces code, you will see that in the
> > LifecycleImpl.java that during the restoreView function, if the
> > current view is null (none was restored), it creates a new view from
> > the view handler and then calls setViewRoot and renderResponse.
> > Calling renderResponse will cause all phases to be skipped.
> >
> > This is a direct violation of the "only during the Invoke Application
> > phase" comments! Not only does it set the view in the wrong phase, it
> > causes the phase in which the view is to be set to be skipped!
> >
> > I looked through the JSF 1.1_01 specification, and there is nothing
> > stating that any phases should be skipped by the JSF implementation.
> > The one diagram almost hints at it, but unfortunately the diagram is
> > poorly drawn and documented.
> >
> > Is this a bug in both MyFaces and the JSF-RI, or is the JavaDoc
> > incorrect (obviously both cannot be right).
>
> Well, if there is no view then there are no components.
>
> So there is nothing to do in the decode phase (no components exist to
> have decode methods called). And there is nothing to do in the validate
> phase (no components exist to do any validation).
>
> And there is nothing to do in the update model phase.
> And there is nothing to do in the invoke application phase.
>
> Therefore setting the view then skipping to render seems ok to me.
>
> The only possible issue is that Phase Listener classes won't be called.
> What does the spec say about Phase Listener callbacks when the view is null?
>
> Regards,
>
> Simon
>

Re: MyFaces is not JSF API compliant?

Posted by Simon Kitching <sk...@obsidium.com>.
Andrew robinson wrote:
> I'm trying to make an JSF page onload event code, and have come across
> and issue with both the JSF RI and MyFaces where the code violates the
> JSF API rules.
> 
> According to the "FacesContext" JavaDoc API, the view should only be
> created and set during the INVOKE_APPLICATION lifecycle phase:
> 
> public abstract void setViewRoot(javax.faces.component.UIViewRoot root)
> Set the root component that is associated with this request. This
> method can only be called by the application handler (or a class that
> the handler calls), and only during the Invoke Application phase of
> the request processing lifecycle.
> Link: http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#setViewRoot(javax.faces.component.UIViewRoot)
> 
> Now, if you look into the MyFaces code, you will see that in the
> LifecycleImpl.java that during the restoreView function, if the
> current view is null (none was restored), it creates a new view from
> the view handler and then calls setViewRoot and renderResponse.
> Calling renderResponse will cause all phases to be skipped.
> 
> This is a direct violation of the "only during the Invoke Application
> phase" comments! Not only does it set the view in the wrong phase, it
> causes the phase in which the view is to be set to be skipped!
> 
> I looked through the JSF 1.1_01 specification, and there is nothing
> stating that any phases should be skipped by the JSF implementation.
> The one diagram almost hints at it, but unfortunately the diagram is
> poorly drawn and documented.
> 
> Is this a bug in both MyFaces and the JSF-RI, or is the JavaDoc
> incorrect (obviously both cannot be right).

Well, if there is no view then there are no components.

So there is nothing to do in the decode phase (no components exist to 
have decode methods called). And there is nothing to do in the validate 
phase (no components exist to do any validation).

And there is nothing to do in the update model phase.
And there is nothing to do in the invoke application phase.

Therefore setting the view then skipping to render seems ok to me.

The only possible issue is that Phase Listener classes won't be called.
What does the spec say about Phase Listener callbacks when the view is null?

Regards,

Simon