dev@javaserverfaces.java.net

[REVIEW] Issue #138 NullPointerException when Restoring Server ViewState

From: Jacob Hookom <jacob_at_hookom.net>
Date: Mon, 20 Jun 2005 07:24:03 -0500

A NullPointerException is thrown from StateManagerImpl.restoreView when the
session expires. Again, the code is checking ExternalContext.getSessionMap()
instead of ExternalContext.getSession(false). Also, there is an application
wide synchronization block in the code, this should be changed to synchronize on
the Session Object of the current thread.

This patch will both log, and return null if it's unable to restore server
session state. In relation to EG Issue #73, now the RestoreStatePhase can
handle the isPostback() && viewRoot == null case. The API docs should also be
elaborated for StateManager.restoreView as to what should happen if the state
cannot be restored (presumeably note returning null is okay).

Modified Files
=======================================
/jsf-ri/src/com/sun/faces/application/StateManagerImpl.java

Diff
=======================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/application/StateManagerImpl.java,v
retrieving revision 1.32
diff -r1.32 StateManagerImpl.java
23a24
> import javax.faces.context.ExternalContext;
268,270c269,270
< Map logicalMap = null,
< actualMap = null,
< sessionMap = Util.getSessionMap(context);
---
>                 ExternalContext externalCtx = context.getExternalContext();
>                 Object sessionObj = externalCtx.getSession(false);
272,273c272,273
<                 
<                 if (null == sessionMap) {
---
>                 // stop evaluating if the session is not available
>                 if (sessionObj == null) {
275c275
<                         logger.fine( "Can't get session map.  Perhaps the session expired? viewId: "
---
>                         logger.fine( "Can't Restore Server View State, session expired for viewId: "
280a281,284
>                 Map logicalMap = null,
>                 actualMap = null,
>                 sessionMap = externalCtx.getSessionMap();
>                 
283c287
< 		synchronized (this) {
---
> 		synchronized (sessionObj) {
284a289
>             if (logicalMap != null) {
286,288c291,296
<                     context.getExternalContext().getRequestMap().put(RIConstants.LOGICAL_VIEW_MAP, 
<                             idInLogicalMap);
< 		    stateArray = (Object []) actualMap.get(idInActualMap);
---
>                     if (actualMap != null) {
>                         context.getExternalContext().getRequestMap().put(RIConstants.LOGICAL_VIEW_MAP, 
>                                 idInLogicalMap);
>                         stateArray = (Object []) actualMap.get(idInActualMap);
>                     }
>             }
289a298,304
>         if (stateArray == null) {
>             if (logger.isLoggable(Level.FINE)) {
>                 logger.fine( "Session Available, but View State does not exist for viewId: "
>                         + viewId);
>             }
>             return null;
>         }


RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/application/StateManagerImpl.java,v
retrieving revision 1.32
diff -r1.32 StateManagerImpl.java
23a24
> import javax.faces.context.ExternalContext;
268,270c269,270
< Map logicalMap = null,
< actualMap = null,
< sessionMap = Util.getSessionMap(context);
---
>                 ExternalContext externalCtx = context.getExternalContext();
>                 Object sessionObj = externalCtx.getSession(false);
272,273c272,273
<                 
<                 if (null == sessionMap) {
---
>                 // stop evaluating if the session is not available
>                 if (sessionObj == null) {
275c275
<                         logger.fine( "Can't get session map.  Perhaps the session expired? viewId: "
---
>                         logger.fine( "Can't Restore Server View State, session expired for viewId: "
280a281,284
>                 Map logicalMap = null,
>                 actualMap = null,
>                 sessionMap = externalCtx.getSessionMap();
>                 
283c287
< 		synchronized (this) {
---
> 		synchronized (sessionObj) {
284a289
>             if (logicalMap != null) {
286,288c291,296
<                     context.getExternalContext().getRequestMap().put(RIConstants.LOGICAL_VIEW_MAP, 
<                             idInLogicalMap);
< 		    stateArray = (Object []) actualMap.get(idInActualMap);
---
>                     if (actualMap != null) {
>                         context.getExternalContext().getRequestMap().put(RIConstants.LOGICAL_VIEW_MAP, 
>                                 idInLogicalMap);
>                         stateArray = (Object []) actualMap.get(idInActualMap);
>                     }
>             }
289a298,304
>         if (stateArray == null) {
>             if (logger.isLoggable(Level.FINE)) {
>                 logger.fine( "Session Available, but View State does not exist for viewId: "
>                         + viewId);
>             }
>             return null;
>         }