RichFaces 3 to RichFaces 4 migration - jsf

I am currently working on a project that I would like to migrate over to RichFaces 4 from version 3.3.3.Final. I was wondering...
is there anything major I should think about or know or think about before migration?
(might be a silly question but...) can you "mix" richfaces 3 with richfaces 4?
One of the main reasons I wanted to make the switch is to use richfaces 4 autocomplete, is there a way to do something like this useing richfaces 3 or would migrating over be the easiest?
I am using JSF.

TLDR: RichFaces reached a richly merited end of life in June 2016. It was a poorly managed catastrophe of a project that deserved no better.
Noting here that the official migration guide is no better than about 30% complete. As a metric on that, I wrote an XSLT stylesheet of 378 lines in 2011 based on the migration guide. I then left the project in abeyance until June 2015 and based on further investigations and getting it working it is already up to 1090 lines. Bearing in mind that any XSLT stylesheet has some overhead, 378/1090 = about 35%.
After you've done what it says in the Migration Guide:
Open the TLD/VLD generated documentation for each component you use in adjacent browser tabs, one for each version, and compare them carefully. There are dozens of undocumented changes in attribute names and purposes, and some attributes have been moved from parent containers to child containers.
There are also important things that have just been arbitrarily removed, such as rich:page and rich:layout.
I'll provide a list of some of the extra things I have discovered at the end of this.
You will then be confronted with the unpleasant realization that they have also changed large numbers of their own style class names, so if you've defined styles for any of those in your own style sheet you have yet more work to do.
You will also discover that their claim that you can define your own style classes and specify them in the rich components to implement your own styles is simply untrue. Your style classes are applied at a containing level but in many cases such as table cells they have seen fit to define fonts etc at the table cell level, where the only way you can override them is by redefining their cells styles by name.
You also have to ensure that your stylesheet is included after the Rich Faces ones. In 3.3 this was automatic, as theirs were included first. Theirs are now included last, so you have to use h:outputStylesheet and do so as late as possible, to ensure it is generated afterwards.
I used an XSLT transform to implement the Migration Guide and accomplish 1-2 above. It presently has over 1000 lines and I have by no means finished yet. Why they couldn't have provided such a thing themselves is a mystery to me.
Why it was deemed necessary to make such major changes between release 3 and 4 is another and deeper mystery. It is a very poorly managed product. I won't be migrating it again, or deploying it anew.
EDIT Undocumented changes I have found (using XPath syntax for brevity):
a4j:status
The documentation is vague on the point, but the for= attribute has been removed: it now operates by default within the nearest parent a4j:region, unless there are tie-ups to specific widgets via the status= attributes. So if you have multiples within the same region they will now all fire.
If you want it to apply to a specific widget via status= you have to change the corresponding a4j:status/#id to an #name attribute.
After you fix all that, it still doesn't work:
An a4j:status with #for (removed) attribute won't stop
with an #name attribute and no #id won't do anything
and with both #name and #id won't stop.
rich:column/#breakBefore now breakRowBefore
rich:page removed.
rich:layout removed.
rich:column/#sortOrder now must be lowercase.
rich:dropDownMenu/#value now rich:dropDownMenu/#label
rich:dropDownMenu/#direction and rich:dropDownMenu/#jointPoint
The values for these have been changed from {top-left, top-right, bottom-left, bottom-right} and {tl, tr, bl, br} respectively to {topLeft, topRight, bottomLeft, bottomRight}.
rich:contextMenu/#submitMode, rich:dropDownMenu/#submitMode, rich:menuItem/#submitMode
These are now all now rich:<whatever>/#mode, and the value "none" needs to be changed to "client".
rich:isUserInRole
This has simply ceased to work, at least for me, with Mojarra 2.2.08 and EL 2.2. Fortunately with EL 2.2 you don't need it any more and can use request.isUserInRole(...).
rich:menuGroup/#value now rich:menuGroup/#label.
rich:tab/#label now rich:tab/#header.
rich:tab/f:facet/#name[.='label'] now rich:tab/f:facet/#name[.='header'].
rich:tabPanel/#activeTabClass, rich:tabPanel/#contentStyle, rich:tabPanel/#disabledTabClass, rich:tabPanel/#inactiveTabClass, rich:tabPanel/#tabClass
Now tabActiveHeaderClass, tabContentClass, tabDisabledHeaderClass, tabHeaderClass, tabInactiveHeaderClass, tabContentClass respectively.
rich:tree/#adviseNodeOpened
This has been removed and rich:treeNode/#expanded added. This is not well documented: it must be an EL, e.g. "#{true}", not "true", and it can be a bean property of the tree node, e.g. "#{node.expanded}", or of any other bean; must be a boolean. (The same is true of the new rich:collapsibleSubTable/#expanded attribute.)
rich:tree/#nodeFace now rich:tree/#nodeType.
rich:tree/#switchType now rich:tree/#toggleType and possibly rich:tree/#selectionType.
rich:tree/#treeNodeVar now var, or possibly just removed.
rich:treeNodesAdaptor
now rich:treeModelAdaptor, and no longer handles arrays, nodesets, ... or anything not a Map or Iterable. It has also lost its var attribute, which as far as I can see breaks it completely for nested use. The only var attribute now available is that of the ancestor rich:tree. So for example if you wanted the parent node and the current child node at the same time, they are simply not available. This change entails either a non-trivial rewrite, or the following kludge.
OLD:
<rich:tree>
<rich:treeNodesAdapter var="vm_host">
<rich:treeNode .../>
<rich:treeNodesAdapter var="vm_guest">
<rich:treeNode .../>
</rich:treeNodesAdapter>
</rich:treeNodesAdapter>
</rich:tree>
NEW:
<rich:tree ... var="node"> <!-- Add a 'var' attribute -->
<rich:treeModelAdapter>
<c:set var="vm_host" value="#{node}"/>
<rich:treeNode .../>
<rich:treeModelAdapter>
<c:set var="vm_guest" value="#{node}"/>
<rich:treeNode .../>
</rich:treeModelAdapter>
</rich:treeModelAdapter>
</rich:tree>
You could also use <ui:param> instead of <c:set>.
The conversion process is made a lot more difficult by RichFaces' refusal to error-check attribute names. You can continue to use the old names, but they just don't work. Silently.

is there anything major I should think about or know or think about before migration?
Their recommendation is to follow their own RichFaces 3.3.x - 4.x Migration Guide — which appears to be far from complete, see EJP's answer below for the real experience.
(might be a silly question but...) can you "mix" richfaces 3 with richfaces 4?
No, you can't. It would conflict with itself.

Related

JSF or Primefaces component

i work on a project where we use JSF + Primefaces
I would like to know if it's preferable to use JSF components as much as possible even if there are sometimes the same components in Primefaces (for basic use)
Using Primefaces only for specific things not available on the JSF version
When should we use Primefaces instead of JSF ?
sorry for any faults
In general, I'd say prefer them than JSF standard components, the reason is simple: CSS skinning. For example, even if h:inputText and p:inputText are exactly the same component, you might want to have the same CSS skinning for all JSF components (specially if you use a premium layout from PF)
But, I think there are few exceptions:
If you use JSF 2.3. For example, I'd rather use h:commandScript than p:remoteCommand. As they're not "visual" components, I'd prefer to use standard components. See also what works better for you ;-)
Also, Oleg presents some performance killer using PF components in datatable, see here http://ovaraksin.blogspot.com/2013/05/jsf-choice-between-legacy-components.html
I think the most important point is consistency, which comes in a couple of flavours.
PrimeFaces (PF) components have a lot of styling put on them (through the theme options). If you use PF components throughout your application, you'll get a consistent style. If you mix PF and JSF components this will look messy.
PF components have a particular way of doing things - organising options, defining ajax calls etc. While it's important to know how the JSF stuff works underneath, using PF components consistently will make your code consistent too.
Finally, in many cases PF components are exact replacements for JSF components, but often with extra features added. There's no reason not to take advantage of them.
Better choose one of them and develop all application using mainly one stack. Will be easy to support, easy update, easy bug fix.
Primefaces at the moment good choose.

How exactly does p:panelGrid extends h:panelGrid

I'm using Primefaces and I know that p:panelGrid extends h:panelGrid as it's clearly stated in the documentation.
However I can't see the exact difference between them. What extra functionalities does p:panelGrid provide? In which cases should I prefer using the Primefaces version over the HTML Basic one?
Although p:panelGrid extends h:panelGrid, it actually lacks many of the attributes that h:panelGrid contains. Which ultimately got me confused.
I can't speak for PrimeFaces' actual intention (I'm no PrimeFaces developer), but based on my observations so far, I can only conclude that they omitted attributes which only invite bad practices in HTML perspective (mainly HTML-deprecated attributes — use CSS instead) or makes no sense otherwise (and are better at its place in a parent or child component). I can only say that it's a Good Thing.
Upon further inspection in the source code I can also confirm that it doesn't technically extend from <h:panelGrid> (HtmlPanelGrid class), but from the UIPanel superclass (which is also used by a.o. <h:panelGroup>). This design decision is most likely done to have more flexibility in the rendered output as shown in the showcase.
Generally, you should only prefer an enhanced component whenever you start to actually need the enhanced/new feature. This usually only happens once you figure out you actually need such one feature and discover that it is missing in the standard component. You'd then usually already know the keywords you're looking for and simply start exploring the component libraries using those keywords if they haven't already implemented it.

Using binding attribute causes javax.faces.FacesException: Cannot find component with identifier

I have a problem I can't quite get a handle on.
First the context: I am developing a web application using Primefaces 3.5 (yes, unfortunately I am stuck with this old version for now), running on JBoss 7.
There is a form with id "form" encompassing all following xhtml code.
I have a component in my view which is provided by usage of the binding attribute:
<p:dashboard id="dashboard" binding="#{myBackingBean.dashboard}" />
Then sometimes I would like to perform an ajax update on this component, this is done by using the RemoteCommand component of primefaces:
<p:remoteCommand
actionListener="#{myBackingBean.someActionListener()}"
process="#this" id="myRmtCmd" oncomplete="myJsFunction();"
update=":form:dashboard" name="myRemoteCommand" />
The RemoteCommand is triggered by a clicking on a Link:
Some Text
This works pretty well so far. However after deploying this code to production I sometimes get a FacesException:
javax.faces.FacesException: Cannot find component with identifier ":form:dashboard"
referenced from "form:myRmtCmd".
This is where my problem lies because I cannot reliably reproduce this exception. My question is this: What could lead to this exception being thrown? It seems to work 95 % of the time but being the perfectionist I am (and many of you reading this are as well, I'm sure ;) ) I would like this code to work 100 % of the time. What am I missing?
Before answering please consider these constraints:
yes, i have to use the binding attribute for providing the dashboard as I need a great deal of control over what gets added to the component
to avoid using IDs I also tried updating the dashboard by its css class via one of primefaces' advanced selectors: #(.ui-dashboard) - this also does not work!
yes, it would be possible to use a commandbutton/link instead of wiring up the remotecommand component to a simple html link but in this case the link is rendered by a JSF renderer component and I made some bad experiences with dynamically adding buttons etc (due to JSF Spec Issue 790)
Cheers,
p.s.
I also had this weird behavior.
There are probably more than one component bindded to #{myBackingBean.dashboard}, so the first one sets the id and there will be no one called "dashboard".

Separation of concerns between Facelets and JSF backing beans

This is such a fundamental MVC question I have a feeling the answer is already on SO and I just can't find it. Please forgive me if it's a dupe.
I am reimplementing a big legacy JSP/servlet app in JSF2/Spring3/Facelets. I think in general we want to leave the presentation formatting to the .xhtml and use the backing bean to make the data suitable for display. This makes for a nice separation of concerns even though I believe both are part of the View. However, the legacy app has an attractive table that contains headings on the left and HTML formatted stuff on the right, like links that pop up a dialog (only one row has this). I decided to put all the content in objects that a datatable iterates through and it worked but I found myself putting sort of ugly HTML (for links and such) in the backing bean, and putting ugly conditions in the datatable (e.g. if this is row 0, then use this CSS class). This works but it doesn't feel right. I've very tightly coupled the backing bean to the presentation, but I can't think of a simple way to get around it. Does anyone have any guidelines around how to handle this? Thanks in advance.
This looks like a valid usecase for a JSF Component. A very good guidance is this book: http://jsfatwork.irian.at/book_de/custom_component.html (Free available online)

JSF Multiple components in grid

I am trying to get the reusable group of jsf 1.2 components inside a panelgrid using Facelet tag file. #Balusc's previous answer at How to make a grid of JSF composite component? was a fabulous resource. I have a couple of followup questions:
In my c:when how do I test for the tagName itself instead of checking for the attributes. Instead of
<c:when test="#{type != 'submit'}">
I want to check tagName itself to decide how to format it. If 'input' do xxx.
2 Is this approach is still valid with jsf 1.2 other than f:ajax? If yes, can I replace with a4j:support...?
In my c:when how do I test for the tagName itself instead of checking for the attributes.
I'm not sure how this question makes sense. It sounds like that you're approaching something not entirely right. Do you maybe have copypasted exactly the same piece of code over multiple tag files? You should not do that. Make it a reuseable <ui:composition> or maybe <ui:decoration> instead which you compose/decorate in every tag file along with a fixed and unique <ui:param> value depending on the taglib file.
Is this approach is still valid with jsf 1.2 other than f:ajax? If yes, can I replace with a4j:support...?
Being able to create tag files is not necessarily specific to JSF, but to the view technology used, which is in this case Facelets. You can even do similar stuff in its predecesor JSP, see also this answer for an example: JSF 1.2 custom component from jsp:include It should work just fine in every JSF version supporting the view technology in question.
As to ajax support, it doesn't matter to the tag file what you're all doing inside the tag file. If you want and can use <a4j:support> then just do it.

Resources