11 March 2019

This is a summary of the steps necessary to debug one kind of nasty bug in JSF.

Today I was debugging a JSF issue on Websphere where the backing-bean was not called for an Ajax form submit. Actually, the command-button action was called but the model values for the form inputs where not set. On JBoss all was fine and also under Webphere there was no error written to any log or such. The partial response just returned the old model values.

A colleague recommended to play around with partial-state-saving and so I did. I first captured the viewId to only disable partial-state-saving for my page.

System.out.println("ViewID is " + FacesContext.getCurrentInstance().getViewRoot().getViewId());

And set it like this in the web.xml:

<context-param>
    <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
    <param-value>/myviewid.xhtml</param-value>
</context-param>

This setting at at least made a NPE appear in the partial-response. But without a full stacktrace.

<partial-response><error><error-name>java.lang.NullPointerException<error-name>...</error></partial-response><error

The next step was to install OmniFaces' FullAjaxExceptionHandler.

web.xml
 <error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/errorpages/500.xhtml</location>
 </error-page>
faces-config.xml
<factory>
    <exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>
500.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
    xmlns:of="http://omnifaces.org/functions">
    <!--    xmlns:p="http://primefaces.org/ui" -->

<h:head>
	<title>error</title>
</h:head>
<h:body>
	<ul>
    <li>Date/time: #{of:formatDate(now, 'yyyy-MM-dd HH:mm:ss')}</li>
    <li>User agent: #{header['user-agent']}</li>
    <li>User IP: #{request.remoteAddr}</li>
    <li>Request URI: #{requestScope['javax.servlet.error.request_uri']}</li>
    <li>Ajax request: #{facesContext.partialViewContext.ajaxRequest ? 'Yes' : 'No'}</li>
    <li>Status code: #{requestScope['javax.servlet.error.status_code']}</li>
    <li>Exception type: #{requestScope['javax.servlet.error.exception_type']}</li>
    <li>Exception message: #{requestScope['javax.servlet.error.message']}</li>
    <li>Exception UUID: #{requestScope['org.omnifaces.exception_uuid']}</li>
    <li>Stack trace:
        <pre>#{of:printStackTrace(requestScope['javax.servlet.error.exception'])}</pre>
    </li>
</ul>
</h:body>

</html>

Now the full stacktrace of the NPE became visible. It was a null-value item in a p:selectCheckboxMenu (of PrimeFaces) that just made MyFaces not work properly under Websphere.