After some extensive research and trying different potential fixes I came to the following conclusion:
I think the offending Seam class is org.jboss.seam.mock.MockViewHandler, which is created when the org.jboss.seam.web.ExceptionFilter catches an exception. It contains the getActionURL(FacesContext, String) which seems to be used to determine the URI to redirect to:
@Override
public String getActionURL(FacesContext ctx, String viewId)
{
String contextPath = ctx.getExternalContext().getRequestContextPath();
String pathInfo = ctx.getExternalContext().getRequestPathInfo();
String servletPath = ctx.getExternalContext().getRequestServletPath();
if (Strings.isEmpty(pathInfo))
{
int loc = viewId.lastIndexOf('.');
if (loc<0) throw new IllegalArgumentException("no file extension in view id: " + viewId);
int sploc = servletPath.lastIndexOf('.');
if (sploc<0) throw new IllegalArgumentException("no file extension in servlet path: " + servletPath);
return contextPath + viewId.substring(0, loc) + servletPath.substring(sploc);
}
else
{
return contextPath + servletPath + viewId;
}
}
In combination with ICEfaces when the NPE is forcibly thrown the Strings in this part of the code contain the following values (with some comments in the brackets after the values):
- viewId: /error.xhtml (the desired error page defined in pages.xml)
- contextPath: /ICE (the ICEfaces application name)
- pathInfo: /send-receive-updates (ICEfaces JavaScript Bridge specific)
- servletPath: /block (ICEfaces JavaScript Bridge specific)
This will result in a redirect URI of /ICE/block/error.xhtml (and some query part, which I will ignore for the moment) which is incorrect in my opinion. The else-block in the method doesn't take the details of viewId into account. As the desired error page is specified as /error.xhtml the resulting redirect URI should toss the servletPath as the viewId starts with a slash. (On a side note, if a full URI is specified in the pages.xml, all the elements (contextPath, pathInfo and servletPath should be ignored and the viewId itself should be the redirect URI.)
Additionally, the "xhtml" part of the resulting redirect URI doesn't seem to be replaced by "seam". I'm not sure in this case if we do something wrong that causes this.
By the way, I used JBoss Seam 2.0.2.SP1 for all of this.
Ted contacted somebody at Seam to verify my suspicion.
seam-generated, libs removed