Same Same But Different: Migrating From RichFaces 4 to PrimeFaces 3

from on 03.09.2013
1

migration.jpgJSF has become the standard of Java Enterprise web development. Many projects not only rely on the JSF core implementation, but also make use of so called extension frameworks, which offer more elaborated components like sortable tables, advanced Ajax features and GUI Themes for styling and Look&Feel. PrimeFaces has been becoming more and more popular as JSF Extension Framework during the last few years.  For one of our customers it was decided, that an existing RichFaces 4 application needed to be migrated from RichFaces 4 to PrimeFaces 3. A comparison of different JSF2 extension frameworks is out of scope of this article, I focus on describing the most important aspects to consider for such a migration and the lessons learned.

The increasing popularity of PrimeFaces can also be observed on Google Trends:

PrimeFaces, RichFaces, ICEFaces Trends

PrimeFaces, RichFaces, ICEFaces Trends

Libraries and Configuration

PrimeFaces comes packaged as a one JAR distribution with no required dependencies. I just removed all the RichFaces and dependent libraries and added the PrimeFaces one. Both frameworks don’t need any additional configuration in the web.xml descriptor.

Remove:

  • richfaces-core-api.jar
  • richfaces-core-impl.jar
  • richfaces-components-api.jar
  • richfaces-components-ui.jar

And add:

  • primefaces.jar

Theming and skinning in RichFaces is defined in web.xml like this:

<context-param>
					<param-name>org.richfaces.skin</param-name>
					<param-value>skin_name</param-value>
				</context-param>

It can be replaced by the PrimeFaces equivalent after the desired theme-JAR has been downloaded and added as dependency:

<context-param>
					<param-name>primefaces.THEME</param-name>
					<param-value>theme_name</param-value>
				</context-param>

Replacing Components in XHTML

As a next step, I replaced all the namespace definitions from RichFaces in all of the Facelet source files to the PrimeFaces namespace. RichFaces is separated into page centric Ajax controls (a4j) and the self-contained components (rich):

xmlns:a4j="http://richfaces.org/a4j"
				xmlns:rich="http://richfaces.org/rich

PrimeFaces only knows one namespace:

xmlns:p="http://primefaces.org/ui

After replacing the namespace definitions, the real work begins. All RichFaces tags need to be replaced by the corresponding PrimeFaces tags. Luckily, a lot of these tags correspond almost one to one, so there is for example a rich:calendar and a p:calendar.

The next step is to change the tag attributes, which often are named differently.  A good source for information is the PrimeFaces User Guide, where all available components and their attributes are described in detail:

http://primefaces.org/documentation.html

Not so obvious differences

Some differences between RichFaces and PrimeFaces are not so obvious at one quick glance.

Ajax Tag Attributes

All Ajax-enabled components in RichFaces have attributes to control rendering and execution of partial requests, so for example the following code snippet defines an action button which only submits the fields with the given ID to the backing bean and renders only a given sub-region after the action has been executed:

<a4j:commandButton render=”regionId” execute=”fieldId”/>

Unfortunately, PrimeFaces does not use the JSF2 default names for these two attributes, so the same piece of code becomes:

<p:commandButton update=”regionId” process=”fieldId”/>

Javascript function for JSF Ajax calls

In RichFaces, there is a tag a4j:jsFunction, which allows to perform Ajax requests directly from JavaScript code, invoke server-side data and return it in a JSON format to use in a client JavaScript calls. It allows binding an action or action listener method, and offers re-render capability like any other Ajax component. The Corresponding tag in PrimeFaces is called p:remoteCommand and offers the same functionality despite some different attribute names.

Working with components via Javascript

Both PrimeFaces and RichFaces offer a JavaScript interface to their JSF components.  Like this it is possible to get an object from a component to call a JavaScript function on it.

RichFaces offers the function rich:component(‘id’) to get the javascript object for the RichFaces component with the given ID:

<h:outputLink value="#" 
				  onclick="#{rich:component('popup')}.hide(); return false;">
				    FOO
				</h:outputLink>
				
				<rich:popup id=”popup”>…</rich:popup>

Where popup is the id of a rich:popup component in the same view or subview.

PrimeFaces chose another way of exposing the JavaScript object of a component by defining it in the widgetVar tag attribute:

<h:outputLink value="#" 
				  onclick=”myDialog.hide(); return false;">
				    FOO
				</h:outputLink>
				
				<p:dialog id=”basicDialog” widgetVar=”myDialog”>…</p:dialog>

Using the Client ID of a component

In JSF, client-IDs are the uniquely generated IDs for HTML elements. This ID is often used when we need to reference an element with JavaScript like for example with jQuery.

In RichFaces there is the rich:clientId(‘id’) function whereas PrimeFaces defines the p:component(‘id’) function to achieve this (don’t confuse this with the rich:component function!):

<h:button id="myButton" value="Sample" />

RichFaces:

<h:outputText 
				  value="RichFaces: client ID : #{rich:clientId(myButton)}" />

PrimeFaces:

<h:outputText 
				  value="PrimeFaces: client ID : #{p:component(myButton)}" />

When working with jQuery, you must notice that the default JSF ID separator colon  (‘:’) must be escaped because it is a reserved jQuery selector term:

$(‘#form:part:myInput’)

must be written as

$(‘#form\\:part\\:myInput’)

PrimeFaces offers the handy PrimeFaces.escapeClientId(clientId) function to escape the client ID:

$(PrimeFaces.escapeClientId(‘#form:part:myInput’))

Referencing components by IDs

When we migrated from RichFaces to PrimeFaces, many components referenced by ID in update or process attributes were not found anymore. This is due to a different component finding algorithm which must be taken into account:

PrimeFaces uses the standard JSF algorithm as provided by UIComponent#findComponent()  (http://docs.oracle.com/javaee/6/api/javax/faces/component/UIComponent.html#findComponent%28java.lang.String%29) to find components by a given client ID.

RichFaces uses the same algorithm but with additional enhancements, where relative component IDs are not only searched in in closest parent container, but in the whole same view. This means, that a migration from RichFaces to PrimeFaces may initially lead to a lot of exceptions complaining that some component IDs have not been found. These ID references must be adapted to match the standard algorithm.

Summary

The migration from RichFaces to PrimeFaces is not a very complicated task. The more AJAX-related features are present in your web application, the more special cases may occur which need some time to be solved. We accomplished the migration of a small web app with four screens in one week for one person. Do you have some experience with migrating to PrimeFaces which you would like to share with us? Do not hesitate to contact us!

Write a comment

Your e-mail address will not be published or shared with third parties. Fields marked with * are required.

One comment for “Same Same But Different: Migrating From RichFaces 4 to PrimeFaces 3

  1. Vladimir D.

    We have migrated RF 4.3 with 500 pages in 2 months in 2 people. We have modified the basic PF components like table, column, tab to be compatible with RF components meanwhile we created custom faceles tags which wrapped the PF/RF components. There is a condition in the tag which framework should be used, so at some time it was possible to switch application from RF to PF or back (by some checkbox) online. As an final step we remove all RF-specific stuff.