Reputation: 450
We are migrating JSF 1.1 (MyFaces) project to JSF 2. The idea is to migrate periodically by keeping both JSP and XHTML together for some time. We use many ajax4jsf-1.1.1 tags in JSP pages. We don't use RichFaces. After configuring the system to JSF 2 (with all config changes mentioned in tutorial by Balusc) When tried to access the JSP page with ajax4jsf.jar in classpath, we get an exception:
Caused by: java.lang.IllegalStateException: setViewHandler may not be executed after a lifecycle request has been completed
at org.apache.myfaces.application.ApplicationImpl.setViewHandler(ApplicationImpl.java:853)
at org.ajax4jsf.framework.ajax.InitPhaseListener.beforePhase(InitPhaseListener.java:92)
at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersBefore(PhaseListenerManager.java:76)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:131)
It looks ajax4jsf.jar is not compatible with JSF 2. Looks some issue with LifeCycle configuration.
Is there any way we can make a4j work with JSF 2 JSPs? I know when we use XHTML we don't need all this.
Upvotes: 6
Views: 5570
Reputation: 1108722
Get rid of Ajax4jsf 1.x altogether. It's indeed not compatible with JSF2. Instead, JSF2 offers a new main ajax tag <f:ajax>
which covers all the core functionality as previously offered by Ajax4jsf 1.x.
If upgrading to RichFaces 4 is not an option (because, as you said yourself, you aren't using RichFaces components anywhere), then just remove Ajax4jsf 1.x and replace all <a4j:xxx>
tags by standard JSF2 equivalents.
<a4j:ajaxListener>
: use <f:ajax listener>
.<a4j:keepAlive>
: just put managed bean in the view scope by @ViewScoped
.<a4j:log>
: use jsf.ajax.addOnEvent()
or jsf.ajax.addOnError()
in JS context.<a4j:commandLink>
: just nest <f:ajax>
inside <h:commandLink>
.<a4j:outputPanel>
: use <h:panelGroup>
and remember to include its ID in <f:ajax render>
or PrimeFaces <p:outputPanel>
.<a4j:repeat>
: just use standard <ui:repeat>
.<a4j:form>
: just use <h:form>
, it will autorecognize <f:ajax>
.<a4j:htmlCommandLink>
: just nest <f:ajax>
inside <h:commandLink>
.<a4j:jsFunction>
: just use standard <h:commandScript>
. It was however introduced late in JSF 2.3. If you can't upgrade to JSF 2.3 then consider OmniFaces <o:commandScript>
or PrimeFaces <p:remoteCommand>
.<a4j:region>
: just use <f:ajax execute>
, you can even wrap <f:ajax>
around a group of components.<a4j:loadBundle>
: just use standard <f:loadBundle>
.<a4j:status>
: use jsf.ajax.addOnEvent()
or jsf.ajax.addOnError()
in JS context.<a4j:actionparam>
: just use standard <f:param>
.<a4j:loadScript>
: just use standard <h:outputScript>
.<a4j:mediaOutput>
: no replacement. Consider PrimeFaces <p:media>
.<a4j:poll>
: no replacement. Consider OmniFaces <o:commandScript>
or PrimeFaces <p:poll>
.<a4j:commandButton>
: just nest <f:ajax>
inside <h:commandButton>
.<a4j:include>
: just use standard <ui:include>
.<a4j:loadStyle>
: just use standard <h:outputStylesheet>
.<a4j:support>
: just use standard <f:ajax>
.You also need to rename/rewrite JSP files to Facelets files. In simple cases, this is usually just a matter of changing root declarations and file extensions. Facelets makes it easier to replace all duplicated code by a single template. The following answer applies:
Upvotes: 15