I will give some context first before describing the issue I'm experiencing.
The environment is JSF, Primefaces 3.5 and GlassFish 3.1.2.2.
I am working on an application used for editing data. The data is split between several forms, each form being in a tabView's tab. The data model is very rich, and in some cases there are several nested tabViews.
To ease development, the application has one composite component describing a form field. It groups the field's label, input, tooltips and other graphic components. The form contains several of these composite components.
The application has been designed and coded with GlassFish 3 and its supplied Mojarra (version 2.1.6). At first, it extensively used JSTL tags (c:if, c:forEach and c:choose), which are very convenient for building a page's content dynamically, depending on the circumstances.
Therefore, the composite component has many c:if tags to build the field depending on its type (input text, combobox, calendar...). Similarly, the application's most complex screen (which uses 3 nested tabViews) is built using a lot of c:if and c:choose tags.
With Mojarra 2.1.6, the application works as desired. However in the complex screens the application's performance is very poor, due to a bug in older Mojarra versions. We then have decided to upgrade Mojarra to the latest 2.1 version, namely the 2.1.27.
Since the upgrade we experience problems, the most critical being a duplicate ID error during form loading and AJAX updating. The duplicate IDs always involve the composite component's inner components. It seems the composite component is instanciated twice in a row with the same clientId. The partial component tree showing an example follows :
+id: DataDashboard
type: org.primefaces.component.dashboard.Dashboard@58a26f8d
+id: Data_property
type: org.primefaces.component.panel.Panel@1049bf71
+id: j_idt1286
type: javax.faces.component.html.HtmlPanelGrid@59b79c11
+id: j_idt1287
type: javax.faces.component.UINamingContainer@7071dc24
+id: j_id4
type: javax.faces.component.UIPanel@25674e1b
+id: j_idt1288
type: javax.faces.component.html.HtmlPanelGrid@2138e1cc
+id: j_idt1289
type: com.sun.faces.facelets.tag.ui.ComponentRef@1d70291e
+id: j_idt1290
type: <html xmlns="http://www.w3.org/1999/xhtml">
+id: hType <===============
type: javax.faces.component.html.HtmlInputHidden@2e9b7fab
+id: lId
type: javax.faces.component.html.HtmlOutputLabel@54c26622
+id: j_idt1299
type: org.primefaces.component.tooltip.Tooltip@26bf6da7
+id: j_idt1300
type: org.primefaces.component.tooltip.Tooltip@61b802d0
(...)
+id: j_idt3300
type: javax.faces.component.html.HtmlPanelGrid@5a4da336
+id: j_idt3301
type: com.sun.faces.facelets.tag.ui.ComponentRef@1f165c8b
+id: j_idt3302
type: <html xmlns="http://www.w3.org/1999/xhtml">
+id: hType <===============
type: javax.faces.component.html.HtmlInputHidden@7515b99e
After reading articles on this site, such as this one or on BalusC's blog, I have decided to get rid of the JSTL tags, which may be involved in the problem (but I can't be sure); this would be "better" anyway (or is it ?).
So, instead of
<c:if test="#{someCriterion}">
(some stuff)
</c:if>
I externalize (some stuff) in another file called someStuff.xhtml and write
<ui:include src="#{someCriterion ? 'someStuff.xhtml' : ''}" />
The criteria used in the tests are the composite component's attributes, Session Scoped Bean's properties, or derivatives of the aforementioned criteria (functions or ternary operators).
As far as I know, I have converted all JSTL tags using this method, and the application behaves the same as before the conversion. Unfortunately, this includes the duplicate ID error.
I have also tried to replicate the error using a test-case application, unfortunately I haven't managed to do so yet. It seems that simple applications work.
I'm quite lost as how to solve this issue. Any help would be appreciated.
Many thanks.
EDIT : added a partial component tree.