4

Trying to narrow in on our issue we are upgrading from Jboss 6 EAP (JSF 2.1) to Jboss 7 EAP (JSF 2.2). Our working application now has an issue with OmniFaces ViewScoped beans.

Versions:

  • Mojarra 2.2.14
  • OminFaces 2.6.9
  • PrimeFaces 6.2.5

We have a datatable like this:

<p:dataTable id="tblLegalHolds" widgetVar="tableLegalHolds" var="row"
        rowKey="#{row.id}" filterEvent="enter" 
        lazy="true"
        value="#{bean.lazyDataModel}"
        rows="15">

NOTE: Our bean is OmniFaces ViewScoped and our table is working fine at this point!

Problem: Next we add a column that contains a navigation to a new page like this:

<p:column width="60" exportable="false">
    <p:button value="Open" outcome="legal-hold-edit">
        <f:param name="id" value="#{row.id}" />
    </p:button>
</p:column>

Now our bean is getting loaded and unloaded immediately and if we do a View Source of the HTML we see the Omnifaces script added twice like so...

OmniFaces.Unload.init('f1c1ff81-c87f-4406-b98f-a3eaff977e96');
OmniFaces.Unload.init('45e7de9d-53c7-4426-a972-797c48c46733');

We added @PostConstruct to our ViewScoped beans to prove its getting called twice. Our faces-config.xml looks like this for that Navigation.

<navigation-case>
    <from-outcome>legal-hold-edit</from-outcome>
    <to-view-id>/legal/legal-hold-edit.xhtml</to-view-id>
    <redirect include-view-params="true"/>
</navigation-case>

Now what is interesting is if we remove the "include-view-params" in faces-config.xml like the code below everything starts working fine the ViewScoped bean is created only once and only 1 OmniFaces.Unload.init script is added to the page.

<navigation-case>
    <from-outcome>legal-hold-edit</from-outcome>
    <to-view-id>/legal/legal-hold-edit.xhtml</to-view-id>
    <redirect/>
</navigation-case>

As an added note our outcome page is using o:viewparam to receive the param like this:

    <f:metadata>
        <o:viewParam name="id" value="#{legalHoldForm.legalHold}" required="false" />
        <f:event type="preInvokeAction" listener="#{controller.initializeViewLegalHold}" />
   </f:metadata>

So my questions are:

  1. Why does removing "include-view-params" make it work?
  2. Is this a bug similar to this recent ViewScoped issue? : https://github.com/omnifaces/omnifaces/issues/463
Melloware
  • 7,402
  • 2
  • 26
  • 47

2 Answers2

5

This appears to be a bug in Mojarra. It's indirectly calling the PreDestroyViewMapEvent when figuring out the view parameters for the other view.

During the render response phase, when the URL for an UIOutcomeTarget component (e.g. <p:button>) is to be generated, and includeViewParams is set to true (as defined in your navigation case), then it needs to consult all <f:viewParam> of the target view. In order to achieve this, it will need to build an UIViewRoot instance of it.

However, it actually temporarily sets that new UIViewRoot as the current view root of the faces context in order to access the <f:viewParam>. It will restore the original view, but this is where it goes wrong in Mojarra. It is restoring context.setProcessingEvents(true) too early. It should actually have done it after restoring the original view.

For now, your best bet is to report this issue against Mojarra and avoid using includeViewParams in combination with OmniFaces @ViewScoped.

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
1

Issue reported: https://github.com/eclipse-ee4j/mojarra/issues/4503

PR Provided: https://github.com/eclipse-ee4j/mojarra/pull/4730

This fix will be included in 2.3.15, 3.0.1 and 4.0.0 of Mojarra.

Melloware
  • 7,402
  • 2
  • 26
  • 47