Skip to main content

JSF 2: State restore causes InstantiationException

2 replies [Last post]
robsta10
Offline
Joined: 2008-02-27
Points: 0

Hello,

I have migrated from JSF 1.2 to 2.0. In my app I have a managed bean in application scope which holds references to some immutable objects of the class named SearchCategory. SearchCategory only has a few final variables which are set via constructor parameters. In fact SearchCategory does not have a zero-parameter constructor. Now, when validation fails for the view where SearchCategory instances are shown the second request results in a InstantiationException because StateHolderSaver calls Class#newInstance(). And as I said before SearchCategory does not provide a zero-parameter constructor. Isn't it a bug that StateHolderSaver relies on classes having a zero-parameter constructor? In JSF 1.2 I was just fine without this zero-parameter constructor. Are there any guidelines for classes potentially being saved and restored by JSF? If yes, where are these documented/specified? Has this something to do with the new partial state saving mechanism?

Kind regards,
R.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
hanafey
Offline
Joined: 2003-06-16
Points: 0

This problem description matches my own experience.

It's hard to pin the blame entirely on StateHolderSaver because the JSF 2 version looks the same as the JSF 1.2 version.

But StateHolderSaver seems to have a bug that reveals itself in JSF 2.

The restore() method has this fragment:

// if the Object to save did not implement Serializable or
// StateHolder
if (className == null) {
return null;
}

The problem is the comment is not reflected in the implementation because className is not null if the object implements neither Serializable nor StateHolder (proposed fix bolded below):

public StateHolderSaver(FacesContext context, Object toSave) {
className = toSave.getClass().getName();

if (toSave instanceof StateHolder) {
// do not save an attached object that is marked transient.
if (!((StateHolder) toSave).isTransient()) {
savedState =
(Serializable) ((StateHolder) toSave).saveState(context);
} else {
className = null;
}
} else if (toSave instanceof Serializable) {
savedState = (Serializable) toSave;
className = null;
}[b] else {
className = null; /////////////// <<<<-------------------------- else clause added.
}[/b]
}

hanafey
Offline
Joined: 2003-06-16
Points: 0

If I add "implements Serializable" to the beans with these saved state errors this error goes away. However, when this is done the StateHolderSaver is not called on behalf of these bean anymore.