Details
-
Type: Bug
-
Status: Closed
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: EE-3.0.0.BETA
-
Fix Version/s: EE-3.0.0.GA
-
Component/s: Samples
-
Labels:None
-
Environment:ICEfaces EE MyFaces
-
Affects:Documentation (User Guide, Ref. Guide, etc.), Sample App./Tutorial, Compatibility/Configuration
Description
Activity
- All
- Comments
- History
- Activity
- Remote Attachments
- Subversion
1) Missing the relevant MyFaces context parameters to make various things work.
Need to add the following to the web.xml of the example. We've done this for other examples to handle various behaviour difficulties. This allow us to use dynamic includes as well as allows for slashes in resource library names:
<context-param>
<param-name>org.apache.myfaces.REFRESH_TRANSIENT_BUILD_ON_PSS</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.REFRESH_TRANSIENT_BUILD_ON_PSS_PRESERVE_STATE</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME</param-name>
<param-value>true</param-value>
</context-param>
2) The strategy of utilizing ui:param entries to reduce EL lookups for the dynamic bindings of ui:include and ui:template paths. For example in showcase.xhtml:
<!-- current content reference, avoids multiple lookups-->
<ui:param name="currentContentDescriptor"
value="#
"/>
<ui:decorate
template="#
">
In the files where we do this, removing the ui:param and switching the binding to the full declaration solves the problem:
<ui:decorate
template="#
">
I was able to successfully use the ui:param technique in a simple testcase with MyFaces and a composite component so it's not that the strategy isn't supported at all. But I was unable to determine the specific reason for the failure in the EE showcase. It may be possible to go back to the ui:param strategy at a later date.
3) The mechanism used to detect required attributes. For example:
<ice-cc:_requiredAttributes comp="dualList" attrs="id,bean">
Once 1) and 2) had been resolved, there were some components that would work but many others that didn't (they wouldn't even render). So for example Slider worked but Dual List didn't. Turns out that the components that weren't working all had the above tag handler wrapped around them. We have a "homemade" recipe for detecting required attributes in the composite components that uses this tag handler. Patrick had originally recommended commenting out the body of the tag handler in _requiredAttributes.xhtml but that didn't seem to solve the issue. What did help was removing the tag handler altogether from those components using it. After that, the components that I tried did work (Dual List, State/Province Selector).
This is likely more of a good data point than an actual solution to the problem.
Created IPCK-357 for the requiredAttributes issue.
I propose that we simply remove the <ice-cc:requiredAttributes> tags from the components in order to move forward with MyFaces compatibility.
The <ui:param> strategy for caching EL results can also just be removed.
Other issues that have been identified during work on this case:
6) Use of restricted symbols. The two tree examples will fail with MyFaces due to the following:
<ice:outputText value="#
{row.data}"
rendered="#
"/>
Since "class" is protected, this will cause a problem with strict checking that is done with MyFaces and it's associated EL implementation. You can turn the checking off by setting a system property (not a context parameter) as per http://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html. By setting org.apache.el.parser.SKIP_IDENTIFIER_CHECK=false, the checking is disabled. However, that's just a workaround and we should remove our use of the word class.
7) It appears that annotated beans in the composite component .jar file may not always be processed correctly. For example the DialogState class may not be getting properly initialized as a @ViewScoped @ManagedBean. Need to verify if this is the case and the cause.
Dialog Example error:
Feb 27, 2012 6:34:57 PM org.apache.myfaces.renderkit.ServerSideStateCacheImpl serializeView
SEVERE: Exiting serializeView - Could not serialize state: com.icesoft.faces.facelets.example.dialog.DialogExampleBean$2
java.io.NotSerializableException: com.icesoft.faces.facelets.example.dialog.DialogExampleBean$2
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at java.util.HashMap.writeObject(HashMap.java:1001)
at sun.reflect.GeneratedMethodAccessor111.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at java.util.HashMap.writeObject(HashMap.java:1001)
at sun.reflect.GeneratedMethodAccessor111.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.serializeView(ServerSideStateCacheImpl.java:390)
at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.saveSerializedViewInServletSession(ServerSideStateCacheImpl.java:240)
at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.saveSerializedView(ServerSideStateCacheImpl.java:872)
at org.apache.myfaces.renderkit.html.HtmlResponseStateManager.getViewState(HtmlResponseStateManager.java:307)
at javax.faces.application.StateManager.getViewState(StateManager.java:253)
at org.icefaces.impl.context.DOMPartialViewContext.renderState(DOMPartialViewContext.java:519)
at org.icefaces.impl.context.DOMPartialViewContext.processPartial(DOMPartialViewContext.java:222)
at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:402)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:755)
at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1900)
at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:285)
at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:115)
at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:241)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:199)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:304)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
The above issue is like due to the following members of com.icesoft.faces.facelets.component.dialog.Dialog:
protected Command yesCommand;
protected Command okCommand;
protected Command noCommand;
protected Command cancelCommand;
The Dialog example bean is scoped to View and they set the Commands but the instances of Command are not serializable - another victory for anonymous inner classes
Command yesCommand = new Command() {
public void execute()
};
Command noCommand = new Command() {
public void execute()
};
I don't see the warning message (problem #5) any more so it looks like the latest changes might have solved that. However, clicking the top-level folder links still doesn't open/collapse the panels (problem #4). I can see the request sent and the updates coming back but they are pretty much empty - just the ViewState.
To help clarify I'm attaching a screenshot (ee-composite-nav-links-comparison.png) of two Safari windows both running EE Composite Showcase. MyFaces version is on the left and Mojarra is on the right. When the link is clicked, it looks like 2 requests are sent sequentially and the second one actually submits the changed value for rendering out the collapsed panel. At least it does for Mojarra, and with MyFaces it doesn't send anything, which would explain the lack of a meaningful DOM diff update.
So here's an interesting behaviour. If you look at the rendered output for the headers of the collapsible panels you see the following (edited to only show the relevant stuff):
<div class="icePnlClpsblColpsdHdr navPnlClpsblColpsdHdr" id="navfrm:navRpt:1:navPcollapsehdr" onclick="document.forms['navfrm']['navfrm:navRpt:1:navPcollapseExpanded'].value='false'; iceSubmit(document.forms['navfrm'],this,event);document.forms['navfrm']['navfrm:navRpt:1:navPcollapseExpanded'].value=''; return false;">
<div ...>
<a ...></a>
<div ...>
<a class="iceCmdLnk navNodeLink" href="javascript:;" id="navfrm:navRpt:1:navComplnk" onblur="setFocus('');" onclick="var form=formOf(this);form['navfrm:j_idcl'].value='navfrm:navRpt:1:navComplnk';form['nodeId'].value='dataTableCompositionComponentsNode';iceSubmit(form,this,event);ice.onAfterUpdate(function()
{form['navfrm:j_idcl'].value='';form['nodeId'].value='';});return false;" onfocus="setFocus(this.id);">Table Components</a>
</div>
</div>
</div>
So there's a top-level <div> that has an onclick handler that sets the value for the hidden field:
document.forms['navfrm']['navfrm:navRpt:1:navPcollapseExpanded'].value='false';
And then there's the anchor itself which does the normal form submission. Turns out that if you click on the <div> but not the anchor, the panel works properly. If you click on the anchor text, it doesn't work because the onclick from the <div> doesn't appear to get called and therefor the value for the hidden field is not set.
Fixed issue with Dialog: 30603 2/27/12 5:27 PM 1 philip.breau IPCK-356 - Dialog throws non-serializable exception
So one way to "fix" the problem with the commandLinks is not to use them. Since clicking on the collapsiblePanel header facet is doing the job anyway, I just replaced the commandLinks with outputText and let the panel header do it's thing:
Index: samples/ee-composite-showcase/src/main/webapp/WEB-INF/includes/content/navigation.xhtml
===================================================================
— samples/ee-composite-showcase/src/main/webapp/WEB-INF/includes/content/navigation.xhtml (revision 30599)
+++ samples/ee-composite-showcase/src/main/webapp/WEB-INF/includes/content/navigation.xhtml (revision )
@@ -33,13 +33,12 @@
<f:facet name="header">
<ice:panelGroup id="navPgrp">
- <ice:commandLink id="navComplnk"
- actionListener="#
{applicationController.navigationEvent}
"
- styleClass="navNodeLink"
- value="#
{msgs[nodeLevel1.label]}">
+ <h:outputText id="navComplnk"
+ value="#{msgs[nodeLevel1.label]}"
{nodeLevel1.id}
+ styleClass="navNodeLink">
<f:param name="nodeId"
value="#"/>
- </ice:commandLink>
+ </h:outputText>
</ice:panelGroup>
</f:facet>
The styling is a bit off but you can reliably open and close the panels this way.
CommandLink nested in the PanelCollapsible has been removed. Showcase now works ok on MyFaces.
So the main issues that are holding up the proper operation of the EE showcase with MyFaces are:
1) Missing the relevant MyFaces context parameters to make various things work.
2) The strategy of utilizing ui:param entries to reduce EL lookups for the dynamic bindings of ui:include and ui:template paths. For example in showcase.xhtml:
<!-- current content reference, avoids multiple lookups-->
{applicationController.currentContextDescriptor}<ui:param name="currentContentDescriptor"
value="#
"/>
<ui:decorate
{currentContentDescriptor.templateRef.path}template="#
">
3) The mechanism used to detect required attributes. For example:
<ice-cc:_requiredAttributes comp="dualList" attrs="id,bean">
4) Clicking on the menu navigation links dropping down the submenu of selections.
5) The following is logged relatively consistently when running the EE Showcase with MyFaces:
22-Feb-2012 11:39:43 AM org.icefaces.impl.event.BridgeSetup addMandatoryResources
WARNING: When processing mandatory resource components, could not create instance of 'com.icesoft.faces.facelets.component.ResourceLoadingComponent'