Here\'s the field:
After reading BalusC's comment I am updating this post again.
I created a small demo application and to see the phases and when the conversion and validation occur.
View:
Managed bean:
@ManagedBean
@SessionScoped
public class DemoBean implements Serializable {
private String field;
public DemoBean() {
System.out.println(Thread.currentThread().getStackTrace()[1]);
}
public String getField() {
System.out.println(Thread.currentThread().getStackTrace()[1]);
return field;
}
public void setField(String field) {
System.out.println(Thread.currentThread().getStackTrace()[1]);
this.field = field;
}
public String demoAxn() {
System.out.println(Thread.currentThread().getStackTrace()[1]);
return null;
}
}
Converter:
@FacesConverter(value="demoConverter")
public class DemoConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
System.out.println(Thread.currentThread().getStackTrace()[1]);
return value;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
System.out.println(Thread.currentThread().getStackTrace()[1]);
return (String) value;
}
}
Validator:
@FacesValidator(value="demoValidator")
public class DemoValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
System.out.println(Thread.currentThread().getStackTrace()[1]);
}
}
Phase listener:
public class DemoPhaseListener implements PhaseListener {
@Override
public void afterPhase(PhaseEvent event) {
System.out.println(Thread.currentThread().getStackTrace()[1]);
System.out.println("PhaseId: " + event.getPhaseId() + " ===============================\n\n");
}
@Override
public void beforePhase(PhaseEvent event) {
System.out.println("\n\nPhaseId: " + event.getPhaseId() + " ===============================");
System.out.println(Thread.currentThread().getStackTrace()[1]);
}
@Override
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
}
Registered the phase listener:
pkg.DemoPhaseListener
With that setting when the "Submit" button is clicked, the output is:
INFO: PhaseId: RESTORE_VIEW 1 =============================== INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) INFO: PhaseId: RESTORE_VIEW 1 =============================== INFO: PhaseId: APPLY_REQUEST_VALUES 2 =============================== INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) INFO: PhaseId: APPLY_REQUEST_VALUES 2 =============================== INFO: PhaseId: PROCESS_VALIDATIONS 3 =============================== INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) INFO: pkg.DemoConverter.getAsObject(DemoConverter.java:13) INFO: pkg.DemoValidator.validate(DemoValidator.java:14) INFO: pkg.DemoBean.getField(DemoBean.java:17) INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) INFO: PhaseId: PROCESS_VALIDATIONS 3 =============================== INFO: PhaseId: UPDATE_MODEL_VALUES 4 =============================== INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) INFO: pkg.DemoBean.setField(DemoBean.java:22) INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) INFO: PhaseId: UPDATE_MODEL_VALUES 4 =============================== INFO: PhaseId: INVOKE_APPLICATION 5 =============================== INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) INFO: pkg.DemoBean.demoAxn(DemoBean.java:27) INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) INFO: PhaseId: INVOKE_APPLICATION 5 =============================== INFO: PhaseId: RENDER_RESPONSE 6 =============================== INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) INFO: pkg.DemoBean.getField(DemoBean.java:17) INFO: pkg.DemoConverter.getAsString(DemoConverter.java:20) INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) INFO: PhaseId: RENDER_RESPONSE 6 ===============================
But when make change to throw a NPE in the converter as follows:
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
System.out.println(Thread.currentThread().getStackTrace()[1]);
throw new NullPointerException();
}
the output is:
INFO: PhaseId: RESTORE_VIEW 1 =============================== INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) INFO: PhaseId: RESTORE_VIEW 1 =============================== INFO: PhaseId: APPLY_REQUEST_VALUES 2 =============================== INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) INFO: PhaseId: APPLY_REQUEST_VALUES 2 =============================== INFO: PhaseId: PROCESS_VALIDATIONS 3 =============================== INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) INFO: pkg.DemoConverter.getAsObject(DemoConverter.java:13) INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) INFO: PhaseId: PROCESS_VALIDATIONS 3 =============================== INFO: pkg.DemoBean.getField(DemoBean.java:17)
But the stacktrace is displayed on the resulting view.