Incorrect handling of FacesContext
----------------------------------
Key: MYFACES-1531
URL: https://issues.apache.org/jira/browse/MYFACES-1531
Project: MyFaces Core
Issue Type: Bug
Affects Versions: 1.1.4
Environment: WindowsXP & Solaris; Tomcat 5.5.17, Liferay 4.2.0 (Portal
Server)
Reporter: Olaf Fricke
We encountered some NPE when accessing the FacesContext in the doView-Method. I
first thought about a bug in the Liferay-Portal-Server (see
http://support.liferay.com/browse/LEP-1869). But then I discovered that it is a
bug in MyFaces, that is triggred because Liferay pools ActionRequest and
RenderRequest objects.
MyFaces changes the external context value in the method
org.apache.myfaces.portlet.MyFacesGenericPortlet#facesRender to switch from
ActionRequest and ActionResponse to RenderRequest and RenderResponse. But that
switch happens to late, so that in doView (and doEdit and doHelp as well) the
FacesContext uses references to the ActionRequest and ActionResponse instead of
RenderRequest and RenderResponse. And unfortunately Liferay has already
recycled the RenderRequest object and thus a NPE is raised when trying to use
the request.
I added the following code to my portlet (indeed, to our own super class) to
make the switch earlier and the NullPointerException when accessing attributes
via the FacesContext will not be raised any longer. (Please note that I cannot
use the FacesContext.getCurrentInstance() method in a portal environment,
because each portlet owns its own context).
public void render(RenderRequest request, RenderResponse response) throws
PortletException,
IOException {
// The following code was taken from
org.apache.myfaces.portlet.MyFacesGenericPortlet#facesRender
//
// get the portlet session local context
ServletFacesContextImpl context = (ServletFacesContextImpl)
request.getPortletSession()
.getAttribute(CURRENT_FACES_CONTEXT);
if (context != null) {
// and set a new external context that uses the render request and
response
context.setExternalContext(makeExternalContext(request, response));
} else {
// no context available for the current portlet yet; create a new
one and put it into the session
context = (ServletFacesContextImpl) facesContext(request, response);
request.getPortletSession().setAttribute(CURRENT_FACES_CONTEXT,
context);
}
super.render(request, response);
}
Later I discovered another problem concerning the FacesContext: When rendering
the very first MyFaces-Portlet, no FacesContext exists for the Portlet.
Therefore the method nonFacesRequest is called. Somewhere inside this method a
new FacesContext is created, but that new FacesContext is never put into the
session. Thus my workaround in the render method was broken again. I fixed that
by extending the method nonFacesRequest as follows:
protected void nonFacesRequest(RenderRequest request, RenderResponse
response)
throws PortletException {
super.nonFacesRequest(request, response);
request.getPortletSession().setAttribute(CURRENT_FACES_CONTEXT,
FacesContext.getCurrentInstance());
}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.