Wednesday, September 27, 2006

Debug JSF lifecycle

Listen and debug JSF lifecycle phases

The JSF lifecycle will be explained and debugged here using the "poor man's debugging" approach with sysout's. We'll also check what happens if you add immediate="true" to the UIInput and UICommand and what happens when a ConverterException and ValidatorException will be thrown.

Well, you probably already know that the JSF lifecycle contains 6 phases:

  1. Restore view
  2. Apply request values
  3. Process validations
  4. Update model values
  5. Invoke application
  6. Render response

You can use a PhaseListener to trace the phases of the JSF lifecycle and execute some processes where required. But you can also use a "dummy" PhaseListener to debug the phases to see what is happening in which phase. Here is a basic example of such a LifeCycleListener:

Note: if you don't have a JSF playground environment setup yet, then you may find this tutorial useful as well: JSF tutorial with Eclipse and Tomcat.

package mypackage;

import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

public class LifeCycleListener implements PhaseListener {

    public PhaseId getPhaseId() {
        return PhaseId.ANY_PHASE;
    }

    public void beforePhase(PhaseEvent event) {
        System.out.println("START PHASE " + event.getPhaseId());
    }

    public void afterPhase(PhaseEvent event) {
        System.out.println("END PHASE " + event.getPhaseId());
    }

}

Add the following lines to the faces-config.xml to activate the LifeCycleListener.

<lifecycle>
    <phase-listener>mypackage.LifeCycleListener</phase-listener>
</lifecycle>

This produces like the following in the system output:

START PHASE RESTORE_VIEW 1
END PHASE RESTORE_VIEW 1
START PHASE APPLY_REQUEST_VALUES 2
END PHASE APPLY_REQUEST_VALUES 2
START PHASE PROCESS_VALIDATIONS 3
END PHASE PROCESS_VALIDATIONS 3
START PHASE UPDATE_MODEL_VALUES 4
END PHASE UPDATE_MODEL_VALUES 4
START PHASE INVOKE_APPLICATION 5
END PHASE INVOKE_APPLICATION 5
START PHASE RENDER_RESPONSE 6
END PHASE RENDER_RESPONSE 6

Back to top

Basic debug example

To trace all phases of the JSF lifecycle, here is some sample code which represents simple JSF form with a "dummy" converter and validator and the appropriate backing bean with all component bindings. The code sample can be used to give us more insights into the phases of the JSF lifecycle, to understand it and to learn about it. Please note that component bindings are rarely used in real world this way. They are in this code sample just there to track and log component set/get actions by JSF. In real world code you should not have the need for them.

Here's the form, just put it in its entirety in the body of your test.jsp file (note: at time of writing, JSF 1.2 is used, but if you're using JSF 2.x, you can of course also put this in a test.xhtml file):

<h:form>
    <h:inputText
        binding="#{myBean.inputComponent}"
        value="#{myBean.inputValue}"
        valueChangeListener="#{myBean.inputChanged}">
        <f:converter converterId="myConverter" />
        <f:validator validatorId="myValidator" />
    </h:inputText>
    <h:commandButton
        value="submit"
        action="#{myBean.action}" />
    <h:outputText
        binding="#{myBean.outputComponent}"
        value="#{myBean.outputValue}" />
    <h:messages />
</h:form>

Here's the dummy converter: MyConverter.java

package mypackage;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

public class MyConverter implements Converter {

    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        System.out.println("MyConverter getAsObject: " + value);
        return value;
    }

    public String getAsString(FacesContext context, UIComponent component, Object value) {
        System.out.println("MyConverter getAsString: " + value);
        return (String) value;
    }

}

Here's the dummy validator: MyValidator.java

package mypackage;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

public class MyValidator implements Validator {

    public void validate(FacesContext context, UIComponent component, Object value)
        throws ValidatorException
    {
        System.out.println("MyValidator validate: " + value);
    }

}

Here's the backing bean: MyBean.java

package mypackage;

import javax.faces.component.html.HtmlInputText;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.event.ValueChangeEvent;

public class MyBean {

    // Init ----------------------------------------------------------------------------------------

    private HtmlInputText inputComponent;
    private String inputValue;
    private HtmlOutputText outputComponent;
    private String outputValue;

    // Constructors -------------------------------------------------------------------------------

    public MyBean() {
        log("constructed");
    }

    // Actions ------------------------------------------------------------------------------------

    public void inputChanged(ValueChangeEvent event) {
        log(event.getOldValue() + " to " + event.getNewValue());
    }

    public void action() {
        outputValue = inputValue;
        log("succes");
    }

    // Getters/setters ----------------------------------------------------------------------------

    public HtmlInputText getInputComponent() {
        log(inputComponent);
        return inputComponent;
    }

    public void setInputComponent(HtmlInputText inputComponent) {
        log(inputComponent);
        this.inputComponent = inputComponent;
    }

    public String getInputValue() {
        log(inputValue);
        return inputValue;
    }

    public void setInputValue(String inputValue) {
        log(inputValue);
        this.inputValue = inputValue;
    }

    public HtmlOutputText getOutputComponent() {
        log(outputComponent);
        return outputComponent;
    }

    public void setOutputComponent(HtmlOutputText outputComponent) {
        log(outputComponent);
        this.outputComponent = outputComponent;
    }

    public String getOutputValue() {
        log(outputValue);
        return outputValue;
    }

    // Helpers ------------------------------------------------------------------------------------

    private void log(Object object) {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        System.out.println("MyBean " + methodName + ": " + object);
    }
}

The minimal faces configuration: faces-config.xml

<converter>
    <converter-id>myConverter</converter-id>
    <converter-class>mypackage.MyConverter</converter-class>
</converter>
<validator>
    <validator-id>myValidator</validator-id>
    <validator-class>mypackage.MyValidator</validator-class>
</validator>
<managed-bean>
    <managed-bean-name>myBean</managed-bean-name>
    <managed-bean-class>mypackage.MyBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

Note: at the time of writing, JSF 1.2 was the standard and JSF 2.0 didn't exist yet. If you're however using JSF 2.x, then you could of course also instead use the @FacesConverter("myConverter"), @FacesValidator("myValidator") and @ManagedBean @RequestScoped annotations respectively.

Back to top

The first call

The first call in a freshly started webapplication with a fresh session should output at least:

START PHASE RESTORE_VIEW 1
END PHASE RESTORE_VIEW 1
START PHASE RENDER_RESPONSE 6
MyBean <init>: constructed
MyBean getInputComponent: null
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean getInputValue: null
MyBean getOutputComponent: null
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
MyBean getOutputValue: null
END PHASE RENDER_RESPONSE 6

1. Restore view.
As the session is fresh, there's no means of any UIViewRoot to restore, so nothing to see here.

2. Apply request values.
This phase is skipped because there is no form submit.

3. Process validations.
This phase is skipped because there is no form submit.

4. Update model values.
This phase is skipped because there is no form submit.

5. Invoke application.
This phase is skipped because there is no form submit.

6. Render response.
The bean is constructed. Behind the scenes a new UIViewRoot is created and stored in the session. If the component binding getters returns precreated components (precreated in e.g. the constructor) and not null, then those will be used, otherwise JSF will create new components. The components will be stored in the UIViewRoot and the bounded components are set in the component bindings. The values to be shown are retrieved from the value binding getters in the backing bean. If the values aren't set yet, they defaults to null. The component bindings are not required by the way. Only use them if you actually need the component in the backing bean for other means than getting/setting the value. In this article they are included just to demonstrate what all happens in the lifecycle.

Back to top

The form submit

The form submit with the value "test" entered should output at least:

START PHASE RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
END PHASE RESTORE_VIEW 1
START PHASE APPLY_REQUEST_VALUES 2
END PHASE APPLY_REQUEST_VALUES 2
START PHASE PROCESS_VALIDATIONS 3
MyConverter getAsObject: test
MyValidator validate: test
MyBean getInputValue: null
MyBean inputChanged: null to test
END PHASE PROCESS_VALIDATIONS 3
START PHASE UPDATE_MODEL_VALUES 4
MyBean setInputValue: test
END PHASE UPDATE_MODEL_VALUES 4
START PHASE INVOKE_APPLICATION 5
MyBean action: succes
END PHASE INVOKE_APPLICATION 5
START PHASE RENDER_RESPONSE 6
MyBean getInputValue: test
MyConverter getAsString: test
MyBean getOutputValue: test
END PHASE RENDER_RESPONSE 6

1. Restore view.
The bean is constructed. The UIViewRoot is restored from session and the bounded components are set in the component bindings.

2. Apply request values.
Nothing to see here. Behind the scenes the submitted form values are obtained as request parameters and set in the relevant components in the UIViewRoot, for example inputComponent.setSubmittedValue("test").

3. Process validations.
The submitted values are passed through the converter getAsObject() method and validated by the validator. If the conversion and validation succeeds, then the initial input value will be retrieved from the value binding getter and behind the scenes the inputComponent.setValue(submittedValue) and inputComponent.setSubmittedValue(null) will be executed. If the retrieved initial input value differs from the submitted value, then the valueChangeListener method will be invoked.

4. Update model values.
The converted and validated values will now be set in the value binding setters of the backing bean. E.g. myBean.setInputValue(inputComponent.getValue()).

5. Invoke application.
The real processing of the form submission happens here.

6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean. If a converter is definied, then the value will be passed through the converter getAsString() method and the result will be shown in the form.

Back to top

Add immediate="true" to UIInput only

Extend the h:inputText in the test.jsp with immediate="true":

    ...
    <h:inputText
        binding="#{myBean.inputComponent}"
        value="#{myBean.inputValue}"
        valueChangeListener="#{myBean.inputChanged}"
        immediate="true">
    ...

The form submit with the value "test" entered should output at least:

START PHASE RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
END PHASE RESTORE_VIEW 1
START PHASE APPLY_REQUEST_VALUES 2
MyConverter getAsObject: test
MyValidator validate: test
MyBean getInputValue: null
MyBean inputChanged: null to test
END PHASE APPLY_REQUEST_VALUES 2
START PHASE PROCESS_VALIDATIONS 3
END PHASE PROCESS_VALIDATIONS 3
START PHASE UPDATE_MODEL_VALUES 4
MyBean setInputValue: test
END PHASE UPDATE_MODEL_VALUES 4
START PHASE INVOKE_APPLICATION 5
MyBean action: succes
END PHASE INVOKE_APPLICATION 5
START PHASE RENDER_RESPONSE 6
MyBean getInputValue: test
MyConverter getAsString: test
MyBean getOutputValue: test
END PHASE RENDER_RESPONSE 6

1. Restore view.
The bean is constructed. The UIViewRoot is restored from session and the bounded components are set in the component bindings.

2. Apply request values.
Behind the scenes the submitted form values are obtained as request parameters and set in the relevant components in the UIViewRoot, for example inputComponent.setSubmittedValue("test"). The submitted values are immediately passed through the converter getAsObject() method and validated by the validator. If the conversion and validation succeeds, then the initial input value will be retrieved from the value binding getter and behind the scenes the inputComponent.setValue(submittedValue) and inputComponent.setSubmittedValue(null) will be executed. If the retrieved initial input value differs from the submitted value, then the valueChangeListener method will be invoked. This all happens in this phase instead of the Process validations phase due to the immediate="true" in the h:inputText.

3. Process validations.
Nothing to see here. The conversion and validation is already processed in the Apply request values phase, before the values being put in the components. This is due to the immediate="true" in the h:inputText.

4. Update model values.
The converted and validated values will now be set in the value binding setters of the backing bean. E.g. myBean.setInputValue(inputComponent.getValue()).

5. Invoke application.
The real processing of the form submission happens here.

6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean. If a converter is definied, then the value will be passed through the converter getAsString() method and the result will be shown in the form.

Note for other components without immediate: any other UIInput components inside the same form which don't have immediate="true" set will just continue the lifecycle as usual.

Back to top

Add immediate="true" to UICommand only

Extend the h:commandButton in the test.jsp with immediate="true" (don't forget to remove from h:inputText):

    ...
    <h:commandButton
        value="submit"
        action="#{myBean.action}"
        immediate="true" />
    ...

The form submit with the value "test" entered should output at least:

START PHASE RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
END PHASE RESTORE_VIEW 1
START PHASE APPLY_REQUEST_VALUES 2
MyBean action: succes
END PHASE APPLY_REQUEST_VALUES 2
START PHASE RENDER_RESPONSE 6
MyBean getOutputValue: null
END PHASE RENDER_RESPONSE 6

1. Restore view.
The bean is constructed. The UIViewRoot is restored from session and the bounded components are set in the component bindings.

2. Apply request values.
The real processing of the form submission happens here. This happens in this phase instead of the Invoke application phase due to the immediate="true" in the h:commandButton. The UIInput components which don't have immediate="true" set will not be converted, validated nor updated, but behind the scenes the inputComponent.setSubmittedValue(submittedValue) will be executed before the action() method will be executed.

3. Process validations.
This phase is skipped due to the immediate="true" in the h:commandButton.

4. Update model values.
This phase is skipped due to the immediate="true" in the h:commandButton.

5. Invoke application.
This phase is skipped due to the immediate="true" in the h:commandButton.

6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean, except for the UIInput components which don't have immediate="true" set. Behind the scenes those will be retrieved from the components in the UIViewRoot, e.g. inputComponent.getSubmittedValue().

Note for all components without immediate: as the Update model values phase is skipped, the value bindings aren't been set and the value binding getters will return null. But the values are still available as submitted value of the relevant components in the UIViewRoot. In this case you can retrieve the non-converted and non-validated input value from inputComponent.getSubmittedValue() in the action() method. You could even change it using inputComponent.setSubmittedValue(newValue) in the action() method.

Back to top

Add immediate="true" to UIInput and UICommand

Extend the h:inputText as well as the h:commandButton in the test.jsp with immediate="true":

    ...
    <h:inputText
        binding="#{myBean.inputComponent}"
        value="#{myBean.inputValue}"
        valueChangeListener="#{myBean.inputChanged}"
        immediate="true">
    ...
    <h:commandButton
        value="submit"
        action="#{myBean.action}"
        immediate="true" />
    ...

The form submit with the value "test" entered should output at least:

START PHASE RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
END PHASE RESTORE_VIEW 1
START PHASE APPLY_REQUEST_VALUES 2
MyConverter getAsObject: test
MyValidator validate: test
MyBean getInputValue: null
MyBean inputChanged: null to test
MyBean action: succes
END PHASE APPLY_REQUEST_VALUES 2
START PHASE RENDER_RESPONSE 6
MyConverter getAsString: test
MyBean getOutputValue: null
END PHASE RENDER_RESPONSE 6

1. Restore view.
The bean is constructed. The UIViewRoot is restored from session and the bounded components are set in the component bindings.

2. Apply request values.
Behind the scenes the submitted form values are obtained as request parameters and set in the relevant components in the UIViewRoot, for example inputComponent.setSubmittedValue("test"). The submitted values are immediately passed through the converter getAsObject() method and validated by the validator. If the conversion and validation succeeds, then the initial input value will be retrieved from the value binding getter and behind the scenes the inputComponent.setValue(submittedValue) and inputComponent.setSubmittedValue(null) will be executed. If the retrieved initial input value differs from the submitted value, then the valueChangeListener method will be invoked. This all happens in this phase instead of the Process validations phase due to the immediate="true" in the h:inputText. Finally the real processing of the form submission happens here. This happens in this phase instead of the Invoke application phase due to the immediate="true" in the h:commandButton.

3. Process validations.
This phase is skipped due to the immediate="true" in the h:commandButton.

4. Update model values.
This phase is skipped due to the immediate="true" in the h:commandButton.

5. Invoke application.
This phase is skipped due to the immediate="true" in the h:commandButton.

6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean. If a converter is definied, then the value will be passed through the converter getAsString() method and the result will be shown in the form.

Note for all components with immediate: as the Update model values phase is skipped, the value bindings aren't been set and the value binding getters will return null. But the values are still available by the relevant components in the UIViewRoot. In this case you can retrieve the input value from inputComponent.getValue() in the action() method. The new input value is also available by the ValueChangeEvent in the inputChanged() method. You could even change it using inputComponent.setValue(newValue) in the action() method.

Note for other components without immediate: any other UIInput components inside the same form which don't have immediate="true" set will not be converted, validated nor updated, but behind the scenes the inputComponent.setSubmittedValue(submittedValue) will be executed before the action() method will be executed. You can retrieve the non-converted and non-validated input value from inputComponent.getSubmittedValue() in the action() method. You could even change it using inputComponent.setSubmittedValue(newValue) in the action() method.

Back to top

Conversion error

Let's see what happens if a conversion error will occur. Change the getAsObject() method of MyConverter.java as follows (and remove the immediate="true" from the test.jsp file):

package mypackage;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;

public class MyConverter implements Converter {

    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        System.out.println("MyConverter getAsObject: " + value);
        throw new ConverterException("Conversion failed.");
    }

    ...
}

The form submit with the value "test" entered should output at least:

START PHASE RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
END PHASE RESTORE_VIEW 1
START PHASE APPLY_REQUEST_VALUES 2
END PHASE APPLY_REQUEST_VALUES 2
START PHASE PROCESS_VALIDATIONS 3
MyConverter getAsObject: test
END PHASE PROCESS_VALIDATIONS 3
START PHASE RENDER_RESPONSE 6
MyBean getOutputValue: null
END PHASE RENDER_RESPONSE 6

1. Restore view.
The bean is constructed. The UIViewRoot is restored from session and the bounded components are set in the component bindings.

2. Apply request values.
Nothing to see here. Behind the scenes the submitted form values are obtained as request parameters and set in the relevant components in the UIViewRoot, for example inputComponent.setSubmittedValue("test").

3. Process validations.
The submitted values are passed through the converter getAsObject() method, where a ConverterException is thrown. The validator and the valueChangeListener are bypassed. Also the inputComponent.setValue(submittedValue) won't take place. The lifecycle will proceed to the Render response phase immediately.

4. Update model values.
This phase is skipped due to the ConverterException.

5. Invoke application.
This phase is skipped due to the ConverterException.

6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean, expecting the values for which a ConverterException has occurred. Behind the scenes those will be retrieved from the components in the UIViewRoot, e.g. inputComponent.getSubmittedValue().

Note: any other UIInput components inside the same form which didn't throw a ConverterException will also skip the update model values and invoke application phases.

Back to top

Validation error

Let's see what happens if a validation error will occur. Change the validate() method of MyValidator.java as follows (and remove the immediate="true" from the test.jsp file and revert MyConverter.java back to original):

package mypackage;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

public class MyValidator implements Validator {

    public void validate(FacesContext context, UIComponent component, Object value)
        throws ValidatorException
    {
        System.out.println("MyValidator validate: " + value);
        throw new ValidatorException(new FacesMessage("Validation failed."));
    }

}

The form submit with the value "test" entered should output at least:

START PHASE RESTORE_VIEW 1
MyBean <init>: constructed
MyBean setInputComponent: javax.faces.component.html.HtmlInputText@2a9fca57
MyBean setOutputComponent: javax.faces.component.html.HtmlOutputText@13bbca56
END PHASE RESTORE_VIEW 1
START PHASE APPLY_REQUEST_VALUES 2
END PHASE APPLY_REQUEST_VALUES 2
START PHASE PROCESS_VALIDATIONS 3
MyConverter getAsObject: test
MyValidator validate: test
END PHASE PROCESS_VALIDATIONS 3
START PHASE RENDER_RESPONSE 6
MyBean getOutputValue: null
END PHASE RENDER_RESPONSE 6

1. Restore view.
The bean is constructed. The UIViewRoot is restored from session and the bounded components are set in the component bindings.

2. Apply request values.
Nothing to see here. Behind the scenes the submitted form values are obtained as request parameters and set in the relevant components in the UIViewRoot, for example inputComponent.setSubmittedValue("test").

3. Process validations.
The values are retrieved as objects from the components, passed through the converter getAsObject() method and validated by the validator, where a ValidatorException is thrown. The valueChangeListener is bypassed. Also the inputComponent.setValue(submittedValue) won't take place. The lifecycle will proceed to the Render response phase immediately.

4. Update model values.
This phase is skipped due to the ValidatorException.

5. Invoke application.
This phase is skipped due to the ValidatorException.

6. Render response.
The values to be shown are retrieved from the value binding getters in the backing bean, except of the values for which a ValidatorException has occurred. Behind the scenes those will be retrieved from the components in the UIViewRoot, e.g. inputComponent.getSubmittedValue().

Note: any other UIInput components inside the same form which didn't throw a ValidatorException will also skip the update model values and invoke application phases.

Back to top

Okay, when should I use the immediate attribute?

If it isn't entirely clear yet, here's a summary, complete with real world use examples when they may be beneficial:

  • If set in UIInput(s) only, the job which is normally invoked during process validations phase will be taken place in apply request values phase instead. Use this to prioritize validation for the UIInput component(s) in question. When validation/conversion fails for any of them, the non-immediate components won't be validated/converted.
  • If set in UICommand only, the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s). Use this to skip the entire processing of the form. E.g. "Cancel" or "Back" button.
  • If set in both UIInput and UICommand components, the job which is normally invoked during the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s) which does not have this attribute set. Use this to skip the processing of the entire form except for certain fields (with immediate). E.g. "Password forgotten" button in a login form with a required and immediate username field and a required but non-immediate password field.
Back to top

Copyright - There is no copyright on the code. You can copy, change and distribute it freely. Just mentioning this site should be fair.

(C) September 2006, BalusC

97 comments:

Gunjan Bohra said...

Thanks BalusC
It's give me good understanding inside JSF .
It's my sugestation that you start post your research on JavaWorld .
Thanks for you help on Sun forum .
With Thanks

Mauricio said...

Nice post, it helped me to clear JSF lifecycle a bit better. But I still have some doubts. :)

Why MyBean.getInputValue method is called twice, once in BeforePhase: PROCESS_VALIDATIONS and another in BeforePhase: RENDER_RESPONSE, in the form submit (without immediate on either UIInput and UICommand)?

One more thing, you could update the post with a calling to log method at MyBean's constructor. How many instances of a Managed Bean (scoped request) are created by a single JSF Request? This is something I still haven't understood in JSF Lifecycle.

I would be very thankful if you could answer.

Greetings from Brazil. :)
Mauricio

BalusC said...

Why MyBean.getInputValue method is called twice
The first time is to compare the old submitted value with the new submitted value. If those values differs, then the valueChangeListener method will be invoked. The second time is just to display the new submitted value.

How many instances of a Managed Bean (scoped request) are created by a single JSF Request?
A request scoped bean is created only once per request. Just copy the code examples into your JSF playground and add a debug statement to the constructor yourself :)

Mauricio said...

Thanks for answering BalusC, I've been learning a lot reading your posts. :)

So, if there weren't any valueChangeListener in inputText the getIntputValue would be called just once in RENDER_RESPONSE. Is that it?

Ok, I'll add a debug statement in constructor for myself. But if more than one instance of MyBean are created per JSF Request, I'll be back! :)

Thank you one more time.
Mauricio

Lance E Sloan said...

BalusC,

As others have said, thank you for this great posting. It helps me understand the JSF lifecycle a lot better.

I think that I could use a PhaseListener to check some other conditions and interrupt processing if they are not right. For example, let's say I want it to check user authorization. I have this class:

public class AuthorizationCheck implements PhaseListener {
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}

public void beforePhase(PhaseEvent event) {
if (not userAuthorized()) {
//do something here, like...
//abort processing
//invoke an error view
}
}

public void afterPhase(PhaseEvent event){
return;
}
}


Since I'm pretty new to JSF, I don't know what to do for the "do something". How do I tell the lifecycle to start over with a different view that will show the user an error message?

BalusC said...

You can invoke ExternalContext#redirect() to redirect the current request to a new request. It will "automatically" abort the JSF lifecycle as it implicitly calls FacesContext#renderResponse().

Lance E Sloan said...

Thank you very much, that put me on the right track.

Sudeep Agrawal said...

Hi BalusC:

I am in a situation where I need to implement a redirect from the construtor of a managedBean.
For instance :
Page 1 : Has a Name Search feature. Search results navigate to Page 2.
Page 2 : Has Extra information about the name based on DB querries from the DB in the page constructor. To Load data requried to display in Page2. There are hyperlinks on each information on this page that goes to the third Page. Once the information is worked, the related information linked to the name is removed from the DB and I will navigate to Page 2.

The problem that I am not able to resolve is, in the construtor of Page 2 when the DB queries donot return any more information on the name, I need to directly go to Page 1. How can I redirect from the contructor of the second page's specific backing bean.
I tried using Navigation Handler, and setting specific rootView. Netiher works when called from the constructor.

If I implement the PhaseListener, then would the pahse Listener logic be applied to all the other pages in the application ?

Please advice.

Thanks,
Sudeep

Sudeep Agrawal said...

I got a work around by using sendRedirect("destinationPage"); in the constructor, however I am not too sure if using sendRedirect or forward is a good practice in JSF.

Could you please advice !

Sri said...

Its really a nice post, which gives the clear understanding of JSF Life Cycle.

All these days I was little confused with the immediate attribute, now its cleared.

Thanks BalusC.

Rafael Ponte said...

Hi BalusC, great post!

Well, your sample has been performed on JSF1.1, right? Because I'm running your sample on JSF1.2 e I'm getting another result when i perform a "refresh" of the page, in fact, i get the same result from the "first call" to "refresh":

BeforePhase: RESTORE_VIEW 1
AfterPhase: RESTORE_VIEW 1
BeforePhase: RENDER_RESPONSE 6
MyBean getInputBinding: null
MyBean setInputBinding: javax.faces.component.html.HtmlInputText@187fafc
MyBean getOutputBinding: null
MyBean setOutputBinding: javax.faces.component.html.HtmlOutputText@6ecec5
MyBean getInputValue: null
MyBean getOutputValue: null
AfterPhase: RENDER_RESPONSE 6

So, Did JSF1.2 change something in this aspect?

Thanks.

tspragg said...

Wonderful Post, I use this site as a referance to just about anything to do with JSF.

One Question. I have a getter that calls a query in order to populate a datatable. Since under the normal lifecycle this getter is called in the APPLY_REQUEST_VALUES and the RENDER_RESPONSE does this not double the amount of calls to the Database?

How would you resolve this?
Thanks alot as your blog and when you hosted your site in the Netherlands really helped me out alot.

Bauke said...

Just invoke that call only once per request. You can do this using the constructor or initialization block of a request scoped managed bean, or by introducing lazy loading in the getter.

maverick-reuters said...

Hello ,
I am working on a J2ee project where we are using JSF . Referring to your article where combination of UI Command Button and Immediate is stated .

I am using the combination of the two inorder to bypass the validations of non -immediate UI components on my form .

I am able to the bypass validations successfully , and subsequently the action method in my managed bean is also called and does some business logic and gets the response from the database ..

However subsequent to getting the response , the response should be populated on same JSF page . It is not getting populated on the same JSF page .

I have checked the mapping of attributes of JSF page and managed bean which is correct .

It would be really great and helpful , if you can please throw some light on this .

thanks ...

Please reply me on divya.prakash@gmail.com

Parminder said...

Thanks for the explanation. I've a question: One of our action methods is not getting called. We saw the logs, but there's no exception anywhere. We tried putting the h:messages tag, but no errors were shown. We haven't put any validations and all our input fields are simple inputText fields that map to primitive values in the backing bean.

Based on your experience, would be going wrong?

BalusC said...

@maverick-reuters: try using action dependent requireness instead of immediate.

@Parminder: assuming that all the phases of the JSF lifecycle are been processed; is the button/link been placed in a h:dataTable (or another iterated component) which obtains the list from a request scoped bean? If so, you need to ensure that it returns the same list in the next request.

Parminder Singh said...

No. The button isn't within a datatable. there's one thing different though. at runtime based on a property in the backing bean i include a page that contains a couple of components (drop down and a text box). please note that the button is not in the included jsp but the master page (the one that includes the other page).

Somok said...

Hi BalusC,

Thanks for your blog, it gave a very good understanding of the JSF lifecycle. It would be great if you help me out with a problem i am facing.
I am developing portlets with JSF framework. I am using Netbeans6.1 as IDE and Liferay 5.0.1 as the Portal container. The application runs on GlassfishV2 server. I am creating a simple application where i will display the name typed. However, the commandButton does not seem to call the action method in the corresponding managed bean. I have implemented a Lifecycle tracker. The logs show that instead of going thru all the lifecycles the application is going directly to Render_Response phase.

The button is within the f:view tag. i am unable to post sample codes of my jsp page. If u provide me a mail id i can mail u all the details.

if i deploy the application as a normal web application instead of a portlet application all the lifecycles are executed correctly.

Any help would be greatly appreciated.

Thanks

k said...

Hi balusc,
I am Ramu ur blog is excellent.
here i am having one problem.
I am using JAASActionListener for my security. i stored user object in a session. i wnt to retrieve that session i another backing bean. but i am gettng null value. please help me.
Thanks Ramu

Deepu said...

Hello BalusC,

Wen i run this program, am receiving the following error..
Plz help me..
javax.servlet.ServletException: java.lang.LinkageError: loader constraints violated when linking javax/el/ExpressionFactory class
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:274)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)


root cause

java.lang.LinkageError: loader constraints violated when linking javax/el/ExpressionFactory class
org.apache.jsp.index_jsp._jspInit(index_jsp.java:37)
org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:52)
org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:159)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:329)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

BalusC said...

This has nothing to do with debugging JSF lifecycle.

Your classpath is just dirty.

Deepu said...

Am using Eclipse3.3.1.1..
I included all necessary libraries..
Am able to run other JSF examples..
Then wr s d problem.. What i should change.. Am new to eclipse and JSF..
So pls help me..

Anand said...

I am using Spring JSF and got a form with validator for each component with some of the fileds have got required property as true.If I put a blank value in the required field it comes up with the validation error message , but subsequently when I put a valid value the data is saved and backing bean is updated correctly , but the page comes back with an empty value for that field.
I have checked each phase and it is passing the data correctly , but still JSF is showing a blank value . If I load the page again it shows me the correct value.
Any idea why it is doing ?

planetnik007 said...

Hi, I have written two custom JSF validators for the same jsp, but only one of them is working. No sysouts from the other jsp are being displayed. The mapping in the faces-config.xml is correct. HeLP!!!

Keshav said...

Hi, I have a command button on my JSF page to submit data to the server. After all the validation, I expect another page to be displayed. This process works as expected the first time. However, I find that the page just reloads itself on form submission the subsequent times (In other words, I have to click the submit button twice) for the other page to reload. I noticed that when the page reloads itself, only the Phases 1 and 6 are called instead of all the phases. Could you please help me out with this?

Karthik Bala said...

Hi BalusC, thank you so much for such a brilliant article which has cleared many of my doubts.
I have a problem in my jsf application, when ever there is a validation error, in the RenderResponse phase the getters for other components are also not called, its ok if the getter for the particular component whose validation has failed is not called but why other getters are also not called? am using jsf1.1
here is the log:
eforePhase: RESTORE_VIEW 1
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: RESTORE_VIEW 1
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: RESTORE_VIEW 1
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: RESTORE_VIEW 1
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: PROCESS_VALIDATIONS 3
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: PROCESS_VALIDATIONS 3
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O getEndOperTime********2359
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: PROCESS_VALIDATIONS 3
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O AfterPhase: PROCESS_VALIDATIONS 3
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O falsejavax.faces.component.html.HtmlCommandButton
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O nameHtmlCommandButton
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O falsejavax.faces.component.html.HtmlForm
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O nameHtmlForm
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: RENDER_RESPONSE 6
[12/13/08 22:29:34:288 IST] 0000002e SystemOut O BeforePhase: RENDER_RESPONSE 6
[12/13/08 22:29:34:303 IST] 0000002e SystemOut O inside onloadmode
[12/13/08 22:29:34:303 IST] 0000002e SystemOut O requestMap:{atmoperationinformationsettings:_id48=SECOM, atmoperationinformationsettings:_id42=ATM/SC, atmoperationinformationsettings:_id37=Confirmation, atmoperationinformationsettings:_id62=SECOM, atmoperationinformationsettings:_id54=dd, atmoperationinformationsettings:_id58=2359, atmoperationinformationsettings=atmoperationinformationsettings}
[12/13/08 22:29:34:303 IST] 0000002e SystemOut O mode1 Inside onloadMode of atmOperation:null
[12/13/08 22:29:34:303 IST] 0000002e SystemOut O AfterPhase: RENDER_RESPONSE 6
[12/13/08 22:29:34:303 IST] 0000002e SystemOut O AfterPhase: RENDER_RESPONSE 6

watch that getter which is being called at processValidations is not being called at renderResponse, wht cud be the reason, pls help me
and even if i try to reopen the page using a menubar in my application, it behaves differently
what i think whenever i click on a html link in my menu bar only restore view and renderresponse will get called, but see the log below which has executed all the phases jus for a request of a page, it is not a form submit right? but then why all the phases are executed?
O BeforePhase: RESTORE_VIEW 1
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: RESTORE_VIEW 1
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: RESTORE_VIEW 1
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: RESTORE_VIEW 1
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: APPLY_REQUEST_VALUES 2
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: PROCESS_VALIDATIONS 3
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: PROCESS_VALIDATIONS 3
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: PROCESS_VALIDATIONS 3
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: PROCESS_VALIDATIONS 3
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: UPDATE_MODEL_VALUES 4
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: UPDATE_MODEL_VALUES 4
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: UPDATE_MODEL_VALUES 4
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: UPDATE_MODEL_VALUES 4
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: INVOKE_APPLICATION 5
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: INVOKE_APPLICATION 5
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: INVOKE_APPLICATION 5
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O AfterPhase: INVOKE_APPLICATION 5
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: RENDER_RESPONSE 6
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O BeforePhase: RENDER_RESPONSE 6
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O requestMap:{mode=atmOpeInfoSetting, frame=M}
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O mode1 Inside onloadMode of atmOperation:atmOpeInfoSetting
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O &&&&&&&&&&&&&&&&& atmOperation Id is called
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O &&&&&&&&&&&&&&&&& Transaction Id is 10040000028
[12/13/08 22:31:06:714 IST] 0000002e SystemOut O Module is Loans!
[12/13/08 22:31:08:589 IST] 0000002e SystemOut O AfterPhase: RENDER_RESPONSE 6
[12/13/08 22:31:08:589 IST] 0000002e SystemOut O AfterPhase: RENDER_RESPONSE 6

maverick-reuters said...

Karthik ,
Hey , Its Divya !! .

About your second ambiguity :

Clicking of Menu : All the phases of JSF1.1. are called . I guess , just check the menu1.js (which controls how your page should be called) . I may be incorrect also , but I guess the code there seems to submit or reload the form again .. (that's why all the phases of jsf lifecycle are called ).

thanks

alex said...

Great article! thank you. I have JFS button which generates report using jasper report. I want to update print date on the same page. But page does not update. I use HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); to generate output stream. Is it possible to force update page, after pressing button? Any ideas? Best regards Alex.

Manju said...

Excellent example explains life cycle of JSF nicely. Fantastic!!!!!

Danilo G. Magrini said...

hi BalusC, sorry my English because it's bad. I'm brazilian.
I've exceptions in methods set's. How I capture them and I show on view in a message component?
e.g.

(...)
public void setAge(int age) throws AgeException {
if(age<0) {
throw new AgeException(Age is not valid.);
}
}

BalusC said...

Use a Validator.

Danilo G. Magrini said...

but with validator my rule of business will be moved to a model of vision. That is correct?

Brian said...

Great job again on this topic. What is the best way to do form validation? That with your example here, validation would take place after each input value. So if you has 3 input values and the user inputs 3 in-correct values, exceptions would only be thrown one at a time.

Basically user would fix one error and resubmit. JSF would then throw another error. The user would have to go through the entire process until all exceptions have been thrown and repaired before the form can be successfully submitted.

Should we just make every input value a string value and do the validation in the backing bean? What is the best approach in your opinion?

Thanks.

BalusC said...

Normally conversion/validation is done for all input fields at once. So I don't know how it happens that in your case it takes place one by one. Which JSF impl/version are you using? Tried the latest?

bucksboy said...

Top notch content

kripa said...

Hi BalusC.. I have a small issue in my application... I have a backing bean defined in my app that gets instantiated once a jsp page that has a binding to the backign bean is rendered.. In the constructor of the backing bean, I am querying the database for a id adn trying to add a message to the FacesContext object through FacesContext.addMessage method.. But when the page renders I could not see the error message displayed on the screen... Can you tel me the reason for that and suggest a way to make the message appear.. I have another question.. Can you please tel me when are the messages getting cleared from facescontext object... i.e during which phase.. Sorry If I have asked a very silly or a basic question.. I am just 1 month old to JSF..

BalusC said...

Maybe you did a redirect or used the wrong client ID.

Use h:messages to see them all. In Sun JSF 1.2 Mojarra you can note any undisplayed messages in appserver logs as well.

kripa said...

Hi BalusC, I used the client ID from the rendered page's HTML(rightclick->view source.. Is that something that I should not be using? also, when I tried to see the id, it was the same id as I had in my jsp page, unlike the fact where you had earlier mentioned in one of your posts in sun forums.
courtesy:http://forums.sun.com/thread.jspa?threadID=5400253

But, h:messages doesn't have a 'for' attribute. f:message tag has that. Can you please tel me the significance of the for attribute please..

BalusC said...

It is just for debugging purposes. If you're using JSF 1.2 or newer you can just check appserver logs instead of using h:messages.

ankur said...

Hi Balcus ...Ur blogs are really good nd i need a submission from u for one Question ....Is really Different browser run the life cycle of JSf differently..For further details Please http://n3.nabble.com/My-Faces-Facelets-Rich-faces-f123374.html

dwaipayan said...

Hi BalusC
I am facing an issue regarding the rendering of my jsf portlets.(JSR 286 running on Portal Server 6.1) When I click the submit button of the portlet sometimes all the values entered in the fields are lost, no action method is called and a message is shown in console as 'Discarding restored view'.This happens for the first time after I browse to that portlet but from the second time onwards in that session this situation does not happen.FYI the javax.faces.STATE_SAVING_METHOD parameter in my web.xml is set to server.I am not clear whether this is causing the problem or not.Please help

BalusC said...

@dwaipayan: sounds like a problem in session management. Start debugging the session ID. Isn't it renewed on 2nd and subsequent requests?

Julio said...

Hi balusC
i have a situation , i have a submit button that doesn't reach to the actionListener, i implemented the phaseListener and it show:
START PHASE RESTORE_VIEW(1)
END PHASE RESTORE_VIEW(1)
START PHASE APPLY_REQUEST_VALUES(2)
END PHASE APPLY_REQUEST_VALUES(2)
START PHASE PROCESS_VALIDATIONS(3)
START PHASE RENDER_RESPONSE(6)
END PHASE RENDER_RESPONSE(6)

it jumps from procces validation directly to render response , the logs doesnt show any error, is there a way i can see the specific error that occur in the process validation phase?

please i need help!
tnx!

BalusC said...

Put a <h:messages> in the JSF page to get notified of all validation/conversion errors.

Julio said...

Hi BalusC
i find my problem of the unknow error, i try with the you recomended me, but still not work, but the real problem was that i have a inputText that was required="true"
but it renderization depends on choosing an option in a t:selectOneMenu, so when it was not renderized and submitted it didn't show no error even in the , i only saw what i was telling you that it jumps from procces validation directly to render response, im still curious if theres a way of detecting that kind of mistakes ,cause im kind of new in this
tnx!

BalusC said...

You need to retain the condition responsible for outcome of the `rendered` attribute in the subsequent request. If you're already on JSF 2.0, put bean in view scope. If you're still on JSF 1.x, either use session scope or pass the conditionals through by h:inputHidden.

Julio said...

tnx!

Shailendra kumar said...

This is I think the best detailed article to date on the effects of using immediate attribute.This has cleared lots of doubts.Thanks for taking the pains of putting up such an extremely well written and explained article. Thanks a lot

julio said...

Hi Balus C
i've a situation , in a jsf page
in wich there is a form with id="formSearch" and a dataTable inside with its paginator to navigate the results but the paginator is not working , nothing hapend when i clickt it , but i get this error in the javascripts errors:
clear_formSearch is not defined

chitra said...

facesContext.getResponse().sendRedirect("Sample.jsp"); is not working when it is called in constructor of backing bean of JSF 1.1. Application is deployed on to WAS 7.0 using RSA 7.5 as IDE. Please let me know the resolution.

BalusC said...

@chitra: You forgot to call FacesContext#responseComplete().

But better use ExternalContext#redirect() instead of HttpServletResponse#sendRedirect().

chitra said...

BalusC,

I tried even that. Still it doesn't work.

Code is below

FacesContext facesContext = FacesContext.getCurrentInstance();
HttpServletRequest req = (HttpServletRequest) facesContext.getExternalContext().getRequest();
HttpServletResponse res = (HttpServletResponse) facesContext.getExternalContext().getResponse();

res.sendRedirect("/SampleFacesWeb2/faces/SampleTwo.jsp");
facesContext.responseComplete();

Same works in action method of the backing bean.

Please advice.

Thanks

Raams said...
This comment has been removed by the author.
Raams said...

Hi BalusC,
After deploying in Weblogic, first time when i am hiting the page, I got the below error. After closing and reopen the browser, the page is loading fine. This is happening in Weblogic server. I used component. Please help me.

Error 500--Internal Server Error
java.lang.IllegalArgumentException: Cannot convert org.richfaces.component.html.HtmlDataTable@4756803 of type class org.richfaces.component.html.HtmlDataTable to class org.richfaces.component.html.HtmlDataTable
at com.sun.el.lang.ELSupport.coerceToType(ELSupport.java:367)
at com.sun.el.parser.AstValue.setValue(AstValue.java:137)
at com.sun.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:255)
at com.sun.facelets.el.TagValueExpression.setValue(TagValueExpression.java:93)
at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:238)
at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:243)
at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:243)
at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:243)
at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:243)
at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:243)
at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:243)
at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:243)
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:198)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:102)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.actional$83$service(FacesServlet.java:265)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:226)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:124)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:283)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3393)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(Unknown Source)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2140)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2046)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1366)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:200)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:172)

Raams said...

BalusC, Any updates on Weblogic deployment error?

Andrew said...

That was remarkable post. I like to read articles that are edifying for they enriched my mind with different knowledge that makes me a better person. These articles especially about recent events, technologies, news, tips and technical skills are the topics that I adore. Keep it up and more power to your website. I look forward for your next article.Thanks Jennifer Liferay Portal Development

Yeray said...

Hi BalusC, Thanks for this tip and the others, are very ussefull.

What happens if there are two request from the same user session? Is possible to cancel the render response phase?

I am working in a project that has a web page that take a lof of time in the Render Response phase. We are looking a solution to cancel the first request wiht a second request but I don't know how to cancel the previous request (that stay a long time in the Render Response phase) with a second request.

The second request is a cancel button with a action method that return the navigation case to reload the current page, but we have bad results with this cancel option and we are trying to cancel the Render Response phase of the first request.

Thank in advance.

karthik said...

nicely explained. thanks

karthik said...
This comment has been removed by the author.
Sudeep Agrawal said...
This comment has been removed by the author.
Prithvi's And Beenish's Blog said...

Hello Blaus,
Your article was great to read. I am very new to JSF 2.0. I am pretty confused between JSF Component Binding VS Value Binding? Will you be kind enough to let me know what is the difference between two. Still i am struggling on the concepts on JSF 2.0 Life cycle. I believe if the life cycle is pretty clear, then debugging large things become easy. Thanks

Prithvi

Ankur Singh said...

Nice post, it helped me to clear JSF life cycle a bit better

Prithvi's And Beenish's Blog said...

Thanks BlausC. Atlast i am able to understand 90% of JSF life-cycle through this topic. Thanks very much.

BR,
Prithvi

Dessislava said...

Hi BalusC,

I implemented the class LifeCycleListener and added the required xml code to the faces-config but I don't get anything displayed in the output. What could be the reason?

I am using facelets and GlassFish3.

Thanks,
Dessi

Hugoss said...

Very very nice, man. Thanks a lot!

M Chisty said...

Truly speaking, this is probably the best article on understanding JSF life cycles. I always had the confusion specially about 'update model values' phase. Most of the articles are theoretical or, too verbose to hold readers interest. This article, with a complete example explains everything crystal clear.

Regards,
... Chisty

localhost8080 said...

Great post!! Thanks!

Gilson D'Elrei said...

Guy, it's time to write a book about it! All JSF world needs to know about it!
Thanks a lot, it's a big contribution for JSF community.

spand said...

I am working on an application that has a method that pulls data from the database and renders a web page with it. It is an ADF application.
The problem is that the same method gets called many times during the life cycle and this slows down the application. IT is taking 7.25 secs to render it the first time. How can I prevent this or optimize it

BalusC said...

Just don't call the DB in a getter method. Call it in (post)constructor or (action)listener method. It's invoked only 1 time. See also Why JSF calls getters multiple times?

Tej said...

Hi BalusC,
Great blog and fantastic post on JSF lifecycle..

want a quick help as im new to JSF ...
I am getting the below error ...but dont know how to debug :( ...JSF with websphere ..
----------------------------------
Error Message: javax.el.ELException: Not a Valid Method Expression:
Error Code: 0
Target Servlet: null
Error Stack:
javax.el.ELException: Not a Valid Method Expression:
at org.apache.el.lang.ExpressionBuilder.createMethodExpression(ExpressionBuilder.java:209)
at org.apache.el.ExpressionFactoryImpl.createMethodExpression(ExpressionFactoryImpl.java:56)
at _ibmjsp.WEB_2D_INF.jspf._pageHeader._jspx_meth_h_commandLink_8(_pageHeader.java:2701)
at _ibmjsp.WEB_2D_INF.jspf._pageHeader._jspx_meth_h_panelGrid_15(_pageHeader.java:2911)
at _ibmjsp.WEB_2D_INF.jspf._pageHeader._jspx_meth_h_panelGrid_13(_pageHeader.java:2976)
at _ibmjsp.WEB_2D_INF.jspf._pageHeader._jspx_meth_h_panelGrid_3(_pageHeader.java:3035)
at _ibmjsp.WEB_2D_INF.jspf._pageHeader._jspx_meth_h_form_1(_pageHeader.java:3117)
at _ibmjsp.WEB_2D_INF.jspf._pageHeader._jspx_meth_f_subview_0(_pageHeader.java:3262)
at _ibmjsp.WEB_2D_INF.jspf._pageHeader._jspService(_pageHeader.java:108)
at com.ibm.ws.jsp.runtime.HttpJspBase.service(HttpJspBase.java:98)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1655)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1595)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:104)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:77)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:908)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:932)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:500)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.wsspi.webcontainer.servlet.GenericServletWrapper.handleRequest(GenericServletWrapper.java:121)
at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.handleRequest(AbstractJSPExtensionServletWrapper.java:239)

-------------------------------
can you please show me some pointers?
would appreciate ur kind help!

many thanks!
Tej

Sunil said...
This comment has been removed by the author.
Sunil said...

Hi BalusC..
I have a query regarding JSF lifecycle.I have a view say view 1...on click of a link on that view, another view say view2 appears.On view1, there is an action link on click of which some view say view3 comes. But the action method binded on the link on view2 is not present in the managed bean, so it gives MethodNotFoundException, so instead of going to view3 it goes to view4.In the same session, when i come back on view1 and clicks the same link to come to view2, the action listener method which was binded on the link on view2, is getting called in apply request value phase itself and same exception gets generated in this phase, which results into non rendering of view2 itself. Can you please explain the behaviour.

Mr.Attitude said...

Hi Balus... I want to write a custom jdf components. ? can you explain it in your blog.. so that it will be very helpful to me..

Manikanta said...

Hi Balu,
I have a requirement that if in the dropdown if any value is changed then it need to show/hide one textbox depending on the value selected in the dropdown. I created the code and it is not working if any other other form fields is given as required="true" then show/hide is not working if i filled the required fields and changing the dropdown then it is working.In the below Amount,type,etc is mandatory if i fill all these and changing the dropdown then show/hide is working other wise it is not working




























public void LoadOtherEvent(ValueChangeEvent val){
UIComponent other = (val.getComponent()).findComponent("other");
RequestContext.getCurrentInstance ().addPartialTarget(other);
}

Nena_C said...

Hi BalusC, thanks for posting this. I came across your post while looking for a solution to a problem I have with tr:commandButton - this button submits to backing bean action when _outside_ a tr:table, but NOT when inside a tr:table - even with immediate="true". Here are the PhaseListener results:

START PHASE RESTORE_VIEW 1
END PHASE RESTORE_VIEW 1
START PHASE APPLY_REQUEST_VALUES 2
END PHASE APPLY_REQUEST_VALUES 2
START PHASE PROCESS_VALIDATIONS 3
END PHASE PROCESS_VALIDATIONS 3
START PHASE UPDATE_MODEL_VALUES 4
END PHASE UPDATE_MODEL_VALUES 4
PhaseTracker> START PHASE INVOKE_APPLICATION 5
END PHASE INVOKE_APPLICATION 5
START PHASE RENDER_RESPONSE 6
END PHASE RENDER_RESPONSE 6

I am using trinidad faces and JSF1.2, deployed to weblogic 11g. It seems that even with code like:











As you can see, the code is fairly simple. Outside of the tr:table, it invokes the bk_listBean action, inside the table it does not. I tried setting both immediate="true" on the tr:table and the button and just on the button, nothing seems to work and i have no idea why ....

Any clues?

Atul Acharya said...

Excellent post.
Cleared a lot of confusion about different phases.

Thanks BalusC.

Unknown said...

Good post after any preliminary reading of lifecycle phases of JSF. - Miten.

hydsteve said...

Nice explanation

My Turf, My Style said...

Clear & well-organized. One typo, expect for => except for

Bauke Scholtz said...

@My Turf: fixed, thank you.

tmmmviii said...

Any idea what the following phase-cycle log entries indicate - no other log entries are created while first and last phase repeat 4 times:

00:07:25,769 INFO [stdout] (http--0.0.0.0-8080-1) START PHASE RESTORE_VIEW 1


00:07:25,854 INFO [stdout] (http--0.0.0.0-8080-1) END PHASE RESTORE_VIEW 1


00:07:25,991 INFO [stdout] (http--0.0.0.0-8080-1) START PHASE RENDER_RESPONSE 6


00:07:28,778 INFO [stdout] (http--0.0.0.0-8080-1) END PHASE RENDER_RESPONSE 6


00:08:18,095 INFO [stdout] (http--0.0.0.0-8080-1) START PHASE RESTORE_VIEW 1


00:08:18,109 INFO [stdout] (http--0.0.0.0-8080-1) END PHASE RESTORE_VIEW 1


00:08:18,249 INFO [stdout] (http--0.0.0.0-8080-1) START PHASE RENDER_RESPONSE 6


00:08:18,404 INFO [stdout] (http--0.0.0.0-8080-2) START PHASE RESTORE_VIEW 1


00:08:18,407 INFO [stdout] (http--0.0.0.0-8080-2) END PHASE RESTORE_VIEW 1


00:08:18,548 INFO [stdout] (http--0.0.0.0-8080-1) END PHASE RENDER_RESPONSE 6


00:08:18,587 INFO [stdout] (http--0.0.0.0-8080-2) START PHASE RENDER_RESPONSE 6


00:08:18,671 INFO [stdout] (http--0.0.0.0-8080-2) END PHASE RENDER_RESPONSE 6


00:08:22,661 INFO [stdout] (http--0.0.0.0-8080-2) START PHASE RESTORE_VIEW 1


00:08:22,685 INFO [stdout] (http--0.0.0.0-8080-2) END PHASE RESTORE_VIEW 1


00:08:22,855 INFO [stdout] (http--0.0.0.0-8080-2) START PHASE RENDER_RESPONSE 6


00:08:52,006 INFO [stdout] (http--0.0.0.0-8080-2) END PHASE RENDER_RESPONSE 6


00:09:07,182 INFO [stdout] (http--0.0.0.0-8080-2) START PHASE RESTORE_VIEW 1


00:09:07,391 INFO [stdout] (http--0.0.0.0-8080-2) END PHASE RESTORE_VIEW 1


00:09:07,499 INFO [stdout] (http--0.0.0.0-8080-2) START PHASE APPLY_REQUEST_VALUES 2


00:09:07,507 INFO [stdout] (http--0.0.0.0-8080-2) END PHASE APPLY_REQUEST_VALUES 2


00:09:07,632 INFO [stdout] (http--0.0.0.0-8080-2) START PHASE PROCESS_VALIDATIONS 3


00:09:08,788 INFO [stdout] (http--0.0.0.0-8080-2) END PHASE PROCESS_VALIDATIONS 3


00:09:08,907 INFO [stdout] (http--0.0.0.0-8080-2) START PHASE UPDATE_MODEL_VALUES 4


00:09:08,935 INFO [stdout] (http--0.0.0.0-8080-2) END PHASE UPDATE_MODEL_VALUES 4


00:09:09,045 INFO [stdout] (http--0.0.0.0-8080-2) START PHASE INVOKE_APPLICATION 5


00:09:09,047 INFO [stdout] (http--0.0.0.0-8080-2) END PHASE INVOKE_APPLICATION 5


00:09:09,157 INFO [stdout] (http--0.0.0.0-8080-2) START PHASE RENDER_RESPONSE 6


00:10:22,598 INFO [stdout] (http--0.0.0.0-8080-2) END PHASE RENDER_RESPONSE 6

Raj said...

Hi, I have a jsf page with few input components and two h:selectOneMenu component.On selection of a value in the first drop down am calling a valuechange listener and submitting the form.Then am populating the value into the other drop down depending on the value selected from the first drop down. Now I enter other fields and on click of the submit button I'm getting null values in my backing bean for all the components. Can someone please guide me the way to sort out this issue.

Gita Danesh said...

First of all thank you for this wonderful article. I have questions about validation error.
In Validation Error part you mentioned
"Update model values.
This phase is skipped due to the ValidatorException."
but in note part you mentioned
"any other UIInput components inside the same form which don't throw a ValidatorException will continue the lifecycle as usual, only the invoke application phase will still be skipped."
So the input component which don't throw a ValidaionException will update its model value?

Bauke Scholtz said...

@Gita: well spotted, that part was incorrect. I've updated the post.

ravindra yadav said...

Nice article, Any one can easly understanding jsf life cycle

Prabu Selvarajan said...

Really a very nice and useful article to understand the JSF life cycle. Thanks a lot :-).

Prabu Selvarajan said...
This comment has been removed by the author.
Raghavendra Hamand said...

Hi BalusC,
I have a doubt for you. If render response is null in the JSF lifecycle then what happens?

Thanks
Raghavendra

R. S. said...

I have a JSF application running on 2.1.18.
I am trying to restrict number of views in my application. I am having doubt which parameter is responsible
1) Is it web.xml context param numberOfViewsInSession or
2) A parameter(com.sun.faces.application.view.activeViewMapsSize) is to be set in Session.

Alberto said...

I have read this post, but I still don't get the whole idea of the JSF lifecylce. Could you add another example where you follow one link from one page to another different page?

Köll S. Cherizard said...
This comment has been removed by the author.
Köll S. Cherizard said...
This comment has been removed by the author.
mike said...

I have doubt, recently i am facing an issue in few pc,when a jsf page is having h:commandbutton in a4j:form, the form is not submmitted. It is showing page cannot be displayed.
Kindly advise on this issue.

riha said...

If immediate="true" is set for both UIInput and UICommand components, then model should have been partially updated for those input components with immediate="true", so that the values that was passed in those input components could be easily retrieved later. Otherwise, in the "Password forgotten" example quoted by you, how would we retrieve the username after the user clicks on the "forgot password" button?

Bauke Scholtz said...

@riha: that happens in apply request values phase.

Raj said...

I have a h:selectOnemenu component in my jsp,but unable to display the value from the database.I get the value from the backing bean,but those values are not displayed in UI. I have a master.jsp(name changed) page and secondary.jsp(name changed) page. My secondary.jsp contains h:selectOneMenu components. secondary.jsp file is included in master.jsp, master.jsp has a h:form component and the secondary.jsp don't have h:form component. When I use the h:output text component I'm able to display the value in the UI(I tried it only for testing). Now if I add a h:form into secondary.jsp, values are displayed as expected in h:selectOnemenu component. I guess adding h:form in secondary.jsp is not the write approach and because of this I'm facing other issue in java script. Need guidance to fix this issue. I'm using jsf mojjara 2.0.3 implementation. This scenario is perfectly working in jsf1.1 without adding h:form to secondary.jsp. We are migrating the application from JSF1.1 to JSF2.0.3, using WAS8.5